Squashed 'third_party/boostorg/move/' content from commit d503fbe

Change-Id: I5f8ac37161a1044b02ffb1f59cf15622fc6acd17
git-subtree-dir: third_party/boostorg/move
git-subtree-split: d503fbe1c8334fa8885e67cb83c96aeaf3938555
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..9915256
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,164 @@
+# Copyright 2016 Peter Dimov
+# Copyright 2017, 2018 James E. King III
+# 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)
+
+#
+# Generic Travis CI build script for boostorg repositories
+#
+# Instructions for customizing this script for your library:
+# 
+# 1. Customize the compilers and language levels you want.
+# 2. If you have move than include/, src/, test/, example/, examples/,
+#    benchmark/ or tools/ directories, set the environment variable DEPINST.
+#    For example if your build uses code in "bench/" and "fog/" directories:
+#        - DEPINST="--include bench --include fog"
+# 3. If you want to enable Coverity Scan, you need to provide the environment
+#    variables COVERITY_SCAN_TOKEN and COVERITY_SCAN_NOTIFICATION_EMAIL in
+#    your github settings.
+# 4. Enable pull request builds in your boostorg/<library> account.
+# 5. The default language level is C++03, you can change CXXSTD to modify it.
+#
+# That's it - the scripts will do everything else for you.
+#
+
+sudo: false
+dist: trusty
+language: cpp
+
+env:
+  global:
+  # see: http://www.boost.org/build/doc/html/bbv2/overview/invocation.html#bbv2.overview.invocation.properties
+  # to use the default for a given environment, comment it out; recommend you build debug and release however..
+  # - B2_ADDRESS_MODEL=address-model=64,32
+  # - B2_LINK=link=shared,static
+  # - B2_THREADING=threading=multi,single
+    - B2_VARIANT=variant=release,debug
+  # - CXXSTD=03
+  # - DEPINST="--include other"
+
+install:
+  - git clone https://github.com/jeking3/boost-ci.git boost-ci
+  - cp -pr boost-ci/ci boost-ci/.codecov.yml .
+  - source ci/travis/install.sh
+
+addons:
+  apt:
+    packages:
+      - binutils-gold
+      - gdb
+      - libc6-dbg
+        
+branches:
+  only:
+    - develop
+    - master
+    
+script:
+  - cd $BOOST_ROOT/libs/$SELF
+  - ci/travis/build.sh
+
+jobs:
+  include:
+    #################### Jobs to run on every pull request ####################
+    - os: linux
+      env: 
+        - COMMENT="C++03"
+        - TOOLSET=gcc,gcc-7,clang
+      addons:
+        apt:
+          packages:
+            - g++-7
+          sources:
+            - ubuntu-toolchain-r-test
+    - os: linux
+      env: 
+        - COMMENT="C++11"
+        - TOOLSET=gcc,gcc-7,clang
+        - CXXSTD=11
+      addons:
+        apt:
+          packages:
+            - g++-7
+          sources:
+            - ubuntu-toolchain-r-test
+    - os: linux
+      env: 
+        - COMMENT=valgrind
+        - TOOLSET=clang 
+        - B2_VARIANT=variant=debug
+        - TESTFLAGS=testing.launcher=valgrind
+        - VALGRIND_OPTS=--error-exitcode=1
+      addons:
+        apt:
+          packages:
+            - clang-5.0
+            - libstdc++-7-dev
+            - valgrind
+          sources:
+            - llvm-toolchain-trusty-5.0
+            - ubuntu-toolchain-r-test
+
+    - os: linux
+      env:
+        - COMMENT=cppcheck
+      script:
+        - cd $BOOST_ROOT/libs/$SELF
+        - ci/travis/cppcheck.sh
+
+    - os: linux
+      env:
+        - COMMENT=UBSAN
+        - B2_VARIANT=variant=debug
+        - TOOLSET=gcc-7
+        - CXXFLAGS="cxxflags=-fno-omit-frame-pointer cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined"
+        - LINKFLAGS="linkflags=-fsanitize=undefined linkflags=-fno-sanitize-recover=undefined linkflags=-fuse-ld=gold"
+        - UBSAN_OPTIONS=print_stacktrace=1
+      addons:
+        apt:
+          packages:
+            - g++-7
+          sources:
+            - ubuntu-toolchain-r-test
+
+    - os: linux
+      env: 
+        - COMMENT=CodeCov
+        - TOOLSET=gcc-7
+      addons:
+        apt:
+          packages:
+            - gcc-7
+            - g++-7
+          sources:
+            - ubuntu-toolchain-r-test
+      script:
+        - pushd /tmp && git clone https://github.com/linux-test-project/lcov.git && export PATH=/tmp/lcov/bin:$PATH && which lcov && lcov --version && popd
+        - cd $BOOST_ROOT/libs/$SELF
+        - ci/travis/codecov.sh
+
+  # does not work with sourced install shell yet: see 
+  # https://travis-ci.org/jeking3/tokenizer/jobs/384903189
+  # for a typical failure
+  # - os: osx
+  #   osx_image: xcode9
+  #   env:
+  #     - TOOLSET=clang
+  #     - CXXSTD=03,11
+
+    #################### Jobs to run on pushes to master, develop ###################
+
+    # Coverity Scan
+    - os: linux
+      if: (env(COVERITY_SCAN_NOTIFICATION_EMAIL) IS present) AND (branch IN (develop, master)) AND (type IN (cron, push))
+      env:
+        - COMMENT="Coverity Scan"
+        - TOOLSET=gcc
+      script:
+        - cd $BOOST_ROOT/libs/$SELF
+        - ci/travis/coverity.sh
+
+notifications:
+  email:
+    false
+
diff --git a/Jamfile b/Jamfile
new file mode 100644
index 0000000..6d861a9
--- /dev/null
+++ b/Jamfile
@@ -0,0 +1,11 @@
+#  Boost.Move Library Jamfile
+#
+#  Copyright (c) 2018 James E. King III
+#
+#  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)
+
+# please order by name to ease maintenance
+build-project example ;
+build-project test ;
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..36b7cd9
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,23 @@
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..22f854c
--- /dev/null
+++ b/README.md
@@ -0,0 +1,35 @@
+Move, part of collection of the [Boost C++ Libraries](http://github.com/boostorg), provides C++0x move semantics in C++03 compilers and allows writing portable code that works optimally in C++03 and C++0x compilers.
+
+### License
+
+Distributed under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt).
+
+### Properties
+
+* C++03
+* Header-Only
+
+### Build Status
+
+Branch          | Travis | Appveyor | Coverity Scan | codecov.io | Deps | Docs | Tests |
+:-------------: | ------ | -------- | ------------- | ---------- | ---- | ---- | ----- |
+[`master`](https://github.com/boostorg/move/tree/master) | [![Build Status](https://travis-ci.org/boostorg/move.svg?branch=master)](https://travis-ci.org/boostorg/move) | [![Build status](https://ci.appveyor.com/api/projects/status/9ckrveolxsonxfnb/branch/master?svg=true)](https://ci.appveyor.com/project/jeking3/move-0k1xg/branch/master) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/16048/badge.svg)](https://scan.coverity.com/projects/boostorg-move) | [![codecov](https://codecov.io/gh/boostorg/move/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/move/branch/master)| [![Deps](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/move.html) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](http://www.boost.org/doc/libs/master/doc/html/move.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](http://www.boost.org/development/tests/master/developer/move.html)
+[`develop`](https://github.com/boostorg/move/tree/develop) | [![Build Status](https://travis-ci.org/boostorg/move.svg?branch=develop)](https://travis-ci.org/boostorg/move) | [![Build status](https://ci.appveyor.com/api/projects/status/9ckrveolxsonxfnb/branch/develop?svg=true)](https://ci.appveyor.com/project/jeking3/move-0k1xg/branch/develop) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/16048/badge.svg)](https://scan.coverity.com/projects/boostorg-move) | [![codecov](https://codecov.io/gh/boostorg/move/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/move/branch/develop) | [![Deps](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/move.html) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](http://www.boost.org/doc/libs/develop/doc/html/move.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](http://www.boost.org/development/tests/develop/developer/move.html)
+
+### Directories
+
+| Name        | Purpose                        |
+| ----------- | ------------------------------ |
+| `doc`       | documentation                  |
+| `example`   | examples                       |
+| `include`   | headers                        |
+| `proj`      | ide projects                   |
+| `test`      | unit tests                     |
+
+### More information
+
+* [Ask questions](http://stackoverflow.com/questions/ask?tags=c%2B%2B,boost,boost-move)
+* [Report bugs](https://github.com/boostorg/move/issues): Be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well.
+* Submit your patches as pull requests against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt).
+* Discussions about the library are held on the [Boost developers mailing list](http://www.boost.org/community/groups.html#main). Be sure to read the [discussion policy](http://www.boost.org/community/policy.html) before posting and add the `[move]` tag at the beginning of the subject line.
+
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000..e10b9e0
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,98 @@
+# Copyright 2016, 2017 Peter Dimov
+# Copyright (C) 2017, 2018 James E. King III
+# 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)
+
+#
+# Generic Appveyor build script for boostorg repositories
+#
+# Instructions for customizing this script for your library:
+#
+# 1. Customize the compilers and language levels you want.
+# 2. If you have move than include/, src/, test/, example/, examples/,
+#    benchmark/ or tools/ directories, set the environment variable DEPINST.
+#    For example if your build uses code in "bench/" and "fog/" directories:
+#        - DEPINST: --include bench --include fog
+# 3. Enable pull request builds in your boostorg/<library> account.
+# 4. The default language level is C++03, you can change CXXSTD to modify it.
+#
+# That's it - the scripts will do everything else for you.
+#
+
+version: 1.0.{build}-{branch}
+
+shallow_clone: true
+
+branches:
+  only:
+    - develop
+    - master
+
+matrix:
+  allow_failures:
+    - MAYFAIL: true
+
+environment:
+  global:
+    # see: http://www.boost.org/build/doc/html/bbv2/overview/invocation.html#bbv2.overview.invocation.properties
+    # to use the default for a given environment, comment it out; recommend you build debug and release however..
+    # on Windows it is important to exercise all the possibilities, especially shared vs static
+    # B2_ADDRESS_MODEL: address-model=64,32
+    # B2_LINK: link=shared,static
+    # B2_THREADING: threading=multi,single
+    B2_VARIANT: variant=release,debug
+    CXXSTD: 03
+    # DEPINST: --include otherdir
+
+  matrix:
+    - FLAVOR: Visual Studio 2017
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+      TOOLSET: msvc-14.1
+      B2_ADDRESS_MODEL: address-model=64,32
+    - FLAVOR: Visual Studio 2015
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+      TOOLSET: msvc-14.0
+      B2_ADDRESS_MODEL: address-model=64,32
+    - FLAVOR: Visual Studio 2010, 2012, 2013
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
+      TOOLSET: msvc-10.0,msvc-11.0,msvc-12.0
+    - FLAVOR: cygwin (32-bit)
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+      ADDPATH: C:\cygwin\bin;
+      B2_ADDRESS_MODEL: address-model=32
+      # https://github.com/boostorg/test/issues/144
+      DEFINES: define=_POSIX_C_SOURCE=200112L
+      THREADING: threadapi=pthread
+      TOOLSET: gcc
+    - FLAVOR: cygwin (64-bit)
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+      ADDPATH: C:\cygwin64\bin;
+      B2_ADDRESS_MODEL: address-model=64
+      # https://github.com/boostorg/test/issues/144
+      DEFINES: define=_POSIX_C_SOURCE=200112L
+      THREADING: threadapi=pthread
+      TOOLSET: gcc
+    - FLAVOR:  mingw32
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+      ARCH:    i686
+      B2_ADDRESS_MODEL: address-model=32
+      SCRIPT:  ci\appveyor\mingw.bat
+    - FLAVOR:  mingw64
+      APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+      ARCH:    x86_64
+      B2_ADDRESS_MODEL: address-model=64
+      SCRIPT:  ci\appveyor\mingw.bat
+
+install:
+  - set SELF=%APPVEYOR_PROJECT_NAME:-=_%
+  - git clone https://github.com/jeking3/boost-ci.git C:\boost-ci
+  - xcopy /s /e /q /i C:\boost-ci\ci .\ci
+  - ci\appveyor\install.bat
+
+build: off
+
+test_script:
+  - set SELF=%APPVEYOR_PROJECT_NAME:-=_%
+  - PATH=%ADDPATH%%PATH%
+  - IF DEFINED SCRIPT (call libs\%SELF%\%SCRIPT%) ELSE (b2 libs/%SELF% toolset=%TOOLSET% cxxstd=%CXXSTD% %CXXFLAGS% %DEFINES% %THREADING% %B2_ADDRESS_MODEL% %B2_LINK% %B2_THREADING% %B2_VARIANT% -j3)
+
diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2
new file mode 100644
index 0000000..d8262d3
--- /dev/null
+++ b/doc/Jamfile.v2
@@ -0,0 +1,59 @@
+#  Boost.Move library documentation Jamfile
+#
+#  Copyright Ion Gaztanaga 2009. 
+#  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)
+#
+# See http://www.boost.org/libs/move for documentation.
+
+
+import doxygen ;
+import quickbook ;
+
+doxygen autodoc
+   :
+      [ glob ../../../boost/move/*.hpp ]
+      [ glob ../../../boost/move/algo/*.hpp ]
+   :
+   <doxygen:param>HIDE_UNDOC_MEMBERS=YES
+   <doxygen:param>HIDE_UNDOC_MEMBERS=YES
+   <doxygen:param>HIDE_UNDOC_CLASSES=YES
+   <doxygen:param>EXTRACT_PRIVATE=NO
+   <doxygen:param>ENABLE_PREPROCESSING=YES
+   <doxygen:param>MACRO_EXPANSION=YES
+   <doxygen:param>"PREDEFINED=\"BOOST_MOVE_DOXYGEN_INVOKED\" \\
+                              \"BOOST_MOVE_SEEDOC(T)=see_documentation\" \\
+                              \"BOOST_RV_REF(T)=T&&\" \\
+                              \"BOOST_RV_REF_BEG=\" \\
+                              \"BOOST_RV_REF_END=&&\" \\
+                              \"BOOST_FWD_REF(T)=T&&\" \\
+                              \"BOOST_MOVE_DOC0PTR(T)=std::nullptr_t\" \\
+                              \"BOOST_MOVE_DOC1ST(T1, T2)=T1\" \\
+                              \"BOOST_MOVE_DOCIGN(T1) \"\\
+                              \"BOOST_MOVE_FORCEINLINE=inline\" \\
+                  "
+   ;
+
+xml move : move.qbk ;
+
+boostbook standalone
+   :
+      move
+   :
+        <format>html:<xsl:param>boost.root=../../../..
+        <format>html:<xsl:param>boost.libraries=../../../../libs/libraries.htm
+        <xsl:param>generate.section.toc.level=3
+        <xsl:param>chunk.first.sections=1
+        <dependency>autodoc
+   ;
+
+###############################################################################
+alias boostdoc
+    : move
+    :
+    : <dependency>autodoc
+    : ;
+explicit boostdoc ;
+alias boostrelease ;
+explicit boostrelease ;
diff --git a/doc/move.qbk b/doc/move.qbk
new file mode 100644
index 0000000..697e9b6
--- /dev/null
+++ b/doc/move.qbk
@@ -0,0 +1,944 @@
+[/
+ / Copyright (c) 2008-2010 Ion Gaztanaga
+ /
+ / 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)
+ /]
+[library Boost.Move
+    [quickbook 1.5]
+    [authors [Gaztanaga, Ion]]
+    [copyright 2008-2014 Ion Gaztanaga]
+    [id move]
+    [dirname move]
+    [purpose Move semantics]
+    [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])
+    ]
+]
+
+[important To be able to use containers of movable-only  values you will need to use containers
+supporting move semantics, like [*Boost.Container] containers]
+
+[note Tested compilers: MSVC-7.1, 8.0, 9.0, GCC 4.3-MinGW in C++03 and C++0x modes, Intel 10.1]
+
+[section:what_is_boost_move What is Boost.Move?]
+
+Rvalue references are a major C++0x feature, enabling move semantics for C++ values. However, we
+don't need C++0x compilers to take advantage of move semanatics. [*Boost.Move] emulates C++0x
+move semantics in C++03 compilers and allows writing portable code that works optimally in C++03 
+and C++0x compilers.
+
+[endsect]
+
+[section:introduction Introduction]
+
+[note
+
+  The first 3 chapters are the adapted from the article
+ [@http://www.artima.com/cppsource/rvalue.html ['A Brief Introduction to Rvalue References]]
+ by Howard E. Hinnant, Bjarne Stroustrup, and Bronek Kozicki
+
+]
+
+Copying can be expensive. For example, for vectors `v2=v1` typically involves a function call,
+a memory allocation, and a loop. This is of course acceptable where we actually need two copies of
+a vector, but in many cases, we don't: We often copy a `vector` from one place to another, just to
+proceed to overwrite the old copy. Consider: 
+
+[c++]
+
+   template <class T> void swap(T& a, T& b)
+   {
+      T tmp(a);   // now we have two copies of a
+      a = b;      // now we have two copies of b
+      b = tmp;    // now we have two copies of tmp (aka a)
+   }
+
+But, we didn't want to have any copies of a or b, we just wanted to swap them. Let's try again: 
+
+[c++]
+
+   template <class T> void swap(T& a, T& b)
+   {
+      T tmp(::boost::move(a));
+      a = ::boost::move(b);   
+      b = ::boost::move(tmp);
+   }
+
+This `move()` gives its target the value of its argument, but is not obliged to preserve the value
+of its source. So, for a `vector`, `move()` could reasonably be expected to leave its argument as
+a zero-capacity vector to avoid having to copy all the elements. In other words, [*move is a potentially
+destructive copy].
+
+In this particular case, we could have optimized swap by a specialization. However, we can't
+specialize every function that copies a large object just before it deletes or overwrites it. That
+would be unmanageable. 
+
+In C++0x, move semantics are implemented with the introduction of rvalue references. They allow us to
+implement `move()` without verbosity or runtime overhead. [*Boost.Move] is a library that offers tools
+to implement those move semantics not only in compilers with `rvalue references` but also in compilers
+conforming to C++03.
+
+[endsect]
+
+[section:implementing_movable_classes Implementing copyable and movable classes]
+
+[import ../example/doc_clone_ptr.cpp]
+
+[section:copyable_and_movable_cpp0x Copyable and movable classes in C++0x]
+
+Consider a simple handle class that owns a resource and also provides copy semantics
+(copy constructor and assignment). For example a `clone_ptr` might own a pointer, and call
+`clone()` on it for copying purposes: 
+
+[c++]
+
+   template <class T>
+   class clone_ptr
+   {
+      private:
+      T* ptr;
+
+      public:
+      // construction
+      explicit clone_ptr(T* p = 0) : ptr(p) {}
+
+      // destruction
+      ~clone_ptr() { delete ptr; }
+
+      // copy semantics
+      clone_ptr(const clone_ptr& p)
+         : ptr(p.ptr ? p.ptr->clone() : 0) {}
+
+      clone_ptr& operator=(const clone_ptr& p)
+      {
+         if (this != &p)
+         {
+            T *p = p.ptr ? p.ptr->clone() : 0;
+            delete ptr;
+            ptr = p;
+         }
+         return *this;
+      }
+
+      // move semantics
+      clone_ptr(clone_ptr&& p)
+         : ptr(p.ptr) { p.ptr = 0; }
+
+      clone_ptr& operator=(clone_ptr&& p)
+      {
+         if(this != &p)
+         {
+            std::swap(ptr, p.ptr);
+            delete p.ptr;
+            p.ptr = 0;
+         }
+         return *this;
+      }
+
+      // Other operations...
+   };
+
+`clone_ptr` has expected copy constructor and assignment semantics, duplicating resources when copying.
+Note that copy constructing or assigning a `clone_ptr` is a relatively expensive operation: 
+
+[copy_clone_ptr]
+
+`clone_ptr` is code that you might find in today's books on C++, except for the part marked as
+`move semantics`. That part is implemented in terms of C++0x `rvalue references`. You can find
+some good introduction and tutorials on rvalue references in these papers:
+
+*  [@http://www.artima.com/cppsource/rvalue.html ['A Brief Introduction to Rvalue References]]
+*  [@http://blogs.msdn.com/vcblog/archive/2009/02/03/rvalue-references-c-0x-features-in-vc10-part-2.aspx ['Rvalue References: C++0x Features in VC10, Part 2]]
+
+When the source of the copy is known to be a `rvalue` (e.g.: a temporary object), one can avoid the
+potentially expensive `clone()` operation by pilfering source's pointer (no one will notice!). The move
+constructor above does exactly that, leaving the rvalue in a default constructed state. The move assignment
+operator simply does the same freeing old resources.
+
+Now when code tries to copy a rvalue `clone_ptr`, or if that code explicitly gives permission to
+consider the source of the copy a rvalue (using `boost::move`), the operation will execute much faster. 
+
+[move_clone_ptr]
+
+[endsect]
+
+[section:copyable_and_movable_cpp03 Copyable and movable classes in portable syntax for both C++03 and C++0x compilers]
+
+Many aspects of move semantics can be emulated for compilers not supporting `rvalue references`
+and [*Boost.Move] offers tools for that purpose. With [*Boost.Move] we can write `clone_ptr`
+so that it will work both in compilers with rvalue references and those who conform to C++03.
+You just need to follow these simple steps:
+
+* Put the following macro in the [*private] section:
+  [macroref BOOST_COPYABLE_AND_MOVABLE BOOST_COPYABLE_AND_MOVABLE(classname)]
+* Leave copy constructor as is.
+* Write a copy assignment taking the parameter as
+  [macroref BOOST_COPY_ASSIGN_REF BOOST_COPY_ASSIGN_REF(classname)]
+* Write a move constructor and a move assignment taking the parameter as
+  [macroref BOOST_RV_REF BOOST_RV_REF(classname)]
+
+Let's see how are applied to `clone_ptr`:
+
+[clone_ptr_def]
+
+[endsect]
+
+[*Question]: What about types that don't own resources? (E.g. `std::complex`?) 
+
+No work needs to be done in that case. The copy constructor is already optimal.
+
+[endsect]
+
+[section:composition_inheritance Composition or inheritance]
+
+For classes made up of other classes (via either composition or inheritance), the move constructor
+and move assignment can be easily coded using the `boost::move` function:
+
+[clone_ptr_base_derived]
+
+[important Due to limitations in the emulation code, a cast to `Base &` is needed before moving the base part in the move
+constructor and call Base's move constructor instead of the copy constructor.]
+
+Each subobject will now be treated individually, calling move to bind to the subobject's move
+constructors and move assignment operators. `Member` has move operations coded (just like
+our earlier `clone_ptr` example) which will completely avoid the tremendously more expensive
+copy operations:
+
+[clone_ptr_move_derived]
+
+Note above that the argument x is treated as a lvalue reference. That's why it is necessary to
+say `move(x)` instead of just x when passing down to the base class. This is a key safety feature of move
+semantics designed to prevent accidently moving twice from some named variable. All moves from 
+lvalues occur explicitly.
+
+[endsect]
+
+[section:movable_only_classes Movable but Non-Copyable Types]
+
+Some types are not amenable to copy semantics but can still be made movable. For example: 
+
+*  `unique_ptr` (non-shared, non-copyable ownership) 
+*  A type representing a thread of execution
+*  A type representing a file descriptor
+
+By making such types movable (though still non-copyable) their utility is tremendously
+increased. Movable but non-copyable types can be returned by value from factory functions:
+
+[c++]
+
+   file_descriptor create_file(/* ... */);
+   //...
+   file_descriptor data_file;
+   //...
+   data_file = create_file(/* ... */);  // No copies!
+
+In the above example, the underlying file handle is passed from object to object, as long
+as the source `file_descriptor` is a rvalue. At all times, there is still only one underlying file
+handle, and only one `file_descriptor` owns it at a time.
+
+To write a movable but not copyable type in portable syntax, you need to follow these simple steps:
+
+* Put the following macro in the [*private] section:
+  [macroref BOOST_MOVABLE_BUT_NOT_COPYABLE BOOST_MOVABLE_BUT_NOT_COPYABLE(classname)]
+* Write a move constructor and a move assignment taking the parameter as
+  [macroref BOOST_RV_REF BOOST_RV_REF(classname)]
+
+Here's the definition of `file descriptor` using portable syntax:
+
+[import ../example/doc_file_descriptor.cpp]
+[file_descriptor_def]
+
+[/
+ /Many standard algorithms benefit from moving elements of the sequence as opposed to
+ /copying them. This not only provides better performance (like the improved `swap`
+ /implementation described above), but also allows these algorithms to operate on movable
+ /but non-copyable types. For example the following code sorts a `vector<unique_ptr<T>>`
+ /based on comparing the pointed-to types: 
+ /
+ /[c++]
+ /
+ /   struct indirect_less
+ /   {
+ /      template <class T>
+ /      bool operator()(const T& x, const T& y)
+ /         {return *x < *y;}
+ /   };
+ /   ...
+ /   std::vector<std::unique_ptr<A>> v;
+ /   ...
+ /   std::sort(v.begin(), v.end(), indirect_less());
+ /
+ /
+ /As sort moves the unique_ptr's around, it will use swap (which no longer requires Copyability)
+ /or move construction / move assignment. Thus during the entire algorithm, the invariant that
+ /each item is owned and referenced by one and only one smart pointer is maintained. If the
+ /algorithm were to attempt a copy (say by programming mistake) a compile time error would result. 
+ /]
+
+[endsect]
+
+[section:move_and_containers Containers and move semantics]
+
+Movable but non-copyable types can be safely inserted into containers and
+movable and copyable types are more efficiently handled if those containers
+internally use move semantics instead of copy semantics.
+If the container needs to "change the location" of an element
+internally (e.g. vector reallocation) it will move the element instead of copying it.
+[*Boost.Container] containers are move-aware so you can write the following:
+
+[file_descriptor_example]
+
+[endsect]
+
+[section:construct_forwarding Constructor Forwarding]
+
+Consider writing a generic factory function that returns an object for a newly
+constructed generic type. Factory functions such as this are valuable for encapsulating
+and localizing the allocation of resources. Obviously, the factory function must accept
+exactly the same sets of arguments as the constructors of the type of objects constructed:
+
+[c++]
+
+   template<class T> T* factory_new()
+   {  return new T();  }
+
+   template<class T> T* factory_new(a1)
+   {  return new T(a1);  }
+
+   template<class T> T* factory_new(a1, a2)
+   {  return new T(a1, a2);  }
+
+Unfortunately, in C++03 the much bigger issue with this approach is that the N-argument case
+would require 2^N overloads, immediately discounting this as a general solution. Fortunately,
+most constructors take arguments by value, by const-reference or by rvalue reference. If these
+limitations are accepted, the forwarding emulation of a N-argument case requires just N overloads.
+This library makes this emulation easy with the help of `BOOST_FWD_REF` and
+`boost::forward`:
+
+[import ../example/doc_construct_forward.cpp]
+[construct_forward_example]
+
+Constructor forwarding comes in handy to implement placement insertion in containers with
+just N overloads if the implementor accepts the limitations of this type of forwarding for
+C++03 compilers. In compilers with rvalue references perfect forwarding is achieved.
+
+[endsect]
+
+[section:move_return Implicit Move when returning a local object]
+
+The C++ standard specifies situations where an implicit move operation is safe and the
+compiler can use it in cases were the (Named) Return Value Optimization) can't be used.
+The typical use case is when a function returns a named (non-temporary) object by value
+and the following code will perfectly compile in C++11:
+
+[c++]
+
+   //Even if movable can't be copied
+   //the compiler will call the move-constructor
+   //to generate the return value
+   //
+   //The compiler can also optimize out the move
+   //and directly construct the object 'm'
+   movable factory()
+   {
+      movable tmp;
+      m = ...
+      //(1) moved instead of copied
+      return tmp;
+   };
+
+   //Initialize object
+   movable m(factory());
+
+
+In compilers without rvalue references and some non-conforming compilers (such as Visual C++ 2010/2012)
+the line marked with `(1)` would trigger a compilation error because `movable` can't be copied. Using a explicit
+`::boost::move(tmp)` would workaround this limitation but it would code suboptimal in C++11 compilers
+(as the compile could not use (N)RVO to optimize-away the copy/move).
+
+[*Boost.Move] offers an additional macro called [macroref BOOST_MOVE_RET BOOST_MOVE_RET] that can be used to
+alleviate this problem obtaining portable move-on-return semantics. Let's use the previously presented
+movable-only `movable` class with classes `copyable` (copy-only type), `copy_movable` (can be copied and moved) and
+`non_copy_movable` (non-copyable and non-movable):
+
+[import ../example/copymovable.hpp]
+[copy_movable_definition]
+
+and build a generic factory function that returns a newly constructed value or a reference to an already
+constructed object.
+
+[import ../example/doc_move_return.cpp]
+[move_return_example]
+
+[*Caution]: When using this macro in a non-conforming or C++03
+compilers, a move will be performed even if the C++11 standard does not allow it
+(e.g. returning a static variable). The user is responsible for using this macro
+only used to return local objects that met C++11 criteria. E.g.:
+
+[c++]
+
+   struct foo
+   {
+      copy_movable operator()() const
+      {
+         //ERROR! The Standard does not allow implicit move returns when the object to be returned 
+         //does not met the criteria for elision of a copy operation (such as returning a static member data)
+         //In C++03 compilers this will MOVE resources from cm
+         //In C++11 compilers this will COPY resources from cm
+         //so DON'T use use BOOST_MOVE_RET without care.
+         return BOOST_MOVE_RET(copy_movable, cm);
+      }
+
+      static copy_movable cm;
+   };
+
+
+[*Note]: When returning a temporary object `BOOST_MOVE_REF` is not needed as copy ellision rules will work on
+both C++03 and C++11 compilers.
+
+[c++]
+
+   //Note: no BOOST_MOVE_RET
+   movable get_movable()
+   {  return movable();  }
+
+   copy_movable get_copy_movable()
+   {  return copy_movable();  }
+
+   copyable get_copyable()
+   {  return copyable();  }
+
+
+[endsect]
+
+[section:move_iterator Move iterators]
+
+[c++]
+
+   template<class Iterator>
+   class move_iterator;
+
+   template<class It>
+   move_iterator<It> make_move_iterator(const It &it);
+
+[classref boost::move_iterator move_iterator] is an iterator adaptor with the
+same behavior as the underlying iterator
+except that its dereference operator implicitly converts the value returned by the
+underlying iterator's dereference operator to a rvalue reference: `boost::move(*underlying_iterator)`
+It is a read-once iterator, but can have up to random access traversal characteristics.
+
+`move_iterator` is very useful because some generic algorithms and container insertion functions
+can be called with move iterators to replace copying with moving. For example:
+
+[import ../example/movable.hpp]
+[movable_definition]
+
+`movable` objects can be moved from one container to another using move iterators and insertion
+and assignment operations.w
+
+[import ../example/doc_move_iterator.cpp]
+[move_iterator_example]
+
+[endsect]
+
+[section:move_inserters Move inserters]
+
+Similar to standard insert iterators, it's possible to deal with move insertion in the same way
+as writing into an array. A special kind of iterator adaptors, called move insert iterators, are
+provided with this library. With regular iterator classes,
+
+[c++]
+
+   while (first != last) *result++ = *first++;
+
+causes a range [first,last) to be copied into a range starting with result. The same code with
+result being a move insert iterator will move insert corresponding elements into the container.
+This device allows all of the copying algorithms in the library to work in the move insert mode
+instead of the regular overwrite mode. This library offers 3 move insert iterators and their
+helper functions:
+
+[c++]
+
+   // Note: C models Container
+   template <typename C> 
+   class back_move_insert_iterator;
+
+   template <typename C>
+   back_move_insert_iterator<C> back_move_inserter(C& x);
+
+   template <typename C>
+   class front_move_insert_iterator;
+
+   template <typename C>
+   front_move_insert_iterator<C> front_move_inserter(C& x);
+
+   template <typename C>
+   class move_insert_iterator;
+
+   template <typename C>
+   move_insert_iterator<C> move_inserter(C& x, typename C::iterator it);
+
+
+A move insert iterator is constructed from a container and possibly one of its iterators pointing
+to where insertion takes place if it is neither at the beginning nor at the end of the container.
+Insert iterators satisfy the requirements of output iterators. `operator*` returns the move insert
+iterator itself. The assignment `operator=(T& x)` is defined on insert iterators to allow writing
+into them, it inserts x right before where the insert iterator is pointing. In other words, an
+`insert iterator` is like a cursor pointing into the container where the insertion takes place.
+`back_move_iterator` move inserts elements at the end of a container, `front_insert_iterator`
+move inserts elements at the beginning of a container, and `move_insert_iterator` move inserts
+elements where the iterator points to in a container. `back_move_inserter`, `front_move_inserter`,
+and `move_inserter` are three functions making the insert iterators out of a container. Here's
+an example of how to use them:
+
+[import ../example/doc_move_inserter.cpp]
+[move_inserter_example]
+
+[endsect]
+
+[section:move_algorithms Move algorithms]
+
+The standard library offers several copy-based algorithms. Some of them, like `std::copy` or
+`std::uninitialized_copy` are basic building blocks for containers and other data structures.
+This library offers move-based functions for those purposes:
+
+[c++]
+
+  template<typename I, typename O> O move(I, I, O);
+  template<typename I, typename O> O move_backward(I, I, O);
+  template<typename I, typename F> F uninitialized_move(I, I, F);
+  template<typename I, typename F> F uninitialized_copy_or_move(I, I, F);
+
+
+The first 3 are move variations of their equivalent copy algorithms, but copy assignment and
+copy construction are replaced with move assignment and construction. The last one has the
+same behaviour as `std::uninitialized_copy` but since several standand library implementations
+don't play very well with `move_iterator`s, this version is a portable version for those
+willing to use move iterators.
+
+[import ../example/doc_move_algorithms.cpp]
+[move_algorithms_example]
+
+[endsect]
+
+[section:emulation_limitations Emulation limitations]
+
+Like any emulation effort, the library has some limitations users should take in
+care to achieve portable and efficient code when using the library with C++03 conformant compilers:
+
+[section:emulation_limitations_base Initializing base classes]
+
+When initializing base classes in move constructors, users must
+cast the reference to a base class reference before moving it or just
+use `BOOST_MOVE_BASE`. Example:
+
+[c++]
+
+   Derived(BOOST_RV_REF(Derived) x)             // Move ctor
+      : Base(boost::move(static_cast<Base&>(x)))
+        //...
+
+or
+
+[c++]
+
+   Derived(BOOST_RV_REF(Derived) x)             // Move ctor
+      : Base(BOOST_MOVE_BASE(Base, x))
+        //...
+
+If casting is not performed the emulation will not move construct
+the base class, because no conversion is available from `BOOST_RV_REF(Derived)` to
+`BOOST_RV_REF(Base)`. Without the cast or `BOOST_MOVE_BASE` we might obtain a compilation
+error (for non-copyable types) or a less-efficient move constructor (for copyable types):
+
+[c++]
+
+   //If Derived is copyable, then Base is copy-constructed.
+   //If not, a compilation error is issued
+   Derived(BOOST_RV_REF(Derived) x)             // Move ctor
+      : Base(boost::move(x))
+        //...
+
+[endsect]
+
+[section:template_parameters Template parameters for perfect forwarding]
+
+The emulation can't deal with C++0x reference collapsing rules that allow perfect forwarding:
+
+[c++]
+   
+   //C++0x
+   template<class T>
+   void forward_function(T &&t)
+   {  inner_function(std::forward<T>(t); }
+
+   //Wrong C++03 emulation
+   template<class T>
+   void forward_function(BOOST_RV_REF<T> t)
+   {  inner_function(boost::forward<T>(t); }
+
+In C++03 emulation BOOST_RV_REF doesn't catch any const rlvalues. For more details on
+forwarding see [link move.construct_forwarding Constructor Forwarding] chapter.
+
+[endsect]
+
+[section:emulation_limitations_binding Binding of rvalue references to lvalues]
+
+The 
+[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1690.html first rvalue reference]
+proposal allowed the binding of rvalue references to lvalues:
+
+[c++]
+
+   func(Type &&t);
+   //....
+   
+   Type t;  //Allowed
+   func(t)
+
+
+Later, as explained in
+[@http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2812.html ['Fixing a Safety Problem with Rvalue References]]
+this behaviour was considered dangerous and eliminated this binding so that rvalue references adhere to the
+principle of type-safe overloading: ['Every function must be type-safe in isolation, without regard to how it has been overloaded]
+
+[*Boost.Move] can't emulate this type-safe overloading principle for C++03 compilers:
+
+[c++]
+
+   //Allowed by move emulation
+   movable m;
+   BOOST_RV_REF(movable) r = m;
+
+[endsect]
+
+[section:assignment_operator Assignment operator in classes derived from or holding copyable and movable types]
+
+The macro [macroref BOOST_COPYABLE_AND_MOVABLE BOOST_COPYABLE_AND_MOVABLE] needs to
+define a copy constructor for `copyable_and_movable` taking a non-const parameter in C++03 compilers:
+
+[c++]
+
+   //Generated by BOOST_COPYABLE_AND_MOVABLE
+   copyable_and_movable &operator=(copyable_and_movable&){/**/}
+
+Since the non-const overload of the copy constructor is generated, compiler-generated
+assignment operators for classes containing `copyable_and_movable`
+will get the non-const copy constructor overload, which will surely surprise users:
+
+[c++]
+
+   class holder
+   {
+      copyable_and_movable c;
+   };
+
+   void func(const holder& h)
+   {
+      holder copy_h(h); //<--- ERROR: can't convert 'const holder&' to 'holder&'
+      //Compiler-generated copy constructor is non-const:
+      // holder& operator(holder &)
+      //!!!
+   }
+
+This limitation forces the user to define a const version of the copy assignment,
+in all classes holding copyable and movable classes which might be annoying in some cases.
+
+An alternative is to implement a single `operator =()` for copyable and movable  classes
+[@http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/ using "pass by value" semantics]:
+
+[c++]
+
+   T& operator=(T x)    // x is a copy of the source; hard work already done
+   {
+      swap(*this, x);  // trade our resources for x's
+      return *this;    // our (old) resources get destroyed with x
+   }
+
+However, "pass by value" is not optimal for classes (like containers, strings, etc.) that reuse resources
+(like previously allocated memory) when x is assigned from a lvalue.
+
+[endsect]
+
+[section:templated_assignment_operator Templated assignment operator in copyable and movable types]
+
+
+[import ../example/doc_template_assign.cpp]
+
+Given a movable and copyable class, if a templated assignment operator (*) is added:
+
+[template_assign_example_foo_bar]
+
+C++98 and C++11 compilers will behave different when assigning from a `[const] Foo` lvalue:
+
+[template_assign_example_main]
+
+This different behaviour is a side-effect of the move emulation that can't be easily avoided by
+[*Boost.Move]. One workaround is to SFINAE-out the templated assignment operator with `disable_if`:
+
+[c++]
+
+   template<class U> // Modified templated assignment
+   typename boost::disable_if<boost::is_same<U, Foo>, Foo&>::type
+      operator=(const U& rhs)
+   {  i = -rhs.i; return *this;  } //(2)
+
+
+[endsect]
+
+[endsect]
+
+[section:how_the_library_works How the library works]
+
+[*Boost.Move] is based on macros that are expanded to true rvalue references in C++0x compilers
+and emulated rvalue reference classes and conversion operators in C++03 compilers.
+
+In C++03 compilers [*Boost.Move] defines a class named `::boost::rv`:
+
+[c++]
+
+   template <class T>
+   class rv : public T
+   {
+      rv();
+      ~rv();
+      rv(rv const&);
+      void operator=(rv const&);
+   };
+
+which is convertible to the movable base class (usual C++ derived to base conversion). When users mark
+their classes as [macroref BOOST_MOVABLE_BUT_NOT_COPYABLE BOOST_MOVABLE_BUT_NOT_COPYABLE] or
+[macroref BOOST_COPYABLE_AND_MOVABLE BOOST_COPYABLE_AND_MOVABLE], these macros define conversion
+operators to references to `::boost::rv`:
+
+[c++]
+
+   #define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\
+      public:\
+      operator ::boost::rv<TYPE>&() \
+      {  return *static_cast< ::boost::rv<TYPE>* >(this);  }\
+      operator const ::boost::rv<TYPE>&() const \
+      {  return static_cast<const ::boost::rv<TYPE>* >(this);  }\
+      private:\
+      //More stuff...
+
+[macroref BOOST_MOVABLE_BUT_NOT_COPYABLE BOOST_MOVABLE_BUT_NOT_COPYABLE] also declares a
+private copy constructor and assignment. [macroref BOOST_COPYABLE_AND_MOVABLE BOOST_COPYABLE_AND_MOVABLE]
+defines a non-const copy constructor `TYPE &operator=(TYPE&)` that forwards to a const version:
+
+   #define BOOST_COPYABLE_AND_MOVABLE(TYPE)\
+      public:\
+      TYPE& operator=(TYPE &t)\
+      {  this->operator=(static_cast<const ::boost::rv<TYPE> &>(const_cast<const TYPE &>(t))); return *this;}\
+      //More stuff...
+
+In C++0x compilers `BOOST_COPYABLE_AND_MOVABLE` expands to nothing and `BOOST_MOVABLE_BUT_NOT_COPYABLE`
+declares copy constructor and assigment operator private.
+
+When users define the [macroref BOOST_RV_REF BOOST_RV_REF] overload of a copy constructor/assignment, in
+C++0x compilers it is expanded to a rvalue reference (`T&&`) overload and in C++03 compilers it is expanded
+to a `::boost::rv<T> &` overload:
+
+[c++]
+
+   #define BOOST_RV_REF(TYPE) ::boost::rv< TYPE >& \
+
+When users define the [macroref BOOST_COPY_ASSIGN_REF BOOST_COPY_ASSIGN_REF] overload,
+it is expanded to a usual copy assignment (`const T &`) overload in C++0x compilers and
+to a `const ::boost::rv &` overload in C++03 compilers:
+
+[c++]
+
+   #define BOOST_COPY_ASSIGN_REF(TYPE) const ::boost::rv< TYPE >&
+   
+As seen, in [*Boost.Move] generates efficient and clean code for C++0x move
+semantics, without modifying any resolution overload. For C++03 compilers
+when overload resolution is performed these are the bindings:
+
+* a) non-const rvalues (e.g.: temporaries), bind to `::boost::rv< TYPE >&`
+* b) const rvalue and lvalues, bind to `const ::boost::rv< TYPE >&`
+* c) non-const lvalues (e.g. non-const references) bind to `TYPE&`
+
+The library does not define the equivalent of
+[macroref BOOST_COPY_ASSIGN_REF BOOST_COPY_ASSIGN_REF] for copy construction (say, `BOOST_COPY_CTOR_REF`)
+because nearly all modern compilers implement RVO and this is much more efficient than any move emulation.
+[funcref boost::move move] just casts `TYPE &` into `::boost::rv<TYPE> &`.
+
+Here's an example that demostrates how different rlvalue objects bind to `::boost::rv` references in the
+presence of three overloads and the conversion operators in C++03 compilers:
+
+[import ../example/doc_how_works.cpp]
+[how_works_example]
+
+[endsect]
+
+
+[section:thanks_to Thanks and credits]
+
+Thanks to all that developed ideas for move emulation: the first emulation was based on Howard Hinnant
+emulation code for `unique_ptr`, David Abrahams suggested the use of `class rv`,
+and Klaus Triendl discovered how to bind const rlvalues using `class rv`.
+
+Many thanks to all boosters that have tested, reviewed and improved the library.
+
+Special thanks to:
+
+* Orson Peters, author of [@https://github.com/orlp/pdqsort Pattern-defeating quicksort (pdqsort)].
+* Andrey Astrelin, author of [@https://github.com/Mrrl/GrailSort Grail Sort].
+
+[endsect]
+
+[section:release_notes Release Notes]
+
+[section:release_notes_boost_1_67 Boost 1.67 Release]
+
+*  Added pdqsort and heap_sort implementations, initially as a detail, they will be official in the future once better tested.
+
+[endsect]
+
+[section:release_notes_boost_1_66 Boost 1.66 Release]
+
+*  Fixed bugs:
+   *  [@https://github.com/boostorg/move/pull/14   Git Pull  #14: ['"Workaround for bogus [-Wignored-attributes] warning on GCC 6.x/7.x"]].
+   *  [@https://github.com/boostorg/move/issues/15 Git Issue #15: ['"Incorrect merge in adaptive_merge when the number of unique items is limited"]].
+
+[endsect]
+
+
+[section:release_notes_boost_1_65 Boost 1.65 Release]
+
+*  Fixed bug:
+   *  [@https://github.com/boostorg/move/pull/11 Git Pull #11: ['"replace 'std::random_shuffle' by '::random_shuffle'"]].
+   *  [@https://github.com/boostorg/move/pull/12 Git Pull #12: ['"Adds support for MSVC ARM64 target'"]].
+
+[endsect]
+
+[section:release_notes_boost_1_64 Boost 1.64 Release]
+
+*  Fixed bug:
+   *  [@https://svn.boost.org/trac/boost/ticket/12920 #12920 ['"movelib::unique_ptr: incorrect pointer type for nested array"]].
+
+[endsect]
+
+[section:release_notes_boost_1_62 Boost 1.62 Release]
+
+*  Documented new limitations reported in Trac tickets
+   [@https://svn.boost.org/trac/boost/ticket/12194 #12194 ['"Copy assignment on moveable and copyable classes uses wrong type"]] and
+   [@https://svn.boost.org/trac/boost/ticket/12307 #12307 ['"Copy assignment from const ref handled differently in C++11/C++98"]].
+
+[endsect]
+
+[section:release_notes_boost_1_61 Boost 1.61 Release]
+
+*  Experimental: asymptotically optimal bufferless merge and sort algorithms: [funcref boost::movelib::adaptive_merge adaptive_merge]
+   and [funcref boost::movelib::adaptive_sort adaptive_sort].
+
+*  Fixed bug:
+   * [@https://svn.boost.org/trac/boost/ticket/11758 Trac #11758: ['"BOOST_MOVABLE_BUT_NOT_COPYABLE doesn't reset private access with rvalue ref version"]],
+
+[endsect]
+
+[section:release_notes_boost_1_60 Boost 1.60 Release]
+
+*  Fixed bug:
+   * [@https://svn.boost.org/trac/boost/ticket/11615 Trac #11615: ['"Boost.Move should use the qualified name for std::size_t in type_traits.hpp"]],
+
+[endsect]
+
+[section:release_notes_boost_1_59 Boost 1.59 Release]
+
+*  Changed `unique_ptr`'s converting constructor taking the source by value in C++03 compilers to allow simple conversions
+   from convertible types returned by value.
+*  Fixed bug:
+   * [@https://svn.boost.org/trac/boost/ticket/11229 Trac #11229: ['"vector incorrectly copies move-only objects using memcpy"]],
+   * [@https://svn.boost.org/trac/boost/ticket/11510 Trac #11510: ['"unique_ptr: -Wshadow warning issued"]],
+
+[endsect]
+
+[section:release_notes_boost_1_58_00 Boost 1.58 Release]
+
+*  Added [macroref BOOST_MOVE_BASE BOOST_MOVE_BASE] utility.
+*  Added [funcref boost::adl_move_swap adl_move_swap] utility.
+*  Reduced dependencies on other Boost libraries to make the library a bit more lightweight.
+*  Fixed bugs:
+   *  [@https://svn.boost.org/trac/boost/ticket/11044 Trac #11044: ['"boost::rv inherits off union, when such passed as template argument"]].
+
+[endsect]
+
+[section:release_notes_boost_1_57_00 Boost 1.57 Release]
+
+*  Added `unique_ptr` smart pointer. Thanks to Howard Hinnant for his excellent unique_ptr emulation code and testsuite.
+*  Added `move_if_noexcept` utility. Thanks to Antony Polukhin for the implementation.
+*  Fixed bugs:
+   *  [@https://svn.boost.org/trac/boost/ticket/9785 Trac #9785: ['"Compiler warning with intel icc in boost/move/core.hpp"]],
+   *  [@https://svn.boost.org/trac/boost/ticket/10460 Trac #10460: ['"Compiler error due to looser throw specifier"]],
+   *  [@https://github.com/boostorg/move/pull/3 Git Pull #3: ['"Don't delete copy constructor when rvalue references are disabled"]],
+
+[endsect]
+ 
+[section:release_notes_boost_1_56_00 Boost 1.56 Release]
+
+*  Added [macroref BOOST_MOVE_RET BOOST_MOVE_RET].
+*  Fixed bugs:
+      *  [@https://svn.boost.org/trac/boost/ticket/9482 #9482: ['"MSVC macros not undefined in boost/move/detail/config_end.hpp"]],
+      *  [@https://svn.boost.org/trac/boost/ticket/9045 #9045: ['"Wrong macro name on docs"]],
+      *  [@https://svn.boost.org/trac/boost/ticket/8420 #8420: ['"move's is_convertible does not compile with aligned data"]].
+
+[endsect]
+
+[section:release_notes_boost_1_55_00 Boost 1.55 Release]
+
+*  Fixed bugs  [@https://svn.boost.org/trac/boost/ticket/7952 #7952],
+               [@https://svn.boost.org/trac/boost/ticket/8764 #8764],
+               [@https://svn.boost.org/trac/boost/ticket/8765 #8765],
+               [@https://svn.boost.org/trac/boost/ticket/8842 #8842],
+               [@https://svn.boost.org/trac/boost/ticket/8979 #8979].
+
+[endsect]
+
+
+[section:release_notes_boost_1_54_00 Boost 1.54 Release]
+
+
+*  Fixed bugs [@https://svn.boost.org/trac/boost/ticket/7969 #7969],
+              [@https://svn.boost.org/trac/boost/ticket/8231 #8231],
+              [@https://svn.boost.org/trac/boost/ticket/8765 #8765].
+
+[endsect]
+
+[section:release_notes_boost_1_53_00 Boost 1.53 Release]
+
+*  Better header segregation (bug
+  [@https://svn.boost.org/trac/boost/ticket/6524 #6524]).
+*  Small documentation fixes
+*  Replaced deprecated BOOST_NO_XXXX with newer BOOST_NO_CXX11_XXX macros.
+*  Fixed [@https://svn.boost.org/trac/boost/ticket/7830 #7830],
+         [@https://svn.boost.org/trac/boost/ticket/7832 #7832].
+
+[endsect]
+
+[section:release_notes_boost_1_51_00 Boost 1.51 Release]
+
+*  Fixed bugs
+  [@https://svn.boost.org/trac/boost/ticket/7095 #7095],
+  [@https://svn.boost.org/trac/boost/ticket/7031 #7031].
+
+[endsect]
+
+[section:release_notes_boost_1_49_00 Boost 1.49 Release]
+
+*  Fixed bugs
+  [@https://svn.boost.org/trac/boost/ticket/6417 #6417],
+  [@https://svn.boost.org/trac/boost/ticket/6183 #6183],
+  [@https://svn.boost.org/trac/boost/ticket/6185 #6185],
+  [@https://svn.boost.org/trac/boost/ticket/6395 #6395],
+  [@https://svn.boost.org/trac/boost/ticket/6396 #6396],
+
+[endsect]
+
+[endsect]
+
+[xinclude autodoc.xml]
diff --git a/example/Jamfile.v2 b/example/Jamfile.v2
new file mode 100644
index 0000000..bc354e0
--- /dev/null
+++ b/example/Jamfile.v2
@@ -0,0 +1,31 @@
+##############################################################################
+##
+## (C) Copyright Ion Gaztanaga 2008-2009 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)
+##
+##
+##############################################################################
+#
+import testing ;
+
+rule test_all
+{
+   local all_rules = ;
+
+   for local fileb in [ glob *.cpp ]
+   {
+      all_rules += [ run $(fileb)
+      :  # additional args
+      :  # test-files
+      :  # requirements
+      ] ;
+   }
+
+   return $(all_rules) ;
+}
+
+test-suite move_example : [ test_all r ] 
+: <link>static
+;
+ 
diff --git a/example/copymovable.hpp b/example/copymovable.hpp
new file mode 100644
index 0000000..173d420
--- /dev/null
+++ b/example/copymovable.hpp
@@ -0,0 +1,64 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_MOVE_TEST_COPYMOVABLE_HPP
+#define BOOST_MOVE_TEST_COPYMOVABLE_HPP
+
+#include <boost/move/detail/config_begin.hpp>
+
+//[copy_movable_definition 
+//header file "copymovable.hpp"
+#include <boost/move/core.hpp>
+
+//A copy_movable class
+class copy_movable
+{
+   BOOST_COPYABLE_AND_MOVABLE(copy_movable)
+   int value_;
+
+   public:
+   copy_movable() : value_(1){}
+
+   //Move constructor and assignment
+   copy_movable(BOOST_RV_REF(copy_movable) m)
+   {  value_ = m.value_;   m.value_ = 0;  }
+
+   copy_movable(const copy_movable &m)
+   {  value_ = m.value_;   }
+
+   copy_movable & operator=(BOOST_RV_REF(copy_movable) m)
+   {  value_ = m.value_;   m.value_ = 0;  return *this;  }
+
+   copy_movable & operator=(BOOST_COPY_ASSIGN_REF(copy_movable) m)
+   {  value_ = m.value_;   return *this;  }
+
+   bool moved() const //Observer
+   {  return value_ == 0; }
+};
+
+//A copyable-only class
+class copyable
+{};
+
+//A copyable-only class
+class non_copy_movable
+{
+   public:
+   non_copy_movable(){}
+   private:
+   non_copy_movable(const non_copy_movable&);
+   non_copy_movable& operator=(const non_copy_movable&);
+};
+
+//]
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif //BOOST_MOVE_TEST_COPYMOVABLE_HPP
diff --git a/example/doc_clone_ptr.cpp b/example/doc_clone_ptr.cpp
new file mode 100644
index 0000000..e0fa73c
--- /dev/null
+++ b/example/doc_clone_ptr.cpp
@@ -0,0 +1,157 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/utility_core.hpp>
+
+//[clone_ptr_base_derived
+class Base
+{
+   BOOST_COPYABLE_AND_MOVABLE(Base)
+
+   public:
+   Base(){}
+
+   Base(const Base &/*x*/) {/**/}            // Copy ctor
+
+   Base(BOOST_RV_REF(Base) /*x*/) {/**/}     // Move ctor
+
+   Base& operator=(BOOST_RV_REF(Base) /*x*/)
+   {/**/ return *this;}                      // Move assign
+
+   Base& operator=(BOOST_COPY_ASSIGN_REF(Base) /*x*/)
+   {/**/ return *this;}                      // Copy assign
+   
+   virtual Base *clone() const
+   {  return new Base(*this);  }
+
+   virtual ~Base(){}
+};
+
+class Member
+{
+   BOOST_COPYABLE_AND_MOVABLE(Member)
+
+   public:
+   Member(){}
+
+   // Compiler-generated copy constructor...
+
+   Member(BOOST_RV_REF(Member))  {/**/}      // Move ctor
+
+   Member &operator=(BOOST_RV_REF(Member))   // Move assign
+   {/**/ return *this;  }
+
+   Member &operator=(BOOST_COPY_ASSIGN_REF(Member))   // Copy assign
+   {/**/ return *this;  }
+};
+
+class Derived : public Base
+{
+   BOOST_COPYABLE_AND_MOVABLE(Derived)
+   Member mem_;
+
+   public:
+   Derived(){}
+
+   // Compiler-generated copy constructor...
+
+   Derived(BOOST_RV_REF(Derived) x)             // Move ctor
+      : Base(BOOST_MOVE_BASE(Base, x)), 
+        mem_(boost::move(x.mem_)) { }
+
+   Derived& operator=(BOOST_RV_REF(Derived) x)  // Move assign
+   {
+      Base::operator=(BOOST_MOVE_BASE(Base, x));
+      mem_ = boost::move(x.mem_);
+      return *this;
+   }
+
+   Derived& operator=(BOOST_COPY_ASSIGN_REF(Derived) x)  // Copy assign
+   {
+      Base::operator=(x);
+      mem_  = x.mem_;
+      return *this;
+   }
+   // ...
+};
+//]
+
+//[clone_ptr_def
+template <class T>
+class clone_ptr
+{
+   private:
+   // Mark this class copyable and movable
+   BOOST_COPYABLE_AND_MOVABLE(clone_ptr)
+   T* ptr;
+
+   public:
+   // Construction
+   explicit clone_ptr(T* p = 0) : ptr(p) {}
+
+   // Destruction
+   ~clone_ptr() { delete ptr; }
+   
+   clone_ptr(const clone_ptr& p) // Copy constructor (as usual)
+      : ptr(p.ptr ? p.ptr->clone() : 0) {}
+
+   clone_ptr& operator=(BOOST_COPY_ASSIGN_REF(clone_ptr) p) // Copy assignment
+   {
+      if (this != &p){
+         T *tmp_p = p.ptr ? p.ptr->clone() : 0;
+         delete ptr;
+         ptr = tmp_p;
+      }
+      return *this;
+   }
+
+   //Move semantics...
+   clone_ptr(BOOST_RV_REF(clone_ptr) p)            //Move constructor
+      : ptr(p.ptr) { p.ptr = 0; }
+
+   clone_ptr& operator=(BOOST_RV_REF(clone_ptr) p) //Move assignment
+   {
+      if (this != &p){
+         delete ptr;
+         ptr = p.ptr;
+         p.ptr = 0;
+      }
+      return *this;
+   }
+};
+//]
+
+int main()
+{
+   {
+   //[copy_clone_ptr
+   clone_ptr<Base> p1(new Derived());
+   // ...
+   clone_ptr<Base> p2 = p1;  // p2 and p1 each own their own pointer
+   //]
+   }
+   {
+   //[move_clone_ptr
+   clone_ptr<Base> p1(new Derived());
+   // ...
+   clone_ptr<Base> p2 = boost::move(p1);  // p2 now owns the pointer instead of p1
+   p2 = clone_ptr<Base>(new Derived());   // temporary is moved to p2
+   }
+   //]
+   //[clone_ptr_move_derived
+   Derived d;
+   Derived d2(boost::move(d));
+   d2 = boost::move(d);
+   //]
+   return 0;
+}
+
+#include <boost/move/detail/config_end.hpp>
diff --git a/example/doc_construct_forward.cpp b/example/doc_construct_forward.cpp
new file mode 100644
index 0000000..388a97c
--- /dev/null
+++ b/example/doc_construct_forward.cpp
@@ -0,0 +1,109 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2009.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/move/detail/config_begin.hpp>
+
+//[construct_forward_example
+#include <boost/move/utility_core.hpp>
+#include <iostream>
+
+class copyable_only_tester
+{
+   public:
+   copyable_only_tester()
+   {  std::cout << "copyable_only_tester()" << std::endl;   }
+
+   copyable_only_tester(const copyable_only_tester&)
+   {  std::cout << "copyable_only_tester(const copyable_only_tester&)" << std::endl;   }
+
+   copyable_only_tester(int)
+   {  std::cout << "copyable_only_tester(int)" << std::endl;   }
+
+   copyable_only_tester(int, double)
+   {  std::cout << "copyable_only_tester(int, double)" << std::endl;   }
+};
+
+class copyable_movable_tester
+{
+   // move semantics
+   BOOST_COPYABLE_AND_MOVABLE(copyable_movable_tester)
+   public:
+
+   copyable_movable_tester()
+   {  std::cout << "copyable_movable_tester()" << std::endl;   }
+
+   copyable_movable_tester(int)
+   {  std::cout << "copyable_movable_tester(int)" << std::endl;   }
+
+   copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester))
+   {  std::cout << "copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester))" << std::endl;   }
+
+   copyable_movable_tester(const copyable_movable_tester &)
+   {  std::cout << "copyable_movable_tester(const copyable_movable_tester &)" << std::endl;   }
+
+   copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester), BOOST_RV_REF(copyable_movable_tester))
+   {  std::cout << "copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester), BOOST_RV_REF(copyable_movable_tester))" << std::endl;   }
+
+   copyable_movable_tester &operator=(BOOST_RV_REF(copyable_movable_tester))
+   {  std::cout << "copyable_movable_tester & operator=(BOOST_RV_REF(copyable_movable_tester))" << std::endl; 
+      return *this;  }
+
+   copyable_movable_tester &operator=(BOOST_COPY_ASSIGN_REF(copyable_movable_tester))
+   {  std::cout << "copyable_movable_tester & operator=(BOOST_COPY_ASSIGN_REF(copyable_movable_tester))" << std::endl;
+      return *this;  }
+};
+
+//1 argument
+template<class MaybeMovable, class MaybeRv>
+void function_construct(BOOST_FWD_REF(MaybeRv) x)
+{  MaybeMovable m(boost::forward<MaybeRv>(x));   }
+
+//2 argument
+template<class MaybeMovable, class MaybeRv, class MaybeRv2>
+void function_construct(BOOST_FWD_REF(MaybeRv) x, BOOST_FWD_REF(MaybeRv2) x2)
+{  MaybeMovable m(boost::forward<MaybeRv>(x), boost::forward<MaybeRv2>(x2));  }
+
+int main()
+{
+   copyable_movable_tester m;
+   //move constructor
+   function_construct<copyable_movable_tester>(boost::move(m));
+   //copy constructor
+   function_construct<copyable_movable_tester>(copyable_movable_tester());
+   //two rvalue constructor
+   function_construct<copyable_movable_tester>(boost::move(m), boost::move(m));
+
+   copyable_only_tester nm;
+   //copy constructor (copyable_only_tester has no move ctor.)
+   function_construct<copyable_only_tester>(boost::move(nm));
+   //copy constructor
+   function_construct<copyable_only_tester>(nm);
+   //int constructor
+   function_construct<copyable_only_tester>(int(0));
+   //int, double constructor
+   function_construct<copyable_only_tester>(int(0), double(0.0));
+
+   //Output is:
+   //copyable_movable_tester()
+   //copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester))
+   //copyable_movable_tester()
+   //copyable_movable_tester(const copyable_movable_tester &)
+   //copyable_movable_tester(BOOST_RV_REF(copyable_movable_tester), BOOST_RV_REF(copyable_movable_tester))
+   //copyable_only_tester()
+   //copyable_only_tester(const copyable_only_tester&)
+   //copyable_only_tester(const copyable_only_tester&)
+   //copyable_only_tester(int)
+   //copyable_only_tester(int, double)
+   return 0;
+}
+//]
+
+#include <boost/move/detail/config_end.hpp>
diff --git a/example/doc_file_descriptor.cpp b/example/doc_file_descriptor.cpp
new file mode 100644
index 0000000..0ec3987
--- /dev/null
+++ b/example/doc_file_descriptor.cpp
@@ -0,0 +1,92 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2008-2012.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/move/detail/config_begin.hpp>
+#include <cassert>
+
+//[file_descriptor_def
+
+#include <boost/move/utility_core.hpp>
+#include <stdexcept>
+
+class file_descriptor
+{
+   //<-
+   int operating_system_open_file(const char *)
+   {
+      return 1;
+   }
+
+   void operating_system_close_file(int fd)
+   {  (void)fd;   assert(fd != 0); }
+   //->
+   int os_descr_;
+
+   private:
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(file_descriptor)
+
+   public:
+   explicit file_descriptor(const char *filename)              //Constructor
+      : os_descr_(operating_system_open_file(filename))
+   {  if(!os_descr_) throw std::runtime_error("file not found");  }
+
+   ~file_descriptor()                                          //Destructor
+   {  if(os_descr_)  operating_system_close_file(os_descr_);  }
+
+   file_descriptor(BOOST_RV_REF(file_descriptor) x)            // Move ctor
+      :  os_descr_(x.os_descr_)
+   {  x.os_descr_ = 0;  }      
+
+   file_descriptor& operator=(BOOST_RV_REF(file_descriptor) x) // Move assign
+   {
+      if(os_descr_) operating_system_close_file(os_descr_);
+      os_descr_   = x.os_descr_;
+      x.os_descr_ = 0;
+      return *this;
+   }
+
+   bool empty() const   {  return os_descr_ == 0;  }
+};
+
+//]
+
+//[file_descriptor_example
+#include <boost/container/vector.hpp>
+#include <cassert>
+
+//Remember: 'file_descriptor' is NOT copyable, but it
+//can be returned from functions thanks to move semantics
+file_descriptor create_file_descriptor(const char *filename)
+{  return file_descriptor(filename);  }
+
+int main()
+{
+   //Open a file obtaining its descriptor, the temporary
+   //returned from 'create_file_descriptor' is moved to 'fd'.
+   file_descriptor fd = create_file_descriptor("filename");
+   assert(!fd.empty());
+
+   //Now move fd into a vector
+   boost::container::vector<file_descriptor> v;
+   v.push_back(boost::move(fd));
+
+   //Check ownership has been transferred
+   assert(fd.empty());
+   assert(!v[0].empty());
+
+   //Compilation error if uncommented since file_descriptor is not copyable
+   //and vector copy construction requires value_type's copy constructor:
+   //boost::container::vector<file_descriptor> v2(v);
+   return 0;
+}
+//]
+
+#include <boost/move/detail/config_end.hpp>
diff --git a/example/doc_how_works.cpp b/example/doc_how_works.cpp
new file mode 100644
index 0000000..ef28be4
--- /dev/null
+++ b/example/doc_how_works.cpp
@@ -0,0 +1,63 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config.hpp>
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+int main()
+{
+   return 0;
+}
+
+#else
+
+#include <boost/move/detail/config_begin.hpp>
+
+//[how_works_example
+#include <boost/move/core.hpp>
+#include <iostream>
+
+class sink_tester
+{
+   public: //conversions provided by BOOST_COPYABLE_AND_MOVABLE
+   operator ::boost::rv<sink_tester>&()
+      {  return *static_cast< ::boost::rv<sink_tester>* >(this);  }
+   operator const ::boost::rv<sink_tester>&() const
+      {  return *static_cast<const ::boost::rv<sink_tester>* >(this);  }
+};
+
+//Functions returning different r/lvalue types
+      sink_tester    rvalue()       {  return sink_tester(); }
+const sink_tester    const_rvalue() {  return sink_tester(); }
+      sink_tester &  lvalue()       {  static sink_tester lv; return lv; }
+const sink_tester &  const_lvalue() {  static const sink_tester clv = sink_tester(); return clv; }
+
+//BOOST_RV_REF overload
+void sink(::boost::rv<sink_tester> &)      { std::cout << "non-const rvalue catched" << std::endl; }
+//BOOST_COPY_ASSIGN_REF overload
+void sink(const ::boost::rv<sink_tester> &){ std::cout << "const (r-l)value catched" << std::endl; }
+//Overload provided by BOOST_COPYABLE_AND_MOVABLE
+void sink(sink_tester &)                   { std::cout << "non-const lvalue catched" << std::endl; }
+
+int main()
+{
+   sink(const_rvalue());   //"const (r-l)value catched"
+   sink(const_lvalue());   //"const (r-l)value catched"
+   sink(lvalue());         //"non-const lvalue catched"
+   sink(rvalue());         //"non-const rvalue catched"
+   return 0;
+}
+//]
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif
diff --git a/example/doc_move_algorithms.cpp b/example/doc_move_algorithms.cpp
new file mode 100644
index 0000000..6fe487a
--- /dev/null
+++ b/example/doc_move_algorithms.cpp
@@ -0,0 +1,46 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/move/detail/config_begin.hpp>
+
+//[move_algorithms_example
+#include "movable.hpp"
+#include <boost/move/algorithm.hpp>
+#include <cassert>
+#include <boost/aligned_storage.hpp>
+
+int main()
+{
+   const std::size_t ArraySize = 10;
+   movable movable_array[ArraySize];
+   movable movable_array2[ArraySize];
+   //move
+   boost::move(&movable_array2[0], &movable_array2[ArraySize], &movable_array[0]);
+   assert(movable_array2[0].moved());
+   assert(!movable_array[0].moved());
+
+   //move backward
+   boost::move_backward(&movable_array[0], &movable_array[ArraySize], &movable_array2[ArraySize]);
+   assert(movable_array[0].moved());
+   assert(!movable_array2[0].moved());
+
+   //uninitialized_move
+   boost::aligned_storage< sizeof(movable)*ArraySize
+                         , boost::alignment_of<movable>::value>::type storage;
+   movable *raw_movable = static_cast<movable*>(static_cast<void*>(&storage));
+   boost::uninitialized_move(&movable_array2[0], &movable_array2[ArraySize], raw_movable);
+   assert(movable_array2[0].moved());
+   assert(!raw_movable[0].moved());
+   return 0;
+}
+//]
+
+#include <boost/move/detail/config_end.hpp>
diff --git a/example/doc_move_inserter.cpp b/example/doc_move_inserter.cpp
new file mode 100644
index 0000000..c715412
--- /dev/null
+++ b/example/doc_move_inserter.cpp
@@ -0,0 +1,52 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/move/detail/config_begin.hpp>
+
+//[move_inserter_example
+#include <boost/container/list.hpp>
+#include "movable.hpp"
+#include <cassert>
+#include <algorithm>
+
+using namespace ::boost::container;
+
+typedef list<movable> list_t;
+typedef list_t::iterator l_iterator;
+
+template<class MoveInsertIterator>
+void test_move_inserter(list_t &l2, MoveInsertIterator mit)
+{
+   //Create a list with 10 default constructed objects
+   list<movable> l(10);
+   assert(!l.begin()->moved());
+   l2.clear();
+
+   //Move insert into l2 containers
+   std::copy(l.begin(), l.end(), mit);
+
+   //Check size and status
+   assert(l2.size() == l.size());
+   assert(l.begin()->moved());
+   assert(!l2.begin()->moved());
+}
+
+int main()
+{
+   list_t l2;
+   test_move_inserter(l2, boost::back_move_inserter(l2));
+   test_move_inserter(l2, boost::front_move_inserter(l2));
+   test_move_inserter(l2, boost::move_inserter(l2, l2.end()));
+   return 0;
+}
+//]
+
+#include <boost/move/detail/config_end.hpp>
diff --git a/example/doc_move_iterator.cpp b/example/doc_move_iterator.cpp
new file mode 100644
index 0000000..86d3893
--- /dev/null
+++ b/example/doc_move_iterator.cpp
@@ -0,0 +1,41 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/move/detail/config_begin.hpp>
+//[move_iterator_example
+#include <boost/container/vector.hpp>
+#include "movable.hpp"
+#include <cassert>
+
+int main()
+{
+   using namespace ::boost::container;
+
+   //Create a vector with 10 default constructed objects
+   vector<movable> v(10);
+   assert(!v[0].moved());
+
+   //Move construct all elements in v into v2
+   vector<movable> v2( boost::make_move_iterator(v.begin())
+                     , boost::make_move_iterator(v.end()));
+   assert(v[0].moved());
+   assert(!v2[0].moved());
+
+   //Now move assign all elements from in v2 back into v
+   v.assign( boost::make_move_iterator(v2.begin())
+           , boost::make_move_iterator(v2.end()));
+   assert(v2[0].moved());
+   assert(!v[0].moved());
+
+   return 0;
+}
+//]
+
+#include <boost/move/detail/config_end.hpp>
diff --git a/example/doc_move_return.cpp b/example/doc_move_return.cpp
new file mode 100644
index 0000000..0d5db0f
--- /dev/null
+++ b/example/doc_move_return.cpp
@@ -0,0 +1,70 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2014.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/move/detail/config_begin.hpp>
+
+//[move_return_example
+#include "movable.hpp"
+#include "copymovable.hpp"
+#include <boost/move/core.hpp>
+
+template<class Type>
+struct factory_functor
+{
+   typedef Type return_type;
+
+   Type operator()() const
+   {  Type t;  return BOOST_MOVE_RET(Type, t);  }
+};
+
+struct return_reference
+{
+   typedef non_copy_movable &return_type;
+
+   non_copy_movable &operator()() const
+   {  return ncm; }
+
+   static non_copy_movable ncm;
+};
+
+non_copy_movable return_reference::ncm;
+
+//A wrapper that locks a mutex while the
+//factory creates a new value.
+//It must generically move the return value
+//if possible both in C++03 and C++11
+template <class Factory>
+typename Factory::return_type lock_wrapper(Factory f)
+{
+   typedef typename Factory::return_type return_type;
+   //LOCK();
+   return_type r = f();
+   //UNLOCK();
+
+   //In C++03: boost::move() if R is not a reference and
+   //has move emulation enabled. In C++11: just return r.
+   return BOOST_MOVE_RET(return_type, r);
+}
+
+int main()
+{
+   movable m            = lock_wrapper(factory_functor<movable>     ());
+   copy_movable cm      = lock_wrapper(factory_functor<copy_movable>());
+   copyable c           = lock_wrapper(factory_functor<copyable>    ());
+   non_copy_movable &mr = lock_wrapper(return_reference             ());
+   //<-
+   (void)m; (void)cm; (void)c; (void)mr;
+   //->
+   return 0;
+}
+//]
+
+#include <boost/move/detail/config_end.hpp>
diff --git a/example/doc_template_assign.cpp b/example/doc_template_assign.cpp
new file mode 100644
index 0000000..e1959a9
--- /dev/null
+++ b/example/doc_template_assign.cpp
@@ -0,0 +1,98 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2014.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/detail/meta_utils_core.hpp>
+
+#include <boost/move/move.hpp>
+
+//[template_assign_example_foo_bar
+
+class Foo
+{
+   BOOST_COPYABLE_AND_MOVABLE(Foo)
+
+   public:
+   int i;
+   explicit Foo(int val)      : i(val)   {}
+
+   Foo(BOOST_RV_REF(Foo) obj) : i(obj.i) {}
+
+   Foo& operator=(BOOST_RV_REF(Foo) rhs)
+   {  i = rhs.i; rhs.i = 0; return *this; }
+
+   Foo& operator=(BOOST_COPY_ASSIGN_REF(Foo) rhs)
+   {  i = rhs.i; return *this;   } //(1)
+
+   template<class U> //(*) TEMPLATED ASSIGNMENT, potential problem
+   //<-
+   #if 1
+   typename ::boost::move_detail::disable_if_same<U, Foo, Foo&>::type
+   operator=(const U& rhs)
+   #else
+   //->
+   Foo& operator=(const U& rhs)
+   //<-
+   #endif
+   //->
+   {  i = -rhs.i; return *this;  } //(2)
+};
+//]
+
+struct Bar
+{
+   int i;
+   explicit Bar(int val) : i(val) {}
+};
+
+
+//<-
+#ifdef NDEBUG
+#undef NDEBUG
+#endif
+//->
+#include <cassert>
+
+int main()
+{
+//[template_assign_example_main
+   Foo foo1(1);
+   //<-
+   assert(foo1.i == 1);
+   //->
+   Foo foo2(2);
+   //<-
+   assert(foo2.i == 2);
+   Bar bar(3);
+   assert(bar.i == 3);
+   //->
+   foo2 = foo1; // Calls (1) in C++11 but (2) in C++98
+   //<-
+   assert(foo2.i == 1);
+   assert(foo1.i == 1); //Fails in C++98 unless workaround is applied
+   foo1 = bar;
+   assert(foo1.i == -3);
+   foo2 = boost::move(foo1);
+   assert(foo1.i == 0);
+   assert(foo2.i == -3);
+   //->
+   const Foo foo5(5);
+   foo2 = foo5; // Calls (1) in C++11 but (2) in C++98
+   //<-
+   assert(foo2.i == 5); //Fails in C++98 unless workaround is applied
+   assert(foo5.i == 5);
+   //->
+//]
+   return 0;
+}
+
+
+#include <boost/move/detail/config_end.hpp>
diff --git a/example/movable.hpp b/example/movable.hpp
new file mode 100644
index 0000000..7b1d990
--- /dev/null
+++ b/example/movable.hpp
@@ -0,0 +1,57 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_MOVE_TEST_MOVABLE_HPP
+#define BOOST_MOVE_TEST_MOVABLE_HPP
+
+#include <boost/move/detail/config_begin.hpp>
+
+//[movable_definition 
+//header file "movable.hpp"
+#include <boost/move/core.hpp>
+#include <boost/move/traits.hpp>
+
+//A movable class
+class movable
+{
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(movable)
+   int value_;
+
+   public:
+   movable() : value_(1){}
+
+   //Move constructor and assignment
+   movable(BOOST_RV_REF(movable) m)
+   {  value_ = m.value_;   m.value_ = 0;  }
+
+   movable & operator=(BOOST_RV_REF(movable) m)
+   {  value_ = m.value_;   m.value_ = 0;  return *this;  }
+
+   bool moved() const //Observer
+   {  return !value_; }
+
+   int value() const //Observer
+   {  return value_; }
+};
+
+namespace boost{
+
+template<>
+struct has_nothrow_move<movable>
+{
+   static const bool value = true;
+};
+
+}  //namespace boost{
+//]
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif //BOOST_MOVE_TEST_MOVABLE_HPP
diff --git a/include/boost/move/adl_move_swap.hpp b/include/boost/move/adl_move_swap.hpp
new file mode 100644
index 0000000..d9096e3
--- /dev/null
+++ b/include/boost/move/adl_move_swap.hpp
@@ -0,0 +1,272 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright 2007, 2008 Steven Watanabe, Joseph Gauterin, Niels Dekker
+// (C) Copyright Ion Gaztanaga 2005-2013. 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)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_MOVE_ADL_MOVE_SWAP_HPP
+#define BOOST_MOVE_ADL_MOVE_SWAP_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+//Based on Boost.Core's swap.
+//Many thanks to Steven Watanabe, Joseph Gauterin and Niels Dekker.
+#include <cstddef> //for std::size_t
+#include <boost/move/detail/workaround.hpp>  //forceinline
+
+//Try to avoid including <algorithm>, as it's quite big
+#if defined(_MSC_VER) && defined(BOOST_DINKUMWARE_STDLIB)
+   #include <utility>   //Dinkum libraries define std::swap in utility which is lighter than algorithm
+#elif defined(BOOST_GNU_STDLIB)
+   //For non-GCC compilers, where GNUC version is not very reliable, or old GCC versions
+   //use the good old stl_algobase header, which is quite lightweight
+   #if !defined(BOOST_GCC) || ((__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ < 3)))
+      #include <bits/stl_algobase.h>
+   #elif (__GNUC__ == 4) && (__GNUC_MINOR__ == 3)
+      //In GCC 4.3 a tiny stl_move.h was created with swap and move utilities
+      #include <bits/stl_move.h>
+   #else
+      //In GCC 4.4 stl_move.h was renamed to move.h
+      #include <bits/move.h>
+   #endif
+#elif defined(_LIBCPP_VERSION)
+   #include <type_traits>  //The initial import of libc++ defines std::swap and still there
+#elif __cplusplus >= 201103L
+   #include <utility>    //Fallback for C++ >= 2011
+#else
+   #include <algorithm>  //Fallback for C++98/03
+#endif
+
+#include <boost/move/utility_core.hpp> //for boost::move
+
+#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+namespace boost_move_member_swap {
+
+struct dont_care
+{
+   dont_care(...);
+};
+
+struct private_type
+{
+   static private_type p;
+   private_type const &operator,(int) const;
+};
+
+typedef char yes_type;            
+struct no_type{ char dummy[2]; }; 
+
+template<typename T>
+no_type is_private_type(T const &);
+
+yes_type is_private_type(private_type const &);
+
+template <typename Type>
+class has_member_function_named_swap
+{
+   struct BaseMixin
+   {
+      void swap();
+   };
+
+   struct Base : public Type, public BaseMixin { Base(); };
+   template <typename T, T t> class Helper{};
+
+   template <typename U>
+   static no_type deduce(U*, Helper<void (BaseMixin::*)(), &U::swap>* = 0);
+   static yes_type deduce(...);
+
+   public:
+   static const bool value = sizeof(yes_type) == sizeof(deduce((Base*)(0)));
+};
+
+template<typename Fun, bool HasFunc>
+struct has_member_swap_impl
+{
+   static const bool value = false;
+};
+
+template<typename Fun>
+struct has_member_swap_impl<Fun, true>
+{
+   struct FunWrap : Fun
+   {
+      FunWrap();
+
+      using Fun::swap;
+      private_type swap(dont_care) const;
+   };
+
+   static Fun &declval_fun();
+   static FunWrap declval_wrap();
+
+   static bool const value =
+      sizeof(no_type) == sizeof(is_private_type( (declval_wrap().swap(declval_fun()), 0)) );
+};
+
+template<typename Fun>
+struct has_member_swap : public has_member_swap_impl
+      <Fun, has_member_function_named_swap<Fun>::value>
+{};
+
+}  //namespace boost_move_member_swap
+
+namespace boost_move_adl_swap{
+
+template<class P1, class P2, bool = P1::value>
+struct and_op_impl
+{  static const bool value = false; };
+
+template<class P1, class P2>
+struct and_op_impl<P1, P2, true>
+{  static const bool value = P2::value;   };
+
+template<class P1, class P2>
+struct and_op
+   : and_op_impl<P1, P2>
+{};
+
+//////
+
+template<class P1, class P2, bool = P1::value>
+struct and_op_not_impl
+{  static const bool value = false; };
+
+template<class P1, class P2>
+struct and_op_not_impl<P1, P2, true>
+{  static const bool value = !P2::value;   };
+
+template<class P1, class P2>
+struct and_op_not
+   : and_op_not_impl<P1, P2>
+{};
+
+template<class T>
+BOOST_MOVE_FORCEINLINE void swap_proxy(T& x, T& y, typename boost::move_detail::enable_if_c<!boost::move_detail::has_move_emulation_enabled_impl<T>::value>::type* = 0)
+{
+   //use std::swap if argument dependent lookup fails
+   //Use using directive ("using namespace xxx;") instead as some older compilers
+   //don't do ADL with using declarations ("using ns::func;").
+   using namespace std;
+   swap(x, y);
+}
+
+template<class T>
+BOOST_MOVE_FORCEINLINE void swap_proxy(T& x, T& y
+               , typename boost::move_detail::enable_if< and_op_not_impl<boost::move_detail::has_move_emulation_enabled_impl<T>
+                                                                        , boost_move_member_swap::has_member_swap<T> >
+                                                       >::type* = 0)
+{  T t(::boost::move(x)); x = ::boost::move(y); y = ::boost::move(t);  }
+
+template<class T>
+BOOST_MOVE_FORCEINLINE void swap_proxy(T& x, T& y
+               , typename boost::move_detail::enable_if< and_op_impl< boost::move_detail::has_move_emulation_enabled_impl<T>
+                                                                    , boost_move_member_swap::has_member_swap<T> >
+                                                       >::type* = 0)
+{  x.swap(y);  }
+
+}  //namespace boost_move_adl_swap{
+
+#else
+
+namespace boost_move_adl_swap{
+
+template<class T>
+BOOST_MOVE_FORCEINLINE void swap_proxy(T& x, T& y)
+{
+   using std::swap;
+   swap(x, y);
+}
+
+}  //namespace boost_move_adl_swap{
+
+#endif   //#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+namespace boost_move_adl_swap{
+
+template<class T, std::size_t N>
+void swap_proxy(T (& x)[N], T (& y)[N])
+{
+   for (std::size_t i = 0; i < N; ++i){
+      ::boost_move_adl_swap::swap_proxy(x[i], y[i]);
+   }
+}
+
+}  //namespace boost_move_adl_swap {
+
+#endif   //!defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+namespace boost{
+
+//! Exchanges the values of a and b, using Argument Dependent Lookup (ADL) to select a
+//! specialized swap function if available. If no specialized swap function is available,
+//! std::swap is used.
+//!
+//! <b>Exception</b>: If T uses Boost.Move's move emulation and the compiler has
+//! no rvalue references then:
+//!
+//!   -  If T has a <code>T::swap(T&)</code> member, that member is called.
+//!   -  Otherwise a move-based swap is called, equivalent to: 
+//!      <code>T t(::boost::move(x)); x = ::boost::move(y); y = ::boost::move(t);</code>.
+template<class T>
+BOOST_MOVE_FORCEINLINE void adl_move_swap(T& x, T& y)
+{
+   ::boost_move_adl_swap::swap_proxy(x, y);
+}
+
+//! Exchanges elements between range [first1, last1) and another range starting at first2
+//! using boost::adl_move_swap.
+//! 
+//! Parameters:
+//!   first1, last1   -   the first range of elements to swap
+//!   first2   -   beginning of the second range of elements to swap
+//!
+//! Type requirements:
+//!   - ForwardIt1, ForwardIt2 must meet the requirements of ForwardIterator.
+//!   - The types of dereferenced ForwardIt1 and ForwardIt2 must meet the
+//!     requirements of Swappable
+//!
+//! Return value: Iterator to the element past the last element exchanged in the range
+//! beginning with first2.
+template<class ForwardIt1, class ForwardIt2>
+ForwardIt2 adl_move_swap_ranges(ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2)
+{
+    while (first1 != last1) {
+      ::boost::adl_move_swap(*first1, *first2);
+      ++first1;
+      ++first2;
+    }
+   return first2;
+}
+
+template<class BidirIt1, class BidirIt2>
+BidirIt2 adl_move_swap_ranges_backward(BidirIt1 first1, BidirIt1 last1, BidirIt2 last2)
+{
+   while (first1 != last1) {
+      ::boost::adl_move_swap(*(--last1), *(--last2));
+   }
+   return last2;
+}
+
+template<class ForwardIt1, class ForwardIt2>
+void adl_move_iter_swap(ForwardIt1 a, ForwardIt2 b)
+{
+   boost::adl_move_swap(*a, *b); 
+}
+
+}  //namespace boost{
+
+#endif   //#ifndef BOOST_MOVE_ADL_MOVE_SWAP_HPP
diff --git a/include/boost/move/algo/adaptive_merge.hpp b/include/boost/move/algo/adaptive_merge.hpp
new file mode 100644
index 0000000..4de4007
--- /dev/null
+++ b/include/boost/move/algo/adaptive_merge.hpp
@@ -0,0 +1,343 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2016.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_MOVE_ADAPTIVE_MERGE_HPP
+#define BOOST_MOVE_ADAPTIVE_MERGE_HPP
+
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/algo/detail/adaptive_sort_merge.hpp>
+
+namespace boost {
+namespace movelib {
+
+///@cond
+namespace detail_adaptive {
+
+template<class RandIt, class Compare, class XBuf>
+inline void adaptive_merge_combine_blocks( RandIt first
+                                      , typename iterator_traits<RandIt>::size_type len1
+                                      , typename iterator_traits<RandIt>::size_type len2
+                                      , typename iterator_traits<RandIt>::size_type collected
+                                      , typename iterator_traits<RandIt>::size_type n_keys
+                                      , typename iterator_traits<RandIt>::size_type l_block
+                                      , bool use_internal_buf
+                                      , bool xbuf_used
+                                      , Compare comp
+                                      , XBuf & xbuf
+                                      )
+{
+   typedef typename iterator_traits<RandIt>::size_type size_type;
+   size_type const len = len1+len2;
+   size_type const l_combine  = len-collected;
+   size_type const l_combine1 = len1-collected;
+
+    if(n_keys){
+      RandIt const first_data = first+collected;
+      RandIt const keys = first;
+      BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2("   A combine: ", len);
+      if(xbuf_used){
+         if(xbuf.size() < l_block){
+            xbuf.initialize_until(l_block, *first);
+         }
+         BOOST_ASSERT(xbuf.size() >= l_block);
+         size_type n_block_a, n_block_b, l_irreg1, l_irreg2;
+         combine_params( keys, comp, l_combine
+                           , l_combine1, l_block, xbuf
+                           , n_block_a, n_block_b, l_irreg1, l_irreg2);   //Outputs
+         op_merge_blocks_with_buf
+            (keys, comp, first_data, l_block, l_irreg1, n_block_a, n_block_b, l_irreg2, comp, move_op(), xbuf.data());
+         BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1("   A mrg xbf: ", len);
+      }
+      else{
+         size_type n_block_a, n_block_b, l_irreg1, l_irreg2;
+         combine_params( keys, comp, l_combine
+                           , l_combine1, l_block, xbuf
+                           , n_block_a, n_block_b, l_irreg1, l_irreg2);   //Outputs
+         if(use_internal_buf){
+            op_merge_blocks_with_buf
+               (keys, comp, first_data, l_block, l_irreg1, n_block_a, n_block_b, l_irreg2, comp, swap_op(), first_data-l_block);
+            BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2("   A mrg buf: ", len);
+         }
+         else{
+            merge_blocks_bufferless
+               (keys, comp, first_data, l_block, l_irreg1, n_block_a, n_block_b, l_irreg2, comp);
+            BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1("   A mrg nbf: ", len);
+         }
+      }
+   }
+   else{
+      xbuf.shrink_to_fit(l_block);
+      if(xbuf.size() < l_block){
+         xbuf.initialize_until(l_block, *first);
+      }
+      size_type *const uint_keys = xbuf.template aligned_trailing<size_type>(l_block);
+      size_type n_block_a, n_block_b, l_irreg1, l_irreg2;
+      combine_params( uint_keys, less(), l_combine
+                     , l_combine1, l_block, xbuf
+                     , n_block_a, n_block_b, l_irreg1, l_irreg2, true);   //Outputs
+      BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2("   A combine: ", len);
+      BOOST_ASSERT(xbuf.size() >= l_block);
+      op_merge_blocks_with_buf
+         (uint_keys, less(), first, l_block, l_irreg1, n_block_a, n_block_b, l_irreg2, comp, move_op(), xbuf.data());
+      xbuf.clear();
+      BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1("   A mrg buf: ", len);
+   }
+}
+
+template<class RandIt, class Compare, class XBuf>
+inline void adaptive_merge_final_merge( RandIt first
+                                      , typename iterator_traits<RandIt>::size_type len1
+                                      , typename iterator_traits<RandIt>::size_type len2
+                                      , typename iterator_traits<RandIt>::size_type collected
+                                      , typename iterator_traits<RandIt>::size_type l_intbuf
+                                      , typename iterator_traits<RandIt>::size_type l_block
+                                      , bool use_internal_buf
+                                      , bool xbuf_used
+                                      , Compare comp
+                                      , XBuf & xbuf
+                                      )
+{
+   typedef typename iterator_traits<RandIt>::size_type size_type;
+   (void)l_block;
+   size_type n_keys = collected-l_intbuf;
+   size_type len = len1+len2;
+   if(use_internal_buf){
+      if(xbuf_used){
+         xbuf.clear();
+         //Nothing to do
+         if(n_keys){
+            unstable_sort(first, first+n_keys, comp, xbuf);
+            stable_merge(first, first+n_keys, first+len, comp, xbuf);
+            BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2("   A key mrg: ", len);
+         }
+      }
+      else{
+         xbuf.clear();
+         unstable_sort(first, first+collected, comp, xbuf);
+         BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2("   A k/b srt: ", len);
+         stable_merge(first, first+collected, first+len, comp, xbuf);
+         BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2("   A k/b mrg: ", len);
+      }
+   }
+   else{
+      xbuf.clear();
+      unstable_sort(first, first+collected, comp, xbuf);
+      BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2("   A k/b srt: ", len);
+      stable_merge(first, first+collected, first+len1+len2, comp, xbuf);
+      BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2("   A k/b mrg: ", len);
+   }
+   BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1("   A fin mrg: ", len);
+}
+
+template<class SizeType>
+inline static SizeType adaptive_merge_n_keys_without_external_keys(SizeType l_block, SizeType len1, SizeType len2, SizeType l_intbuf)
+{
+   typedef SizeType size_type;
+   //This is the minimum number of keys to implement the ideal algorithm
+   size_type n_keys = len1/l_block+len2/l_block;
+   const size_type second_half_blocks = len2/l_block;
+   const size_type first_half_aux = len1-l_intbuf;
+   while(n_keys >= ((first_half_aux-n_keys)/l_block + second_half_blocks)){
+      --n_keys;
+   }
+   ++n_keys;
+   return n_keys;
+}
+
+template<class SizeType>
+inline static SizeType adaptive_merge_n_keys_with_external_keys(SizeType l_block, SizeType len1, SizeType len2, SizeType l_intbuf)
+{
+   typedef SizeType size_type;
+   //This is the minimum number of keys to implement the ideal algorithm
+   size_type n_keys = (len1-l_intbuf)/l_block + len2/l_block;
+   return n_keys;
+}
+
+template<class SizeType, class Xbuf>
+inline SizeType adaptive_merge_n_keys_intbuf(SizeType &rl_block, SizeType len1, SizeType len2, Xbuf & xbuf, SizeType &l_intbuf_inout)
+{
+   typedef SizeType size_type;
+   size_type l_block = rl_block;
+   size_type l_intbuf = xbuf.capacity() >= l_block ? 0u : l_block;
+
+   while(xbuf.capacity() >= l_block*2){
+      l_block *= 2;
+   }
+
+   //This is the minimum number of keys to implement the ideal algorithm
+   size_type n_keys = adaptive_merge_n_keys_without_external_keys(l_block, len1, len2, l_intbuf);
+   BOOST_ASSERT(n_keys >= ((len1-l_intbuf-n_keys)/l_block + len2/l_block));
+
+   if(xbuf.template supports_aligned_trailing<size_type>
+      ( l_block
+      , adaptive_merge_n_keys_with_external_keys(l_block, len1, len2, l_intbuf)))
+   {
+      n_keys = 0u;
+   }
+   l_intbuf_inout = l_intbuf;
+   rl_block = l_block;
+   return n_keys;
+}
+
+// Main explanation of the merge algorithm.
+//
+// csqrtlen = ceil(sqrt(len));
+//
+// * First, csqrtlen [to be used as buffer] + (len/csqrtlen - 1) [to be used as keys] => to_collect
+//   unique elements are extracted from elements to be sorted and placed in the beginning of the range.
+//
+// * Step "combine_blocks": the leading (len1-to_collect) elements plus trailing len2 elements
+//   are merged with a non-trivial ("smart") algorithm to form an ordered range trailing "len-to_collect" elements.
+//
+//   Explanation of the "combine_blocks" step:
+//
+//         * Trailing [first+to_collect, first+len1) elements are divided in groups of cqrtlen elements.
+//           Remaining elements that can't form a group are grouped in front of those elements.
+//         * Trailing [first+len1, first+len1+len2) elements are divided in groups of cqrtlen elements.
+//           Remaining elements that can't form a group are grouped in the back of those elements.
+//         * In parallel the following two steps are performed:
+//             *  Groups are selection-sorted by first or last element (depending whether they are going
+//                to be merged to left or right) and keys are reordered accordingly as an imitation-buffer.
+//             * Elements of each block pair are merged using the csqrtlen buffer taking into account
+//                if they belong to the first half or second half (marked by the key).
+//
+// * In the final merge step leading "to_collect" elements are merged with rotations
+//   with the rest of merged elements in the "combine_blocks" step.
+//
+// Corner cases:
+//
+// * If no "to_collect" elements can be extracted:
+//
+//    * If more than a minimum number of elements is extracted
+//      then reduces the number of elements used as buffer and keys in the
+//      and "combine_blocks" steps. If "combine_blocks" has no enough keys due to this reduction
+//      then uses a rotation based smart merge.
+//
+//    * If the minimum number of keys can't be extracted, a rotation-based merge is performed.
+//
+// * If auxiliary memory is more or equal than min(len1, len2), a buffered merge is performed.
+//
+// * If the len1 or len2 are less than 2*csqrtlen then a rotation-based merge is performed.
+//
+// * If auxiliary memory is more than csqrtlen+n_keys*sizeof(std::size_t),
+//   then no csqrtlen need to be extracted and "combine_blocks" will use integral
+//   keys to combine blocks.
+template<class RandIt, class Compare, class XBuf>
+void adaptive_merge_impl
+   ( RandIt first
+   , typename iterator_traits<RandIt>::size_type len1
+   , typename iterator_traits<RandIt>::size_type len2
+   , Compare comp
+   , XBuf & xbuf
+   )
+{
+   typedef typename iterator_traits<RandIt>::size_type size_type;
+
+   if(xbuf.capacity() >= min_value<size_type>(len1, len2)){
+      buffered_merge(first, first+len1, first+(len1+len2), comp, xbuf);
+   }
+   else{
+      const size_type len = len1+len2;
+      //Calculate ideal parameters and try to collect needed unique keys
+      size_type l_block = size_type(ceil_sqrt(len));
+
+      //One range is not big enough to extract keys and the internal buffer so a
+      //rotation-based based merge will do just fine
+      if(len1 <= l_block*2 || len2 <= l_block*2){
+         merge_bufferless(first, first+len1, first+len1+len2, comp);
+         return;
+      }
+
+      //Detail the number of keys and internal buffer. If xbuf has enough memory, no
+      //internal buffer is needed so l_intbuf will remain 0.
+      size_type l_intbuf = 0;
+      size_type n_keys = adaptive_merge_n_keys_intbuf(l_block, len1, len2, xbuf, l_intbuf);
+      size_type const to_collect = l_intbuf+n_keys;
+      //Try to extract needed unique values from the first range
+      size_type const collected  = collect_unique(first, first+len1, to_collect, comp, xbuf);
+      BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1("\n   A collect: ", len);
+
+      //Not the minimum number of keys is not available on the first range, so fallback to rotations
+      if(collected != to_collect && collected < 4){
+         merge_bufferless(first, first+collected, first+len1, comp);
+         merge_bufferless(first, first + len1, first + len1 + len2, comp);
+         return;
+      }
+
+      //If not enough keys but more than minimum, adjust the internal buffer and key count
+      bool use_internal_buf = collected == to_collect;
+      if (!use_internal_buf){
+         l_intbuf = 0u;
+         n_keys = collected;
+         l_block  = lblock_for_combine(l_intbuf, n_keys, len, use_internal_buf);
+         //If use_internal_buf is false, then then internal buffer will be zero and rotation-based combination will be used
+         l_intbuf = use_internal_buf ? l_block : 0u;
+      }
+
+      bool const xbuf_used = collected == to_collect && xbuf.capacity() >= l_block;
+      //Merge trailing elements using smart merges
+      adaptive_merge_combine_blocks(first, len1, len2, collected,   n_keys, l_block, use_internal_buf, xbuf_used, comp, xbuf);
+      //Merge buffer and keys with the rest of the values
+      adaptive_merge_final_merge   (first, len1, len2, collected, l_intbuf, l_block, use_internal_buf, xbuf_used, comp, xbuf);
+   }
+}
+
+}  //namespace detail_adaptive {
+
+///@endcond
+
+//! <b>Effects</b>: Merges two consecutive sorted ranges [first, middle) and [middle, last)
+//!   into one sorted range [first, last) according to the given comparison function comp.
+//!   The algorithm is stable (if there are equivalent elements in the original two ranges,
+//!   the elements from the first range (preserving their original order) precede the elements
+//!   from the second range (preserving their original order).
+//!
+//! <b>Requires</b>:
+//!   - RandIt must meet the requirements of ValueSwappable and RandomAccessIterator.
+//!   - The type of dereferenced RandIt must meet the requirements of MoveAssignable and MoveConstructible.
+//!
+//! <b>Parameters</b>:
+//!   - first: the beginning of the first sorted range. 
+//!   - middle: the end of the first sorted range and the beginning of the second
+//!   - last: the end of the second sorted range
+//!   - comp: comparison function object which returns true if the first argument is is ordered before the second.
+//!   - uninitialized, uninitialized_len: raw storage starting on "uninitialized", able to hold "uninitialized_len"
+//!      elements of type iterator_traits<RandIt>::value_type. Maximum performance is achieved when uninitialized_len
+//!      is min(std::distance(first, middle), std::distance(middle, last)).
+//!
+//! <b>Throws</b>: If comp throws or the move constructor, move assignment or swap of the type
+//!   of dereferenced RandIt throws.
+//!
+//! <b>Complexity</b>: Always K x O(N) comparisons and move assignments/constructors/swaps.
+//!   Constant factor for comparisons and data movement is minimized when uninitialized_len
+//!   is min(std::distance(first, middle), std::distance(middle, last)).
+//!   Pretty good enough performance is achieved when uninitialized_len is
+//!   ceil(sqrt(std::distance(first, last)))*2.
+//!
+//! <b>Caution</b>: Experimental implementation, not production-ready.
+template<class RandIt, class Compare>
+void adaptive_merge( RandIt first, RandIt middle, RandIt last, Compare comp
+                , typename iterator_traits<RandIt>::value_type* uninitialized = 0
+                , std::size_t uninitialized_len = 0)
+{
+   typedef typename iterator_traits<RandIt>::size_type  size_type;
+   typedef typename iterator_traits<RandIt>::value_type value_type;
+
+   ::boost::movelib::detail_adaptive::adaptive_xbuf<value_type> xbuf(uninitialized, uninitialized_len);
+   ::boost::movelib::detail_adaptive::adaptive_merge_impl(first, size_type(middle - first), size_type(last - middle), comp, xbuf);
+}
+
+}  //namespace movelib {
+}  //namespace boost {
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif   //#define BOOST_MOVE_ADAPTIVE_MERGE_HPP
diff --git a/include/boost/move/algo/adaptive_sort.hpp b/include/boost/move/algo/adaptive_sort.hpp
new file mode 100644
index 0000000..4f50bf1
--- /dev/null
+++ b/include/boost/move/algo/adaptive_sort.hpp
@@ -0,0 +1,631 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2016.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_MOVE_ADAPTIVE_SORT_HPP
+#define BOOST_MOVE_ADAPTIVE_SORT_HPP
+
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/algo/detail/adaptive_sort_merge.hpp>
+
+namespace boost {
+namespace movelib {
+
+///@cond
+namespace detail_adaptive {
+
+template<class RandIt>
+void move_data_backward( RandIt cur_pos
+              , typename iterator_traits<RandIt>::size_type const l_data
+              , RandIt new_pos
+              , bool const xbuf_used)
+{
+   //Move buffer to the total combination right
+   if(xbuf_used){
+      boost::move_backward(cur_pos, cur_pos+l_data, new_pos+l_data);      
+   }
+   else{
+      boost::adl_move_swap_ranges_backward(cur_pos, cur_pos+l_data, new_pos+l_data);      
+      //Rotate does less moves but it seems slower due to cache issues
+      //rotate_gcd(first-l_block, first+len-l_block, first+len);
+   }
+}
+
+template<class RandIt>
+void move_data_forward( RandIt cur_pos
+              , typename iterator_traits<RandIt>::size_type const l_data
+              , RandIt new_pos
+              , bool const xbuf_used)
+{
+   //Move buffer to the total combination right
+   if(xbuf_used){
+      boost::move(cur_pos, cur_pos+l_data, new_pos);
+   }
+   else{
+      boost::adl_move_swap_ranges(cur_pos, cur_pos+l_data, new_pos);
+      //Rotate does less moves but it seems slower due to cache issues
+      //rotate_gcd(first-l_block, first+len-l_block, first+len);
+   }
+}
+
+// build blocks of length 2*l_build_buf. l_build_buf is power of two
+// input: [0, l_build_buf) elements are buffer, rest unsorted elements
+// output: [0, l_build_buf) elements are buffer, blocks 2*l_build_buf and last subblock sorted
+//
+// First elements are merged from right to left until elements start
+// at first. All old elements [first, first + l_build_buf) are placed at the end
+// [first+len-l_build_buf, first+len). To achieve this:
+// - If we have external memory to merge, we save elements from the buffer
+//   so that a non-swapping merge is used. Buffer elements are restored
+//   at the end of the buffer from the external memory.
+//
+// - When the external memory is not available or it is insufficient
+//   for a merge operation, left swap merging is used.
+//
+// Once elements are merged left to right in blocks of l_build_buf, then a single left
+// to right merge step is performed to achieve merged blocks of size 2K.
+// If external memory is available, usual merge is used, swap merging otherwise.
+//
+// As a last step, if auxiliary memory is available in-place merge is performed.
+// until all is merged or auxiliary memory is not large enough.
+template<class RandIt, class Compare, class XBuf>
+typename iterator_traits<RandIt>::size_type  
+   adaptive_sort_build_blocks
+      ( RandIt const first
+      , typename iterator_traits<RandIt>::size_type const len
+      , typename iterator_traits<RandIt>::size_type const l_base
+      , typename iterator_traits<RandIt>::size_type const l_build_buf
+      , XBuf & xbuf
+      , Compare comp)
+{
+   typedef typename iterator_traits<RandIt>::size_type  size_type;
+   BOOST_ASSERT(l_build_buf <= len);
+   BOOST_ASSERT(0 == ((l_build_buf / l_base)&(l_build_buf/l_base-1)));
+
+   //Place the start pointer after the buffer
+   RandIt first_block = first + l_build_buf;
+   size_type const elements_in_blocks = len - l_build_buf;
+
+   //////////////////////////////////
+   // Start of merge to left step
+   //////////////////////////////////
+   size_type l_merged = 0u;
+
+   BOOST_ASSERT(l_build_buf);
+   //If there is no enough buffer for the insertion sort step, just avoid the external buffer
+   size_type kbuf = min_value<size_type>(l_build_buf, size_type(xbuf.capacity()));
+   kbuf = kbuf < l_base ? 0 : kbuf;
+
+   if(kbuf){
+      //Backup internal buffer values in external buffer so they can be overwritten
+      xbuf.move_assign(first+l_build_buf-kbuf, kbuf);
+      l_merged = op_insertion_sort_step_left(first_block, elements_in_blocks, l_base, comp, move_op());
+
+      //Now combine them using the buffer. Elements from buffer can be
+      //overwritten since they've been saved to xbuf
+      l_merged = op_merge_left_step_multiple
+         ( first_block - l_merged, elements_in_blocks, l_merged, l_build_buf, kbuf - l_merged, comp, move_op());
+
+      //Restore internal buffer from external buffer unless kbuf was l_build_buf,
+      //in that case restoration will happen later
+      if(kbuf != l_build_buf){
+         boost::move(xbuf.data()+kbuf-l_merged, xbuf.data() + kbuf, first_block-l_merged+elements_in_blocks);
+      }
+   }
+   else{
+      l_merged = insertion_sort_step(first_block, elements_in_blocks, l_base, comp);
+      rotate_gcd(first_block - l_merged, first_block, first_block+elements_in_blocks);
+   }
+
+   //Now combine elements using the buffer. Elements from buffer can't be
+   //overwritten since xbuf was not big enough, so merge swapping elements.
+   l_merged = op_merge_left_step_multiple
+      (first_block - l_merged, elements_in_blocks, l_merged, l_build_buf, l_build_buf - l_merged, comp, swap_op());
+
+   BOOST_ASSERT(l_merged == l_build_buf);
+
+   //////////////////////////////////
+   // Start of merge to right step
+   //////////////////////////////////
+
+   //If kbuf is l_build_buf then we can merge right without swapping
+   //Saved data is still in xbuf
+   if(kbuf && kbuf == l_build_buf){
+      op_merge_right_step_once(first, elements_in_blocks, l_build_buf, comp, move_op());
+      //Restore internal buffer from external buffer if kbuf was l_build_buf.
+      //as this operation was previously delayed.
+      boost::move(xbuf.data(), xbuf.data() + kbuf, first);
+   }
+   else{
+      op_merge_right_step_once(first, elements_in_blocks, l_build_buf, comp, swap_op());
+   }
+   xbuf.clear();
+   //2*l_build_buf or total already merged
+   return min_value(elements_in_blocks, 2*l_build_buf);
+}
+
+template<class RandItKeys, class KeyCompare, class RandIt, class Compare, class XBuf>
+void adaptive_sort_combine_blocks
+   ( RandItKeys const keys
+   , KeyCompare key_comp
+   , RandIt const first
+   , typename iterator_traits<RandIt>::size_type const len
+   , typename iterator_traits<RandIt>::size_type const l_prev_merged
+   , typename iterator_traits<RandIt>::size_type const l_block
+   , bool const use_buf
+   , bool const xbuf_used
+   , XBuf & xbuf
+   , Compare comp
+   , bool merge_left)
+{
+   (void)xbuf;
+   typedef typename iterator_traits<RandIt>::size_type   size_type;
+
+   size_type const l_reg_combined   = 2*l_prev_merged;
+   size_type l_irreg_combined = 0;
+   size_type const l_total_combined = calculate_total_combined(len, l_prev_merged, &l_irreg_combined);
+   size_type const n_reg_combined = len/l_reg_combined;
+   RandIt combined_first = first;
+
+   (void)l_total_combined;
+   BOOST_ASSERT(l_total_combined <= len);
+
+   size_type const max_i = n_reg_combined + (l_irreg_combined != 0);
+
+   if(merge_left || !use_buf) {
+      for( size_type combined_i = 0; combined_i != max_i; ++combined_i, combined_first += l_reg_combined) {
+         //Now merge blocks
+         bool const is_last = combined_i==n_reg_combined;
+         size_type const l_cur_combined = is_last ? l_irreg_combined : l_reg_combined;
+
+         range_xbuf<RandIt, move_op> rbuf( (use_buf && xbuf_used) ? (combined_first-l_block) : combined_first, combined_first);
+         size_type n_block_a, n_block_b, l_irreg1, l_irreg2;
+         combine_params( keys, key_comp, l_cur_combined
+                        , l_prev_merged, l_block, rbuf
+                        , n_block_a, n_block_b, l_irreg1, l_irreg2);   //Outputs
+         BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2("   A combpar:            ", len + l_block);
+         BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(combined_first, combined_first + n_block_a*l_block+l_irreg1, comp));
+            BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(combined_first + n_block_a*l_block+l_irreg1, combined_first + n_block_a*l_block+l_irreg1+n_block_b*l_block+l_irreg2, comp));
+         if(!use_buf){
+            merge_blocks_bufferless
+               (keys, key_comp, combined_first, l_block, 0u, n_block_a, n_block_b, l_irreg2, comp);
+         }
+         else{
+            merge_blocks_left
+               (keys, key_comp, combined_first, l_block, 0u, n_block_a, n_block_b, l_irreg2, comp, xbuf_used);
+         }
+         BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2("   After merge_blocks_L: ", len + l_block);
+      }
+   }
+   else{
+      combined_first += l_reg_combined*(max_i-1);
+      for( size_type combined_i = max_i; combined_i--; combined_first -= l_reg_combined) {
+         bool const is_last = combined_i==n_reg_combined;
+         size_type const l_cur_combined = is_last ? l_irreg_combined : l_reg_combined;
+
+         RandIt const combined_last(combined_first+l_cur_combined);
+         range_xbuf<RandIt, move_op> rbuf(combined_last, xbuf_used ? (combined_last+l_block) : combined_last);
+         size_type n_block_a, n_block_b, l_irreg1, l_irreg2;
+         combine_params( keys, key_comp, l_cur_combined
+                        , l_prev_merged, l_block, rbuf
+                        , n_block_a, n_block_b, l_irreg1, l_irreg2);  //Outputs
+         BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2("   A combpar:            ", len + l_block);
+         BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(combined_first, combined_first + n_block_a*l_block+l_irreg1, comp));
+         BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(combined_first + n_block_a*l_block+l_irreg1, combined_first + n_block_a*l_block+l_irreg1+n_block_b*l_block+l_irreg2, comp));
+         merge_blocks_right
+            (keys, key_comp, combined_first, l_block, n_block_a, n_block_b, l_irreg2, comp, xbuf_used);
+         BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2("   After merge_blocks_R: ", len + l_block);
+      }
+   }
+}
+
+//Returns true if buffer is placed in 
+//[buffer+len-l_intbuf, buffer+len). Otherwise, buffer is
+//[buffer,buffer+l_intbuf)
+template<class RandIt, class Compare, class XBuf>
+bool adaptive_sort_combine_all_blocks
+   ( RandIt keys
+   , typename iterator_traits<RandIt>::size_type &n_keys
+   , RandIt const buffer
+   , typename iterator_traits<RandIt>::size_type const l_buf_plus_data
+   , typename iterator_traits<RandIt>::size_type l_merged
+   , typename iterator_traits<RandIt>::size_type &l_intbuf
+   , XBuf & xbuf
+   , Compare comp)
+{
+   typedef typename iterator_traits<RandIt>::size_type  size_type;
+   RandIt const first = buffer + l_intbuf;
+   size_type const l_data = l_buf_plus_data - l_intbuf;
+   size_type const l_unique = l_intbuf+n_keys;
+   //Backup data to external buffer once if possible
+   bool const common_xbuf = l_data > l_merged && l_intbuf && l_intbuf <= xbuf.capacity();
+   if(common_xbuf){
+      xbuf.move_assign(buffer, l_intbuf);
+   }
+
+   bool prev_merge_left = true;
+   size_type l_prev_total_combined = l_merged, l_prev_block = 0;
+   bool prev_use_internal_buf = true;
+
+   for( size_type n = 0; l_data > l_merged
+      ; l_merged*=2
+      , ++n){
+      //If l_intbuf is non-zero, use that internal buffer.
+      //    Implies l_block == l_intbuf && use_internal_buf == true
+      //If l_intbuf is zero, see if half keys can be reused as a reduced emergency buffer,
+      //    Implies l_block == n_keys/2 && use_internal_buf == true
+      //Otherwise, just give up and and use all keys to merge using rotations (use_internal_buf = false)
+      bool use_internal_buf = false;
+      size_type const l_block = lblock_for_combine(l_intbuf, n_keys, 2*l_merged, use_internal_buf);
+      BOOST_ASSERT(!l_intbuf || (l_block == l_intbuf));
+      BOOST_ASSERT(n == 0 || (!use_internal_buf || prev_use_internal_buf) );
+      BOOST_ASSERT(n == 0 || (!use_internal_buf || l_prev_block == l_block) );
+      
+      bool const is_merge_left = (n&1) == 0;
+      size_type const l_total_combined = calculate_total_combined(l_data, l_merged);
+      if(n && prev_use_internal_buf && prev_merge_left){
+         if(is_merge_left || !use_internal_buf){
+            move_data_backward(first-l_prev_block, l_prev_total_combined, first, common_xbuf);
+         }
+         else{
+            //Put the buffer just after l_total_combined
+            RandIt const buf_end = first+l_prev_total_combined;
+            RandIt const buf_beg = buf_end-l_block;
+            if(l_prev_total_combined > l_total_combined){
+               size_type const l_diff = l_prev_total_combined - l_total_combined;
+               move_data_backward(buf_beg-l_diff, l_diff, buf_end-l_diff, common_xbuf);
+            }
+            else if(l_prev_total_combined < l_total_combined){
+               size_type const l_diff = l_total_combined - l_prev_total_combined;
+               move_data_forward(buf_end, l_diff, buf_beg, common_xbuf);
+            }
+         }
+         BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2("   After move_data     : ", l_data + l_intbuf);
+      }
+
+      //Combine to form l_merged*2 segments
+      if(n_keys){
+         size_type upper_n_keys_this_iter = 2*l_merged/l_block;
+         if(upper_n_keys_this_iter > 256){
+            adaptive_sort_combine_blocks
+               ( keys, comp, !use_internal_buf || is_merge_left ? first : first-l_block
+               , l_data, l_merged, l_block, use_internal_buf, common_xbuf, xbuf, comp, is_merge_left);
+         }
+         else{
+            unsigned char uint_keys[256];
+            adaptive_sort_combine_blocks
+               ( uint_keys, less(), !use_internal_buf || is_merge_left ? first : first-l_block
+               , l_data, l_merged, l_block, use_internal_buf, common_xbuf, xbuf, comp, is_merge_left);
+            }
+      }
+      else{
+         size_type *const uint_keys = xbuf.template aligned_trailing<size_type>();
+         adaptive_sort_combine_blocks
+            ( uint_keys, less(), !use_internal_buf || is_merge_left ? first : first-l_block
+            , l_data, l_merged, l_block, use_internal_buf, common_xbuf, xbuf, comp, is_merge_left);
+      }
+
+      BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1(is_merge_left ? "   After comb blocks L:  " : "   After comb blocks R:  ", l_data + l_intbuf);
+      prev_merge_left = is_merge_left;
+      l_prev_total_combined = l_total_combined;
+      l_prev_block = l_block;
+      prev_use_internal_buf = use_internal_buf;
+   }
+   BOOST_ASSERT(l_prev_total_combined == l_data);
+   bool const buffer_right = prev_use_internal_buf && prev_merge_left;
+
+   l_intbuf = prev_use_internal_buf ? l_prev_block : 0u;
+   n_keys = l_unique - l_intbuf;
+   //Restore data from to external common buffer if used
+   if(common_xbuf){
+      if(buffer_right){
+         boost::move(xbuf.data(), xbuf.data() + l_intbuf, buffer+l_data);
+      }
+      else{
+         boost::move(xbuf.data(), xbuf.data() + l_intbuf, buffer);
+      }
+   }
+   return buffer_right;
+}
+
+
+template<class RandIt, class Compare, class XBuf>
+void adaptive_sort_final_merge( bool buffer_right
+                              , RandIt const first
+                              , typename iterator_traits<RandIt>::size_type const l_intbuf
+                              , typename iterator_traits<RandIt>::size_type const n_keys
+                              , typename iterator_traits<RandIt>::size_type const len
+                              , XBuf & xbuf
+                              , Compare comp)
+{
+   //BOOST_ASSERT(n_keys || xbuf.size() == l_intbuf);
+   xbuf.clear();
+
+   typedef typename iterator_traits<RandIt>::size_type  size_type;
+   size_type const n_key_plus_buf = l_intbuf+n_keys;
+   if(buffer_right){
+      //Use stable sort as some buffer elements might not be unique (see non_unique_buf)
+      stable_sort(first+len-l_intbuf, first+len, comp, xbuf);
+      stable_merge(first+n_keys, first+len-l_intbuf, first+len, antistable<Compare>(comp), xbuf);
+      unstable_sort(first, first+n_keys, comp, xbuf);
+      stable_merge(first, first+n_keys, first+len, comp, xbuf);
+   }
+   else{
+      //Use stable sort as some buffer elements might not be unique (see non_unique_buf)
+      stable_sort(first, first+n_key_plus_buf, comp, xbuf);
+      if(xbuf.capacity() >= n_key_plus_buf){
+         buffered_merge(first, first+n_key_plus_buf, first+len, comp, xbuf);
+      }
+      else if(xbuf.capacity() >= min_value<size_type>(l_intbuf, n_keys)){
+         stable_merge(first+n_keys, first+n_key_plus_buf, first+len, comp, xbuf);
+         stable_merge(first, first+n_keys, first+len, comp, xbuf);
+      }
+      else{
+         stable_merge(first, first+n_key_plus_buf, first+len, comp, xbuf);
+      }
+   }
+   BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1("   After final_merge   : ", len);
+}
+
+template<class RandIt, class Compare, class Unsigned, class XBuf>
+bool adaptive_sort_build_params
+   (RandIt first, Unsigned const len, Compare comp
+   , Unsigned &n_keys, Unsigned &l_intbuf, Unsigned &l_base, Unsigned &l_build_buf
+   , XBuf & xbuf
+   )
+{
+   typedef Unsigned size_type;
+
+   //Calculate ideal parameters and try to collect needed unique keys
+   l_base = 0u;
+
+   //Try to find a value near sqrt(len) that is 2^N*l_base where
+   //l_base <= AdaptiveSortInsertionSortThreshold. This property is important
+   //as build_blocks merges to the left iteratively duplicating the
+   //merged size and all the buffer must be used just before the final
+   //merge to right step. This guarantees "build_blocks" produces 
+   //segments of size l_build_buf*2, maximizing the classic merge phase.
+   l_intbuf = size_type(ceil_sqrt_multiple(len, &l_base));
+
+   //The internal buffer can be expanded if there is enough external memory
+   while(xbuf.capacity() >= l_intbuf*2){
+      l_intbuf *= 2;
+   }
+
+   //This is the minimum number of keys to implement the ideal algorithm
+   //
+   //l_intbuf is used as buffer plus the key count
+   size_type n_min_ideal_keys = l_intbuf-1;
+   while(n_min_ideal_keys >= (len-l_intbuf-n_min_ideal_keys)/l_intbuf){
+      --n_min_ideal_keys;
+   }
+   n_min_ideal_keys += 1;
+   BOOST_ASSERT(n_min_ideal_keys <= l_intbuf);
+
+   if(xbuf.template supports_aligned_trailing<size_type>(l_intbuf, (len-l_intbuf-1)/l_intbuf+1)){
+      n_keys = 0u;
+      l_build_buf = l_intbuf;
+   }
+   else{
+      //Try to achieve a l_build_buf of length l_intbuf*2, so that we can merge with that
+      //l_intbuf*2 buffer in "build_blocks" and use half of them as buffer and the other half
+      //as keys in combine_all_blocks. In that case n_keys >= n_min_ideal_keys but by a small margin.
+      //
+      //If available memory is 2*sqrt(l), then only sqrt(l) unique keys are needed,
+      //(to be used for keys in combine_all_blocks) as the whole l_build_buf
+      //will be backuped in the buffer during build_blocks.
+      bool const non_unique_buf = xbuf.capacity() >= l_intbuf;
+      size_type const to_collect = non_unique_buf ? n_min_ideal_keys : l_intbuf*2;
+      size_type collected = collect_unique(first, first+len, to_collect, comp, xbuf);
+
+      //If available memory is 2*sqrt(l), then for "build_params" 
+      //the situation is the same as if 2*l_intbuf were collected.
+      if(non_unique_buf && collected == n_min_ideal_keys){
+         l_build_buf = l_intbuf;
+         n_keys = n_min_ideal_keys;
+      }
+      else if(collected == 2*l_intbuf){
+         //l_intbuf*2 elements found. Use all of them in the build phase 
+         l_build_buf = l_intbuf*2;
+         n_keys = l_intbuf;
+      }
+      else if(collected == (n_min_ideal_keys+l_intbuf)){ 
+         l_build_buf = l_intbuf;
+         n_keys = n_min_ideal_keys;
+      }
+      //If collected keys are not enough, try to fix n_keys and l_intbuf. If no fix
+      //is possible (due to very low unique keys), then go to a slow sort based on rotations.
+      else{
+         BOOST_ASSERT(collected < (n_min_ideal_keys+l_intbuf));
+         if(collected < 4){  //No combination possible with less that 4 keys
+            return false;
+         }
+         n_keys = l_intbuf;
+         while(n_keys&(n_keys-1)){
+            n_keys &= n_keys-1;  // make it power or 2
+         }
+         while(n_keys > collected){
+            n_keys/=2;
+         }
+         //AdaptiveSortInsertionSortThreshold is always power of two so the minimum is power of two
+         l_base = min_value<Unsigned>(n_keys, AdaptiveSortInsertionSortThreshold);
+         l_intbuf = 0;
+         l_build_buf = n_keys;
+      }
+      BOOST_ASSERT((n_keys+l_intbuf) >= l_build_buf);
+   }
+
+   return true;
+}
+
+// Main explanation of the sort algorithm.
+//
+// csqrtlen = ceil(sqrt(len));
+//
+// * First, 2*csqrtlen unique elements elements are extracted from elements to be
+//   sorted and placed in the beginning of the range.
+//
+// * Step "build_blocks": In this nearly-classic merge step, 2*csqrtlen unique elements
+//   will be used as auxiliary memory, so trailing len-2*csqrtlen elements are
+//   are grouped in blocks of sorted 4*csqrtlen elements. At the end of the step
+//   2*csqrtlen unique elements are again the leading elements of the whole range.
+//
+// * Step "combine_blocks": pairs of previously formed blocks are merged with a different
+//   ("smart") algorithm to form blocks of 8*csqrtlen elements. This step is slower than the
+//   "build_blocks" step and repeated iteratively (forming blocks of 16*csqrtlen, 32*csqrtlen
+//   elements, etc) of until all trailing (len-2*csqrtlen) elements are merged.
+//
+//   In "combine_blocks" len/csqrtlen elements used are as "keys" (markers) to
+//   know if elements belong to the first or second block to be merged and another 
+//   leading csqrtlen elements are used as buffer. Explanation of the "combine_blocks" step:
+//
+//   Iteratively until all trailing (len-2*csqrtlen) elements are merged:
+//      Iteratively for each pair of previously merged block:
+//         * Blocks are divided groups of csqrtlen elements and
+//           2*merged_block/csqrtlen keys are sorted to be used as markers
+//         * Groups are selection-sorted by first or last element (depending whether they are going
+//           to be merged to left or right) and keys are reordered accordingly as an imitation-buffer.
+//         * Elements of each block pair are merged using the csqrtlen buffer taking into account
+//           if they belong to the first half or second half (marked by the key).
+//
+// * In the final merge step leading elements (2*csqrtlen) are sorted and merged with
+//   rotations with the rest of sorted elements in the "combine_blocks" step.
+//
+// Corner cases:
+//
+// * If no 2*csqrtlen elements can be extracted:
+//
+//    * If csqrtlen+len/csqrtlen are extracted, then only csqrtlen elements are used
+//      as buffer in the "build_blocks" step forming blocks of 2*csqrtlen elements. This
+//      means that an additional "combine_blocks" step will be needed to merge all elements.
+//    
+//    * If no csqrtlen+len/csqrtlen elements can be extracted, but still more than a minimum,
+//      then reduces the number of elements used as buffer and keys in the "build_blocks"
+//      and "combine_blocks" steps. If "combine_blocks" has no enough keys due to this reduction
+//      then uses a rotation based smart merge.
+//
+//    * If the minimum number of keys can't be extracted, a rotation-based sorting is performed.
+//
+// * If auxiliary memory is more or equal than ceil(len/2), half-copying mergesort is used.
+//
+// * If auxiliary memory is more than csqrtlen+n_keys*sizeof(std::size_t),
+//   then only csqrtlen elements need to be extracted and "combine_blocks" will use integral
+//   keys to combine blocks.
+//
+// * If auxiliary memory is available, the "build_blocks" will be extended to build bigger blocks
+//   using classic merge and "combine_blocks" will use bigger blocks when merging.
+template<class RandIt, class Compare, class XBuf>
+void adaptive_sort_impl
+   ( RandIt first
+   , typename iterator_traits<RandIt>::size_type const len
+   , Compare comp
+   , XBuf & xbuf
+   )
+{
+   typedef typename iterator_traits<RandIt>::size_type  size_type;
+
+   //Small sorts go directly to insertion sort
+   if(len <= size_type(AdaptiveSortInsertionSortThreshold)){
+      insertion_sort(first, first + len, comp);
+   }
+   else if((len-len/2) <= xbuf.capacity()){
+      merge_sort(first, first+len, comp, xbuf.data());
+   }
+   else{
+      //Make sure it is at least four
+      BOOST_STATIC_ASSERT(AdaptiveSortInsertionSortThreshold >= 4);
+
+      size_type l_base = 0;
+      size_type l_intbuf = 0;
+      size_type n_keys = 0;
+      size_type l_build_buf = 0;
+
+      //Calculate and extract needed unique elements. If a minimum is not achieved
+      //fallback to a slow stable sort
+      if(!adaptive_sort_build_params(first, len, comp, n_keys, l_intbuf, l_base, l_build_buf, xbuf)){
+         stable_sort(first, first+len, comp, xbuf);
+      }
+      else{
+         BOOST_ASSERT(l_build_buf);
+         //Otherwise, continue the adaptive_sort
+         BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1("\n   After collect_unique: ", len);
+         size_type const n_key_plus_buf = l_intbuf+n_keys;
+         //l_build_buf is always power of two if l_intbuf is zero
+         BOOST_ASSERT(l_intbuf || (0 == (l_build_buf & (l_build_buf-1))));
+
+         //Classic merge sort until internal buffer and xbuf are exhausted
+         size_type const l_merged = adaptive_sort_build_blocks
+            (first+n_key_plus_buf-l_build_buf, len-n_key_plus_buf+l_build_buf, l_base, l_build_buf, xbuf, comp);
+         BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1("   After build_blocks:   ", len);
+
+         //Non-trivial merge
+         bool const buffer_right = adaptive_sort_combine_all_blocks
+            (first, n_keys, first+n_keys, len-n_keys, l_merged, l_intbuf, xbuf, comp);
+
+         //Sort keys and buffer and merge the whole sequence
+         adaptive_sort_final_merge(buffer_right, first, l_intbuf, n_keys, len, xbuf, comp);
+      }
+   }
+}
+
+}  //namespace detail_adaptive {
+
+///@endcond
+
+//! <b>Effects</b>: Sorts the elements in the range [first, last) in ascending order according
+//!   to comparison functor "comp". The sort is stable (order of equal elements
+//!   is guaranteed to be preserved). Performance is improved if additional raw storage is
+//!   provided.
+//!
+//! <b>Requires</b>:
+//!   - RandIt must meet the requirements of ValueSwappable and RandomAccessIterator.
+//!   - The type of dereferenced RandIt must meet the requirements of MoveAssignable and MoveConstructible.
+//!
+//! <b>Parameters</b>:
+//!   - first, last: the range of elements to sort
+//!   - comp: comparison function object which returns true if the first argument is is ordered before the second.
+//!   - uninitialized, uninitialized_len: raw storage starting on "uninitialized", able to hold "uninitialized_len"
+//!      elements of type iterator_traits<RandIt>::value_type. Maximum performance is achieved when uninitialized_len
+//!      is ceil(std::distance(first, last)/2).
+//!
+//! <b>Throws</b>: If comp throws or the move constructor, move assignment or swap of the type
+//!   of dereferenced RandIt throws.
+//!
+//! <b>Complexity</b>: Always K x O(Nxlog(N)) comparisons and move assignments/constructors/swaps.
+//!   Comparisons are close to minimum even with no additional memory. Constant factor for data movement is minimized
+//!   when uninitialized_len is ceil(std::distance(first, last)/2). Pretty good enough performance is achieved when
+//!   ceil(sqrt(std::distance(first, last)))*2.
+//!
+//! <b>Caution</b>: Experimental implementation, not production-ready.
+template<class RandIt, class RandRawIt, class Compare>
+void adaptive_sort( RandIt first, RandIt last, Compare comp
+               , RandRawIt uninitialized
+               , std::size_t uninitialized_len)
+{
+   typedef typename iterator_traits<RandIt>::size_type  size_type;
+   typedef typename iterator_traits<RandIt>::value_type value_type;
+
+   ::boost::movelib::detail_adaptive::adaptive_xbuf<value_type, RandRawIt> xbuf(uninitialized, uninitialized_len);
+   ::boost::movelib::detail_adaptive::adaptive_sort_impl(first, size_type(last - first), comp, xbuf);
+}
+
+template<class RandIt, class Compare>
+void adaptive_sort( RandIt first, RandIt last, Compare comp)
+{
+   typedef typename iterator_traits<RandIt>::value_type value_type;
+   adaptive_sort(first, last, comp, (value_type*)0, 0u);
+}
+
+}  //namespace movelib {
+}  //namespace boost {
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif   //#define BOOST_MOVE_ADAPTIVE_SORT_HPP
diff --git a/include/boost/move/algo/detail/adaptive_sort_merge.hpp b/include/boost/move/algo/detail/adaptive_sort_merge.hpp
new file mode 100644
index 0000000..4c28086
--- /dev/null
+++ b/include/boost/move/algo/detail/adaptive_sort_merge.hpp
@@ -0,0 +1,1690 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2016.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// Stable sorting that works in O(N*log(N)) worst time
+// and uses O(1) extra memory
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// The main idea of the adaptive_sort algorithm was developed by Andrey Astrelin
+// and explained in the article from the russian collaborative blog
+// Habrahabr (http://habrahabr.ru/post/205290/). The algorithm is based on
+// ideas from B-C. Huang and M. A. Langston explained in their article
+// "Fast Stable Merging and Sorting in Constant Extra Space (1989-1992)"
+// (http://comjnl.oxfordjournals.org/content/35/6/643.full.pdf).
+//
+// This implementation by Ion Gaztanaga uses previous ideas with additional changes:
+// 
+// - Use of GCD-based rotation.
+// - Non power of two buffer-sizes.
+// - Tries to find sqrt(len)*2 unique keys, so that the merge sort
+//   phase can form up to sqrt(len)*4 segments if enough keys are found.
+// - The merge-sort phase can take advantage of external memory to
+//   save some additional combination steps.
+// - Combination phase: Blocks are selection sorted and merged in parallel.
+// - The combination phase is performed alternating merge to left and merge
+//   to right phases minimizing swaps due to internal buffer repositioning.
+// - When merging blocks special optimizations are made to avoid moving some
+//   elements twice.
+//
+// The adaptive_merge algorithm was developed by Ion Gaztanaga reusing some parts
+// from the sorting algorithm and implementing an additional block merge algorithm
+// without moving elements to left or right.
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_MOVE_ADAPTIVE_SORT_MERGE_HPP
+#define BOOST_MOVE_ADAPTIVE_SORT_MERGE_HPP
+
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/detail/reverse_iterator.hpp>
+#include <boost/move/algo/move.hpp>
+#include <boost/move/algo/detail/merge.hpp>
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/move/algo/detail/insertion_sort.hpp>
+#include <boost/move/algo/detail/merge_sort.hpp>
+#include <boost/move/algo/detail/heap_sort.hpp>
+#include <boost/move/algo/detail/merge.hpp>
+#include <boost/move/algo/detail/is_sorted.hpp>
+#include <boost/assert.hpp>
+#include <boost/cstdint.hpp>
+
+#ifndef BOOST_MOVE_ADAPTIVE_SORT_STATS_LEVEL
+   #define BOOST_MOVE_ADAPTIVE_SORT_STATS_LEVEL 1
+#endif
+
+#ifdef BOOST_MOVE_ADAPTIVE_SORT_STATS
+   #if BOOST_MOVE_ADAPTIVE_SORT_STATS_LEVEL == 2
+      #define BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1(STR, L) \
+         print_stats(STR, L)\
+      //
+
+      #define BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(STR, L) \
+         print_stats(STR, L)\
+      //
+   #else
+      #define BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1(STR, L) \
+         print_stats(STR, L)\
+      //
+
+      #define BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(STR, L)
+   #endif
+#else
+   #define BOOST_MOVE_ADAPTIVE_SORT_PRINT_L1(STR, L)
+   #define BOOST_MOVE_ADAPTIVE_SORT_PRINT_L2(STR, L)
+#endif
+
+#ifdef BOOST_MOVE_ADAPTIVE_SORT_INVARIANTS
+   #define BOOST_MOVE_ADAPTIVE_SORT_INVARIANT  BOOST_ASSERT
+#else
+   #define BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(L)
+#endif
+
+namespace boost {
+namespace movelib {
+
+#if defined(BOOST_MOVE_ADAPTIVE_SORT_INVARIANTS)
+
+bool is_sorted(::order_perf_type *first, ::order_perf_type *last, ::order_type_less)
+{
+   if (first != last) {
+      const order_perf_type *next = first, *cur(first);
+      while (++next != last) {
+         if (!(cur->key < next->key || (cur->key == next->key && cur->val < next->val)))
+            return false;
+         cur = next;
+      }
+   }
+   return true;
+}
+
+#endif   //BOOST_MOVE_ADAPTIVE_SORT_INVARIANTS
+
+namespace detail_adaptive {
+
+static const std::size_t AdaptiveSortInsertionSortThreshold = 16;
+//static const std::size_t AdaptiveSortInsertionSortThreshold = 4;
+BOOST_STATIC_ASSERT((AdaptiveSortInsertionSortThreshold&(AdaptiveSortInsertionSortThreshold-1)) == 0);
+
+#if defined BOOST_HAS_INTPTR_T
+   typedef ::boost::uintptr_t uintptr_t;
+#else
+   typedef std::size_t uintptr_t;
+#endif
+
+template<class T>
+const T &min_value(const T &a, const T &b)
+{
+   return a < b ? a : b;
+}
+
+template<class T>
+const T &max_value(const T &a, const T &b)
+{
+   return a > b ? a : b;
+}
+
+template<class ForwardIt, class Pred, class V>
+typename iterator_traits<ForwardIt>::size_type
+   count_if_with(ForwardIt first, ForwardIt last, Pred pred, const V &v)
+{
+   typedef typename iterator_traits<ForwardIt>::size_type size_type;
+   size_type count = 0;
+   while(first != last) {
+      count += static_cast<size_type>(0 != pred(*first, v));
+      ++first;
+   }
+   return count;
+}
+
+template<class T, class RandRawIt = T*>
+class adaptive_xbuf
+{
+   adaptive_xbuf(const adaptive_xbuf &);
+   adaptive_xbuf & operator=(const adaptive_xbuf &);
+
+   public:
+   typedef RandRawIt iterator;
+
+   adaptive_xbuf()
+      : m_ptr(), m_size(0), m_capacity(0)
+   {}
+
+   adaptive_xbuf(RandRawIt raw_memory, std::size_t capacity)
+      : m_ptr(raw_memory), m_size(0), m_capacity(capacity)
+   {}
+
+   template<class RandIt>
+   void move_assign(RandIt first, std::size_t n)
+   {
+      if(n <= m_size){
+         boost::move(first, first+n, m_ptr);
+         std::size_t size = m_size;
+         while(size-- != n){
+            m_ptr[size].~T();
+         }
+         m_size = n;
+      }
+      else{
+         RandRawIt result = boost::move(first, first+m_size, m_ptr);
+         boost::uninitialized_move(first+m_size, first+n, result);
+         m_size = n;
+      }
+   }
+
+   template<class RandIt>
+   void push_back(RandIt first, std::size_t n)
+   {
+      BOOST_ASSERT(m_capacity - m_size >= n);
+      boost::uninitialized_move(first, first+n, m_ptr+m_size);
+      m_size += n;
+   }
+
+   template<class RandIt>
+   iterator add(RandIt it)
+   {
+      BOOST_ASSERT(m_size < m_capacity);
+      RandRawIt p_ret = m_ptr + m_size;
+      ::new(&*p_ret) T(::boost::move(*it));
+      ++m_size;
+      return p_ret;
+   }
+
+   template<class RandIt>
+   void insert(iterator pos, RandIt it)
+   {
+      if(pos == (m_ptr + m_size)){
+         this->add(it);
+      }
+      else{
+         this->add(m_ptr+m_size-1);
+         //m_size updated
+         boost::move_backward(pos, m_ptr+m_size-2, m_ptr+m_size-1);
+         *pos = boost::move(*it);
+      }
+   }
+
+   void set_size(std::size_t size)
+   {
+      m_size = size;
+   }
+
+   void shrink_to_fit(std::size_t const size)
+   {
+      if(m_size > size){
+         for(std::size_t szt_i = size; szt_i != m_size; ++szt_i){
+            m_ptr[szt_i].~T();
+         }
+         m_size = size;
+      }
+   }
+
+   void initialize_until(std::size_t const size, T &t)
+   {
+      BOOST_ASSERT(m_size < m_capacity);
+      if(m_size < size){
+         ::new((void*)&m_ptr[m_size]) T(::boost::move(t));
+         ++m_size;
+         for(; m_size != size; ++m_size){
+            ::new((void*)&m_ptr[m_size]) T(::boost::move(m_ptr[m_size-1]));
+         }
+         t = ::boost::move(m_ptr[m_size-1]);
+      }
+   }
+
+   private:
+   template<class RIt>
+   static bool is_raw_ptr(RIt)
+   {
+      return false;
+   }
+
+   static bool is_raw_ptr(T*)
+   {
+      return true;
+   }
+
+   public:
+   template<class U>
+   bool supports_aligned_trailing(std::size_t size, std::size_t trail_count) const
+   {
+      if(this->is_raw_ptr(this->data()) && m_capacity){
+         uintptr_t u_addr_sz = uintptr_t(&*(this->data()+size));
+         uintptr_t u_addr_cp = uintptr_t(&*(this->data()+this->capacity()));
+         u_addr_sz = ((u_addr_sz + sizeof(U)-1)/sizeof(U))*sizeof(U);
+         return (u_addr_cp >= u_addr_sz) && ((u_addr_cp - u_addr_sz)/sizeof(U) >= trail_count);
+      }
+      return false;
+   }
+
+   template<class U>
+   U *aligned_trailing() const
+   {
+      return this->aligned_trailing<U>(this->size());
+   }
+
+   template<class U>
+   U *aligned_trailing(std::size_t pos) const
+   {
+      uintptr_t u_addr = uintptr_t(&*(this->data()+pos));
+      u_addr = ((u_addr + sizeof(U)-1)/sizeof(U))*sizeof(U);
+      return (U*)u_addr;
+   }
+
+   ~adaptive_xbuf()
+   {
+      this->clear();
+   }
+
+   std::size_t capacity() const
+   {  return m_capacity;   }
+
+   iterator data() const
+   {  return m_ptr;   }
+
+   iterator end() const
+   {  return m_ptr+m_size;   }
+
+   std::size_t size() const
+   {  return m_size;   }
+
+   bool empty() const
+   {  return !m_size;   }
+
+   void clear()
+   {
+      this->shrink_to_fit(0u);
+   }
+
+   private:
+   RandRawIt m_ptr;
+   std::size_t m_size;
+   std::size_t m_capacity;
+};
+
+template<class Iterator, class Op>
+class range_xbuf
+{
+   range_xbuf(const range_xbuf &);
+   range_xbuf & operator=(const range_xbuf &);
+
+   public:
+   typedef typename iterator_traits<Iterator>::size_type size_type;
+   typedef Iterator iterator;
+
+   range_xbuf(Iterator first, Iterator last)
+      : m_first(first), m_last(first), m_cap(last)
+   {}
+
+   template<class RandIt>
+   void move_assign(RandIt first, std::size_t n)
+   {
+      BOOST_ASSERT(size_type(n) <= size_type(m_cap-m_first));
+      m_last = Op()(forward_t(), first, first+n, m_first);
+   }
+
+   ~range_xbuf()
+   {}
+
+   std::size_t capacity() const
+   {  return m_cap-m_first;   }
+
+   Iterator data() const
+   {  return m_first;   }
+
+   Iterator end() const
+   {  return m_last;   }
+
+   std::size_t size() const
+   {  return m_last-m_first;   }
+
+   bool empty() const
+   {  return m_first == m_last;   }
+
+   void clear()
+   {
+      m_last = m_first;
+   }
+
+   template<class RandIt>
+   iterator add(RandIt it)
+   {
+      Iterator pos(m_last);
+      *pos = boost::move(*it);
+      ++m_last;
+      return pos;
+   }
+
+   void set_size(std::size_t size)
+   {
+      m_last  = m_first;
+      m_last += size;
+   }
+
+   private:
+   Iterator const m_first;
+   Iterator m_last;
+   Iterator const m_cap;
+};
+
+
+template<class RandIt, class Compare>
+RandIt skip_until_merge
+   ( RandIt first1, RandIt const last1
+   , const typename iterator_traits<RandIt>::value_type &next_key, Compare comp)
+{
+   while(first1 != last1 && !comp(next_key, *first1)){
+      ++first1;
+   }
+   return first1;
+}
+
+
+template<class RandItKeys, class RandIt>
+void swap_and_update_key
+   ( RandItKeys const key_next
+   , RandItKeys const key_range2
+   , RandItKeys &key_mid
+   , RandIt const begin
+   , RandIt const end
+   , RandIt const with)
+{
+   if(begin != with){
+      ::boost::adl_move_swap_ranges(begin, end, with);
+      ::boost::adl_move_swap(*key_next, *key_range2);
+      if(key_next == key_mid){
+         key_mid = key_range2;
+      }
+      else if(key_mid == key_range2){
+         key_mid = key_next;
+      }
+   }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//                         MERGE BUFFERLESS
+//
+///////////////////////////////////////////////////////////////////////////////
+
+// [first1, last1) merge [last1,last2) -> [first1,last2)
+template<class RandIt, class Compare>
+RandIt partial_merge_bufferless_impl
+   (RandIt first1, RandIt last1, RandIt const last2, bool *const pis_range1_A, Compare comp)
+{
+   if(last1 == last2){
+      return first1;
+   }
+   bool const is_range1_A = *pis_range1_A;
+   if(first1 != last1 && comp(*last1, last1[-1])){
+      do{
+         RandIt const old_last1 = last1;
+         last1  = boost::movelib::lower_bound(last1, last2, *first1, comp);
+         first1 = rotate_gcd(first1, old_last1, last1);//old_last1 == last1 supported
+         if(last1 == last2){
+            return first1;
+         }
+         do{
+            ++first1;
+         } while(last1 != first1 && !comp(*last1, *first1) );
+      } while(first1 != last1);
+   }
+   *pis_range1_A = !is_range1_A;
+   return last1;
+}
+
+// [first1, last1) merge [last1,last2) -> [first1,last2)
+template<class RandIt, class Compare>
+RandIt partial_merge_bufferless
+   (RandIt first1, RandIt last1, RandIt const last2, bool *const pis_range1_A, Compare comp)
+{
+   return *pis_range1_A ? partial_merge_bufferless_impl(first1, last1, last2, pis_range1_A, comp)
+                        : partial_merge_bufferless_impl(first1, last1, last2, pis_range1_A, antistable<Compare>(comp));
+}
+
+template<class SizeType>
+static SizeType needed_keys_count(SizeType n_block_a, SizeType n_block_b)
+{
+   return n_block_a + n_block_b;
+}
+
+template<class RandItKeys, class KeyCompare, class RandIt, class Compare>
+typename iterator_traits<RandIt>::size_type
+   find_next_block
+      ( RandItKeys key_first
+      , KeyCompare key_comp
+      , RandIt const first
+      , typename iterator_traits<RandIt>::size_type const l_block
+      , typename iterator_traits<RandIt>::size_type const ix_first_block
+      , typename iterator_traits<RandIt>::size_type const ix_last_block
+      , Compare comp)
+{
+   typedef typename iterator_traits<RandIt>::size_type      size_type;
+   typedef typename iterator_traits<RandIt>::value_type     value_type;
+   typedef typename iterator_traits<RandItKeys>::value_type key_type;
+   BOOST_ASSERT(ix_first_block <= ix_last_block);
+   size_type ix_min_block = 0u;
+   for (size_type szt_i = ix_first_block; szt_i < ix_last_block; ++szt_i) {
+      const value_type &min_val = first[ix_min_block*l_block];
+      const value_type &cur_val = first[szt_i*l_block];
+      const key_type   &min_key = key_first[ix_min_block];
+      const key_type   &cur_key = key_first[szt_i];
+
+      bool const less_than_minimum = comp(cur_val, min_val) ||
+         (!comp(min_val, cur_val) && key_comp(cur_key, min_key));
+
+      if (less_than_minimum) {
+         ix_min_block = szt_i;
+      }
+   }
+   return ix_min_block;
+}
+
+template<class RandItKeys, class KeyCompare, class RandIt, class Compare>
+void merge_blocks_bufferless
+   ( RandItKeys key_first
+   , KeyCompare key_comp
+   , RandIt const first
+   , typename iterator_traits<RandIt>::size_type const l_block
+   , typename iterator_traits<RandIt>::size_type const l_irreg1
+   , typename iterator_traits<RandIt>::size_type const n_block_a
+   , typename iterator_traits<RandIt>::size_type const n_block_b
+   , typename iterator_traits<RandIt>::size_type const l_irreg2
+   , Compare comp)
+{
+   typedef typename iterator_traits<RandIt>::size_type size_type;
+   size_type const key_count = needed_keys_count(n_block_a, n_block_b); (void)key_count;
+   //BOOST_ASSERT(n_block_a || n_block_b);
+   BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted_and_unique(key_first, key_first + key_count, key_comp));
+   BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!n_block_b || n_block_a == count_if_with(key_first, key_first + key_count, key_comp, key_first[n_block_a]));
+
+   size_type n_bef_irreg2 = 0;
+   bool l_irreg_pos_count = true;
+   RandItKeys key_mid(key_first + n_block_a);
+   RandIt const first_irr2 = first + l_irreg1 + (n_block_a+n_block_b)*l_block;
+   RandIt const last_irr2  = first_irr2 + l_irreg2;
+
+   {  //Selection sort blocks
+      size_type n_block_left = n_block_b + n_block_a;
+      RandItKeys key_range2(key_first);
+
+      size_type min_check = n_block_a == n_block_left ? 0u : n_block_a;
+      size_type max_check = min_value(min_check+1, n_block_left);
+      for (RandIt f = first+l_irreg1; n_block_left; --n_block_left, ++key_range2, f += l_block, min_check -= min_check != 0, max_check -= max_check != 0) {
+         size_type const next_key_idx = find_next_block(key_range2, key_comp, f, l_block, min_check, max_check, comp);
+         RandItKeys const key_next(key_range2 + next_key_idx);
+         max_check = min_value(max_value(max_check, next_key_idx+2), n_block_left);
+
+         RandIt const first_min = f + next_key_idx*l_block;
+
+         //Check if irregular b block should go here.
+         //If so, break to the special code handling the irregular block
+         if (l_irreg_pos_count && l_irreg2 && comp(*first_irr2, *first_min)){
+            l_irreg_pos_count = false;
+         }
+         n_bef_irreg2 += l_irreg_pos_count;
+
+         swap_and_update_key(key_next, key_range2, key_mid, f, f + l_block, first_min);
+         BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(f, f+l_block, comp));
+         BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first_min, first_min + l_block, comp));
+         BOOST_MOVE_ADAPTIVE_SORT_INVARIANT((f == (first+l_irreg1)) || !comp(*f, *(f-l_block)));
+      }
+   }
+   BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first+l_irreg1+n_bef_irreg2*l_block, first_irr2, comp));
+
+   RandIt first1 = first;
+   RandIt last1  = first+l_irreg1;
+   RandItKeys const key_end (key_first+n_bef_irreg2);
+   bool is_range1_A = true;
+
+   for( ; key_first != key_end; ++key_first){
+      bool is_range2_A = key_mid == (key_first+key_count) || key_comp(*key_first, *key_mid);
+      first1 = is_range1_A == is_range2_A
+         ? last1 : partial_merge_bufferless(first1, last1, last1 + l_block, &is_range1_A, comp);
+      last1 += l_block;
+      BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first, first1, comp));
+   }
+
+   merge_bufferless(is_range1_A ? first1 : last1, first_irr2, last_irr2, comp);
+   BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first, last_irr2, comp));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//                            BUFFERED MERGE
+//
+///////////////////////////////////////////////////////////////////////////////
+template<class RandIt, class Compare, class Op, class Buf>
+void op_buffered_merge
+      ( RandIt first, RandIt const middle, RandIt last
+      , Compare comp, Op op
+      , Buf &xbuf)
+{
+   if(first != middle && middle != last && comp(*middle, middle[-1])){
+      typedef typename iterator_traits<RandIt>::size_type   size_type;
+      size_type const len1 = size_type(middle-first);
+      size_type const len2 = size_type(last-middle);
+      if(len1 <= len2){
+         first = boost::movelib::upper_bound(first, middle, *middle, comp);
+         xbuf.move_assign(first, size_type(middle-first));
+         op_merge_with_right_placed
+            (xbuf.data(), xbuf.end(), first, middle, last, comp, op);
+      }
+      else{
+         last = boost::movelib::lower_bound(middle, last, middle[-1], comp);
+         xbuf.move_assign(middle, size_type(last-middle));
+         op_merge_with_left_placed
+            (first, middle, last, xbuf.data(), xbuf.end(), comp, op);
+      }
+   }
+}
+
+template<class RandIt, class Compare, class XBuf>
+void buffered_merge
+      ( RandIt first, RandIt const middle, RandIt last
+      , Compare comp
+      , XBuf &xbuf)
+{
+   op_buffered_merge(first, middle, last, comp, move_op(), xbuf);
+}
+
+// Complexity: 2*distance(first, last)+max_collected^2/2
+//
+// Tries to collect at most n_keys unique elements from [first, last),
+// in the begining of the range, and ordered according to comp
+// 
+// Returns the number of collected keys
+template<class RandIt, class Compare, class XBuf>
+typename iterator_traits<RandIt>::size_type
+   collect_unique
+      ( RandIt const first, RandIt const last
+      , typename iterator_traits<RandIt>::size_type const max_collected, Compare comp
+      , XBuf & xbuf)
+{
+   typedef typename iterator_traits<RandIt>::size_type size_type;
+   size_type h = 0;
+   if(max_collected){
+      ++h;  // first key is always here
+      RandIt h0 = first;
+      RandIt u = first; ++u;
+      RandIt search_end = u;
+
+      if(xbuf.capacity() >= max_collected){
+         typename XBuf::iterator const ph0 = xbuf.add(first);
+         while(u != last && h < max_collected){
+            typename XBuf::iterator const r = boost::movelib::lower_bound(ph0, xbuf.end(), *u, comp);
+            //If key not found add it to [h, h+h0)
+            if(r == xbuf.end() || comp(*u, *r) ){
+               RandIt const new_h0 = boost::move(search_end, u, h0);
+               search_end = u;
+               ++search_end;
+               ++h;
+               xbuf.insert(r, u);
+               h0 = new_h0;
+            }
+            ++u;
+         }
+         boost::move_backward(first, h0, h0+h);
+         boost::move(xbuf.data(), xbuf.end(), first);
+      }
+      else{
+         while(u != last && h < max_collected){
+            RandIt const r = boost::movelib::lower_bound(h0, search_end, *u, comp);
+            //If key not found add it to [h, h+h0)
+            if(r == search_end || comp(*u, *r) ){
+               RandIt const new_h0 = rotate_gcd(h0, search_end, u);
+               search_end = u;
+               ++search_end;
+               ++h;
+               rotate_gcd(r+(new_h0-h0), u, search_end);
+               h0 = new_h0;
+            }
+            ++u;
+         }
+         rotate_gcd(first, h0, h0+h);
+      }
+   }
+   return h;
+}
+
+template<class Unsigned>
+Unsigned floor_sqrt(Unsigned const n)
+{
+   Unsigned x = n;
+   Unsigned y = x/2 + (x&1);
+   while (y < x){
+      x = y;
+      y = (x + n / x)/2;
+   }
+   return x;
+}
+
+template<class Unsigned>
+Unsigned ceil_sqrt(Unsigned const n)
+{
+   Unsigned r = floor_sqrt(n);
+   return r + Unsigned((n%r) != 0);
+}
+
+template<class Unsigned>
+Unsigned floor_merge_multiple(Unsigned const n, Unsigned &base, Unsigned &pow)
+{
+   Unsigned s = n;
+   Unsigned p = 0;
+   while(s > AdaptiveSortInsertionSortThreshold){
+      s /= 2;
+      ++p;
+   }
+   base = s;
+   pow = p;
+   return s << p;
+}
+
+template<class Unsigned>
+Unsigned ceil_merge_multiple(Unsigned const n, Unsigned &base, Unsigned &pow)
+{
+   Unsigned fm = floor_merge_multiple(n, base, pow);
+
+   if(fm != n){
+      if(base < AdaptiveSortInsertionSortThreshold){
+         ++base;
+      }
+      else{
+         base = AdaptiveSortInsertionSortThreshold/2 + 1;
+         ++pow;
+      }
+   }
+   return base << pow;
+}
+
+template<class Unsigned>
+Unsigned ceil_sqrt_multiple(Unsigned const n, Unsigned *pbase = 0)
+{
+   Unsigned const r = ceil_sqrt(n);
+   Unsigned pow = 0;
+   Unsigned base = 0;
+   Unsigned const res = ceil_merge_multiple(r, base, pow);
+   if(pbase) *pbase = base;
+   return res;
+}
+
+struct less
+{
+   template<class T>
+   bool operator()(const T &l, const T &r)
+   {  return l < r;  }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//                            MERGE BLOCKS
+//
+///////////////////////////////////////////////////////////////////////////////
+
+//#define ADAPTIVE_SORT_MERGE_SLOW_STABLE_SORT_IS_NLOGN
+
+#if defined ADAPTIVE_SORT_MERGE_SLOW_STABLE_SORT_IS_NLOGN
+template<class RandIt, class Compare>
+void slow_stable_sort
+   ( RandIt const first, RandIt const last, Compare comp)
+{
+   boost::movelib::inplace_stable_sort(first, last, comp);
+}
+
+#else //ADAPTIVE_SORT_MERGE_SLOW_STABLE_SORT_IS_NLOGN
+
+template<class RandIt, class Compare>
+void slow_stable_sort
+   ( RandIt const first, RandIt const last, Compare comp)
+{
+   typedef typename iterator_traits<RandIt>::size_type size_type;
+   size_type L = size_type(last - first);
+   {  //Use insertion sort to merge first elements
+      size_type m = 0;
+      while((L - m) > size_type(AdaptiveSortInsertionSortThreshold)){
+         insertion_sort(first+m, first+m+size_type(AdaptiveSortInsertionSortThreshold), comp);
+         m += AdaptiveSortInsertionSortThreshold;
+      }
+      insertion_sort(first+m, last, comp);
+   }
+
+   size_type h = AdaptiveSortInsertionSortThreshold;
+   for(bool do_merge = L > h; do_merge; h*=2){
+      do_merge = (L - h) > h;
+      size_type p0 = 0;
+      if(do_merge){
+         size_type const h_2 = 2*h;
+         while((L-p0) > h_2){
+            merge_bufferless(first+p0, first+p0+h, first+p0+h_2, comp);
+            p0 += h_2;
+         }
+      }
+      if((L-p0) > h){
+         merge_bufferless(first+p0, first+p0+h, last, comp);
+      }
+   }
+}
+
+#endif   //ADAPTIVE_SORT_MERGE_SLOW_STABLE_SORT_IS_NLOGN
+
+//Returns new l_block and updates use_buf
+template<class Unsigned>
+Unsigned lblock_for_combine
+   (Unsigned const l_block, Unsigned const n_keys, Unsigned const l_data, bool &use_buf)
+{
+   BOOST_ASSERT(l_data > 1);
+
+   //We need to guarantee lblock >= l_merged/(n_keys/2) keys for the combination.
+   //We have at least 4 keys guaranteed (which are the minimum to merge 2 ranges)
+   //If l_block != 0, then n_keys is already enough to merge all blocks in all
+   //phases as we've found all needed keys for that buffer and length before.
+   //If l_block == 0 then see if half keys can be used as buffer and the rest
+   //as keys guaranteeing that n_keys >= (2*l_merged)/lblock = 
+   if(!l_block){
+      //If l_block == 0 then n_keys is power of two
+      //(guaranteed by build_params(...))
+      BOOST_ASSERT(n_keys >= 4);
+      //BOOST_ASSERT(0 == (n_keys &(n_keys-1)));
+
+      //See if half keys are at least 4 and if half keys fulfill
+      Unsigned const new_buf  = n_keys/2;
+      Unsigned const new_keys = n_keys-new_buf;
+      use_buf = new_keys >= 4 && new_keys >= l_data/new_buf;
+      if(use_buf){
+         return new_buf;
+      }
+      else{
+         return l_data/n_keys;
+      }
+   }
+   else{
+      use_buf = true;
+      return l_block;
+   }
+}
+
+template<class RandIt, class Compare, class XBuf>
+void stable_sort( RandIt first, RandIt last, Compare comp, XBuf & xbuf)
+{
+   typedef typename iterator_traits<RandIt>::size_type size_type;
+   size_type const len = size_type(last - first);
+   size_type const half_len = len/2 + (len&1);
+   if(std::size_t(xbuf.capacity() - xbuf.size()) >= half_len) {
+      merge_sort(first, last, comp, xbuf.data()+xbuf.size());
+   }
+   else{
+      slow_stable_sort(first, last, comp);
+   }
+}
+
+template<class RandIt, class Comp, class XBuf>
+void unstable_sort( RandIt first, RandIt last
+                    , Comp comp
+                    , XBuf & xbuf)
+{
+   heap_sort(first, last, comp);(void)xbuf;
+}
+
+template<class RandIt, class Compare, class XBuf>
+void stable_merge
+      ( RandIt first, RandIt const middle, RandIt last
+      , Compare comp
+      , XBuf &xbuf)
+{
+   BOOST_ASSERT(xbuf.empty());
+   typedef typename iterator_traits<RandIt>::size_type   size_type;
+   size_type const len1  = size_type(middle-first);
+   size_type const len2  = size_type(last-middle);
+   size_type const l_min = min_value(len1, len2);
+   if(xbuf.capacity() >= l_min){
+      buffered_merge(first, middle, last, comp, xbuf);
+      xbuf.clear();
+   }
+   else{
+      merge_bufferless(first, middle, last, comp);
+   }
+}
+
+template<class RandIt, class Comp, class XBuf>
+void initialize_keys( RandIt first, RandIt last
+                    , Comp comp
+                    , XBuf & xbuf)
+{
+   unstable_sort(first, last, comp, xbuf);
+   BOOST_ASSERT(boost::movelib::is_sorted_and_unique(first, last, comp));
+}
+
+template<class RandIt, class U>
+void initialize_keys( RandIt first, RandIt last
+                    , less
+                    , U &)
+{
+   typedef typename iterator_traits<RandIt>::value_type value_type;
+   std::size_t count = std::size_t(last - first);
+   for(std::size_t i = 0; i != count; ++i){
+      *first = static_cast<value_type>(i);
+      ++first;
+   }
+}
+
+template <class Unsigned>
+Unsigned calculate_total_combined(Unsigned const len, Unsigned const l_prev_merged, Unsigned *pl_irreg_combined = 0)
+{
+   typedef Unsigned size_type;
+
+   size_type const l_combined = 2*l_prev_merged;
+   size_type l_irreg_combined = len%l_combined;
+   size_type l_total_combined = len;
+   if(l_irreg_combined <= l_prev_merged){
+      l_total_combined -= l_irreg_combined;
+      l_irreg_combined = 0;
+   }
+   if(pl_irreg_combined)
+      *pl_irreg_combined = l_irreg_combined;
+   return l_total_combined;
+}
+
+template<class RandItKeys, class KeyCompare, class SizeType, class XBuf>
+void combine_params
+   ( RandItKeys const keys
+   , KeyCompare key_comp
+   , SizeType l_combined
+   , SizeType const l_prev_merged
+   , SizeType const l_block
+   , XBuf & xbuf
+   //Output
+   , SizeType &n_block_a
+   , SizeType &n_block_b
+   , SizeType &l_irreg1
+   , SizeType &l_irreg2
+   //Options
+   , bool do_initialize_keys = true)
+{
+   typedef SizeType   size_type;
+
+   //Initial parameters for selection sort blocks
+   l_irreg1 = l_prev_merged%l_block;
+   l_irreg2 = (l_combined-l_irreg1)%l_block;
+   BOOST_ASSERT(((l_combined-l_irreg1-l_irreg2)%l_block) == 0);
+   size_type const n_reg_block = (l_combined-l_irreg1-l_irreg2)/l_block;
+   n_block_a = l_prev_merged/l_block;
+   n_block_b = n_reg_block - n_block_a;
+   BOOST_ASSERT(n_reg_block>=n_block_a);
+
+   //Key initialization
+   if (do_initialize_keys) {
+      initialize_keys(keys, keys + needed_keys_count(n_block_a, n_block_b), key_comp, xbuf);
+   }
+}
+
+
+
+//////////////////////////////////
+//
+//          partial_merge
+//
+//////////////////////////////////
+template<class InputIt1, class InputIt2, class OutputIt, class Compare, class Op>
+OutputIt op_partial_merge_impl
+   (InputIt1 &r_first1, InputIt1 const last1, InputIt2 &r_first2, InputIt2 const last2, OutputIt d_first, Compare comp, Op op)
+{
+   InputIt1 first1(r_first1);
+   InputIt2 first2(r_first2);
+   if(first2 != last2 && last1 != first1)
+   while(1){
+      if(comp(*first2, *first1)) {
+         op(first2++, d_first++);
+         if(first2 == last2){
+            break;
+         }
+      }
+      else{
+         op(first1++, d_first++);
+         if(first1 == last1){
+            break;
+         }
+      }
+   }
+   r_first1 = first1;
+   r_first2 = first2;
+   return d_first;
+}
+
+template<class InputIt1, class InputIt2, class OutputIt, class Compare, class Op>
+OutputIt op_partial_merge
+   (InputIt1 &r_first1, InputIt1 const last1, InputIt2 &r_first2, InputIt2 const last2, OutputIt d_first, Compare comp, Op op, bool is_stable)
+{
+   return is_stable ? op_partial_merge_impl(r_first1, last1, r_first2, last2, d_first, comp, op)
+                    : op_partial_merge_impl(r_first1, last1, r_first2, last2, d_first, antistable<Compare>(comp), op);
+}
+
+//////////////////////////////////
+//////////////////////////////////
+//////////////////////////////////
+//
+//    op_partial_merge_and_save
+//
+//////////////////////////////////
+//////////////////////////////////
+//////////////////////////////////
+template<class InputIt1, class InputIt2, class OutputIt, class Compare, class Op>
+OutputIt op_partial_merge_and_swap_impl
+   (InputIt1 &r_first1, InputIt1 const last1, InputIt2 &r_first2, InputIt2 const last2, InputIt2 &r_first_min, OutputIt d_first, Compare comp, Op op)
+{
+   InputIt1 first1(r_first1);
+   InputIt2 first2(r_first2);
+   
+   if(first2 != last2 && last1 != first1) {
+      InputIt2 first_min(r_first_min);
+      bool non_empty_ranges = true;
+      do{
+         if(comp(*first_min, *first1)) {
+            op(three_way_t(), first2++, first_min++, d_first++);
+            non_empty_ranges = first2 != last2;
+         }
+         else{
+            op(first1++, d_first++);
+            non_empty_ranges = first1 != last1;
+         }
+      } while(non_empty_ranges);
+      r_first_min = first_min;
+      r_first1 = first1;
+      r_first2 = first2;
+   }
+   return d_first;
+}
+
+template<class RandIt, class InputIt2, class OutputIt, class Compare, class Op>
+OutputIt op_partial_merge_and_swap
+   (RandIt &r_first1, RandIt const last1, InputIt2 &r_first2, InputIt2 const last2, InputIt2 &r_first_min, OutputIt d_first, Compare comp, Op op, bool is_stable)
+{
+   return is_stable ? op_partial_merge_and_swap_impl(r_first1, last1, r_first2, last2, r_first_min, d_first, comp, op)
+                    : op_partial_merge_and_swap_impl(r_first1, last1, r_first2, last2, r_first_min, d_first, antistable<Compare>(comp), op);
+}
+
+template<class RandIt1, class RandIt2, class RandItB, class Compare, class Op>
+RandItB op_buffered_partial_merge_and_swap_to_range1_and_buffer
+   ( RandIt1 first1, RandIt1 const last1
+   , RandIt2 &rfirst2, RandIt2 const last2, RandIt2 &rfirst_min
+   , RandItB &rfirstb, Compare comp, Op op )
+{
+   RandItB firstb = rfirstb;
+   RandItB lastb  = firstb;
+   RandIt2 first2 = rfirst2;
+
+   //Move to buffer while merging
+   //Three way moves need less moves when op is swap_op so use it
+   //when merging elements from range2 to the destination occupied by range1
+   if(first1 != last1 && first2 != last2){
+      RandIt2 first_min = rfirst_min;
+      op(four_way_t(), first2++, first_min++, first1++, lastb++);
+
+      while(first1 != last1){
+         if(first2 == last2){
+            lastb = op(forward_t(), first1, last1, firstb);
+            break;
+         }
+
+         if(comp(*first_min, *firstb)){
+            op( four_way_t(), first2++, first_min++, first1++, lastb++);
+         }
+         else{
+            op(three_way_t(), firstb++, first1++, lastb++);
+         }
+      }
+      rfirst2 = first2;
+      rfirstb = firstb;
+      rfirst_min = first_min;
+   }
+
+   return lastb;
+}
+
+template<class RandIt1, class RandIt2, class RandItB, class Compare, class Op>
+RandItB op_buffered_partial_merge_to_range1_and_buffer
+   ( RandIt1 first1, RandIt1 const last1
+   , RandIt2 &rfirst2, RandIt2 const last2
+   , RandItB &rfirstb, Compare comp, Op op )
+{
+   RandItB firstb = rfirstb;
+   RandItB lastb  = firstb;
+   RandIt2 first2 = rfirst2;
+
+   //Move to buffer while merging
+   //Three way moves need less moves when op is swap_op so use it
+   //when merging elements from range2 to the destination occupied by range1
+   if(first1 != last1 && first2 != last2){
+      op(three_way_t(), first2++, first1++, lastb++);
+
+      while(true){
+         if(first1 == last1){
+            break;
+         }
+         if(first2 == last2){
+            lastb = op(forward_t(), first1, last1, firstb);
+            break;
+         }
+         if (comp(*first2, *firstb)) {
+            op(three_way_t(), first2++, first1++, lastb++);
+         }
+         else {
+            op(three_way_t(), firstb++, first1++, lastb++);
+         }
+      }
+      rfirst2 = first2;
+      rfirstb = firstb;
+   }
+
+   return lastb;
+}
+
+template<class RandIt, class RandItBuf, class Compare, class Op>
+RandIt op_partial_merge_and_save_impl
+   ( RandIt first1, RandIt const last1, RandIt &rfirst2, RandIt last2, RandIt first_min
+   , RandItBuf &buf_first1_in_out, RandItBuf &buf_last1_in_out
+   , Compare comp, Op op
+   )
+{
+   RandItBuf buf_first1 = buf_first1_in_out;
+   RandItBuf buf_last1  = buf_last1_in_out;
+   RandIt first2(rfirst2);
+
+   bool const do_swap = first2 != first_min;
+   if(buf_first1 == buf_last1){
+      //Skip any element that does not need to be moved
+      RandIt new_first1 = skip_until_merge(first1, last1, *first_min, comp);
+      buf_first1 += (new_first1-first1);
+      first1 = new_first1;
+      buf_last1  = do_swap ? op_buffered_partial_merge_and_swap_to_range1_and_buffer(first1, last1, first2, last2, first_min, buf_first1, comp, op)
+                           : op_buffered_partial_merge_to_range1_and_buffer    (first1, last1, first2, last2, buf_first1, comp, op);
+      first1 = last1;
+   }
+   else{
+      BOOST_ASSERT((last1-first1) == (buf_last1 - buf_first1));
+   }
+
+   //Now merge from buffer
+   first1 = do_swap ? op_partial_merge_and_swap_impl(buf_first1, buf_last1, first2, last2, first_min, first1, comp, op)
+                    : op_partial_merge_impl    (buf_first1, buf_last1, first2, last2, first1, comp, op);
+   buf_first1_in_out = buf_first1;
+   buf_last1_in_out  = buf_last1;
+   rfirst2 = first2;
+   return first1;
+}
+
+template<class RandIt, class RandItBuf, class Compare, class Op>
+RandIt op_partial_merge_and_save
+   ( RandIt first1, RandIt const last1, RandIt &rfirst2, RandIt last2, RandIt first_min
+   , RandItBuf &buf_first1_in_out
+   , RandItBuf &buf_last1_in_out
+   , Compare comp
+   , Op op
+   , bool is_stable)
+{
+   return is_stable
+      ? op_partial_merge_and_save_impl
+         (first1, last1, rfirst2, last2, first_min, buf_first1_in_out, buf_last1_in_out, comp, op)
+      : op_partial_merge_and_save_impl
+         (first1, last1, rfirst2, last2, first_min, buf_first1_in_out, buf_last1_in_out, antistable<Compare>(comp), op)
+      ;
+}
+
+//////////////////////////////////
+//////////////////////////////////
+//////////////////////////////////
+//
+//    op_merge_blocks_with_irreg
+//
+//////////////////////////////////
+//////////////////////////////////
+//////////////////////////////////
+
+template<class RandItKeys, class KeyCompare, class RandIt, class RandIt2, class OutputIt, class Compare, class Op>
+OutputIt op_merge_blocks_with_irreg
+   ( RandItKeys key_first
+   , RandItKeys key_mid
+   , KeyCompare key_comp
+   , RandIt first_reg
+   , RandIt2 &first_irr
+   , RandIt2 const last_irr
+   , OutputIt dest
+   , typename iterator_traits<RandIt>::size_type const l_block
+   , typename iterator_traits<RandIt>::size_type n_block_left
+   , typename iterator_traits<RandIt>::size_type min_check
+   , typename iterator_traits<RandIt>::size_type max_check
+   , Compare comp, bool const is_stable, Op op)
+{
+   typedef typename iterator_traits<RandIt>::size_type size_type;
+
+   for(; n_block_left; --n_block_left, ++key_first, min_check -= min_check != 0, max_check -= max_check != 0){
+      size_type next_key_idx = find_next_block(key_first, key_comp, first_reg, l_block, min_check, max_check, comp);  
+      max_check = min_value(max_value(max_check, next_key_idx+2), n_block_left);
+      RandIt const last_reg  = first_reg + l_block;
+      RandIt first_min = first_reg + next_key_idx*l_block;
+      RandIt const last_min  = first_min + l_block; (void)last_min;
+
+      BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first_reg, last_reg, comp));
+      BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!next_key_idx || is_sorted(first_min, last_min, comp));
+      BOOST_MOVE_ADAPTIVE_SORT_INVARIANT((!next_key_idx || !comp(*first_reg, *first_min )));
+
+      OutputIt orig_dest = dest; (void)orig_dest;
+      dest = next_key_idx ? op_partial_merge_and_swap(first_irr, last_irr, first_reg, last_reg, first_min, dest, comp, op, is_stable)
+                          : op_partial_merge         (first_irr, last_irr, first_reg, last_reg, dest, comp, op, is_stable);
+      BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(orig_dest, dest, comp));
+
+      if(first_reg == dest){
+         dest = next_key_idx ? ::boost::adl_move_swap_ranges(first_min, last_min, first_reg)
+                             : last_reg;
+      }
+      else{
+         dest = next_key_idx ? op(three_way_forward_t(), first_reg, last_reg, first_min, dest)
+                             : op(forward_t(), first_reg, last_reg, dest);
+      }
+
+      RandItKeys const key_next(key_first + next_key_idx);
+      swap_and_update_key(key_next, key_first, key_mid, last_reg, last_reg, first_min);
+
+      BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(orig_dest, dest, comp));
+      first_reg = last_reg;
+   }
+   return dest;
+}
+
+//////////////////////////////////
+//////////////////////////////////
+//////////////////////////////////
+//
+//    op_merge_blocks_left/right
+//
+//////////////////////////////////
+//////////////////////////////////
+//////////////////////////////////
+
+template<class RandItKeys, class KeyCompare, class RandIt, class Compare, class Op>
+void op_merge_blocks_left
+   ( RandItKeys const key_first
+   , KeyCompare key_comp
+   , RandIt const first
+   , typename iterator_traits<RandIt>::size_type const l_block
+   , typename iterator_traits<RandIt>::size_type const l_irreg1
+   , typename iterator_traits<RandIt>::size_type const n_block_a
+   , typename iterator_traits<RandIt>::size_type const n_block_b
+   , typename iterator_traits<RandIt>::size_type const l_irreg2
+   , Compare comp, Op op)
+{
+   typedef typename iterator_traits<RandIt>::size_type size_type;
+   size_type const key_count = needed_keys_count(n_block_a, n_block_b); (void)key_count;
+//   BOOST_ASSERT(n_block_a || n_block_b);
+   BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted_and_unique(key_first, key_first + key_count, key_comp));
+   BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!n_block_b || n_block_a == count_if_with(key_first, key_first + key_count, key_comp, key_first[n_block_a]));
+
+   size_type n_block_b_left = n_block_b;
+   size_type n_block_a_left = n_block_a;
+   size_type n_block_left = n_block_b + n_block_a;
+   RandItKeys key_mid(key_first + n_block_a);
+
+   RandIt buffer = first - l_block;
+   RandIt first1 = first;
+   RandIt last1  = first1 + l_irreg1;
+   RandIt first2 = last1;
+   RandIt const irreg2 = first2 + n_block_left*l_block;
+   bool is_range1_A = true;
+
+   RandItKeys key_range2(key_first);
+
+   ////////////////////////////////////////////////////////////////////////////
+   //Process all regular blocks before the irregular B block
+   ////////////////////////////////////////////////////////////////////////////
+   size_type min_check = n_block_a == n_block_left ? 0u : n_block_a;
+   size_type max_check = min_value(min_check+1, n_block_left);
+   for (; n_block_left; --n_block_left, ++key_range2, min_check -= min_check != 0, max_check -= max_check != 0) {
+      size_type const next_key_idx = find_next_block(key_range2, key_comp, first2, l_block, min_check, max_check, comp);
+      max_check = min_value(max_value(max_check, next_key_idx+2), n_block_left);
+      RandIt const first_min = first2 + next_key_idx*l_block;
+      RandIt const last_min  = first_min + l_block; (void)last_min;
+      RandIt const last2  = first2 + l_block;
+
+      BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first1, last1, comp));
+      BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first2, last2, comp));
+      BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!n_block_left || is_sorted(first_min, last_min, comp));
+
+      //Check if irregular b block should go here.
+      //If so, break to the special code handling the irregular block
+      if (!n_block_b_left &&
+            ( (l_irreg2 && comp(*irreg2, *first_min)) || (!l_irreg2 && is_range1_A)) ){
+         break;
+      }
+
+      RandItKeys const key_next(key_range2 + next_key_idx);
+      bool const is_range2_A = key_mid == (key_first+key_count) || key_comp(*key_next, *key_mid);
+
+      bool const is_buffer_middle = last1 == buffer;
+      BOOST_MOVE_ADAPTIVE_SORT_INVARIANT( ( is_buffer_middle && size_type(first2-buffer) == l_block && buffer == last1) ||
+                                          (!is_buffer_middle && size_type(first1-buffer) == l_block && first2 == last1));
+
+      if(is_range1_A == is_range2_A){
+         BOOST_ASSERT((first1 == last1) || !comp(*first_min, last1[-1]));
+         if(!is_buffer_middle){
+            buffer = op(forward_t(), first1, last1, buffer);
+         }
+         swap_and_update_key(key_next, key_range2, key_mid, first2, last2, first_min);
+         first1 = first2;
+         last1  = last2;
+      }
+      else {
+         RandIt unmerged;
+         RandIt buf_beg;
+         RandIt buf_end;
+         if(is_buffer_middle){
+            buf_end = buf_beg = first2 - (last1-first1);
+            unmerged = op_partial_merge_and_save( first1, last1, first2, last2, first_min
+                                                , buf_beg, buf_end, comp, op, is_range1_A);
+         }  
+         else{
+            buf_beg = first1;
+            buf_end = last1;
+            unmerged = op_partial_merge_and_save
+               (buffer, buffer+(last1-first1), first2, last2, first_min, buf_beg, buf_end, comp, op, is_range1_A);
+         }
+         (void)unmerged;
+         BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first-l_block, unmerged, comp));
+
+         swap_and_update_key( key_next, key_range2, key_mid, first2, last2
+                            , last_min - size_type(last2 - first2));
+
+         if(buf_beg != buf_end){  //range2 exhausted: is_buffer_middle for the next iteration
+            first1 = buf_beg;
+            last1  = buf_end;
+            BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(buf_end == (last2-l_block));
+            buffer = last1;
+         }
+         else{ //range1 exhausted: !is_buffer_middle for the next iteration
+            first1 = first2;
+            last1  = last2;
+            buffer = first2 - l_block;
+            is_range1_A = is_range2_A;
+         }
+      }
+      BOOST_MOVE_ADAPTIVE_SORT_INVARIANT( (is_range2_A && n_block_a_left) || (!is_range2_A && n_block_b_left));
+      is_range2_A ? --n_block_a_left : --n_block_b_left;
+      first2 = last2;
+   }
+
+   BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!n_block_b || n_block_a == count_if_with(key_first, key_range2 + n_block_left, key_comp, *key_mid));
+   BOOST_ASSERT(!n_block_b_left);
+
+   ////////////////////////////////////////////////////////////////////////////
+   //Process remaining range 1 left before the irregular B block
+   ////////////////////////////////////////////////////////////////////////////
+   bool const is_buffer_middle = last1 == buffer;
+   RandIt first_irr2 = irreg2;
+   RandIt const last_irr2  = first_irr2 + l_irreg2;
+   if(l_irreg2 && is_range1_A){
+      if(is_buffer_middle){
+         first1 = skip_until_merge(first1, last1, *first_irr2, comp);
+         //Even if we copy backward, no overlapping occurs so use forward copy
+         //that can be faster specially with trivial types
+         RandIt const new_first1 = first2 - (last1 - first1);
+         op(forward_t(), first1, last1, new_first1);
+         first1 = new_first1;
+         last1 = first2;
+         buffer = first1 - l_block;
+      }
+      buffer = op_partial_merge_impl(first1, last1, first_irr2, last_irr2, buffer, comp, op);
+      buffer = op(forward_t(), first1, last1, buffer);
+   }
+   else if(!is_buffer_middle){
+      buffer = op(forward_t(), first1, last1, buffer);
+   }
+   BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first-l_block, buffer, comp));
+
+   ////////////////////////////////////////////////////////////////////////////
+   //Process irregular B block and remaining A blocks
+   ////////////////////////////////////////////////////////////////////////////
+   buffer = op_merge_blocks_with_irreg
+      ( key_range2, key_mid, key_comp, first2, first_irr2, last_irr2
+      , buffer, l_block, n_block_left, min_check, max_check, comp, false, op);
+   buffer = op(forward_t(), first_irr2, last_irr2, buffer);(void)buffer;
+   BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first-l_block, buffer, comp));
+}
+
+// first - first element to merge.
+// first[-l_block, 0) - buffer (if use_buf == true)
+// l_block - length of regular blocks. First nblocks are stable sorted by 1st elements and key-coded
+// keys - sequence of keys, in same order as blocks. key<midkey means stream A
+// n_bef_irreg2/n_aft_irreg2 are regular blocks
+// l_irreg2 is a irregular block, that is to be combined after n_bef_irreg2 blocks and before n_aft_irreg2 blocks
+// If l_irreg2==0 then n_aft_irreg2==0 (no irregular blocks).
+template<class RandItKeys, class KeyCompare, class RandIt, class Compare>
+void merge_blocks_left
+   ( RandItKeys const key_first
+   , KeyCompare key_comp
+   , RandIt const first
+   , typename iterator_traits<RandIt>::size_type const l_block
+   , typename iterator_traits<RandIt>::size_type const l_irreg1
+   , typename iterator_traits<RandIt>::size_type const n_block_a
+   , typename iterator_traits<RandIt>::size_type const n_block_b
+   , typename iterator_traits<RandIt>::size_type const l_irreg2
+   , Compare comp
+   , bool const xbuf_used)
+{
+   BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!n_block_b || n_block_a == count_if_with(key_first, key_first + needed_keys_count(n_block_a, n_block_b), key_comp, key_first[n_block_a]));
+   if(xbuf_used){
+      op_merge_blocks_left
+         (key_first, key_comp, first, l_block, l_irreg1, n_block_a, n_block_b, l_irreg2, comp, move_op());
+   }
+   else{
+      op_merge_blocks_left
+         (key_first, key_comp, first, l_block, l_irreg1, n_block_a, n_block_b, l_irreg2, comp, swap_op());
+   }
+}
+
+// first - first element to merge.
+// [first+l_block*(n_bef_irreg2+n_aft_irreg2)+l_irreg2, first+l_block*(n_bef_irreg2+n_aft_irreg2+1)+l_irreg2) - buffer
+// l_block - length of regular blocks. First nblocks are stable sorted by 1st elements and key-coded
+// keys - sequence of keys, in same order as blocks. key<midkey means stream A
+// n_bef_irreg2/n_aft_irreg2 are regular blocks
+// l_irreg2 is a irregular block, that is to be combined after n_bef_irreg2 blocks and before n_aft_irreg2 blocks
+// If l_irreg2==0 then n_aft_irreg2==0 (no irregular blocks).
+template<class RandItKeys, class KeyCompare, class RandIt, class Compare>
+void merge_blocks_right
+   ( RandItKeys const key_first
+   , KeyCompare key_comp
+   , RandIt const first
+   , typename iterator_traits<RandIt>::size_type const l_block
+   , typename iterator_traits<RandIt>::size_type const n_block_a
+   , typename iterator_traits<RandIt>::size_type const n_block_b
+   , typename iterator_traits<RandIt>::size_type const l_irreg2
+   , Compare comp
+   , bool const xbuf_used)
+{
+   merge_blocks_left
+      ( (make_reverse_iterator)(key_first + needed_keys_count(n_block_a, n_block_b))
+      , inverse<KeyCompare>(key_comp)
+      , (make_reverse_iterator)(first + ((n_block_a+n_block_b)*l_block+l_irreg2))
+      , l_block
+      , l_irreg2
+      , n_block_b
+      , n_block_a
+      , 0
+      , inverse<Compare>(comp), xbuf_used);
+}
+
+//////////////////////////////////
+//////////////////////////////////
+//////////////////////////////////
+//
+//    op_merge_blocks_with_buf
+//
+//////////////////////////////////
+//////////////////////////////////
+//////////////////////////////////
+template<class RandItKeys, class KeyCompare, class RandIt, class Compare, class Op, class RandItBuf>
+void op_merge_blocks_with_buf
+   ( RandItKeys key_first
+   , KeyCompare key_comp
+   , RandIt const first
+   , typename iterator_traits<RandIt>::size_type const l_block
+   , typename iterator_traits<RandIt>::size_type const l_irreg1
+   , typename iterator_traits<RandIt>::size_type const n_block_a
+   , typename iterator_traits<RandIt>::size_type const n_block_b
+   , typename iterator_traits<RandIt>::size_type const l_irreg2
+   , Compare comp
+   , Op op
+   , RandItBuf const buf_first)
+{
+   typedef typename iterator_traits<RandIt>::size_type size_type;
+   size_type const key_count = needed_keys_count(n_block_a, n_block_b); (void)key_count;
+   //BOOST_ASSERT(n_block_a || n_block_b);
+   BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(boost::movelib::is_sorted_and_unique(key_first, key_first + key_count, key_comp));
+   BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!n_block_b || n_block_a == count_if_with(key_first, key_first + key_count, key_comp, key_first[n_block_a]));
+
+   size_type n_block_b_left = n_block_b;
+   size_type n_block_a_left = n_block_a;
+   size_type n_block_left = n_block_b + n_block_a;
+   RandItKeys key_mid(key_first + n_block_a);
+
+   RandItBuf buffer = buf_first;
+   RandItBuf buffer_end = buffer;
+   RandIt first1 = first;
+   RandIt last1  = first1 + l_irreg1;
+   RandIt first2 = last1;
+   RandIt const first_irr2 = first2 + n_block_left*l_block;
+   bool is_range1_A = true;
+
+   RandItKeys key_range2(key_first);
+
+   ////////////////////////////////////////////////////////////////////////////
+   //Process all regular blocks before the irregular B block
+   ////////////////////////////////////////////////////////////////////////////
+   size_type min_check = n_block_a == n_block_left ? 0u : n_block_a;
+   size_type max_check = min_value(min_check+1, n_block_left);
+   for (; n_block_left; --n_block_left, ++key_range2, min_check -= min_check != 0, max_check -= max_check != 0) {
+      size_type const next_key_idx = find_next_block(key_range2, key_comp, first2, l_block, min_check, max_check, comp);
+      max_check = min_value(max_value(max_check, next_key_idx+2), n_block_left);
+      RandIt       first_min = first2 + next_key_idx*l_block;
+      RandIt const last_min  = first_min + l_block; (void)last_min;
+      RandIt const last2  = first2 + l_block;
+
+      bool const buffer_empty = buffer == buffer_end; (void)buffer_empty;
+      BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(buffer_empty ? is_sorted(first1, last1, comp) : is_sorted(buffer, buffer_end, comp));
+      BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first2, last2, comp));
+      BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!n_block_left || is_sorted(first_min, last_min, comp));
+
+      //Check if irregular b block should go here.
+      //If so, break to the special code handling the irregular block
+      if (!n_block_b_left &&
+            ( (l_irreg2 && comp(*first_irr2, *first_min)) || (!l_irreg2 && is_range1_A)) ){
+         break;
+      }
+
+      RandItKeys const key_next(key_range2 + next_key_idx);
+      bool const is_range2_A = key_mid == (key_first+key_count) || key_comp(*key_next, *key_mid);
+
+      if(is_range1_A == is_range2_A){
+         BOOST_MOVE_ADAPTIVE_SORT_INVARIANT((first1 == last1) || (buffer_empty ? !comp(*first_min, last1[-1]) : !comp(*first_min, buffer_end[-1])));
+         //If buffered, put those elements in place
+         RandIt res = op(forward_t(), buffer, buffer_end, first1);
+         buffer    = buffer_end = buf_first;
+         BOOST_ASSERT(buffer_empty || res == last1); (void)res;
+         swap_and_update_key(key_next, key_range2, key_mid, first2, last2, first_min);
+         BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first2, last2, comp));
+         BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first_min, last_min, comp));
+         first1 = first2;
+         BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first, first1, comp));
+      }
+      else {
+         RandIt const unmerged = op_partial_merge_and_save(first1, last1, first2, last2, first_min, buffer, buffer_end, comp, op, is_range1_A);
+         bool const is_range_1_empty = buffer == buffer_end;
+         BOOST_ASSERT(is_range_1_empty || (buffer_end-buffer) == (last1+l_block-unmerged));
+         if(is_range_1_empty){
+            buffer    = buffer_end = buf_first;
+            first_min = last_min - (last2 - first2);
+         }
+         else{
+            first_min = last_min;
+         }
+         BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(!is_range_1_empty || (last_min-first_min) == (last2-unmerged));
+         swap_and_update_key(key_next, key_range2, key_mid, first2, last2, first_min);
+
+         BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first_min, last_min, comp));
+         is_range1_A ^= is_range_1_empty;
+         first1 = unmerged;
+         BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first, unmerged, comp));
+      }
+      BOOST_ASSERT( (is_range2_A && n_block_a_left) || (!is_range2_A && n_block_b_left));
+      is_range2_A ? --n_block_a_left : --n_block_b_left;
+      last1 += l_block;
+      first2 = last2;
+   }
+
+   RandIt res = op(forward_t(), buffer, buffer_end, first1); (void)res;
+   BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first, res, comp));
+
+   ////////////////////////////////////////////////////////////////////////////
+   //Process irregular B block and remaining A blocks
+   ////////////////////////////////////////////////////////////////////////////
+   RandIt const last_irr2 = first_irr2 + l_irreg2;
+   op(forward_t(), first_irr2, first_irr2+l_irreg2, buf_first);
+   buffer = buf_first;
+   buffer_end = buffer+l_irreg2;
+
+   reverse_iterator<RandItBuf> rbuf_beg(buffer_end);
+   RandIt dest = op_merge_blocks_with_irreg
+      ((make_reverse_iterator)(key_first + n_block_b + n_block_a), (make_reverse_iterator)(key_mid), inverse<KeyCompare>(key_comp)
+      , (make_reverse_iterator)(first_irr2), rbuf_beg
+      , (make_reverse_iterator)(buffer), (make_reverse_iterator)(last_irr2)
+      , l_block, n_block_left, 0, n_block_left
+      , inverse<Compare>(comp), true, op).base();
+   BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(dest, last_irr2, comp));
+
+   buffer_end = rbuf_beg.base();
+   BOOST_ASSERT((dest-last1) == (buffer_end-buffer));
+   op_merge_with_left_placed(is_range1_A ? first1 : last1, last1, dest, buffer, buffer_end, comp, op);
+
+   BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(first, last_irr2, comp));
+}
+
+//////////////////////////////////
+//////////////////////////////////
+//////////////////////////////////
+//
+//  op_insertion_sort_step_left/right
+//
+//////////////////////////////////
+//////////////////////////////////
+//////////////////////////////////
+
+template<class RandIt, class Compare, class Op>
+typename iterator_traits<RandIt>::size_type
+   op_insertion_sort_step_left
+      ( RandIt const first
+      , typename iterator_traits<RandIt>::size_type const length
+      , typename iterator_traits<RandIt>::size_type const step
+      , Compare comp, Op op)
+{
+   typedef typename iterator_traits<RandIt>::size_type size_type;
+   size_type const s = min_value<size_type>(step, AdaptiveSortInsertionSortThreshold);
+   size_type m = 0;
+
+   while((length - m) > s){
+      insertion_sort_op(first+m, first+m+s, first+m-s, comp, op);
+      m += s;
+   }
+   insertion_sort_op(first+m, first+length, first+m-s, comp, op);
+   return s;
+}
+
+template<class RandIt, class Compare, class Op>
+void op_merge_right_step_once
+      ( RandIt first_block
+      , typename iterator_traits<RandIt>::size_type const elements_in_blocks
+      , typename iterator_traits<RandIt>::size_type const l_build_buf
+      , Compare comp
+      , Op op)
+{
+   typedef typename iterator_traits<RandIt>::size_type size_type;
+   size_type restk = elements_in_blocks%(2*l_build_buf);
+   size_type p = elements_in_blocks - restk;
+   BOOST_ASSERT(0 == (p%(2*l_build_buf)));
+
+   if(restk <= l_build_buf){
+      op(backward_t(),first_block+p, first_block+p+restk, first_block+p+restk+l_build_buf);
+   }
+   else{
+      op_merge_right(first_block+p, first_block+p+l_build_buf, first_block+p+restk, first_block+p+restk+l_build_buf, comp, op);
+   }
+   while(p>0){
+      p -= 2*l_build_buf;
+      op_merge_right(first_block+p, first_block+p+l_build_buf, first_block+p+2*l_build_buf, first_block+p+3*l_build_buf, comp, op);
+   }
+}
+
+
+//////////////////////////////////
+//////////////////////////////////
+//////////////////////////////////
+//
+//    insertion_sort_step
+//
+//////////////////////////////////
+//////////////////////////////////
+//////////////////////////////////
+template<class RandIt, class Compare>
+typename iterator_traits<RandIt>::size_type
+   insertion_sort_step
+      ( RandIt const first
+      , typename iterator_traits<RandIt>::size_type const length
+      , typename iterator_traits<RandIt>::size_type const step
+      , Compare comp)
+{
+   typedef typename iterator_traits<RandIt>::size_type size_type;
+   size_type const s = min_value<size_type>(step, AdaptiveSortInsertionSortThreshold);
+   size_type m = 0;
+
+   while((length - m) > s){
+      insertion_sort(first+m, first+m+s, comp);
+      m += s;
+   }
+   insertion_sort(first+m, first+length, comp);
+   return s;
+}
+
+//////////////////////////////////
+//////////////////////////////////
+//////////////////////////////////
+//
+//    op_merge_left_step_multiple
+//
+//////////////////////////////////
+//////////////////////////////////
+//////////////////////////////////
+template<class RandIt, class Compare, class Op>
+typename iterator_traits<RandIt>::size_type  
+   op_merge_left_step_multiple
+      ( RandIt first_block
+      , typename iterator_traits<RandIt>::size_type const elements_in_blocks
+      , typename iterator_traits<RandIt>::size_type l_merged
+      , typename iterator_traits<RandIt>::size_type const l_build_buf
+      , typename iterator_traits<RandIt>::size_type l_left_space
+      , Compare comp
+      , Op op)
+{
+   typedef typename iterator_traits<RandIt>::size_type size_type;
+   for(; l_merged < l_build_buf && l_left_space >= l_merged; l_merged*=2){
+      size_type p0=0;
+      RandIt pos = first_block;
+      while((elements_in_blocks - p0) > 2*l_merged) {
+         op_merge_left(pos-l_merged, pos, pos+l_merged, pos+2*l_merged, comp, op);
+         BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(pos-l_merged, pos+l_merged, comp));
+         p0 += 2*l_merged;
+         pos = first_block+p0;
+      }
+      if((elements_in_blocks-p0) > l_merged) {
+         op_merge_left(pos-l_merged, pos, pos+l_merged, first_block+elements_in_blocks, comp, op);
+         BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(pos-l_merged, pos-l_merged+(first_block+elements_in_blocks-pos), comp));
+      }
+      else {
+         op(forward_t(), pos, first_block+elements_in_blocks, pos-l_merged);
+         BOOST_MOVE_ADAPTIVE_SORT_INVARIANT(is_sorted(pos-l_merged, first_block+elements_in_blocks-l_merged, comp));
+      }
+      first_block -= l_merged;
+      l_left_space -= l_merged;
+   }
+   return l_merged;
+}
+
+
+}  //namespace detail_adaptive {
+}  //namespace movelib {
+}  //namespace boost {
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif   //#define BOOST_MOVE_ADAPTIVE_SORT_MERGE_HPP
diff --git a/include/boost/move/algo/detail/basic_op.hpp b/include/boost/move/algo/detail/basic_op.hpp
new file mode 100644
index 0000000..ea5faf0
--- /dev/null
+++ b/include/boost/move/algo/detail/basic_op.hpp
@@ -0,0 +1,121 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2016.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_MOVE_ALGO_BASIC_OP
+#define BOOST_MOVE_ALGO_BASIC_OP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/utility_core.hpp>
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/move/detail/iterator_traits.hpp>
+
+namespace boost {
+namespace movelib {
+
+struct forward_t{};
+struct backward_t{};
+struct three_way_t{};
+struct three_way_forward_t{};
+struct four_way_t{};
+
+struct move_op
+{
+   template <class SourceIt, class DestinationIt>
+   BOOST_MOVE_FORCEINLINE void operator()(SourceIt source, DestinationIt dest)
+   {  *dest = ::boost::move(*source);  }
+
+   template <class SourceIt, class DestinationIt>
+   BOOST_MOVE_FORCEINLINE DestinationIt operator()(forward_t, SourceIt first, SourceIt last, DestinationIt dest_begin)
+   {  return ::boost::move(first, last, dest_begin);  }
+
+   template <class SourceIt, class DestinationIt>
+   BOOST_MOVE_FORCEINLINE DestinationIt operator()(backward_t, SourceIt first, SourceIt last, DestinationIt dest_last)
+   {  return ::boost::move_backward(first, last, dest_last);  }
+
+   template <class SourceIt, class DestinationIt1, class DestinationIt2>
+   BOOST_MOVE_FORCEINLINE void operator()(three_way_t, SourceIt srcit, DestinationIt1 dest1it, DestinationIt2 dest2it)
+   {
+      *dest2it = boost::move(*dest1it);
+      *dest1it = boost::move(*srcit);
+   }
+
+   template <class SourceIt, class DestinationIt1, class DestinationIt2>
+   DestinationIt2 operator()(three_way_forward_t, SourceIt srcit, SourceIt srcitend, DestinationIt1 dest1it, DestinationIt2 dest2it)
+   {
+      //Destination2 range can overlap SourceIt range so avoid boost::move
+      while(srcit != srcitend){
+         this->operator()(three_way_t(), srcit++, dest1it++, dest2it++);
+      }
+      return dest2it;
+   }
+
+   template <class SourceIt, class DestinationIt1, class DestinationIt2, class DestinationIt3>
+   BOOST_MOVE_FORCEINLINE void operator()(four_way_t, SourceIt srcit, DestinationIt1 dest1it, DestinationIt2 dest2it, DestinationIt3 dest3it)
+   {
+      *dest3it = boost::move(*dest2it);
+      *dest2it = boost::move(*dest1it);
+      *dest1it = boost::move(*srcit);
+   }
+};
+
+struct swap_op
+{
+   template <class SourceIt, class DestinationIt>
+   BOOST_MOVE_FORCEINLINE void operator()(SourceIt source, DestinationIt dest)
+   {  boost::adl_move_swap(*dest, *source);  }
+
+   template <class SourceIt, class DestinationIt>
+   BOOST_MOVE_FORCEINLINE DestinationIt operator()(forward_t, SourceIt first, SourceIt last, DestinationIt dest_begin)
+   {  return boost::adl_move_swap_ranges(first, last, dest_begin);  }
+
+   template <class SourceIt, class DestinationIt>
+   BOOST_MOVE_FORCEINLINE DestinationIt operator()(backward_t, SourceIt first, SourceIt last, DestinationIt dest_begin)
+   {  return boost::adl_move_swap_ranges_backward(first, last, dest_begin);  }
+
+   template <class SourceIt, class DestinationIt1, class DestinationIt2>
+   BOOST_MOVE_FORCEINLINE void operator()(three_way_t, SourceIt srcit, DestinationIt1 dest1it, DestinationIt2 dest2it)
+   {
+      typename ::boost::movelib::iterator_traits<SourceIt>::value_type tmp(boost::move(*dest2it));
+      *dest2it = boost::move(*dest1it);
+      *dest1it = boost::move(*srcit);
+      *srcit = boost::move(tmp);
+   }
+
+   template <class SourceIt, class DestinationIt1, class DestinationIt2>
+   DestinationIt2 operator()(three_way_forward_t, SourceIt srcit, SourceIt srcitend, DestinationIt1 dest1it, DestinationIt2 dest2it)
+   {
+      while(srcit != srcitend){
+         this->operator()(three_way_t(), srcit++, dest1it++, dest2it++);
+      }
+      return dest2it;
+   }
+
+   template <class SourceIt, class DestinationIt1, class DestinationIt2, class DestinationIt3>
+   BOOST_MOVE_FORCEINLINE void operator()(four_way_t, SourceIt srcit, DestinationIt1 dest1it, DestinationIt2 dest2it, DestinationIt3 dest3it)
+   {
+      typename ::boost::movelib::iterator_traits<SourceIt>::value_type tmp(boost::move(*dest3it));
+      *dest3it = boost::move(*dest2it);
+      *dest2it = boost::move(*dest1it);
+      *dest1it = boost::move(*srcit);
+      *srcit = boost::move(tmp);
+   }
+};
+
+
+}} //namespace boost::movelib
+
+#endif   //BOOST_MOVE_ALGO_BASIC_OP
diff --git a/include/boost/move/algo/detail/heap_sort.hpp b/include/boost/move/algo/detail/heap_sort.hpp
new file mode 100644
index 0000000..5474d9f
--- /dev/null
+++ b/include/boost/move/algo/detail/heap_sort.hpp
@@ -0,0 +1,111 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2017-2018.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
+
+#ifndef BOOST_MOVE_DETAIL_HEAP_SORT_HPP
+#define BOOST_MOVE_DETAIL_HEAP_SORT_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/detail/workaround.hpp>
+#include <boost/move/detail/iterator_traits.hpp>
+#include <boost/move/algo/detail/is_sorted.hpp>
+#include <boost/move/utility_core.hpp>
+
+namespace boost {  namespace movelib{
+
+template <class RandomAccessIterator, class Compare>
+class heap_sort_helper
+{
+   typedef typename boost::movelib::iterator_traits<RandomAccessIterator>::size_type  size_type;
+   typedef typename boost::movelib::iterator_traits<RandomAccessIterator>::value_type value_type;
+
+   static void adjust_heap(RandomAccessIterator first, size_type hole_index, size_type const len, value_type &value, Compare comp)
+   {
+      size_type const top_index = hole_index;
+      size_type second_child = 2 * (hole_index + 1);
+
+      while (second_child < len) {
+         if (comp(*(first + second_child), *(first + (second_child - 1))))
+            second_child--;
+         *(first + hole_index) = boost::move(*(first + second_child));
+         hole_index = second_child;
+         second_child = 2 * (second_child + 1);
+      }
+      if (second_child == len) {
+         *(first + hole_index) = boost::move(*(first + (second_child - 1)));
+         hole_index = second_child - 1;
+      }
+
+      {  //push_heap-like ending
+         size_type parent = (hole_index - 1) / 2;
+         while (hole_index > top_index && comp(*(first + parent), value)) {
+            *(first + hole_index) = boost::move(*(first + parent));
+            hole_index = parent;
+            parent = (hole_index - 1) / 2;
+         }    
+         *(first + hole_index) = boost::move(value);
+      }
+   }
+
+   static void make_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp)
+   {
+      size_type const len = size_type(last - first);
+      if (len > 1) {
+         size_type parent = len/2u - 1u;
+
+         do {
+            value_type v(boost::move(*(first + parent)));
+            adjust_heap(first, parent, len, v, comp);
+         }while (parent--);
+      }
+   }
+
+   static void sort_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp)
+   {
+      size_type len = size_type(last - first);
+      while (len > 1) {
+         //move biggest to the safe zone
+         --last;
+         value_type v(boost::move(*last));
+         *last = boost::move(*first);
+         adjust_heap(first, size_type(0), --len, v, comp);
+      }
+   }
+
+   public:
+   static void sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp)
+   {
+      make_heap(first, last, comp);
+      sort_heap(first, last, comp);
+      BOOST_ASSERT(boost::movelib::is_sorted(first, last, comp));
+   }
+};
+
+template <class RandomAccessIterator, class Compare>
+BOOST_MOVE_FORCEINLINE void heap_sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp)
+{
+   heap_sort_helper<RandomAccessIterator, Compare>::sort(first, last, comp);
+}
+
+}} //namespace boost {  namespace movelib{
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_MOVE_DETAIL_HEAP_SORT_HPP
diff --git a/include/boost/move/algo/detail/insertion_sort.hpp b/include/boost/move/algo/detail/insertion_sort.hpp
new file mode 100644
index 0000000..5c378c3
--- /dev/null
+++ b/include/boost/move/algo/detail/insertion_sort.hpp
@@ -0,0 +1,128 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2014.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
+
+#ifndef BOOST_MOVE_DETAIL_INSERT_SORT_HPP
+#define BOOST_MOVE_DETAIL_INSERT_SORT_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/utility_core.hpp>
+#include <boost/move/algo/move.hpp>
+#include <boost/move/detail/iterator_traits.hpp>
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/move/utility_core.hpp>
+#include <boost/move/detail/placement_new.hpp>
+#include <boost/move/detail/destruct_n.hpp>
+#include <boost/move/algo/detail/basic_op.hpp>
+#include <boost/move/detail/placement_new.hpp>
+#include <boost/move/detail/iterator_to_raw_pointer.hpp>
+
+namespace boost {  namespace movelib{
+
+// @cond
+
+template <class Compare, class ForwardIterator, class BirdirectionalIterator, class Op>
+void insertion_sort_op(ForwardIterator first1, ForwardIterator last1, BirdirectionalIterator first2, Compare comp, Op op)
+{
+   if (first1 != last1){
+      BirdirectionalIterator last2 = first2;
+      op(first1, last2);
+      for (++last2; ++first1 != last1; ++last2){
+         BirdirectionalIterator j2 = last2;
+         BirdirectionalIterator i2 = j2;
+         if (comp(*first1, *--i2)){
+            op(i2, j2);
+            for (--j2; i2 != first2 && comp(*first1, *--i2); --j2) {
+               op(i2, j2);
+            }
+         }
+         op(first1, j2);
+      }
+   }
+}
+
+template <class Compare, class ForwardIterator, class BirdirectionalIterator>
+void insertion_sort_swap(ForwardIterator first1, ForwardIterator last1, BirdirectionalIterator first2, Compare comp)
+{
+   insertion_sort_op(first1, last1, first2, comp, swap_op());
+}
+
+
+template <class Compare, class ForwardIterator, class BirdirectionalIterator>
+void insertion_sort_copy(ForwardIterator first1, ForwardIterator last1, BirdirectionalIterator first2, Compare comp)
+{
+   insertion_sort_op(first1, last1, first2, comp, move_op());
+}
+
+// @endcond
+
+template <class Compare, class BirdirectionalIterator>
+void insertion_sort(BirdirectionalIterator first, BirdirectionalIterator last, Compare comp)
+{
+   typedef typename boost::movelib::iterator_traits<BirdirectionalIterator>::value_type value_type;
+   if (first != last){
+      BirdirectionalIterator i = first;
+      for (++i; i != last; ++i){
+         BirdirectionalIterator j = i;
+         if (comp(*i,  *--j)) {
+            value_type tmp(::boost::move(*i));
+            *i = ::boost::move(*j);
+            for (BirdirectionalIterator k = j; k != first && comp(tmp,  *--k); --j) {
+               *j = ::boost::move(*k);
+            }
+            *j = ::boost::move(tmp);
+         }
+      }
+   }
+}
+
+template <class Compare, class BirdirectionalIterator, class BirdirectionalRawIterator>
+void insertion_sort_uninitialized_copy
+   (BirdirectionalIterator first1, BirdirectionalIterator const last1
+   , BirdirectionalRawIterator const first2
+   , Compare comp)
+{
+   typedef typename iterator_traits<BirdirectionalIterator>::value_type value_type;
+   if (first1 != last1){
+      BirdirectionalRawIterator last2 = first2;
+      ::new((iterator_to_raw_pointer)(last2), boost_move_new_t()) value_type(::boost::move(*first1));
+      destruct_n<value_type, BirdirectionalRawIterator> d(first2);
+      d.incr();
+      for (++last2; ++first1 != last1; ++last2){
+         BirdirectionalRawIterator j2 = last2;
+         BirdirectionalRawIterator k2 = j2;
+         if (comp(*first1, *--k2)){
+            ::new((iterator_to_raw_pointer)(j2), boost_move_new_t()) value_type(::boost::move(*k2));
+            d.incr();
+            for (--j2; k2 != first2 && comp(*first1, *--k2); --j2)
+               *j2 = ::boost::move(*k2);
+            *j2 = ::boost::move(*first1);
+         }
+         else{
+            ::new((iterator_to_raw_pointer)(j2), boost_move_new_t()) value_type(::boost::move(*first1));
+            d.incr();
+         }
+      }
+      d.release();
+   }
+}
+
+}} //namespace boost {  namespace movelib{
+
+#endif //#ifndef BOOST_MOVE_DETAIL_INSERT_SORT_HPP
diff --git a/include/boost/move/algo/detail/is_sorted.hpp b/include/boost/move/algo/detail/is_sorted.hpp
new file mode 100644
index 0000000..d3dccfc
--- /dev/null
+++ b/include/boost/move/algo/detail/is_sorted.hpp
@@ -0,0 +1,55 @@
+#ifndef BOOST_MOVE_DETAIL_IS_SORTED_HPP
+#define BOOST_MOVE_DETAIL_IS_SORTED_HPP
+///////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2017-2018. 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)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+namespace boost {
+namespace movelib {
+
+template<class ForwardIt, class Pred>
+bool is_sorted(ForwardIt const first, ForwardIt last, Pred pred)
+{
+   if (first != last) {
+      ForwardIt next = first, cur(first);
+      while (++next != last) {
+         if (pred(*next, *cur))
+            return false;
+         cur = next;
+      }
+   }
+   return true;
+}
+
+template<class ForwardIt, class Pred>
+bool is_sorted_and_unique(ForwardIt first, ForwardIt last, Pred pred)
+{
+   if (first != last) {
+      ForwardIt next = first;
+      while (++next != last) {
+         if (!pred(*first, *next))
+            return false;
+         first = next;
+      }
+   }
+   return true;
+}
+
+}  //namespace movelib {
+}  //namespace boost {
+
+#endif   //BOOST_MOVE_DETAIL_IS_SORTED_HPP
diff --git a/include/boost/move/algo/detail/merge.hpp b/include/boost/move/algo/detail/merge.hpp
new file mode 100644
index 0000000..8607735
--- /dev/null
+++ b/include/boost/move/algo/detail/merge.hpp
@@ -0,0 +1,553 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2016.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_MOVE_MERGE_HPP
+#define BOOST_MOVE_MERGE_HPP
+
+#include <boost/move/algo/move.hpp>
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/move/algo/detail/basic_op.hpp>
+#include <boost/move/detail/iterator_traits.hpp>
+#include <boost/move/detail/destruct_n.hpp>
+#include <boost/move/algo/predicate.hpp>
+#include <boost/move/detail/iterator_to_raw_pointer.hpp>
+#include <boost/assert.hpp>
+
+namespace boost {
+namespace movelib {
+
+// @cond
+
+/*
+template<typename Unsigned>
+inline Unsigned gcd(Unsigned x, Unsigned y)
+{
+   if(0 == ((x &(x-1)) | (y & (y-1)))){
+      return x < y ? x : y;
+   }
+   else{
+      do
+      {
+         Unsigned t = x % y;
+         x = y;
+         y = t;
+      } while (y);
+      return x;
+   }
+}
+*/
+
+//Modified version from "An Optimal In-Place Array Rotation Algorithm", Ching-Kuang Shene
+template<typename Unsigned>
+Unsigned gcd(Unsigned x, Unsigned y)
+{
+   if(0 == ((x &(x-1)) | (y & (y-1)))){
+      return x < y ? x : y;
+   }
+   else{
+      Unsigned z = 1;
+      while((!(x&1)) & (!(y&1))){
+         z <<=1, x>>=1, y>>=1;
+      }
+      while(x && y){
+         if(!(x&1))
+            x >>=1;
+         else if(!(y&1))
+            y >>=1;
+         else if(x >=y)
+            x = (x-y) >> 1;
+         else
+            y = (y-x) >> 1;
+      }
+      return z*(x+y);
+   }
+}
+
+template<typename RandIt>
+RandIt rotate_gcd(RandIt first, RandIt middle, RandIt last)
+{
+   typedef typename iterator_traits<RandIt>::size_type size_type;
+   typedef typename iterator_traits<RandIt>::value_type value_type;
+
+   if(first == middle)
+      return last;
+   if(middle == last)
+      return first;
+   const size_type middle_pos = size_type(middle - first);
+   RandIt ret = last - middle_pos;
+   if (middle == ret){
+      boost::adl_move_swap_ranges(first, middle, middle);
+   }
+   else{
+      const size_type length = size_type(last - first);
+      for( RandIt it_i(first), it_gcd(it_i + gcd(length, middle_pos))
+         ; it_i != it_gcd
+         ; ++it_i){
+         value_type temp(boost::move(*it_i));
+         RandIt it_j = it_i;
+         RandIt it_k = it_j+middle_pos;
+         do{
+            *it_j = boost::move(*it_k);
+            it_j = it_k;
+            size_type const left = size_type(last - it_j);
+            it_k = left > middle_pos ? it_j + middle_pos : first + (middle_pos - left);
+         } while(it_k != it_i);
+         *it_j = boost::move(temp);
+      }
+   }
+   return ret;
+}
+
+template <class RandIt, class T, class Compare>
+RandIt lower_bound
+   (RandIt first, const RandIt last, const T& key, Compare comp)
+{
+   typedef typename iterator_traits
+      <RandIt>::size_type size_type;
+   size_type len = size_type(last - first);
+   RandIt middle;
+
+   while (len) {
+      size_type step = len >> 1;
+      middle = first;
+      middle += step;
+
+      if (comp(*middle, key)) {
+         first = ++middle;
+         len -= step + 1;
+      }
+      else{
+         len = step;
+      }
+   }
+   return first;
+}
+
+template <class RandIt, class T, class Compare>
+RandIt upper_bound
+   (RandIt first, const RandIt last, const T& key, Compare comp)
+{
+   typedef typename iterator_traits
+      <RandIt>::size_type size_type;
+   size_type len = size_type(last - first);
+   RandIt middle;
+
+   while (len) {
+      size_type step = len >> 1;
+      middle = first;
+      middle += step;
+
+      if (!comp(key, *middle)) {
+         first = ++middle;
+         len -= step + 1;
+      }
+      else{
+         len = step;
+      }
+   }
+   return first;
+}
+
+
+template<class RandIt, class Compare, class Op>
+void op_merge_left( RandIt buf_first
+                    , RandIt first1
+                    , RandIt const last1
+                    , RandIt const last2
+                    , Compare comp
+                    , Op op)
+{
+   for(RandIt first2=last1; first2 != last2; ++buf_first){
+      if(first1 == last1){
+         op(forward_t(), first2, last2, buf_first);
+         return;
+      }
+      else if(comp(*first2, *first1)){
+         op(first2, buf_first);
+         ++first2;
+      }
+      else{
+         op(first1, buf_first);
+         ++first1;
+      }
+   }
+   if(buf_first != first1){//In case all remaining elements are in the same place
+                           //(e.g. buffer is exactly the size of the second half
+                           //and all elements from the second half are less)
+      op(forward_t(), first1, last1, buf_first);
+   }
+}
+
+// [buf_first, first1) -> buffer
+// [first1, last1) merge [last1,last2) -> [buf_first,buf_first+(last2-first1))
+// Elements from buffer are moved to [last2 - (first1-buf_first), last2)
+// Note: distance(buf_first, first1) >= distance(last1, last2), so no overlapping occurs
+template<class RandIt, class Compare>
+void merge_left
+   (RandIt buf_first, RandIt first1, RandIt const last1, RandIt const last2, Compare comp)
+{
+   op_merge_left(buf_first, first1, last1, last2, comp, move_op());
+}
+
+// [buf_first, first1) -> buffer
+// [first1, last1) merge [last1,last2) -> [buf_first,buf_first+(last2-first1))
+// Elements from buffer are swapped to [last2 - (first1-buf_first), last2)
+// Note: distance(buf_first, first1) >= distance(last1, last2), so no overlapping occurs
+template<class RandIt, class Compare>
+void swap_merge_left
+   (RandIt buf_first, RandIt first1, RandIt const last1, RandIt const last2, Compare comp)
+{
+   op_merge_left(buf_first, first1, last1, last2, comp, swap_op());
+}
+
+template<class RandIt, class Compare, class Op>
+void op_merge_right
+   (RandIt const first1, RandIt last1, RandIt last2, RandIt buf_last, Compare comp, Op op)
+{
+   RandIt const first2 = last1;
+   while(first1 != last1){
+      if(last2 == first2){
+         op(backward_t(), first1, last1, buf_last);
+         return;
+      }
+      --last2;
+      --last1;
+      --buf_last;
+      if(comp(*last2, *last1)){
+         op(last1, buf_last);
+         ++last2;
+      }
+      else{
+         op(last2, buf_last);
+         ++last1;
+      }
+   }
+   if(last2 != buf_last){  //In case all remaining elements are in the same place
+                           //(e.g. buffer is exactly the size of the first half
+                           //and all elements from the second half are less)
+      op(backward_t(), first2, last2, buf_last);
+   }
+}
+
+// [last2, buf_last) - buffer
+// [first1, last1) merge [last1,last2) -> [first1+(buf_last-last2), buf_last)
+// Note: distance[last2, buf_last) >= distance[first1, last1), so no overlapping occurs
+template<class RandIt, class Compare>
+void merge_right
+   (RandIt first1, RandIt last1, RandIt last2, RandIt buf_last, Compare comp)
+{
+   op_merge_right(first1, last1, last2, buf_last, comp, move_op());
+}
+
+// [last2, buf_last) - buffer
+// [first1, last1) merge [last1,last2) -> [first1+(buf_last-last2), buf_last)
+// Note: distance[last2, buf_last) >= distance[first1, last1), so no overlapping occurs
+template<class RandIt, class Compare>
+void swap_merge_right
+   (RandIt first1, RandIt last1, RandIt last2, RandIt buf_last, Compare comp)
+{
+   op_merge_right(first1, last1, last2, buf_last, comp, swap_op());
+}
+
+//Complexity: min(len1,len2)^2 + max(len1,len2)
+template<class RandIt, class Compare>
+void merge_bufferless_ON2(RandIt first, RandIt middle, RandIt last, Compare comp)
+{
+   if((middle - first) < (last - middle)){
+      while(first != middle){
+         RandIt const old_last1 = middle;
+         middle = boost::movelib::lower_bound(middle, last, *first, comp);
+         first = rotate_gcd(first, old_last1, middle);
+         if(middle == last){
+            break;
+         }
+         do{
+            ++first;
+         } while(first != middle && !comp(*middle, *first));
+      }
+   }
+   else{
+      while(middle != last){
+         RandIt p = boost::movelib::upper_bound(first, middle, last[-1], comp);
+         last = rotate_gcd(p, middle, last);
+         middle = p;
+         if(middle == first){
+            break;
+         }
+         --p;
+         do{
+            --last;
+         } while(middle != last && !comp(last[-1], *p));
+      }
+   }
+}
+
+static const std::size_t MergeBufferlessONLogNRotationThreshold = 32;
+
+template <class RandIt, class Distance, class Compare>
+void merge_bufferless_ONlogN_recursive
+   (RandIt first, RandIt middle, RandIt last, Distance len1, Distance len2, Compare comp)
+{
+   typedef typename iterator_traits<RandIt>::size_type size_type;
+
+   while(1) {
+      //trivial cases
+      if (!len2) {
+         return;
+      }
+      else if (!len1) {
+         return;
+      }
+      else if (size_type(len1 | len2) == 1u) {
+         if (comp(*middle, *first))
+            adl_move_swap(*first, *middle);  
+         return;
+      }
+      else if(size_type(len1+len2) < MergeBufferlessONLogNRotationThreshold){
+         merge_bufferless_ON2(first, middle, last, comp);
+         return;
+      }
+
+      RandIt first_cut = first;
+      RandIt second_cut = middle;
+      Distance len11 = 0;
+      Distance len22 = 0;
+      if (len1 > len2) {
+         len11 = len1 / 2;
+         first_cut +=  len11;
+         second_cut = boost::movelib::lower_bound(middle, last, *first_cut, comp);
+         len22 = size_type(second_cut - middle);
+      }
+      else {
+         len22 = len2 / 2;
+         second_cut += len22;
+         first_cut = boost::movelib::upper_bound(first, middle, *second_cut, comp);
+         len11 = size_type(first_cut - first);
+      }
+      RandIt new_middle = rotate_gcd(first_cut, middle, second_cut);
+
+      //Avoid one recursive call doing a manual tail call elimination on the biggest range
+      const Distance len_internal = len11+len22;
+      if( len_internal < (len1 + len2 - len_internal) ) {
+         merge_bufferless_ONlogN_recursive(first,      first_cut,  new_middle, len11,        len22,        comp);
+         first = new_middle;
+         middle = second_cut;
+         len1 -= len11;
+         len2 -= len22;
+      }
+      else {
+         merge_bufferless_ONlogN_recursive(new_middle, second_cut, last,       len1 - len11, len2 - len22, comp);
+         middle = first_cut;
+         last = new_middle;
+         len1 = len11;
+         len2 = len22;
+      }
+   }
+}
+
+//Complexity: NlogN
+template<class RandIt, class Compare>
+void merge_bufferless_ONlogN(RandIt first, RandIt middle, RandIt last, Compare comp)
+{
+   merge_bufferless_ONlogN_recursive
+      (first, middle, last, middle - first, last - middle, comp); 
+}
+
+template<class RandIt, class Compare>
+void merge_bufferless(RandIt first, RandIt middle, RandIt last, Compare comp)
+{
+   #define BOOST_ADAPTIVE_MERGE_NLOGN_MERGE
+   #ifdef BOOST_ADAPTIVE_MERGE_NLOGN_MERGE
+   merge_bufferless_ONlogN(first, middle, last, comp);
+   #else
+   merge_bufferless_ON2(first, middle, last, comp);
+   #endif   //BOOST_ADAPTIVE_MERGE_NLOGN_MERGE
+}
+
+// [r_first, r_last) are already in the right part of the destination range.
+template <class Compare, class InputIterator, class InputOutIterator, class Op>
+void op_merge_with_right_placed
+   ( InputIterator first, InputIterator last
+   , InputOutIterator dest_first, InputOutIterator r_first, InputOutIterator r_last
+   , Compare comp, Op op)
+{
+   BOOST_ASSERT((last - first) == (r_first - dest_first));
+   while ( first != last ) {
+      if (r_first == r_last) {
+         InputOutIterator end = op(forward_t(), first, last, dest_first);
+         BOOST_ASSERT(end == r_last);
+         (void)end;
+         return;
+      }
+      else if (comp(*r_first, *first)) {
+         op(r_first, dest_first);
+         ++r_first;
+      }
+      else {
+         op(first, dest_first);
+         ++first;
+      }
+      ++dest_first;
+   }
+   // Remaining [r_first, r_last) already in the correct place
+}
+
+template <class Compare, class InputIterator, class InputOutIterator>
+void swap_merge_with_right_placed
+   ( InputIterator first, InputIterator last
+   , InputOutIterator dest_first, InputOutIterator r_first, InputOutIterator r_last
+   , Compare comp)
+{
+   op_merge_with_right_placed(first, last, dest_first, r_first, r_last, comp, swap_op());
+}
+
+// [first, last) are already in the right part of the destination range.
+template <class Compare, class Op, class BidirIterator, class BidirOutIterator>
+void op_merge_with_left_placed
+   ( BidirOutIterator const first, BidirOutIterator last, BidirOutIterator dest_last
+   , BidirIterator const r_first, BidirIterator r_last
+   , Compare comp, Op op)
+{
+   BOOST_ASSERT((dest_last - last) == (r_last - r_first));
+   while( r_first != r_last ) {
+      if(first == last) {
+         BidirOutIterator res = op(backward_t(), r_first, r_last, dest_last);
+         BOOST_ASSERT(last == res);
+         (void)res;
+         return;
+      }
+      --r_last;
+      --last;
+      if(comp(*r_last, *last)){
+         ++r_last;
+         --dest_last;
+         op(last, dest_last);
+      }
+      else{
+         ++last;
+         --dest_last;
+         op(r_last, dest_last);
+      }
+   }
+   // Remaining [first, last) already in the correct place
+}
+
+// @endcond
+
+// [irst, last) are already in the right part of the destination range.
+template <class Compare, class BidirIterator, class BidirOutIterator>
+void merge_with_left_placed
+   ( BidirOutIterator const first, BidirOutIterator last, BidirOutIterator dest_last
+   , BidirIterator const r_first, BidirIterator r_last
+   , Compare comp)
+{
+   op_merge_with_left_placed(first, last, dest_last, r_first, r_last, comp, move_op());
+}
+
+// [r_first, r_last) are already in the right part of the destination range.
+template <class Compare, class InputIterator, class InputOutIterator>
+void merge_with_right_placed
+   ( InputIterator first, InputIterator last
+   , InputOutIterator dest_first, InputOutIterator r_first, InputOutIterator r_last
+   , Compare comp)
+{
+   op_merge_with_right_placed(first, last, dest_first, r_first, r_last, comp, move_op());
+}
+
+// [r_first, r_last) are already in the right part of the destination range.
+// [dest_first, r_first) is uninitialized memory
+template <class Compare, class InputIterator, class InputOutIterator>
+void uninitialized_merge_with_right_placed
+   ( InputIterator first, InputIterator last
+   , InputOutIterator dest_first, InputOutIterator r_first, InputOutIterator r_last
+   , Compare comp)
+{
+   BOOST_ASSERT((last - first) == (r_first - dest_first));
+   typedef typename iterator_traits<InputOutIterator>::value_type value_type;
+   InputOutIterator const original_r_first = r_first;
+
+   destruct_n<value_type, InputOutIterator> d(dest_first);
+
+   while ( first != last && dest_first != original_r_first ) {
+      if (r_first == r_last) {
+         for(; dest_first != original_r_first; ++dest_first, ++first){
+            ::new((iterator_to_raw_pointer)(dest_first)) value_type(::boost::move(*first));
+            d.incr();
+         }
+         d.release();
+         InputOutIterator end = ::boost::move(first, last, original_r_first);
+         BOOST_ASSERT(end == r_last);
+         (void)end;
+         return;
+      }
+      else if (comp(*r_first, *first)) {
+         ::new((iterator_to_raw_pointer)(dest_first)) value_type(::boost::move(*r_first));
+         d.incr();
+         ++r_first;
+      }
+      else {
+         ::new((iterator_to_raw_pointer)(dest_first)) value_type(::boost::move(*first));
+         d.incr();
+         ++first;
+      }
+      ++dest_first;
+   }
+   d.release();
+   merge_with_right_placed(first, last, original_r_first, r_first, r_last, comp);
+}
+
+/*
+// [r_first, r_last) are already in the right part of the destination range.
+// [dest_first, r_first) is uninitialized memory
+template <class Compare, class BidirOutIterator, class BidirIterator>
+void uninitialized_merge_with_left_placed
+   ( BidirOutIterator dest_first, BidirOutIterator r_first, BidirOutIterator r_last
+   , BidirIterator first, BidirIterator last
+   , Compare comp)
+{
+   BOOST_ASSERT((last - first) == (r_last - r_first));
+   typedef typename iterator_traits<BidirOutIterator>::value_type value_type;
+   BidirOutIterator const original_r_last = r_last;
+
+   destruct_n<value_type> d(&*dest_last);
+
+   while ( first != last && dest_first != original_r_first ) {
+      if (r_first == r_last) {
+         for(; dest_first != original_r_first; ++dest_first, ++first){
+            ::new(&*dest_first) value_type(::boost::move(*first));
+            d.incr();
+         }
+         d.release();
+         BidirOutIterator end = ::boost::move(first, last, original_r_first);
+         BOOST_ASSERT(end == r_last);
+         (void)end;
+         return;
+      }
+      else if (comp(*r_first, *first)) {
+         ::new(&*dest_first) value_type(::boost::move(*r_first));
+         d.incr();
+         ++r_first;
+      }
+      else {
+         ::new(&*dest_first) value_type(::boost::move(*first));
+         d.incr();
+         ++first;
+      }
+      ++dest_first;
+   }
+   d.release();
+   merge_with_right_placed(first, last, original_r_first, r_first, r_last, comp);
+}
+*/
+
+}  //namespace movelib {
+}  //namespace boost {
+
+#endif   //#define BOOST_MOVE_MERGE_HPP
diff --git a/include/boost/move/algo/detail/merge_sort.hpp b/include/boost/move/algo/detail/merge_sort.hpp
new file mode 100644
index 0000000..62d185a
--- /dev/null
+++ b/include/boost/move/algo/detail/merge_sort.hpp
@@ -0,0 +1,139 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2016.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
+
+#ifndef BOOST_MOVE_DETAIL_MERGE_SORT_HPP
+#define BOOST_MOVE_DETAIL_MERGE_SORT_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/detail/workaround.hpp>
+
+#include <boost/move/utility_core.hpp>
+#include <boost/move/algo/move.hpp>
+#include <boost/move/algo/detail/merge.hpp>
+#include <boost/move/detail/iterator_traits.hpp>
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/move/detail/destruct_n.hpp>
+#include <boost/move/algo/detail/insertion_sort.hpp>
+#include <cassert>
+
+namespace boost {
+namespace movelib {
+
+// @cond
+
+static const unsigned MergeSortInsertionSortThreshold = 16;
+
+template <class RandIt, class Compare>
+void inplace_stable_sort(RandIt first, RandIt last, Compare comp)
+{
+   typedef typename iterator_traits<RandIt>::size_type  size_type;
+   if (size_type(last - first) <= size_type(MergeSortInsertionSortThreshold)) {
+      insertion_sort(first, last, comp);
+      return;
+   }
+   RandIt middle = first + (last - first) / 2;
+   inplace_stable_sort(first, middle, comp);
+   inplace_stable_sort(middle, last, comp);
+   merge_bufferless_ONlogN_recursive
+      (first, middle, last, size_type(middle - first), size_type(last - middle), comp);
+}
+
+// @endcond
+
+template<class RandIt, class RandIt2, class Compare>
+void merge_sort_copy( RandIt first, RandIt last
+                   , RandIt2 dest, Compare comp)
+{
+   typedef typename iterator_traits<RandIt>::size_type  size_type;
+
+   size_type const count = size_type(last - first);
+   if(count <= MergeSortInsertionSortThreshold){
+      insertion_sort_copy(first, last, dest, comp);
+   }
+   else{
+      size_type const half = count/2;
+      merge_sort_copy(first + half, last        , dest+half   , comp);
+      merge_sort_copy(first       , first + half, first + half, comp);
+      merge_with_right_placed
+         ( first + half, first + half + half
+         , dest, dest+half, dest + count
+         , comp);
+   }
+}
+
+template<class RandIt, class RandItRaw, class Compare>
+void merge_sort_uninitialized_copy( RandIt first, RandIt last
+                                 , RandItRaw uninitialized
+                                 , Compare comp)
+{
+   typedef typename iterator_traits<RandIt>::size_type  size_type;
+   typedef typename iterator_traits<RandIt>::value_type value_type;
+
+   size_type const count = size_type(last - first);
+   if(count <= MergeSortInsertionSortThreshold){
+      insertion_sort_uninitialized_copy(first, last, uninitialized, comp);
+   }
+   else{
+      size_type const half = count/2;
+      merge_sort_uninitialized_copy(first + half, last, uninitialized + half, comp);
+      destruct_n<value_type, RandItRaw> d(uninitialized+half);
+      d.incr(count-half);
+      merge_sort_copy(first, first + half, first + half, comp);
+      uninitialized_merge_with_right_placed
+         ( first + half, first + half + half
+         , uninitialized, uninitialized+half, uninitialized+count
+         , comp);
+      d.release();
+   }
+}
+
+template<class RandIt, class RandItRaw, class Compare>
+void merge_sort( RandIt first, RandIt last, Compare comp
+               , RandItRaw uninitialized)
+{
+   typedef typename iterator_traits<RandIt>::size_type  size_type;
+   typedef typename iterator_traits<RandIt>::value_type value_type;
+
+   size_type const count = size_type(last - first);
+   if(count <= MergeSortInsertionSortThreshold){
+      insertion_sort(first, last, comp);
+   }
+   else{
+      size_type const half = count/2;
+      size_type const rest = count -  half;
+      RandIt const half_it = first + half;
+      RandIt const rest_it = first + rest;
+
+      merge_sort_uninitialized_copy(half_it, last, uninitialized, comp);
+      destruct_n<value_type, RandItRaw> d(uninitialized);
+      d.incr(rest);
+      merge_sort_copy(first, half_it, rest_it, comp);
+      merge_with_right_placed
+         ( uninitialized, uninitialized + rest
+         , first, rest_it, last, antistable<Compare>(comp));
+   }
+}
+
+}} //namespace boost {  namespace movelib{
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_MOVE_DETAIL_MERGE_SORT_HPP
diff --git a/include/boost/move/algo/detail/pdqsort.hpp b/include/boost/move/algo/detail/pdqsort.hpp
new file mode 100644
index 0000000..b6a1278
--- /dev/null
+++ b/include/boost/move/algo/detail/pdqsort.hpp
@@ -0,0 +1,334 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Orson Peters  2017.
+// (C) Copyright Ion Gaztanaga 2017-2018.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+//
+// This implementation of Pattern-defeating quicksort (pdqsort) was written
+// by Orson Peters, and discussed in the Boost mailing list:
+// http://boost.2283326.n4.nabble.com/sort-pdqsort-td4691031.html
+//
+// This implementation is the adaptation by Ion Gaztanaga of code originally in GitHub
+// with permission from the author to relicense it under the Boost Software License
+// (see the Boost mailing list for details).
+//
+// The original copyright statement is pasted here for completeness:
+//
+//  pdqsort.h - Pattern-defeating quicksort.
+//  Copyright (c) 2015 Orson Peters
+//  This software is provided 'as-is', without any express or implied warranty. In no event will the
+//  authors be held liable for any damages arising from the use of this software.
+//  Permission is granted to anyone to use this software for any purpose, including commercial
+//  applications, and to alter it and redistribute it freely, subject to the following restrictions:
+//  1. The origin of this software must not be misrepresented; you must not claim that you wrote the
+//     original software. If you use this software in a product, an acknowledgment in the product
+//     documentation would be appreciated but is not required.
+//  2. Altered source versions must be plainly marked as such, and must not be misrepresented as
+//     being the original software.
+//  3. This notice may not be removed or altered from any source distribution.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_MOVE_ALGO_PDQSORT_HPP
+#define BOOST_MOVE_ALGO_PDQSORT_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/detail/workaround.hpp>
+#include <boost/move/utility_core.hpp>
+#include <boost/move/algo/detail/insertion_sort.hpp>
+#include <boost/move/algo/detail/heap_sort.hpp>
+#include <boost/move/detail/iterator_traits.hpp>
+
+#include <boost/move/adl_move_swap.hpp>
+#include <cstddef>
+
+namespace boost {
+namespace movelib {
+
+namespace pdqsort_detail {
+
+   //A simple pair implementation to avoid including <utility>
+   template<class T1, class T2>
+   struct pair
+   {
+      pair()
+      {}
+
+      pair(const T1 &t1, const T2 &t2)
+         : first(t1), second(t2)
+      {}
+
+      T1 first;
+      T2 second;
+   };
+
+    enum {
+        // Partitions below this size are sorted using insertion sort.
+        insertion_sort_threshold = 24,
+
+        // Partitions above this size use Tukey's ninther to select the pivot.
+        ninther_threshold = 128,
+
+        // When we detect an already sorted partition, attempt an insertion sort that allows this
+        // amount of element moves before giving up.
+        partial_insertion_sort_limit = 8,
+
+        // Must be multiple of 8 due to loop unrolling, and < 256 to fit in unsigned char.
+        block_size = 64,
+
+        // Cacheline size, assumes power of two.
+        cacheline_size = 64
+
+    };
+
+    // Returns floor(log2(n)), assumes n > 0.
+    template<class Unsigned>
+    Unsigned log2(Unsigned n) {
+        Unsigned log = 0;
+        while (n >>= 1) ++log;
+        return log;
+    }
+
+    // Attempts to use insertion sort on [begin, end). Will return false if more than
+    // partial_insertion_sort_limit elements were moved, and abort sorting. Otherwise it will
+    // successfully sort and return true.
+    template<class Iter, class Compare>
+    inline bool partial_insertion_sort(Iter begin, Iter end, Compare comp) {
+        typedef typename boost::movelib::iterator_traits<Iter>::value_type T;
+        typedef typename boost::movelib::iterator_traits<Iter>::size_type  size_type;
+        if (begin == end) return true;
+        
+        size_type limit = 0;
+        for (Iter cur = begin + 1; cur != end; ++cur) {
+            if (limit > partial_insertion_sort_limit) return false;
+
+            Iter sift = cur;
+            Iter sift_1 = cur - 1;
+
+            // Compare first so we can avoid 2 moves for an element already positioned correctly.
+            if (comp(*sift, *sift_1)) {
+                T tmp = boost::move(*sift);
+
+                do { *sift-- = boost::move(*sift_1); }
+                while (sift != begin && comp(tmp, *--sift_1));
+
+                *sift = boost::move(tmp);
+                limit += size_type(cur - sift);
+            }
+        }
+
+        return true;
+    }
+
+    template<class Iter, class Compare>
+    inline void sort2(Iter a, Iter b, Compare comp) {
+        if (comp(*b, *a)) boost::adl_move_iter_swap(a, b);
+    }
+
+    // Sorts the elements *a, *b and *c using comparison function comp.
+    template<class Iter, class Compare>
+    inline void sort3(Iter a, Iter b, Iter c, Compare comp) {
+        sort2(a, b, comp);
+        sort2(b, c, comp);
+        sort2(a, b, comp);
+    }
+
+    // Partitions [begin, end) around pivot *begin using comparison function comp. Elements equal
+    // to the pivot are put in the right-hand partition. Returns the position of the pivot after
+    // partitioning and whether the passed sequence already was correctly partitioned. Assumes the
+    // pivot is a median of at least 3 elements and that [begin, end) is at least
+    // insertion_sort_threshold long.
+    template<class Iter, class Compare>
+    pdqsort_detail::pair<Iter, bool> partition_right(Iter begin, Iter end, Compare comp) {
+        typedef typename boost::movelib::iterator_traits<Iter>::value_type T;
+        
+        // Move pivot into local for speed.
+        T pivot(boost::move(*begin));
+
+        Iter first = begin;
+        Iter last = end;
+
+        // Find the first element greater than or equal than the pivot (the median of 3 guarantees
+        // this exists).
+        while (comp(*++first, pivot));
+
+        // Find the first element strictly smaller than the pivot. We have to guard this search if
+        // there was no element before *first.
+        if (first - 1 == begin) while (first < last && !comp(*--last, pivot));
+        else                    while (                !comp(*--last, pivot));
+
+        // If the first pair of elements that should be swapped to partition are the same element,
+        // the passed in sequence already was correctly partitioned.
+        bool already_partitioned = first >= last;
+        
+        // Keep swapping pairs of elements that are on the wrong side of the pivot. Previously
+        // swapped pairs guard the searches, which is why the first iteration is special-cased
+        // above.
+        while (first < last) {
+            boost::adl_move_iter_swap(first, last);
+            while (comp(*++first, pivot));
+            while (!comp(*--last, pivot));
+        }
+
+        // Put the pivot in the right place.
+        Iter pivot_pos = first - 1;
+        *begin = boost::move(*pivot_pos);
+        *pivot_pos = boost::move(pivot);
+
+        return pdqsort_detail::pair<Iter, bool>(pivot_pos, already_partitioned);
+    }
+
+    // Similar function to the one above, except elements equal to the pivot are put to the left of
+    // the pivot and it doesn't check or return if the passed sequence already was partitioned.
+    // Since this is rarely used (the many equal case), and in that case pdqsort already has O(n)
+    // performance, no block quicksort is applied here for simplicity.
+    template<class Iter, class Compare>
+    inline Iter partition_left(Iter begin, Iter end, Compare comp) {
+        typedef typename boost::movelib::iterator_traits<Iter>::value_type T;
+
+        T pivot(boost::move(*begin));
+        Iter first = begin;
+        Iter last = end;
+        
+        while (comp(pivot, *--last));
+
+        if (last + 1 == end) while (first < last && !comp(pivot, *++first));
+        else                 while (                !comp(pivot, *++first));
+
+        while (first < last) {
+            boost::adl_move_iter_swap(first, last);
+            while (comp(pivot, *--last));
+            while (!comp(pivot, *++first));
+        }
+
+        Iter pivot_pos = last;
+        *begin = boost::move(*pivot_pos);
+        *pivot_pos = boost::move(pivot);
+
+        return pivot_pos;
+    }
+
+
+   template<class Iter, class Compare>
+   void pdqsort_loop( Iter begin, Iter end, Compare comp
+                    , typename boost::movelib::iterator_traits<Iter>::size_type bad_allowed
+                    , bool leftmost = true)
+   {
+        typedef typename boost::movelib::iterator_traits<Iter>::size_type size_type;
+
+        // Use a while loop for tail recursion elimination.
+        while (true) {
+            size_type size = size_type(end - begin);
+
+            // Insertion sort is faster for small arrays.
+            if (size < insertion_sort_threshold) {
+                insertion_sort(begin, end, comp);
+                return;
+            }
+
+            // Choose pivot as median of 3 or pseudomedian of 9.
+            size_type s2 = size / 2;
+            if (size > ninther_threshold) {
+                sort3(begin, begin + s2, end - 1, comp);
+                sort3(begin + 1, begin + (s2 - 1), end - 2, comp);
+                sort3(begin + 2, begin + (s2 + 1), end - 3, comp);
+                sort3(begin + (s2 - 1), begin + s2, begin + (s2 + 1), comp);
+                boost::adl_move_iter_swap(begin, begin + s2);
+            } else sort3(begin + s2, begin, end - 1, comp);
+
+            // If *(begin - 1) is the end of the right partition of a previous partition operation
+            // there is no element in [begin, end) that is smaller than *(begin - 1). Then if our
+            // pivot compares equal to *(begin - 1) we change strategy, putting equal elements in
+            // the left partition, greater elements in the right partition. We do not have to
+            // recurse on the left partition, since it's sorted (all equal).
+            if (!leftmost && !comp(*(begin - 1), *begin)) {
+                begin = partition_left(begin, end, comp) + 1;
+                continue;
+            }
+
+            // Partition and get results.
+            pdqsort_detail::pair<Iter, bool> part_result = partition_right(begin, end, comp);
+            Iter pivot_pos = part_result.first;
+            bool already_partitioned = part_result.second;
+
+            // Check for a highly unbalanced partition.
+            size_type l_size = size_type(pivot_pos - begin);
+            size_type r_size = size_type(end - (pivot_pos + 1));
+            bool highly_unbalanced = l_size < size / 8 || r_size < size / 8;
+
+            // If we got a highly unbalanced partition we shuffle elements to break many patterns.
+            if (highly_unbalanced) {
+                // If we had too many bad partitions, switch to heapsort to guarantee O(n log n).
+                if (--bad_allowed == 0) {
+                    boost::movelib::heap_sort(begin, end, comp);
+                    return;
+                }
+
+                if (l_size >= insertion_sort_threshold) {
+                    boost::adl_move_iter_swap(begin,             begin + l_size / 4);
+                    boost::adl_move_iter_swap(pivot_pos - 1, pivot_pos - l_size / 4);
+
+                    if (l_size > ninther_threshold) {
+                        boost::adl_move_iter_swap(begin + 1,         begin + (l_size / 4 + 1));
+                        boost::adl_move_iter_swap(begin + 2,         begin + (l_size / 4 + 2));
+                        boost::adl_move_iter_swap(pivot_pos - 2, pivot_pos - (l_size / 4 + 1));
+                        boost::adl_move_iter_swap(pivot_pos - 3, pivot_pos - (l_size / 4 + 2));
+                    }
+                }
+                
+                if (r_size >= insertion_sort_threshold) {
+                    boost::adl_move_iter_swap(pivot_pos + 1, pivot_pos + (1 + r_size / 4));
+                    boost::adl_move_iter_swap(end - 1,                   end - r_size / 4);
+                    
+                    if (r_size > ninther_threshold) {
+                        boost::adl_move_iter_swap(pivot_pos + 2, pivot_pos + (2 + r_size / 4));
+                        boost::adl_move_iter_swap(pivot_pos + 3, pivot_pos + (3 + r_size / 4));
+                        boost::adl_move_iter_swap(end - 2,             end - (1 + r_size / 4));
+                        boost::adl_move_iter_swap(end - 3,             end - (2 + r_size / 4));
+                    }
+                }
+            } else {
+                // If we were decently balanced and we tried to sort an already partitioned
+                // sequence try to use insertion sort.
+                if (already_partitioned && partial_insertion_sort(begin, pivot_pos, comp)
+                                        && partial_insertion_sort(pivot_pos + 1, end, comp)) return;
+            }
+                
+            // Sort the left partition first using recursion and do tail recursion elimination for
+            // the right-hand partition.
+            pdqsort_loop<Iter, Compare>(begin, pivot_pos, comp, bad_allowed, leftmost);
+            begin = pivot_pos + 1;
+            leftmost = false;
+        }
+    }
+}
+
+
+template<class Iter, class Compare>
+void pdqsort(Iter begin, Iter end, Compare comp)
+{
+   if (begin == end) return;
+   typedef typename boost::movelib::iterator_traits<Iter>::size_type size_type;
+   pdqsort_detail::pdqsort_loop<Iter, Compare>(begin, end, comp, pdqsort_detail::log2(size_type(end - begin)));
+}
+
+}  //namespace movelib {
+}  //namespace boost {
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif   //BOOST_MOVE_ALGO_PDQSORT_HPP
diff --git a/include/boost/move/algo/detail/set_difference.hpp b/include/boost/move/algo/detail/set_difference.hpp
new file mode 100644
index 0000000..51d0475
--- /dev/null
+++ b/include/boost/move/algo/detail/set_difference.hpp
@@ -0,0 +1,207 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2017-2017.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_MOVE_SET_DIFFERENCE_HPP
+#define BOOST_MOVE_SET_DIFFERENCE_HPP
+
+#include <boost/move/algo/move.hpp>
+#include <boost/move/iterator.hpp>
+#include <boost/move/utility_core.hpp>
+
+namespace boost {
+
+namespace move_detail{
+
+template<class InputIt, class OutputIt>
+OutputIt copy(InputIt first, InputIt last, OutputIt result)
+{
+   while (first != last) {
+      *result++ = *first;
+      ++result;
+      ++first;
+   }
+   return result;
+}
+
+}  //namespace move_detail{
+
+namespace movelib {
+
+//Moves the elements from the sorted range [first1, last1) which are not found in the sorted
+//range [first2, last2) to the range beginning at result.
+//The resulting range is also sorted. Equivalent elements are treated individually,
+//that is, if some element is found m times in [first1, last1) and n times in [first2, last2),
+//it will be moved to result exactly max(m-n, 0) times.
+//The resulting range cannot overlap with either of the input ranges.
+template<class InputIt1, class InputIt2,
+         class OutputIt, class Compare>
+OutputIt set_difference
+   (InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt result, Compare comp)
+{
+   while (first1 != last1) {
+      if (first2 == last2)
+         return boost::move_detail::copy(first1, last1, result);
+
+      if (comp(*first1, *first2)) {
+         *result = *first1;
+         ++result;
+         ++first1;
+      }
+      else {
+         if (!comp(*first2, *first1)) {
+            ++first1;
+         }
+         ++first2;
+      }
+   }
+   return result;
+}
+
+//Moves the elements from the sorted range [first1, last1) which are not found in the sorted
+//range [first2, last2) to the range beginning at first1 (in place operation in range1).
+//The resulting range is also sorted. Equivalent elements are treated individually,
+//that is, if some element is found m times in [first1, last1) and n times in [first2, last2),
+//it will be moved to result exactly max(m-n, 0) times.
+template<class InputOutputIt1, class InputIt2, class Compare>
+InputOutputIt1 inplace_set_difference
+   (InputOutputIt1 first1, InputOutputIt1 last1, InputIt2 first2, InputIt2 last2, Compare comp )
+{
+   while (first1 != last1) {
+      //Skip copying from range 1 if no element has to be skipped
+      if (first2 == last2){
+         return last1;
+      }
+      else if (comp(*first1, *first2)){
+         ++first1;
+      }
+      else{
+         if (!comp(*first2, *first1)) {
+            InputOutputIt1 result = first1;
+            //An element from range 1 must be skipped, no longer an inplace operation
+            return boost::movelib::set_difference
+               ( boost::make_move_iterator(++first1)
+               , boost::make_move_iterator(last1)
+               , ++first2, last2, result, comp);
+         }
+         ++first2;
+      }
+   }
+   return first1;
+}
+
+//Moves the elements from the sorted range [first1, last1) which are not found in the sorted
+//range [first2, last2) to the range beginning at first1.
+//The resulting range is also sorted. Equivalent elements from range 1 are moved past to end
+//of the result,
+//that is, if some element is found m times in [first1, last1) and n times in [first2, last2),
+//it will be moved to result exactly max(m-n, 0) times.
+//The resulting range cannot overlap with either of the input ranges.
+template<class ForwardIt1, class InputIt2,
+         class OutputIt, class Compare>
+OutputIt set_unique_difference
+   (ForwardIt1 first1, ForwardIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt result, Compare comp)
+{
+   while (first1 != last1) {
+      if (first2 == last2){
+         //unique_copy-like sequence with forward iterators but don't write i
+         //to result before comparing as moving *i could alter the value in i.
+         ForwardIt1 i = first1;
+         while (++first1 != last1) {
+            if (comp(*i, *first1)) {
+               *result = *i;
+               ++result;
+               i = first1;
+            }
+         }
+         *result = *i;
+         ++result;
+         break;
+      }
+
+      if (comp(*first1, *first2)) {
+         //Skip equivalent elements in range1 but don't write i
+         //to result before comparing as moving *i could alter the value in i.
+         ForwardIt1 i = first1;
+         while (++first1 != last1) {
+            if (comp(*i, *first1)) {
+               break;
+            }
+         }
+         *result = *i;
+         ++result;
+      }
+      else {
+         if (comp(*first2, *first1)) {
+            ++first2;
+         }
+         else{
+            ++first1;
+         }
+      }
+   }
+   return result;
+}
+
+//Moves the elements from the sorted range [first1, last1) which are not found in the sorted
+//range [first2, last2) to the range beginning at first1 (in place operation in range1).
+//The resulting range is also sorted. Equivalent elements are treated individually,
+//that is, if some element is found m times in [first1, last1) and n times in [first2, last2),
+//it will be moved to result exactly max(m-n, 0) times.
+template<class ForwardOutputIt1, class ForwardIt2, class Compare>
+ForwardOutputIt1 inplace_set_unique_difference
+   (ForwardOutputIt1 first1, ForwardOutputIt1 last1, ForwardIt2 first2, ForwardIt2 last2, Compare comp )
+{
+   while (first1 != last1) {
+      //Skip copying from range 1 if no element has to be skipped
+      if (first2 == last2){
+         //unique-like algorithm for the remaining range 1
+         ForwardOutputIt1 result = first1;
+         while (++first1 != last1) {
+            if (comp(*result, *first1) && ++result != first1) {
+               *result = boost::move(*first1);
+            }
+         }
+         return ++result;
+      }
+      else if (comp(*first2, *first1)) {
+         ++first2;
+      }
+      else if (comp(*first1, *first2)){
+         //skip any adjacent equivalent elementin range 1
+         ForwardOutputIt1 result = first1;
+         if (++first1 != last1 && !comp(*result, *first1)) {
+            //Some elements from range 1 must be skipped, no longer an inplace operation
+            while (++first1 != last1 && !comp(*result, *first1)){}
+            return boost::movelib::set_unique_difference
+               ( boost::make_move_iterator(first1)
+               , boost::make_move_iterator(last1)
+               , first2, last2, ++result, comp);
+         }
+      }
+      else{
+         ForwardOutputIt1 result = first1;
+         //Some elements from range 1 must be skipped, no longer an inplace operation
+         while (++first1 != last1 && !comp(*result, *first1)){}
+         //An element from range 1 must be skipped, no longer an inplace operation
+         return boost::movelib::set_unique_difference
+            ( boost::make_move_iterator(first1)
+            , boost::make_move_iterator(last1)
+            , first2, last2, result, comp);
+      }
+   }
+   return first1;
+}
+
+
+
+}  //namespace movelib {
+}  //namespace boost {
+
+#endif   //#define BOOST_MOVE_SET_DIFFERENCE_HPP
diff --git a/include/boost/move/algo/move.hpp b/include/boost/move/algo/move.hpp
new file mode 100644
index 0000000..2390877
--- /dev/null
+++ b/include/boost/move/algo/move.hpp
@@ -0,0 +1,156 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2012-2016.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
+
+#ifndef BOOST_MOVE_ALGO_MOVE_HPP
+#define BOOST_MOVE_ALGO_MOVE_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/config_begin.hpp>
+
+#include <boost/move/utility_core.hpp>
+#include <boost/move/detail/iterator_traits.hpp>
+#include <boost/move/detail/iterator_to_raw_pointer.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
+
+namespace boost {
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                               move
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#if !defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)
+
+   //! <b>Effects</b>: Moves elements in the range [first,last) into the range [result,result + (last -
+   //!   first)) starting from first and proceeding to last. For each non-negative integer n < (last-first),
+   //!   performs *(result + n) = ::boost::move (*(first + n)).
+   //!
+   //! <b>Effects</b>: result + (last - first).
+   //!
+   //! <b>Requires</b>: result shall not be in the range [first,last).
+   //!
+   //! <b>Complexity</b>: Exactly last - first move assignments.
+   template <typename I, // I models InputIterator
+            typename O> // O models OutputIterator
+   O move(I f, I l, O result)
+   {
+      while (f != l) {
+         *result = ::boost::move(*f);
+         ++f; ++result;
+      }
+      return result;
+   }
+
+   //////////////////////////////////////////////////////////////////////////////
+   //
+   //                               move_backward
+   //
+   //////////////////////////////////////////////////////////////////////////////
+
+   //! <b>Effects</b>: Moves elements in the range [first,last) into the range
+   //!   [result - (last-first),result) starting from last - 1 and proceeding to
+   //!   first. For each positive integer n <= (last - first),
+   //!   performs *(result - n) = ::boost::move(*(last - n)).
+   //!
+   //! <b>Requires</b>: result shall not be in the range [first,last).
+   //!
+   //! <b>Returns</b>: result - (last - first).
+   //!
+   //! <b>Complexity</b>: Exactly last - first assignments.
+   template <typename I, // I models BidirectionalIterator
+   typename O> // O models BidirectionalIterator
+   O move_backward(I f, I l, O result)
+   {
+      while (f != l) {
+         --l; --result;
+         *result = ::boost::move(*l);
+      }
+      return result;
+   }
+
+#else
+
+   using ::std::move_backward;
+
+#endif   //!defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                               uninitialized_move
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! <b>Effects</b>:
+//!   \code
+//!   for (; first != last; ++result, ++first)
+//!      new (static_cast<void*>(&*result))
+//!         typename iterator_traits<ForwardIterator>::value_type(boost::move(*first));
+//!   \endcode
+//!
+//! <b>Returns</b>: result
+template
+   <typename I, // I models InputIterator
+    typename F> // F models ForwardIterator
+F uninitialized_move(I f, I l, F r
+   /// @cond
+//   ,typename ::boost::move_detail::enable_if<has_move_emulation_enabled<typename boost::movelib::iterator_traits<I>::value_type> >::type* = 0
+   /// @endcond
+   )
+{
+   typedef typename boost::movelib::iterator_traits<I>::value_type input_value_type;
+
+   F back = r;
+   BOOST_TRY{
+      while (f != l) {
+         void * const addr = static_cast<void*>(::boost::move_detail::addressof(*r));
+         ::new(addr) input_value_type(::boost::move(*f));
+         ++f; ++r;
+      }
+   }
+   BOOST_CATCH(...){
+      for (; back != r; ++back){
+         boost::movelib::iterator_to_raw_pointer(back)->~input_value_type();
+      }
+      BOOST_RETHROW;
+   }
+   BOOST_CATCH_END
+   return r;
+}
+
+/// @cond
+/*
+template
+   <typename I,   // I models InputIterator
+    typename F>   // F models ForwardIterator
+F uninitialized_move(I f, I l, F r,
+   typename ::boost::move_detail::disable_if<has_move_emulation_enabled<typename boost::movelib::iterator_traits<I>::value_type> >::type* = 0)
+{
+   return std::uninitialized_copy(f, l, r);
+}
+*/
+
+/// @endcond
+
+}  //namespace boost {
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_MOVE_ALGO_MOVE_HPP
diff --git a/include/boost/move/algo/predicate.hpp b/include/boost/move/algo/predicate.hpp
new file mode 100644
index 0000000..0287d66
--- /dev/null
+++ b/include/boost/move/algo/predicate.hpp
@@ -0,0 +1,86 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2016.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_MOVE_ALGO_PREDICATE_HPP
+#define BOOST_MOVE_ALGO_PREDICATE_HPP
+
+#include <boost/move/algo/move.hpp>
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/move/algo/detail/basic_op.hpp>
+#include <boost/move/detail/iterator_traits.hpp>
+#include <boost/move/detail/destruct_n.hpp>
+#include <boost/assert.hpp>
+
+namespace boost {
+namespace movelib {
+
+template<class Comp>
+struct antistable
+{
+   explicit antistable(Comp &comp)
+      : m_comp(comp)
+   {}
+
+   template<class U, class V>
+   bool operator()(const U &u, const V & v)
+   {  return !m_comp(v, u);  }
+
+   private:
+   antistable & operator=(const antistable &);
+   Comp &m_comp;
+};
+
+template <class Comp>
+class negate
+{
+   public:
+   negate()
+   {}
+
+   explicit negate(Comp comp)
+      : m_comp(comp)
+   {}
+
+   template <class T1, class T2>
+   bool operator()(const T1& l, const T2& r)
+   {
+      return !m_comp(l, r);
+   }
+
+   private:
+   Comp m_comp;
+};
+
+
+template <class Comp>
+class inverse
+{
+   public:
+   inverse()
+   {}
+
+   explicit inverse(Comp comp)
+      : m_comp(comp)
+   {}
+
+   template <class T1, class T2>
+   bool operator()(const T1& l, const T2& r)
+   {
+      return m_comp(r, l);
+   }
+
+   private:
+   Comp m_comp;
+};
+
+}  //namespace movelib {
+}  //namespace boost {
+
+#endif   //#define BOOST_MOVE_ALGO_PREDICATE_HPP
diff --git a/include/boost/move/algo/unique.hpp b/include/boost/move/algo/unique.hpp
new file mode 100644
index 0000000..8022a65
--- /dev/null
+++ b/include/boost/move/algo/unique.hpp
@@ -0,0 +1,55 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2017-2017.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_MOVE_ALGO_UNIQUE_HPP
+#define BOOST_MOVE_ALGO_UNIQUE_HPP
+
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/utility_core.hpp>
+
+namespace boost {
+namespace movelib {
+
+//! <b>Requires</b>: The comparison function shall be an equivalence relation. The type of *first shall satisfy
+//! the MoveAssignable requirements
+//!
+//! <b>Effects</b>: For a nonempty range, eliminates all but the first element from every consecutive group
+//!   of equivalent elements referred to by the iterator i in the range [first + 1, last) for which the
+//!   following conditions hold: pred(*(i - 1), *i) != false.
+//!
+//! <b>Returns</b>: The end of the resulting range.
+//!
+//! <b>Complexity</b>: For nonempty ranges, exactly (last - first) - 1 applications of the corresponding predicate.
+template<class ForwardIterator, class BinaryPredicate>
+ForwardIterator unique(ForwardIterator first, ForwardIterator last, BinaryPredicate pred)
+{
+    if (first != last) {
+      ForwardIterator next(first);
+      ++next;
+      for (; next != last; ++next, ++first) {
+         if (pred(*first, *next)) { //Find first equal element
+            while (++next != last)
+               if (!pred(*first, *next))
+                  *++first = ::boost::move(*next);
+            break;
+         }
+      }
+      ++first;
+   }
+   return first;
+}
+
+}  //namespace movelib {
+}  //namespace boost {
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif   //#define BOOST_MOVE_ALGO_UNIQUE_HPP
diff --git a/include/boost/move/algorithm.hpp b/include/boost/move/algorithm.hpp
new file mode 100644
index 0000000..825d771
--- /dev/null
+++ b/include/boost/move/algorithm.hpp
@@ -0,0 +1,167 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2012-2012.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
+
+#ifndef BOOST_MOVE_ALGORITHM_HPP
+#define BOOST_MOVE_ALGORITHM_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/config_begin.hpp>
+
+#include <boost/move/utility_core.hpp>
+#include <boost/move/iterator.hpp>
+#include <boost/move/algo/move.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
+
+#include <algorithm> //copy, copy_backward
+#include <memory>    //uninitialized_copy
+
+namespace boost {
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                            uninitialized_copy_or_move
+//
+//////////////////////////////////////////////////////////////////////////////
+
+namespace move_detail {
+
+template
+<typename I,   // I models InputIterator
+typename F>   // F models ForwardIterator
+inline F uninitialized_move_move_iterator(I f, I l, F r
+//                             ,typename ::boost::move_detail::enable_if< has_move_emulation_enabled<typename I::value_type> >::type* = 0
+)
+{
+   return ::boost::uninitialized_move(f, l, r);
+}
+/*
+template
+<typename I,   // I models InputIterator
+typename F>   // F models ForwardIterator
+F uninitialized_move_move_iterator(I f, I l, F r,
+                                   typename ::boost::move_detail::disable_if< has_move_emulation_enabled<typename I::value_type> >::type* = 0)
+{
+   return std::uninitialized_copy(f.base(), l.base(), r);
+}
+*/
+}  //namespace move_detail {
+
+template
+<typename I,   // I models InputIterator
+typename F>   // F models ForwardIterator
+inline F uninitialized_copy_or_move(I f, I l, F r,
+                             typename ::boost::move_detail::enable_if< move_detail::is_move_iterator<I> >::type* = 0)
+{
+   return ::boost::move_detail::uninitialized_move_move_iterator(f, l, r);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                            copy_or_move
+//
+//////////////////////////////////////////////////////////////////////////////
+
+namespace move_detail {
+
+template
+<typename I,   // I models InputIterator
+typename F>   // F models ForwardIterator
+inline F move_move_iterator(I f, I l, F r
+//                             ,typename ::boost::move_detail::enable_if< has_move_emulation_enabled<typename I::value_type> >::type* = 0
+)
+{
+   return ::boost::move(f, l, r);
+}
+/*
+template
+<typename I,   // I models InputIterator
+typename F>   // F models ForwardIterator
+F move_move_iterator(I f, I l, F r,
+                                   typename ::boost::move_detail::disable_if< has_move_emulation_enabled<typename I::value_type> >::type* = 0)
+{
+   return std::copy(f.base(), l.base(), r);
+}
+*/
+
+}  //namespace move_detail {
+
+template
+<typename I,   // I models InputIterator
+typename F>   // F models ForwardIterator
+inline F copy_or_move(I f, I l, F r,
+                             typename ::boost::move_detail::enable_if< move_detail::is_move_iterator<I> >::type* = 0)
+{
+   return ::boost::move_detail::move_move_iterator(f, l, r);
+}
+
+/// @endcond
+
+//! <b>Effects</b>:
+//!   \code
+//!   for (; first != last; ++result, ++first)
+//!      new (static_cast<void*>(&*result))
+//!         typename iterator_traits<ForwardIterator>::value_type(*first);
+//!   \endcode
+//!
+//! <b>Returns</b>: result
+//!
+//! <b>Note</b>: This function is provided because
+//!   <i>std::uninitialized_copy</i> from some STL implementations
+//!    is not compatible with <i>move_iterator</i>
+template
+<typename I,   // I models InputIterator
+typename F>   // F models ForwardIterator
+inline F uninitialized_copy_or_move(I f, I l, F r
+   /// @cond
+   ,typename ::boost::move_detail::disable_if< move_detail::is_move_iterator<I> >::type* = 0
+   /// @endcond
+   )
+{
+   return std::uninitialized_copy(f, l, r);
+}
+
+//! <b>Effects</b>:
+//!   \code
+//!   for (; first != last; ++result, ++first)
+//!      *result = *first;
+//!   \endcode
+//!
+//! <b>Returns</b>: result
+//!
+//! <b>Note</b>: This function is provided because
+//!   <i>std::uninitialized_copy</i> from some STL implementations
+//!    is not compatible with <i>move_iterator</i>
+template
+<typename I,   // I models InputIterator
+typename F>   // F models ForwardIterator
+inline F copy_or_move(I f, I l, F r
+   /// @cond
+   ,typename ::boost::move_detail::disable_if< move_detail::is_move_iterator<I> >::type* = 0
+   /// @endcond
+   )
+{
+   return std::copy(f, l, r);
+}
+
+}  //namespace boost {
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_MOVE_ALGORITHM_HPP
diff --git a/include/boost/move/core.hpp b/include/boost/move/core.hpp
new file mode 100644
index 0000000..c0f5be5
--- /dev/null
+++ b/include/boost/move/core.hpp
@@ -0,0 +1,490 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2012-2012.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
+//! This header implements macros to define movable classes and
+//! move-aware functions
+
+#ifndef BOOST_MOVE_CORE_HPP
+#define BOOST_MOVE_CORE_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/detail/workaround.hpp>
+
+// @cond
+
+//boost_move_no_copy_constructor_or_assign typedef
+//used to detect noncopyable types for other Boost libraries.
+#if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+   #define BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \
+      private:\
+      TYPE(TYPE &);\
+      TYPE& operator=(TYPE &);\
+      public:\
+      typedef int boost_move_no_copy_constructor_or_assign; \
+      private:\
+   //
+#else
+   #define BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \
+      public:\
+      TYPE(TYPE const &) = delete;\
+      TYPE& operator=(TYPE const &) = delete;\
+      public:\
+      typedef int boost_move_no_copy_constructor_or_assign; \
+      private:\
+   //
+#endif   //BOOST_NO_CXX11_DELETED_FUNCTIONS
+
+// @endcond
+
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+   #include <boost/move/detail/type_traits.hpp>
+
+   #define BOOST_MOVE_TO_RV_CAST(RV_TYPE, ARG) reinterpret_cast<RV_TYPE>(ARG)
+
+   //Move emulation rv breaks standard aliasing rules so add workarounds for some compilers
+   #define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS BOOST_MAY_ALIAS
+
+   namespace boost {
+
+   //////////////////////////////////////////////////////////////////////////////
+   //
+   //                            struct rv
+   //
+   //////////////////////////////////////////////////////////////////////////////
+   template <class T>
+   class rv
+      : public ::boost::move_detail::if_c
+         < ::boost::move_detail::is_class<T>::value
+         , T
+         , ::boost::move_detail::nat
+         >::type
+   {
+      rv();
+      ~rv() throw();
+      rv(rv const&);
+      void operator=(rv const&);
+   } BOOST_MOVE_ATTRIBUTE_MAY_ALIAS;
+
+
+   //////////////////////////////////////////////////////////////////////////////
+   //
+   //                            is_rv
+   //
+   //////////////////////////////////////////////////////////////////////////////
+
+   namespace move_detail {
+
+   template <class T>
+   struct is_rv
+        //Derive from integral constant because some Boost code assummes it has
+        //a "type" internal typedef
+      : integral_constant<bool, ::boost::move_detail::is_rv_impl<T>::value >
+   {};
+
+   template <class T>
+   struct is_not_rv
+   {
+      static const bool value = !is_rv<T>::value;
+   };
+
+   }  //namespace move_detail {
+
+   //////////////////////////////////////////////////////////////////////////////
+   //
+   //                               has_move_emulation_enabled
+   //
+   //////////////////////////////////////////////////////////////////////////////
+   template<class T>
+   struct has_move_emulation_enabled
+      : ::boost::move_detail::has_move_emulation_enabled_impl<T>
+   {};
+
+   template<class T>
+   struct has_move_emulation_disabled
+   {
+      static const bool value = !::boost::move_detail::has_move_emulation_enabled_impl<T>::value;
+   };
+
+   }  //namespace boost {
+
+   #define BOOST_RV_REF(TYPE)\
+      ::boost::rv< TYPE >& \
+   //
+
+   #define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
+      ::boost::rv< TYPE<ARG1, ARG2> >& \
+   //
+
+   #define BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
+      ::boost::rv< TYPE<ARG1, ARG2, ARG3> >& \
+   //
+
+   #define BOOST_RV_REF_BEG\
+      ::boost::rv<   \
+   //
+
+   #define BOOST_RV_REF_END\
+      >& \
+   //
+
+   #define BOOST_RV_REF_BEG_IF_CXX11 \
+      \
+   //
+
+   #define BOOST_RV_REF_END_IF_CXX11 \
+      \
+   //
+
+   #define BOOST_FWD_REF(TYPE)\
+      const TYPE & \
+   //
+
+   #define BOOST_COPY_ASSIGN_REF(TYPE)\
+      const ::boost::rv< TYPE >& \
+   //
+
+   #define BOOST_COPY_ASSIGN_REF_BEG \
+      const ::boost::rv<  \
+   //
+
+   #define BOOST_COPY_ASSIGN_REF_END \
+      >& \
+   //
+
+   #define BOOST_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
+      const ::boost::rv< TYPE<ARG1, ARG2> >& \
+   //
+
+   #define BOOST_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
+      const ::boost::rv< TYPE<ARG1, ARG2, ARG3> >& \
+   //
+
+   #define BOOST_CATCH_CONST_RLVALUE(TYPE)\
+      const ::boost::rv< TYPE >& \
+   //
+
+   namespace boost {
+   namespace move_detail {
+
+   template <class Ret, class T>
+   BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c
+      <  ::boost::move_detail::is_lvalue_reference<Ret>::value ||
+        !::boost::has_move_emulation_enabled<T>::value
+      , T&>::type
+         move_return(T& x) BOOST_NOEXCEPT
+   {
+      return x;
+   }
+
+   template <class Ret, class T>
+   BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c
+      < !::boost::move_detail::is_lvalue_reference<Ret>::value &&
+         ::boost::has_move_emulation_enabled<T>::value
+      , ::boost::rv<T>&>::type
+         move_return(T& x) BOOST_NOEXCEPT
+   {
+      return *BOOST_MOVE_TO_RV_CAST(::boost::rv<T>*, ::boost::move_detail::addressof(x));
+   }
+
+   template <class Ret, class T>
+   BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c
+      < !::boost::move_detail::is_lvalue_reference<Ret>::value &&
+         ::boost::has_move_emulation_enabled<T>::value
+      , ::boost::rv<T>&>::type
+         move_return(::boost::rv<T>& x) BOOST_NOEXCEPT
+   {
+      return x;
+   }
+
+   }  //namespace move_detail {
+   }  //namespace boost {
+
+   #define BOOST_MOVE_RET(RET_TYPE, REF)\
+      boost::move_detail::move_return< RET_TYPE >(REF)
+   //
+
+   #define BOOST_MOVE_BASE(BASE_TYPE, ARG) \
+      ::boost::move((BASE_TYPE&)(ARG))
+   //
+
+   //////////////////////////////////////////////////////////////////////////////
+   //
+   //                         BOOST_MOVABLE_BUT_NOT_COPYABLE
+   //
+   //////////////////////////////////////////////////////////////////////////////
+   #define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\
+      BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE)\
+      public:\
+      BOOST_MOVE_FORCEINLINE operator ::boost::rv<TYPE>&() \
+      {  return *BOOST_MOVE_TO_RV_CAST(::boost::rv<TYPE>*, this);  }\
+      BOOST_MOVE_FORCEINLINE operator const ::boost::rv<TYPE>&() const \
+      {  return *BOOST_MOVE_TO_RV_CAST(const ::boost::rv<TYPE>*, this);  }\
+      private:\
+   //
+
+   //////////////////////////////////////////////////////////////////////////////
+   //
+   //                         BOOST_COPYABLE_AND_MOVABLE
+   //
+   //////////////////////////////////////////////////////////////////////////////
+
+   #define BOOST_COPYABLE_AND_MOVABLE(TYPE)\
+      public:\
+      BOOST_MOVE_FORCEINLINE TYPE& operator=(TYPE &t)\
+      {  this->operator=(const_cast<const TYPE&>(t)); return *this;}\
+      public:\
+      BOOST_MOVE_FORCEINLINE operator ::boost::rv<TYPE>&() \
+      {  return *BOOST_MOVE_TO_RV_CAST(::boost::rv<TYPE>*, this);  }\
+      BOOST_MOVE_FORCEINLINE operator const ::boost::rv<TYPE>&() const \
+      {  return *BOOST_MOVE_TO_RV_CAST(const ::boost::rv<TYPE>*, this);  }\
+      private:\
+   //
+
+   #define BOOST_COPYABLE_AND_MOVABLE_ALT(TYPE)\
+      public:\
+      BOOST_MOVE_FORCEINLINE operator ::boost::rv<TYPE>&() \
+      {  return *BOOST_MOVE_TO_RV_CAST(::boost::rv<TYPE>*, this);  }\
+      BOOST_MOVE_FORCEINLINE operator const ::boost::rv<TYPE>&() const \
+      {  return *BOOST_MOVE_TO_RV_CAST(const ::boost::rv<TYPE>*, this);  }\
+      private:\
+   //
+
+   namespace boost{
+   namespace move_detail{
+
+   template< class T>
+   struct forward_type
+   { typedef const T &type; };
+
+   template< class T>
+   struct forward_type< boost::rv<T> >
+   { typedef T type; };
+
+   }}
+
+#else    //BOOST_NO_CXX11_RVALUE_REFERENCES
+
+   //! This macro marks a type as movable but not copyable, disabling copy construction
+   //! and assignment. The user will need to write a move constructor/assignment as explained
+   //! in the documentation to fully write a movable but not copyable class.
+   #define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\
+      BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE)\
+      public:\
+      typedef int boost_move_emulation_t;\
+      private:\
+   //
+
+   //! This macro marks a type as copyable and movable.
+   //! The user will need to write a move constructor/assignment and a copy assignment
+   //! as explained in the documentation to fully write a copyable and movable class.
+   #define BOOST_COPYABLE_AND_MOVABLE(TYPE)\
+   //
+
+   #if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+   #define BOOST_COPYABLE_AND_MOVABLE_ALT(TYPE)\
+   //
+   #endif   //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+   namespace boost {
+
+   //!This trait yields to a compile-time true boolean if T was marked as
+   //!BOOST_MOVABLE_BUT_NOT_COPYABLE or BOOST_COPYABLE_AND_MOVABLE and
+   //!rvalue references are not available on the platform. False otherwise.
+   template<class T>
+   struct has_move_emulation_enabled
+   {
+      static const bool value = false;
+   };
+
+   template<class T>
+   struct has_move_emulation_disabled
+   {
+      static const bool value = true;
+   };
+
+   }  //namespace boost{
+
+   //!This macro is used to achieve portable syntax in move
+   //!constructors and assignments for classes marked as
+   //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE
+   #define BOOST_RV_REF(TYPE)\
+      TYPE && \
+   //
+
+   //!This macro is used to achieve portable syntax in move
+   //!constructors and assignments for template classes marked as
+   //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE.
+   //!As macros have problems with comma-separated template arguments,
+   //!the template argument must be preceded with BOOST_RV_REF_BEG
+   //!and ended with BOOST_RV_REF_END
+   #define BOOST_RV_REF_BEG\
+         \
+   //
+
+   //!This macro is used to achieve portable syntax in move
+   //!constructors and assignments for template classes marked as
+   //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE.
+   //!As macros have problems with comma-separated template arguments,
+   //!the template argument must be preceded with BOOST_RV_REF_BEG
+   //!and ended with BOOST_RV_REF_END
+   #define BOOST_RV_REF_END\
+      && \
+   //
+
+   //!This macro expands to BOOST_RV_REF_BEG if BOOST_NO_CXX11_RVALUE_REFERENCES
+   //!is not defined, empty otherwise
+   #define BOOST_RV_REF_BEG_IF_CXX11 \
+      BOOST_RV_REF_BEG \
+   //
+
+   //!This macro expands to BOOST_RV_REF_END if BOOST_NO_CXX11_RVALUE_REFERENCES
+   //!is not defined, empty otherwise
+   #define BOOST_RV_REF_END_IF_CXX11 \
+      BOOST_RV_REF_END \
+   //
+
+   //!This macro is used to achieve portable syntax in copy
+   //!assignment for classes marked as BOOST_COPYABLE_AND_MOVABLE.
+   #define BOOST_COPY_ASSIGN_REF(TYPE)\
+      const TYPE & \
+   //
+
+   //! This macro is used to implement portable perfect forwarding
+   //! as explained in the documentation.
+   #define BOOST_FWD_REF(TYPE)\
+      TYPE && \
+   //
+
+   #if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+   #define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
+      TYPE<ARG1, ARG2> && \
+   //
+
+   #define BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
+      TYPE<ARG1, ARG2, ARG3> && \
+   //
+
+   #define BOOST_COPY_ASSIGN_REF_BEG \
+      const \
+   //
+
+   #define BOOST_COPY_ASSIGN_REF_END \
+      & \
+   //
+
+   #define BOOST_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
+      const TYPE<ARG1, ARG2> & \
+   //
+
+   #define BOOST_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
+      const TYPE<ARG1, ARG2, ARG3>& \
+   //
+
+   #define BOOST_CATCH_CONST_RLVALUE(TYPE)\
+      const TYPE & \
+   //
+
+   #endif   //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+   #if !defined(BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+      //!This macro is used to achieve portable move return semantics.
+      //!The C++11 Standard allows implicit move returns when the object to be returned
+      //!is designated by a lvalue and:
+      //!   - The criteria for elision of a copy operation are met OR
+      //!   - The criteria would be met save for the fact that the source object is a function parameter
+      //!
+      //!For C++11 conforming compilers this macros only yields to REF:
+      //! <code>return BOOST_MOVE_RET(RET_TYPE, REF);</code> -> <code>return REF;</code>
+      //!
+      //!For compilers without rvalue references
+      //!this macro does an explicit move if the move emulation is activated
+      //!and the return type (RET_TYPE) is not a reference.
+      //!
+      //!For non-conforming compilers with rvalue references like Visual 2010 & 2012,
+      //!an explicit move is performed if RET_TYPE is not a reference.
+      //!
+      //! <b>Caution</b>: When using this macro in non-conforming or C++03
+      //!compilers, a move will be performed even if the C++11 standard does not allow it
+      //!(e.g. returning a static variable). The user is responsible for using this macro
+      //!only to return local objects that met C++11 criteria.
+      #define BOOST_MOVE_RET(RET_TYPE, REF)\
+         REF
+      //
+
+   #else //!defined(BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+      #include <boost/move/detail/meta_utils.hpp>
+
+      namespace boost {
+      namespace move_detail {
+
+      template <class Ret, class T>
+      BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c
+         <  ::boost::move_detail::is_lvalue_reference<Ret>::value
+         , T&>::type
+            move_return(T& x) BOOST_NOEXCEPT
+      {
+         return x;
+      }
+
+      template <class Ret, class T>
+      BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c
+         < !::boost::move_detail::is_lvalue_reference<Ret>::value
+         , Ret && >::type
+            move_return(T&& t) BOOST_NOEXCEPT
+      {
+         return static_cast< Ret&& >(t);
+      }
+
+      }  //namespace move_detail {
+      }  //namespace boost {
+
+      #define BOOST_MOVE_RET(RET_TYPE, REF)\
+         boost::move_detail::move_return< RET_TYPE >(REF)
+      //
+
+   #endif   //!defined(BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+   //!This macro is used to achieve portable optimal move constructors.
+   //!
+   //!When implementing the move constructor, in C++03 compilers the moved-from argument must be
+   //!cast to the base type before calling `::boost::move()` due to rvalue reference limitations.
+   //!
+   //!In C++11 compilers the cast from a rvalue reference of a derived type to a rvalue reference of
+   //!a base type is implicit.
+   #define BOOST_MOVE_BASE(BASE_TYPE, ARG) \
+      ::boost::move((BASE_TYPE&)(ARG))
+   //
+
+   namespace boost {
+   namespace move_detail {
+
+   template< class T> struct forward_type { typedef T type; };
+
+   }}
+
+#endif   //BOOST_NO_CXX11_RVALUE_REFERENCES
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_MOVE_CORE_HPP
diff --git a/include/boost/move/default_delete.hpp b/include/boost/move/default_delete.hpp
new file mode 100644
index 0000000..31ae67a
--- /dev/null
+++ b/include/boost/move/default_delete.hpp
@@ -0,0 +1,217 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2014. 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_MOVE_DEFAULT_DELETE_HPP_INCLUDED
+#define BOOST_MOVE_DEFAULT_DELETE_HPP_INCLUDED
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/detail/workaround.hpp>
+#include <boost/move/detail/unique_ptr_meta_utils.hpp>
+#include <boost/move/utility_core.hpp>
+#include <boost/static_assert.hpp>
+
+#include <cstddef>   //For std::size_t,std::nullptr_t
+
+//!\file
+//! Describes the default deleter (destruction policy) of <tt>unique_ptr</tt>: <tt>default_delete</tt>.
+
+namespace boost{
+// @cond
+namespace move_upd {
+
+namespace bmupmu = ::boost::move_upmu;
+
+////////////////////////////////////////
+////        enable_def_del
+////////////////////////////////////////
+
+//compatible with a pointer type T*:
+//When either Y* is convertible to T*
+//Y is U[N] and T is U cv []
+template<class U, class T>
+struct def_del_compatible_cond
+   : bmupmu::is_convertible<U*, T*>
+{};
+
+template<class U, class T, std::size_t N>
+struct def_del_compatible_cond<U[N], T[]>
+   : def_del_compatible_cond<U[], T[]>
+{};
+
+template<class U, class T, class Type = bmupmu::nat>
+struct enable_def_del
+   : bmupmu::enable_if_c<def_del_compatible_cond<U, T>::value, Type>
+{};
+
+////////////////////////////////////////
+////        enable_defdel_call
+////////////////////////////////////////
+
+//When 2nd is T[N], 1st(*)[N] shall be convertible to T(*)[N]; 
+//When 2nd is T[],  1st(*)[] shall be convertible to T(*)[]; 
+//Otherwise, 1st* shall be convertible to 2nd*.
+
+template<class U, class T, class Type = bmupmu::nat>
+struct enable_defdel_call
+   : public enable_def_del<U, T, Type>
+{};
+
+template<class U, class T, class Type>
+struct enable_defdel_call<U, T[], Type>
+   : public enable_def_del<U[], T[], Type>
+{};
+
+template<class U, class T, class Type, std::size_t N>
+struct enable_defdel_call<U, T[N], Type>
+   : public enable_def_del<U[N], T[N], Type>
+{};
+
+////////////////////////////////////////
+////     Some bool literal zero conversion utilities
+////////////////////////////////////////
+
+struct bool_conversion {int for_bool; int for_arg(); };
+typedef int bool_conversion::* explicit_bool_arg;
+
+#if !defined(BOOST_NO_CXX11_NULLPTR) && !defined(BOOST_NO_CXX11_DECLTYPE)
+   typedef decltype(nullptr) nullptr_type;
+#elif !defined(BOOST_NO_CXX11_NULLPTR)
+   typedef std::nullptr_t nullptr_type;
+#else
+   typedef int (bool_conversion::*nullptr_type)();
+#endif
+
+template<bool B>
+struct is_array_del
+{};
+
+template<class T>
+void call_delete(T *p, is_array_del<true>)
+{
+   delete [] p;
+}
+
+template<class T>
+void call_delete(T *p, is_array_del<false>)
+{
+   delete p;
+}
+
+}  //namespace move_upd {
+// @endcond
+
+namespace movelib {
+
+namespace bmupd = boost::move_upd;
+namespace bmupmu = ::boost::move_upmu;
+
+//!The class template <tt>default_delete</tt> serves as the default deleter
+//!(destruction policy) for the class template <tt>unique_ptr</tt>.
+//!
+//! \tparam T The type to be deleted. It may be an incomplete type
+template <class T>
+struct default_delete
+{
+   //! Default constructor.
+   //!
+   BOOST_CONSTEXPR default_delete()
+   //Avoid "defaulted on its first declaration must not have an exception-specification" error for GCC 4.6
+   #if !defined(BOOST_GCC) || (BOOST_GCC < 40600 && BOOST_GCC >= 40700) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
+   BOOST_NOEXCEPT
+   #endif
+   #if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
+   = default;
+   #else
+   {};
+   #endif
+
+   #if defined(BOOST_MOVE_DOXYGEN_INVOKED)
+   //! Trivial copy constructor
+   //!
+   default_delete(const default_delete&) BOOST_NOEXCEPT = default;
+   //! Trivial assignment
+   //!
+   default_delete &operator=(const default_delete&) BOOST_NOEXCEPT = default;
+   #else
+   typedef typename bmupmu::remove_extent<T>::type element_type;
+   #endif
+
+   //! <b>Effects</b>: Constructs a default_delete object from another <tt>default_delete<U></tt> object.
+   //!
+   //! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
+   //!   - If T is not an array type and U* is implicitly convertible to T*.
+   //!   - If T is an array type and U* is a more CV qualified pointer to remove_extent<T>::type.
+   template <class U>
+   default_delete(const default_delete<U>&
+      BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_def_del<U BOOST_MOVE_I T>::type* =0)
+      ) BOOST_NOEXCEPT
+   {
+      //If T is not an array type, U derives from T
+      //and T has no virtual destructor, then you have a problem
+      BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor<default_delete, U>::value ));
+   }
+
+   //! <b>Effects</b>: Constructs a default_delete object from another <tt>default_delete<U></tt> object.
+   //!
+   //! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
+   //!   - If T is not an array type and U* is implicitly convertible to T*.
+   //!   - If T is an array type and U* is a more CV qualified pointer to remove_extent<T>::type.
+   template <class U>
+   BOOST_MOVE_DOC1ST(default_delete&, 
+      typename bmupd::enable_def_del<U BOOST_MOVE_I T BOOST_MOVE_I default_delete &>::type)
+      operator=(const default_delete<U>&) BOOST_NOEXCEPT
+   {
+      //If T is not an array type, U derives from T
+      //and T has no virtual destructor, then you have a problem
+      BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor<default_delete, U>::value ));
+      return *this;
+   }
+
+   //! <b>Effects</b>: if T is not an array type, calls <tt>delete</tt> on static_cast<T*>(ptr),
+   //!   otherwise calls <tt>delete[]</tt> on static_cast<remove_extent<T>::type*>(ptr).
+   //!
+   //! <b>Remarks</b>: If U is an incomplete type, the program is ill-formed.
+   //!   This operator shall not participate in overload resolution unless:
+   //!      - T is not an array type and U* is convertible to T*, OR
+   //!      - T is an array type, and remove_cv<U>::type is the same type as
+   //!         remove_cv<remove_extent<T>::type>::type and U* is convertible to remove_extent<T>::type*.
+   template <class U>
+   BOOST_MOVE_DOC1ST(void, typename bmupd::enable_defdel_call<U BOOST_MOVE_I T BOOST_MOVE_I void>::type)
+      operator()(U* ptr) const BOOST_NOEXCEPT
+   {
+      //U must be a complete type
+      BOOST_STATIC_ASSERT(sizeof(U) > 0);
+      //If T is not an array type, U derives from T
+      //and T has no virtual destructor, then you have a problem
+      BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor<default_delete, U>::value ));
+      element_type * const p = static_cast<element_type*>(ptr);
+      move_upd::call_delete(p, move_upd::is_array_del<bmupmu::is_array<T>::value>());
+   }
+
+   //! <b>Effects</b>: Same as <tt>(*this)(static_cast<element_type*>(nullptr))</tt>.
+   //!
+   void operator()(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) const BOOST_NOEXCEPT
+   {  BOOST_STATIC_ASSERT(sizeof(element_type) > 0);  }
+};
+
+}  //namespace movelib {
+}  //namespace boost{
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif   //#ifndef BOOST_MOVE_DEFAULT_DELETE_HPP_INCLUDED
diff --git a/include/boost/move/detail/config_begin.hpp b/include/boost/move/detail/config_begin.hpp
new file mode 100644
index 0000000..637eb15
--- /dev/null
+++ b/include/boost/move/detail/config_begin.hpp
@@ -0,0 +1,21 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2012-2012. 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_CONFIG_HPP
+#include <boost/config.hpp>
+#endif
+
+#ifdef BOOST_MSVC
+#  pragma warning (push)
+#  pragma warning (disable : 4324) // structure was padded due to __declspec(align())
+#  pragma warning (disable : 4675) // "function":  resolved overload was found by argument-dependent lookup
+#  pragma warning (disable : 4996) // "function": was declared deprecated (_CRT_SECURE_NO_DEPRECATE/_SCL_SECURE_NO_WARNINGS)
+#  pragma warning (disable : 4714) // "function": marked as __forceinline not inlined
+#  pragma warning (disable : 4127) // conditional expression is constant
+#endif
diff --git a/include/boost/move/detail/config_end.hpp b/include/boost/move/detail/config_end.hpp
new file mode 100644
index 0000000..71a99e9
--- /dev/null
+++ b/include/boost/move/detail/config_end.hpp
@@ -0,0 +1,12 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2012-2012. 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#if defined BOOST_MSVC
+#  pragma warning (pop)
+#endif
diff --git a/include/boost/move/detail/destruct_n.hpp b/include/boost/move/detail/destruct_n.hpp
new file mode 100644
index 0000000..9f60fc2
--- /dev/null
+++ b/include/boost/move/detail/destruct_n.hpp
@@ -0,0 +1,66 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2016.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
+
+#ifndef BOOST_MOVE_DETAIL_DESTRUCT_N_HPP
+#define BOOST_MOVE_DETAIL_DESTRUCT_N_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <cstddef>
+
+namespace boost {
+namespace movelib{
+
+template<class T, class RandItUninit>
+class destruct_n
+{
+   public:
+   explicit destruct_n(RandItUninit raw)
+      : m_ptr(raw), m_size()
+   {}
+
+   void incr()
+   {
+      ++m_size;
+   }
+
+   void incr(std::size_t n)
+   {
+      m_size += n;
+   }
+
+   void release()
+   {
+      m_size = 0u;
+   }
+
+   ~destruct_n()
+   {
+      while(m_size--){
+         m_ptr[m_size].~T();
+      }
+   }
+   private:
+   RandItUninit m_ptr;
+   std::size_t m_size;
+};
+
+}} //namespace boost {  namespace movelib{
+
+#endif //#ifndef BOOST_MOVE_DETAIL_DESTRUCT_N_HPP
diff --git a/include/boost/move/detail/fwd_macros.hpp b/include/boost/move/detail/fwd_macros.hpp
new file mode 100644
index 0000000..a5df5f1
--- /dev/null
+++ b/include/boost/move/detail/fwd_macros.hpp
@@ -0,0 +1,881 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2014. 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)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_MOVE_DETAIL_FWD_MACROS_HPP
+#define BOOST_MOVE_DETAIL_FWD_MACROS_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/workaround.hpp>
+
+namespace boost {
+namespace move_detail {
+
+template <typename T> struct unvoid { typedef T type; };
+template <> struct unvoid<void> { struct type { }; };
+template <> struct unvoid<const void> { struct type { }; };
+
+}  //namespace move_detail {
+}  //namespace boost {
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+#if defined(BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG)
+
+namespace boost {
+namespace move_detail {
+
+   template<class T>
+   struct mref;
+
+   template<class T>
+   struct mref<T &>
+   {
+      explicit mref(T &t) : t_(t){}
+      T &t_;
+      T & get() {  return t_;   }
+   };
+
+   template<class T>
+   struct mref
+   {
+      explicit mref(T &&t) : t_(t) {}
+      T &t_;
+      T &&get() {  return ::boost::move(t_);   }
+   };
+
+}  //namespace move_detail {
+}  //namespace boost {
+
+#endif   //BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG
+#endif   //!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+//BOOST_MOVE_REPEATN(MACRO)
+#define BOOST_MOVE_REPEAT(x, MACRO)   BOOST_MOVE_REPEAT_I(x,MACRO)
+#define BOOST_MOVE_REPEAT_I(x, MACRO) BOOST_MOVE_REPEAT##x(MACRO)
+#define BOOST_MOVE_REPEAT0(MACRO)
+#define BOOST_MOVE_REPEAT1(MACRO)                              MACRO
+#define BOOST_MOVE_REPEAT2(MACRO)  BOOST_MOVE_REPEAT1(MACRO),  MACRO
+#define BOOST_MOVE_REPEAT3(MACRO)  BOOST_MOVE_REPEAT2(MACRO),  MACRO
+#define BOOST_MOVE_REPEAT4(MACRO)  BOOST_MOVE_REPEAT3(MACRO),  MACRO
+#define BOOST_MOVE_REPEAT5(MACRO)  BOOST_MOVE_REPEAT4(MACRO),  MACRO
+#define BOOST_MOVE_REPEAT6(MACRO)  BOOST_MOVE_REPEAT5(MACRO),  MACRO
+#define BOOST_MOVE_REPEAT7(MACRO)  BOOST_MOVE_REPEAT6(MACRO),  MACRO
+#define BOOST_MOVE_REPEAT8(MACRO)  BOOST_MOVE_REPEAT7(MACRO),  MACRO
+#define BOOST_MOVE_REPEAT9(MACRO)  BOOST_MOVE_REPEAT8(MACRO),  MACRO
+#define BOOST_MOVE_REPEAT10(MACRO) BOOST_MOVE_REPEAT9(MACRO),  MACRO
+#define BOOST_MOVE_REPEAT11(MACRO) BOOST_MOVE_REPEAT10(MACRO), MACRO
+#define BOOST_MOVE_REPEAT12(MACRO) BOOST_MOVE_REPEAT11(MACRO), MACRO
+#define BOOST_MOVE_REPEAT13(MACRO) BOOST_MOVE_REPEAT12(MACRO), MACRO
+
+//BOOST_MOVE_FWDN
+#define BOOST_MOVE_FWD0
+#define BOOST_MOVE_FWD1                  ::boost::forward<P0>(p0)
+#define BOOST_MOVE_FWD2 BOOST_MOVE_FWD1, ::boost::forward<P1>(p1)
+#define BOOST_MOVE_FWD3 BOOST_MOVE_FWD2, ::boost::forward<P2>(p2)
+#define BOOST_MOVE_FWD4 BOOST_MOVE_FWD3, ::boost::forward<P3>(p3)
+#define BOOST_MOVE_FWD5 BOOST_MOVE_FWD4, ::boost::forward<P4>(p4)
+#define BOOST_MOVE_FWD6 BOOST_MOVE_FWD5, ::boost::forward<P5>(p5)
+#define BOOST_MOVE_FWD7 BOOST_MOVE_FWD6, ::boost::forward<P6>(p6)
+#define BOOST_MOVE_FWD8 BOOST_MOVE_FWD7, ::boost::forward<P7>(p7)
+#define BOOST_MOVE_FWD9 BOOST_MOVE_FWD8, ::boost::forward<P8>(p8)
+
+//BOOST_MOVE_FWDQN
+#define BOOST_MOVE_FWDQ0
+#define BOOST_MOVE_FWDQ1                   ::boost::forward<Q0>(q0)
+#define BOOST_MOVE_FWDQ2 BOOST_MOVE_FWDQ1, ::boost::forward<Q1>(q1)
+#define BOOST_MOVE_FWDQ3 BOOST_MOVE_FWDQ2, ::boost::forward<Q2>(q2)
+#define BOOST_MOVE_FWDQ4 BOOST_MOVE_FWDQ3, ::boost::forward<Q3>(q3)
+#define BOOST_MOVE_FWDQ5 BOOST_MOVE_FWDQ4, ::boost::forward<Q4>(q4)
+#define BOOST_MOVE_FWDQ6 BOOST_MOVE_FWDQ5, ::boost::forward<Q5>(q5)
+#define BOOST_MOVE_FWDQ7 BOOST_MOVE_FWDQ6, ::boost::forward<Q6>(q6)
+#define BOOST_MOVE_FWDQ8 BOOST_MOVE_FWDQ7, ::boost::forward<Q7>(q7)
+#define BOOST_MOVE_FWDQ9 BOOST_MOVE_FWDQ8, ::boost::forward<Q8>(q8)
+
+//BOOST_MOVE_TMPL_GETN
+#define BOOST_MOVE_TMPL_GET0
+#define BOOST_MOVE_TMPL_GET1                       p.template get<0>()
+#define BOOST_MOVE_TMPL_GET2 BOOST_MOVE_TMPL_GET1, p.template get<1>()
+#define BOOST_MOVE_TMPL_GET3 BOOST_MOVE_TMPL_GET2, p.template get<2>()
+#define BOOST_MOVE_TMPL_GET4 BOOST_MOVE_TMPL_GET3, p.template get<3>()
+#define BOOST_MOVE_TMPL_GET5 BOOST_MOVE_TMPL_GET4, p.template get<4>()
+#define BOOST_MOVE_TMPL_GET6 BOOST_MOVE_TMPL_GET5, p.template get<5>()
+#define BOOST_MOVE_TMPL_GET7 BOOST_MOVE_TMPL_GET6, p.template get<6>()
+#define BOOST_MOVE_TMPL_GET8 BOOST_MOVE_TMPL_GET7, p.template get<7>()
+#define BOOST_MOVE_TMPL_GET9 BOOST_MOVE_TMPL_GET8, p.template get<8>()
+
+//BOOST_MOVE_TMPL_GETQN
+#define BOOST_MOVE_TMPL_GETQ0
+#define BOOST_MOVE_TMPL_GETQ1                        q.template get<0>()
+#define BOOST_MOVE_TMPL_GETQ2 BOOST_MOVE_TMPL_GETQ1, q.template get<1>()
+#define BOOST_MOVE_TMPL_GETQ3 BOOST_MOVE_TMPL_GETQ2, q.template get<2>()
+#define BOOST_MOVE_TMPL_GETQ4 BOOST_MOVE_TMPL_GETQ3, q.template get<3>()
+#define BOOST_MOVE_TMPL_GETQ5 BOOST_MOVE_TMPL_GETQ4, q.template get<4>()
+#define BOOST_MOVE_TMPL_GETQ6 BOOST_MOVE_TMPL_GETQ5, q.template get<5>()
+#define BOOST_MOVE_TMPL_GETQ7 BOOST_MOVE_TMPL_GETQ6, q.template get<6>()
+#define BOOST_MOVE_TMPL_GETQ8 BOOST_MOVE_TMPL_GETQ7, q.template get<7>()
+#define BOOST_MOVE_TMPL_GETQ9 BOOST_MOVE_TMPL_GETQ8, q.template get<8>()
+
+//BOOST_MOVE_GET_IDXN
+#define BOOST_MOVE_GET_IDX0
+#define BOOST_MOVE_GET_IDX1                      get<0>(p)
+#define BOOST_MOVE_GET_IDX2 BOOST_MOVE_GET_IDX1, get<1>(p)
+#define BOOST_MOVE_GET_IDX3 BOOST_MOVE_GET_IDX2, get<2>(p)
+#define BOOST_MOVE_GET_IDX4 BOOST_MOVE_GET_IDX3, get<3>(p)
+#define BOOST_MOVE_GET_IDX5 BOOST_MOVE_GET_IDX4, get<4>(p)
+#define BOOST_MOVE_GET_IDX6 BOOST_MOVE_GET_IDX5, get<5>(p)
+#define BOOST_MOVE_GET_IDX7 BOOST_MOVE_GET_IDX6, get<6>(p)
+#define BOOST_MOVE_GET_IDX8 BOOST_MOVE_GET_IDX7, get<7>(p)
+#define BOOST_MOVE_GET_IDX9 BOOST_MOVE_GET_IDX8, get<8>(p)
+
+//BOOST_MOVE_GET_IDXQN
+#define BOOST_MOVE_GET_IDXQ0
+#define BOOST_MOVE_GET_IDXQ1                       get<0>(q)
+#define BOOST_MOVE_GET_IDXQ2 BOOST_MOVE_GET_IDXQ1, get<1>(q)
+#define BOOST_MOVE_GET_IDXQ3 BOOST_MOVE_GET_IDXQ2, get<2>(q)
+#define BOOST_MOVE_GET_IDXQ4 BOOST_MOVE_GET_IDXQ3, get<3>(q)
+#define BOOST_MOVE_GET_IDXQ5 BOOST_MOVE_GET_IDXQ4, get<4>(q)
+#define BOOST_MOVE_GET_IDXQ6 BOOST_MOVE_GET_IDXQ5, get<5>(q)
+#define BOOST_MOVE_GET_IDXQ7 BOOST_MOVE_GET_IDXQ6, get<6>(q)
+#define BOOST_MOVE_GET_IDXQ8 BOOST_MOVE_GET_IDXQ7, get<7>(q)
+#define BOOST_MOVE_GET_IDXQ9 BOOST_MOVE_GET_IDXQ8, get<8>(q)
+
+//BOOST_MOVE_ARGN
+#define BOOST_MOVE_ARG0
+#define BOOST_MOVE_ARG1                  p0
+#define BOOST_MOVE_ARG2 BOOST_MOVE_ARG1, p1
+#define BOOST_MOVE_ARG3 BOOST_MOVE_ARG2, p2
+#define BOOST_MOVE_ARG4 BOOST_MOVE_ARG3, p3
+#define BOOST_MOVE_ARG5 BOOST_MOVE_ARG4, p4
+#define BOOST_MOVE_ARG6 BOOST_MOVE_ARG5, p5
+#define BOOST_MOVE_ARG7 BOOST_MOVE_ARG6, p6
+#define BOOST_MOVE_ARG8 BOOST_MOVE_ARG7, p7
+#define BOOST_MOVE_ARG9 BOOST_MOVE_ARG8, p8
+
+//BOOST_MOVE_ARGQN
+#define BOOST_MOVE_ARGQ0
+#define BOOST_MOVE_ARGQ1                   q0
+#define BOOST_MOVE_ARGQ2 BOOST_MOVE_ARGQ1, q1
+#define BOOST_MOVE_ARGQ3 BOOST_MOVE_ARGQ2, q2
+#define BOOST_MOVE_ARGQ4 BOOST_MOVE_ARGQ3, q3
+#define BOOST_MOVE_ARGQ5 BOOST_MOVE_ARGQ4, q4
+#define BOOST_MOVE_ARGQ6 BOOST_MOVE_ARGQ5, q5
+#define BOOST_MOVE_ARGQ7 BOOST_MOVE_ARGQ6, q6
+#define BOOST_MOVE_ARGQ8 BOOST_MOVE_ARGQ7, q7
+#define BOOST_MOVE_ARGQ9 BOOST_MOVE_ARGQ8, q8
+
+//BOOST_MOVE_DECLVALN
+#define BOOST_MOVE_DECLVAL0
+#define BOOST_MOVE_DECLVAL1                      ::boost::move_detail::declval<P0>()
+#define BOOST_MOVE_DECLVAL2 BOOST_MOVE_DECLVAL1, ::boost::move_detail::declval<P1>()
+#define BOOST_MOVE_DECLVAL3 BOOST_MOVE_DECLVAL2, ::boost::move_detail::declval<P2>()
+#define BOOST_MOVE_DECLVAL4 BOOST_MOVE_DECLVAL3, ::boost::move_detail::declval<P3>()
+#define BOOST_MOVE_DECLVAL5 BOOST_MOVE_DECLVAL4, ::boost::move_detail::declval<P4>()
+#define BOOST_MOVE_DECLVAL6 BOOST_MOVE_DECLVAL5, ::boost::move_detail::declval<P5>()
+#define BOOST_MOVE_DECLVAL7 BOOST_MOVE_DECLVAL6, ::boost::move_detail::declval<P6>()
+#define BOOST_MOVE_DECLVAL8 BOOST_MOVE_DECLVAL7, ::boost::move_detail::declval<P7>()
+#define BOOST_MOVE_DECLVAL9 BOOST_MOVE_DECLVAL8, ::boost::move_detail::declval<P8>()
+
+//BOOST_MOVE_DECLVALQN
+#define BOOST_MOVE_DECLVALQ0
+#define BOOST_MOVE_DECLVALQ1                       ::boost::move_detail::declval<Q0>()
+#define BOOST_MOVE_DECLVALQ2 BOOST_MOVE_DECLVALQ1, ::boost::move_detail::declval<Q1>()
+#define BOOST_MOVE_DECLVALQ3 BOOST_MOVE_DECLVALQ2, ::boost::move_detail::declval<Q2>()
+#define BOOST_MOVE_DECLVALQ4 BOOST_MOVE_DECLVALQ3, ::boost::move_detail::declval<Q3>()
+#define BOOST_MOVE_DECLVALQ5 BOOST_MOVE_DECLVALQ4, ::boost::move_detail::declval<Q4>()
+#define BOOST_MOVE_DECLVALQ6 BOOST_MOVE_DECLVALQ5, ::boost::move_detail::declval<Q5>()
+#define BOOST_MOVE_DECLVALQ7 BOOST_MOVE_DECLVALQ6, ::boost::move_detail::declval<Q6>()
+#define BOOST_MOVE_DECLVALQ8 BOOST_MOVE_DECLVALQ7, ::boost::move_detail::declval<Q7>()
+#define BOOST_MOVE_DECLVALQ9 BOOST_MOVE_DECLVALQ8, ::boost::move_detail::declval<Q8>()
+
+#ifdef BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG
+   #define BOOST_MOVE_MREF(T)    ::boost::move_detail::mref<T>
+   #define BOOST_MOVE_MFWD(N)    ::boost::forward<P##N>(this->m_p##N.get())
+   #define BOOST_MOVE_MFWDQ(N)   ::boost::forward<Q##N>(this->m_q##N.get())
+#else
+   #define BOOST_MOVE_MREF(T)    BOOST_FWD_REF(T)
+   #define BOOST_MOVE_MFWD(N)    ::boost::forward<P##N>(this->m_p##N)
+   #define BOOST_MOVE_MFWDQ(N)   ::boost::forward<Q##N>(this->m_q##N)
+#endif
+#define BOOST_MOVE_MITFWD(N)  *this->m_p##N
+#define BOOST_MOVE_MINC(N)    ++this->m_p##N
+#define BOOST_MOVE_MITFWDQ(N) *this->m_q##N
+#define BOOST_MOVE_MINCQ(N)   ++this->m_q##N
+
+
+//BOOST_MOVE_MFWDN
+#define BOOST_MOVE_MFWD0
+#define BOOST_MOVE_MFWD1                   BOOST_MOVE_MFWD(0)
+#define BOOST_MOVE_MFWD2 BOOST_MOVE_MFWD1, BOOST_MOVE_MFWD(1)
+#define BOOST_MOVE_MFWD3 BOOST_MOVE_MFWD2, BOOST_MOVE_MFWD(2)
+#define BOOST_MOVE_MFWD4 BOOST_MOVE_MFWD3, BOOST_MOVE_MFWD(3)
+#define BOOST_MOVE_MFWD5 BOOST_MOVE_MFWD4, BOOST_MOVE_MFWD(4)
+#define BOOST_MOVE_MFWD6 BOOST_MOVE_MFWD5, BOOST_MOVE_MFWD(5)
+#define BOOST_MOVE_MFWD7 BOOST_MOVE_MFWD6, BOOST_MOVE_MFWD(6)
+#define BOOST_MOVE_MFWD8 BOOST_MOVE_MFWD7, BOOST_MOVE_MFWD(7)
+#define BOOST_MOVE_MFWD9 BOOST_MOVE_MFWD8, BOOST_MOVE_MFWD(8)
+
+//BOOST_MOVE_MFWDN
+#define BOOST_MOVE_MFWDQ0
+#define BOOST_MOVE_MFWDQ1                    BOOST_MOVE_MFWDQ(0)
+#define BOOST_MOVE_MFWDQ2 BOOST_MOVE_MFWDQ1, BOOST_MOVE_MFWDQ(1)
+#define BOOST_MOVE_MFWDQ3 BOOST_MOVE_MFWDQ2, BOOST_MOVE_MFWDQ(2)
+#define BOOST_MOVE_MFWDQ4 BOOST_MOVE_MFWDQ3, BOOST_MOVE_MFWDQ(3)
+#define BOOST_MOVE_MFWDQ5 BOOST_MOVE_MFWDQ4, BOOST_MOVE_MFWDQ(4)
+#define BOOST_MOVE_MFWDQ6 BOOST_MOVE_MFWDQ5, BOOST_MOVE_MFWDQ(5)
+#define BOOST_MOVE_MFWDQ7 BOOST_MOVE_MFWDQ6, BOOST_MOVE_MFWDQ(6)
+#define BOOST_MOVE_MFWDQ8 BOOST_MOVE_MFWDQ7, BOOST_MOVE_MFWDQ(7)
+#define BOOST_MOVE_MFWDQ9 BOOST_MOVE_MFWDQ8, BOOST_MOVE_MFWDQ(8)
+
+//BOOST_MOVE_MINCN
+#define BOOST_MOVE_MINC0
+#define BOOST_MOVE_MINC1                   BOOST_MOVE_MINC(0)
+#define BOOST_MOVE_MINC2 BOOST_MOVE_MINC1, BOOST_MOVE_MINC(1)
+#define BOOST_MOVE_MINC3 BOOST_MOVE_MINC2, BOOST_MOVE_MINC(2)
+#define BOOST_MOVE_MINC4 BOOST_MOVE_MINC3, BOOST_MOVE_MINC(3)
+#define BOOST_MOVE_MINC5 BOOST_MOVE_MINC4, BOOST_MOVE_MINC(4)
+#define BOOST_MOVE_MINC6 BOOST_MOVE_MINC5, BOOST_MOVE_MINC(5)
+#define BOOST_MOVE_MINC7 BOOST_MOVE_MINC6, BOOST_MOVE_MINC(6)
+#define BOOST_MOVE_MINC8 BOOST_MOVE_MINC7, BOOST_MOVE_MINC(7)
+#define BOOST_MOVE_MINC9 BOOST_MOVE_MINC8, BOOST_MOVE_MINC(8)
+
+//BOOST_MOVE_MINCQN
+#define BOOST_MOVE_MINCQ0
+#define BOOST_MOVE_MINCQ1                    BOOST_MOVE_MINCQ(0)
+#define BOOST_MOVE_MINCQ2 BOOST_MOVE_MINCQ1, BOOST_MOVE_MINCQ(1)
+#define BOOST_MOVE_MINCQ3 BOOST_MOVE_MINCQ2, BOOST_MOVE_MINCQ(2)
+#define BOOST_MOVE_MINCQ4 BOOST_MOVE_MINCQ3, BOOST_MOVE_MINCQ(3)
+#define BOOST_MOVE_MINCQ5 BOOST_MOVE_MINCQ4, BOOST_MOVE_MINCQ(4)
+#define BOOST_MOVE_MINCQ6 BOOST_MOVE_MINCQ5, BOOST_MOVE_MINCQ(5)
+#define BOOST_MOVE_MINCQ7 BOOST_MOVE_MINCQ6, BOOST_MOVE_MINCQ(6)
+#define BOOST_MOVE_MINCQ8 BOOST_MOVE_MINCQ7, BOOST_MOVE_MINCQ(7)
+#define BOOST_MOVE_MINCQ9 BOOST_MOVE_MINCQ8, BOOST_MOVE_MINCQ(8)
+
+//BOOST_MOVE_MITFWDN
+#define BOOST_MOVE_MITFWD0
+#define BOOST_MOVE_MITFWD1                     BOOST_MOVE_MITFWD(0)
+#define BOOST_MOVE_MITFWD2 BOOST_MOVE_MITFWD1, BOOST_MOVE_MITFWD(1)
+#define BOOST_MOVE_MITFWD3 BOOST_MOVE_MITFWD2, BOOST_MOVE_MITFWD(2)
+#define BOOST_MOVE_MITFWD4 BOOST_MOVE_MITFWD3, BOOST_MOVE_MITFWD(3)
+#define BOOST_MOVE_MITFWD5 BOOST_MOVE_MITFWD4, BOOST_MOVE_MITFWD(4)
+#define BOOST_MOVE_MITFWD6 BOOST_MOVE_MITFWD5, BOOST_MOVE_MITFWD(5)
+#define BOOST_MOVE_MITFWD7 BOOST_MOVE_MITFWD6, BOOST_MOVE_MITFWD(6)
+#define BOOST_MOVE_MITFWD8 BOOST_MOVE_MITFWD7, BOOST_MOVE_MITFWD(7)
+#define BOOST_MOVE_MITFWD9 BOOST_MOVE_MITFWD8, BOOST_MOVE_MITFWD(8)
+
+//BOOST_MOVE_MITFWDQN
+#define BOOST_MOVE_MITFWDQ0
+#define BOOST_MOVE_MITFWDQ1                      BOOST_MOVE_MITFWDQ(0)
+#define BOOST_MOVE_MITFWDQ2 BOOST_MOVE_MITFWDQ1, BOOST_MOVE_MITFWDQ(1)
+#define BOOST_MOVE_MITFWDQ3 BOOST_MOVE_MITFWDQ2, BOOST_MOVE_MITFWDQ(2)
+#define BOOST_MOVE_MITFWDQ4 BOOST_MOVE_MITFWDQ3, BOOST_MOVE_MITFWDQ(3)
+#define BOOST_MOVE_MITFWDQ5 BOOST_MOVE_MITFWDQ4, BOOST_MOVE_MITFWDQ(4)
+#define BOOST_MOVE_MITFWDQ6 BOOST_MOVE_MITFWDQ5, BOOST_MOVE_MITFWDQ(5)
+#define BOOST_MOVE_MITFWDQ7 BOOST_MOVE_MITFWDQ6, BOOST_MOVE_MITFWDQ(6)
+#define BOOST_MOVE_MITFWDQ8 BOOST_MOVE_MITFWDQ7, BOOST_MOVE_MITFWDQ(7)
+#define BOOST_MOVE_MITFWDQ9 BOOST_MOVE_MITFWDQ8, BOOST_MOVE_MITFWDQ(8)
+
+//BOOST_MOVE_FWD_INITN
+#define BOOST_MOVE_FWD_INIT0
+#define BOOST_MOVE_FWD_INIT1                       m_p0(::boost::forward<P0>(p0))
+#define BOOST_MOVE_FWD_INIT2 BOOST_MOVE_FWD_INIT1, m_p1(::boost::forward<P1>(p1))
+#define BOOST_MOVE_FWD_INIT3 BOOST_MOVE_FWD_INIT2, m_p2(::boost::forward<P2>(p2))
+#define BOOST_MOVE_FWD_INIT4 BOOST_MOVE_FWD_INIT3, m_p3(::boost::forward<P3>(p3))
+#define BOOST_MOVE_FWD_INIT5 BOOST_MOVE_FWD_INIT4, m_p4(::boost::forward<P4>(p4))
+#define BOOST_MOVE_FWD_INIT6 BOOST_MOVE_FWD_INIT5, m_p5(::boost::forward<P5>(p5))
+#define BOOST_MOVE_FWD_INIT7 BOOST_MOVE_FWD_INIT6, m_p6(::boost::forward<P6>(p6))
+#define BOOST_MOVE_FWD_INIT8 BOOST_MOVE_FWD_INIT7, m_p7(::boost::forward<P7>(p7))
+#define BOOST_MOVE_FWD_INIT9 BOOST_MOVE_FWD_INIT8, m_p8(::boost::forward<P8>(p8))
+
+//BOOST_MOVE_FWD_INITQN
+#define BOOST_MOVE_FWD_INITQ0
+#define BOOST_MOVE_FWD_INITQ1                        m_q0(::boost::forward<Q0>(q0))
+#define BOOST_MOVE_FWD_INITQ2 BOOST_MOVE_FWD_INITQ1, m_q1(::boost::forward<Q1>(q1))
+#define BOOST_MOVE_FWD_INITQ3 BOOST_MOVE_FWD_INITQ2, m_q2(::boost::forward<Q2>(q2))
+#define BOOST_MOVE_FWD_INITQ4 BOOST_MOVE_FWD_INITQ3, m_q3(::boost::forward<Q3>(q3))
+#define BOOST_MOVE_FWD_INITQ5 BOOST_MOVE_FWD_INITQ4, m_q4(::boost::forward<Q4>(q4))
+#define BOOST_MOVE_FWD_INITQ6 BOOST_MOVE_FWD_INITQ5, m_q5(::boost::forward<Q5>(q5))
+#define BOOST_MOVE_FWD_INITQ7 BOOST_MOVE_FWD_INITQ6, m_q6(::boost::forward<Q6>(q6))
+#define BOOST_MOVE_FWD_INITQ8 BOOST_MOVE_FWD_INITQ7, m_q7(::boost::forward<Q7>(q7))
+#define BOOST_MOVE_FWD_INITQ9 BOOST_MOVE_FWD_INITQ8, m_q8(::boost::forward<Q8>(q8))
+
+//BOOST_MOVE_VAL_INITN
+#define BOOST_MOVE_VAL_INIT0
+#define BOOST_MOVE_VAL_INIT1                       m_p0(p0)
+#define BOOST_MOVE_VAL_INIT2 BOOST_MOVE_VAL_INIT1, m_p1(p1)
+#define BOOST_MOVE_VAL_INIT3 BOOST_MOVE_VAL_INIT2, m_p2(p2)
+#define BOOST_MOVE_VAL_INIT4 BOOST_MOVE_VAL_INIT3, m_p3(p3)
+#define BOOST_MOVE_VAL_INIT5 BOOST_MOVE_VAL_INIT4, m_p4(p4)
+#define BOOST_MOVE_VAL_INIT6 BOOST_MOVE_VAL_INIT5, m_p5(p5)
+#define BOOST_MOVE_VAL_INIT7 BOOST_MOVE_VAL_INIT6, m_p6(p6)
+#define BOOST_MOVE_VAL_INIT8 BOOST_MOVE_VAL_INIT7, m_p7(p7)
+#define BOOST_MOVE_VAL_INIT9 BOOST_MOVE_VAL_INIT8, m_p8(p8)
+
+//BOOST_MOVE_VAL_INITQN
+#define BOOST_MOVE_VAL_INITQ0
+#define BOOST_MOVE_VAL_INITQ1                        m_q0(q0)
+#define BOOST_MOVE_VAL_INITQ2 BOOST_MOVE_VAL_INITQ1, m_q1(q1)
+#define BOOST_MOVE_VAL_INITQ3 BOOST_MOVE_VAL_INITQ2, m_q2(q2)
+#define BOOST_MOVE_VAL_INITQ4 BOOST_MOVE_VAL_INITQ3, m_q3(q3)
+#define BOOST_MOVE_VAL_INITQ5 BOOST_MOVE_VAL_INITQ4, m_q4(q4)
+#define BOOST_MOVE_VAL_INITQ6 BOOST_MOVE_VAL_INITQ5, m_q5(q5)
+#define BOOST_MOVE_VAL_INITQ7 BOOST_MOVE_VAL_INITQ6, m_q6(q6)
+#define BOOST_MOVE_VAL_INITQ8 BOOST_MOVE_VAL_INITQ7, m_q7(q7)
+#define BOOST_MOVE_VAL_INITQ9 BOOST_MOVE_VAL_INITQ8, m_q8(q8)
+
+//BOOST_MOVE_UREFN
+#define BOOST_MOVE_UREF0
+#define BOOST_MOVE_UREF1                   BOOST_FWD_REF(P0) p0
+#define BOOST_MOVE_UREF2 BOOST_MOVE_UREF1, BOOST_FWD_REF(P1) p1
+#define BOOST_MOVE_UREF3 BOOST_MOVE_UREF2, BOOST_FWD_REF(P2) p2
+#define BOOST_MOVE_UREF4 BOOST_MOVE_UREF3, BOOST_FWD_REF(P3) p3
+#define BOOST_MOVE_UREF5 BOOST_MOVE_UREF4, BOOST_FWD_REF(P4) p4
+#define BOOST_MOVE_UREF6 BOOST_MOVE_UREF5, BOOST_FWD_REF(P5) p5
+#define BOOST_MOVE_UREF7 BOOST_MOVE_UREF6, BOOST_FWD_REF(P6) p6
+#define BOOST_MOVE_UREF8 BOOST_MOVE_UREF7, BOOST_FWD_REF(P7) p7
+#define BOOST_MOVE_UREF9 BOOST_MOVE_UREF8, BOOST_FWD_REF(P8) p8
+
+//BOOST_MOVE_UREFQN
+#define BOOST_MOVE_UREFQ0
+#define BOOST_MOVE_UREFQ1                    BOOST_FWD_REF(Q0) q0
+#define BOOST_MOVE_UREFQ2 BOOST_MOVE_UREFQ1, BOOST_FWD_REF(Q1) q1
+#define BOOST_MOVE_UREFQ3 BOOST_MOVE_UREFQ2, BOOST_FWD_REF(Q2) q2
+#define BOOST_MOVE_UREFQ4 BOOST_MOVE_UREFQ3, BOOST_FWD_REF(Q3) q3
+#define BOOST_MOVE_UREFQ5 BOOST_MOVE_UREFQ4, BOOST_FWD_REF(Q4) q4
+#define BOOST_MOVE_UREFQ6 BOOST_MOVE_UREFQ5, BOOST_FWD_REF(Q5) q5
+#define BOOST_MOVE_UREFQ7 BOOST_MOVE_UREFQ6, BOOST_FWD_REF(Q6) q6
+#define BOOST_MOVE_UREFQ8 BOOST_MOVE_UREFQ7, BOOST_FWD_REF(Q7) q7
+#define BOOST_MOVE_UREFQ9 BOOST_MOVE_UREFQ8, BOOST_FWD_REF(Q8) q8
+
+//BOOST_MOVE_VALN
+#define BOOST_MOVE_VAL0
+#define BOOST_MOVE_VAL1                  BOOST_FWD_REF(P0) p0
+#define BOOST_MOVE_VAL2 BOOST_MOVE_VAL1, BOOST_FWD_REF(P1) p1
+#define BOOST_MOVE_VAL3 BOOST_MOVE_VAL2, BOOST_FWD_REF(P2) p2
+#define BOOST_MOVE_VAL4 BOOST_MOVE_VAL3, BOOST_FWD_REF(P3) p3
+#define BOOST_MOVE_VAL5 BOOST_MOVE_VAL4, BOOST_FWD_REF(P4) p4
+#define BOOST_MOVE_VAL6 BOOST_MOVE_VAL5, BOOST_FWD_REF(P5) p5
+#define BOOST_MOVE_VAL7 BOOST_MOVE_VAL6, BOOST_FWD_REF(P6) p6
+#define BOOST_MOVE_VAL8 BOOST_MOVE_VAL7, BOOST_FWD_REF(P7) p7
+#define BOOST_MOVE_VAL9 BOOST_MOVE_VAL8, BOOST_FWD_REF(P8) p8
+
+//BOOST_MOVE_VALQN
+#define BOOST_MOVE_VALQ0
+#define BOOST_MOVE_VALQ1                   BOOST_FWD_REF(Q0) q0
+#define BOOST_MOVE_VALQ2 BOOST_MOVE_VALQ1, BOOST_FWD_REF(Q1) q1
+#define BOOST_MOVE_VALQ3 BOOST_MOVE_VALQ2, BOOST_FWD_REF(Q2) q2
+#define BOOST_MOVE_VALQ4 BOOST_MOVE_VALQ3, BOOST_FWD_REF(Q3) q3
+#define BOOST_MOVE_VALQ5 BOOST_MOVE_VALQ4, BOOST_FWD_REF(Q4) q4
+#define BOOST_MOVE_VALQ6 BOOST_MOVE_VALQ5, BOOST_FWD_REF(Q5) q5
+#define BOOST_MOVE_VALQ7 BOOST_MOVE_VALQ6, BOOST_FWD_REF(Q6) q6
+#define BOOST_MOVE_VALQ8 BOOST_MOVE_VALQ7, BOOST_FWD_REF(Q7) q7
+#define BOOST_MOVE_VALQ9 BOOST_MOVE_VALQ8, BOOST_FWD_REF(Q8) q8
+
+
+#define BOOST_MOVE_UNVOIDCREF(T) const typename boost::move_detail::unvoid<T>::type&
+//BOOST_MOVE_CREFN
+#define BOOST_MOVE_CREF0
+#define BOOST_MOVE_CREF1                   BOOST_MOVE_UNVOIDCREF(P0) p0
+#define BOOST_MOVE_CREF2 BOOST_MOVE_CREF1, BOOST_MOVE_UNVOIDCREF(P1) p1
+#define BOOST_MOVE_CREF3 BOOST_MOVE_CREF2, BOOST_MOVE_UNVOIDCREF(P2) p2
+#define BOOST_MOVE_CREF4 BOOST_MOVE_CREF3, BOOST_MOVE_UNVOIDCREF(P3) p3
+#define BOOST_MOVE_CREF5 BOOST_MOVE_CREF4, BOOST_MOVE_UNVOIDCREF(P4) p4
+#define BOOST_MOVE_CREF6 BOOST_MOVE_CREF5, BOOST_MOVE_UNVOIDCREF(P5) p5
+#define BOOST_MOVE_CREF7 BOOST_MOVE_CREF6, BOOST_MOVE_UNVOIDCREF(P6) p6
+#define BOOST_MOVE_CREF8 BOOST_MOVE_CREF7, BOOST_MOVE_UNVOIDCREF(P7) p7
+#define BOOST_MOVE_CREF9 BOOST_MOVE_CREF8, BOOST_MOVE_UNVOIDCREF(P8) p8
+
+//BOOST_MOVE_CREFQN
+#define BOOST_MOVE_CREFQ0
+#define BOOST_MOVE_CREFQ1                    BOOST_MOVE_UNVOIDCREF(Q0) q0
+#define BOOST_MOVE_CREFQ2 BOOST_MOVE_CREFQ1, BOOST_MOVE_UNVOIDCREF(Q1) q1
+#define BOOST_MOVE_CREFQ3 BOOST_MOVE_CREFQ2, BOOST_MOVE_UNVOIDCREF(Q2) q2
+#define BOOST_MOVE_CREFQ4 BOOST_MOVE_CREFQ3, BOOST_MOVE_UNVOIDCREF(Q3) q3
+#define BOOST_MOVE_CREFQ5 BOOST_MOVE_CREFQ4, BOOST_MOVE_UNVOIDCREF(Q4) q4
+#define BOOST_MOVE_CREFQ6 BOOST_MOVE_CREFQ5, BOOST_MOVE_UNVOIDCREF(Q5) q5
+#define BOOST_MOVE_CREFQ7 BOOST_MOVE_CREFQ6, BOOST_MOVE_UNVOIDCREF(Q6) q6
+#define BOOST_MOVE_CREFQ8 BOOST_MOVE_CREFQ7, BOOST_MOVE_UNVOIDCREF(Q7) q7
+#define BOOST_MOVE_CREFQ9 BOOST_MOVE_CREFQ8, BOOST_MOVE_UNVOIDCREF(Q8) q8
+
+//BOOST_MOVE_CLASSN
+#define BOOST_MOVE_CLASS0
+#define BOOST_MOVE_CLASS1                    class P0
+#define BOOST_MOVE_CLASS2 BOOST_MOVE_CLASS1, class P1
+#define BOOST_MOVE_CLASS3 BOOST_MOVE_CLASS2, class P2
+#define BOOST_MOVE_CLASS4 BOOST_MOVE_CLASS3, class P3
+#define BOOST_MOVE_CLASS5 BOOST_MOVE_CLASS4, class P4
+#define BOOST_MOVE_CLASS6 BOOST_MOVE_CLASS5, class P5
+#define BOOST_MOVE_CLASS7 BOOST_MOVE_CLASS6, class P6
+#define BOOST_MOVE_CLASS8 BOOST_MOVE_CLASS7, class P7
+#define BOOST_MOVE_CLASS9 BOOST_MOVE_CLASS8, class P8
+
+//BOOST_MOVE_CLASSQN
+#define BOOST_MOVE_CLASSQ0
+#define BOOST_MOVE_CLASSQ1                     class Q0
+#define BOOST_MOVE_CLASSQ2 BOOST_MOVE_CLASSQ1, class Q1
+#define BOOST_MOVE_CLASSQ3 BOOST_MOVE_CLASSQ2, class Q2
+#define BOOST_MOVE_CLASSQ4 BOOST_MOVE_CLASSQ3, class Q3
+#define BOOST_MOVE_CLASSQ5 BOOST_MOVE_CLASSQ4, class Q4
+#define BOOST_MOVE_CLASSQ6 BOOST_MOVE_CLASSQ5, class Q5
+#define BOOST_MOVE_CLASSQ7 BOOST_MOVE_CLASSQ6, class Q6
+#define BOOST_MOVE_CLASSQ8 BOOST_MOVE_CLASSQ7, class Q7
+#define BOOST_MOVE_CLASSQ9 BOOST_MOVE_CLASSQ8, class Q8
+
+//BOOST_MOVE_CLASSDFLTN
+#define BOOST_MOVE_CLASSDFLT0
+#define BOOST_MOVE_CLASSDFLT1                        class P0 = void
+#define BOOST_MOVE_CLASSDFLT2 BOOST_MOVE_CLASSDFLT1, class P1 = void
+#define BOOST_MOVE_CLASSDFLT3 BOOST_MOVE_CLASSDFLT2, class P2 = void
+#define BOOST_MOVE_CLASSDFLT4 BOOST_MOVE_CLASSDFLT3, class P3 = void
+#define BOOST_MOVE_CLASSDFLT5 BOOST_MOVE_CLASSDFLT4, class P4 = void
+#define BOOST_MOVE_CLASSDFLT6 BOOST_MOVE_CLASSDFLT5, class P5 = void
+#define BOOST_MOVE_CLASSDFLT7 BOOST_MOVE_CLASSDFLT6, class P6 = void
+#define BOOST_MOVE_CLASSDFLT8 BOOST_MOVE_CLASSDFLT7, class P7 = void
+#define BOOST_MOVE_CLASSDFLT9 BOOST_MOVE_CLASSDFLT8, class P8 = void
+
+//BOOST_MOVE_CLASSDFLTQN
+#define BOOST_MOVE_CLASSDFLTQ0
+#define BOOST_MOVE_CLASSDFLTQ1                         class Q0 = void
+#define BOOST_MOVE_CLASSDFLTQ2 BOOST_MOVE_CLASSDFLTQ1, class Q1 = void
+#define BOOST_MOVE_CLASSDFLTQ3 BOOST_MOVE_CLASSDFLTQ2, class Q2 = void
+#define BOOST_MOVE_CLASSDFLTQ4 BOOST_MOVE_CLASSDFLTQ3, class Q3 = void
+#define BOOST_MOVE_CLASSDFLTQ5 BOOST_MOVE_CLASSDFLTQ4, class Q4 = void
+#define BOOST_MOVE_CLASSDFLTQ6 BOOST_MOVE_CLASSDFLTQ5, class Q5 = void
+#define BOOST_MOVE_CLASSDFLTQ7 BOOST_MOVE_CLASSDFLTQ6, class Q6 = void
+#define BOOST_MOVE_CLASSDFLTQ8 BOOST_MOVE_CLASSDFLTQ7, class Q7 = void
+#define BOOST_MOVE_CLASSDFLTQ9 BOOST_MOVE_CLASSDFLTQ8, class Q8 = void
+
+//BOOST_MOVE_LAST_TARGN
+#define BOOST_MOVE_LAST_TARG0 void
+#define BOOST_MOVE_LAST_TARG1 P0
+#define BOOST_MOVE_LAST_TARG2 P1
+#define BOOST_MOVE_LAST_TARG3 P2
+#define BOOST_MOVE_LAST_TARG4 P3
+#define BOOST_MOVE_LAST_TARG5 P4
+#define BOOST_MOVE_LAST_TARG6 P5
+#define BOOST_MOVE_LAST_TARG7 P6
+#define BOOST_MOVE_LAST_TARG8 P7
+#define BOOST_MOVE_LAST_TARG9 P8
+
+//BOOST_MOVE_LAST_TARGQN
+#define BOOST_MOVE_LAST_TARGQ0 void
+#define BOOST_MOVE_LAST_TARGQ1 Q0
+#define BOOST_MOVE_LAST_TARGQ2 Q1
+#define BOOST_MOVE_LAST_TARGQ3 Q2
+#define BOOST_MOVE_LAST_TARGQ4 Q3
+#define BOOST_MOVE_LAST_TARGQ5 Q4
+#define BOOST_MOVE_LAST_TARGQ6 Q5
+#define BOOST_MOVE_LAST_TARGQ7 Q6
+#define BOOST_MOVE_LAST_TARGQ8 Q7
+#define BOOST_MOVE_LAST_TARGQ9 Q8
+
+
+//BOOST_MOVE_TARGN
+#define BOOST_MOVE_TARG0
+#define BOOST_MOVE_TARG1                   P0
+#define BOOST_MOVE_TARG2 BOOST_MOVE_TARG1, P1
+#define BOOST_MOVE_TARG3 BOOST_MOVE_TARG2, P2
+#define BOOST_MOVE_TARG4 BOOST_MOVE_TARG3, P3
+#define BOOST_MOVE_TARG5 BOOST_MOVE_TARG4, P4
+#define BOOST_MOVE_TARG6 BOOST_MOVE_TARG5, P5
+#define BOOST_MOVE_TARG7 BOOST_MOVE_TARG6, P6
+#define BOOST_MOVE_TARG8 BOOST_MOVE_TARG7, P7
+#define BOOST_MOVE_TARG9 BOOST_MOVE_TARG8, P8
+
+//BOOST_MOVE_TARGQN
+#define BOOST_MOVE_TARGQ0
+#define BOOST_MOVE_TARGQ1                    Q0
+#define BOOST_MOVE_TARGQ2 BOOST_MOVE_TARGQ1, Q1
+#define BOOST_MOVE_TARGQ3 BOOST_MOVE_TARGQ2, Q2
+#define BOOST_MOVE_TARGQ4 BOOST_MOVE_TARGQ3, Q3
+#define BOOST_MOVE_TARGQ5 BOOST_MOVE_TARGQ4, Q4
+#define BOOST_MOVE_TARGQ6 BOOST_MOVE_TARGQ5, Q5
+#define BOOST_MOVE_TARGQ7 BOOST_MOVE_TARGQ6, Q6
+#define BOOST_MOVE_TARGQ8 BOOST_MOVE_TARGQ7, Q7
+#define BOOST_MOVE_TARGQ9 BOOST_MOVE_TARGQ8, Q8
+
+//BOOST_MOVE_FWD_TN
+#define BOOST_MOVE_FWD_T0
+#define BOOST_MOVE_FWD_T1                    typename ::boost::move_detail::forward_type<P0>::type
+#define BOOST_MOVE_FWD_T2 BOOST_MOVE_FWD_T1, typename ::boost::move_detail::forward_type<P1>::type
+#define BOOST_MOVE_FWD_T3 BOOST_MOVE_FWD_T2, typename ::boost::move_detail::forward_type<P2>::type
+#define BOOST_MOVE_FWD_T4 BOOST_MOVE_FWD_T3, typename ::boost::move_detail::forward_type<P3>::type
+#define BOOST_MOVE_FWD_T5 BOOST_MOVE_FWD_T4, typename ::boost::move_detail::forward_type<P4>::type
+#define BOOST_MOVE_FWD_T6 BOOST_MOVE_FWD_T5, typename ::boost::move_detail::forward_type<P5>::type
+#define BOOST_MOVE_FWD_T7 BOOST_MOVE_FWD_T6, typename ::boost::move_detail::forward_type<P6>::type
+#define BOOST_MOVE_FWD_T8 BOOST_MOVE_FWD_T7, typename ::boost::move_detail::forward_type<P7>::type
+#define BOOST_MOVE_FWD_T9 BOOST_MOVE_FWD_T8, typename ::boost::move_detail::forward_type<P8>::type
+
+//BOOST_MOVE_FWD_TQN
+#define BOOST_MOVE_FWD_TQ0
+#define BOOST_MOVE_FWD_TQ1                     typename ::boost::move_detail::forward_type<Q0>::type
+#define BOOST_MOVE_FWD_TQ2 BOOST_MOVE_FWD_TQ1, typename ::boost::move_detail::forward_type<Q1>::type
+#define BOOST_MOVE_FWD_TQ3 BOOST_MOVE_FWD_TQ2, typename ::boost::move_detail::forward_type<Q2>::type
+#define BOOST_MOVE_FWD_TQ4 BOOST_MOVE_FWD_TQ3, typename ::boost::move_detail::forward_type<Q3>::type
+#define BOOST_MOVE_FWD_TQ5 BOOST_MOVE_FWD_TQ4, typename ::boost::move_detail::forward_type<Q4>::type
+#define BOOST_MOVE_FWD_TQ6 BOOST_MOVE_FWD_TQ5, typename ::boost::move_detail::forward_type<Q5>::type
+#define BOOST_MOVE_FWD_TQ7 BOOST_MOVE_FWD_TQ6, typename ::boost::move_detail::forward_type<Q6>::type
+#define BOOST_MOVE_FWD_TQ8 BOOST_MOVE_FWD_TQ7, typename ::boost::move_detail::forward_type<Q7>::type
+#define BOOST_MOVE_FWD_TQ9 BOOST_MOVE_FWD_TQ8, typename ::boost::move_detail::forward_type<Q8>::type
+
+//BOOST_MOVE_MREFX
+#define BOOST_MOVE_MREF0
+#define BOOST_MOVE_MREF1                  BOOST_MOVE_MREF(P0) m_p0;
+#define BOOST_MOVE_MREF2 BOOST_MOVE_MREF1 BOOST_MOVE_MREF(P1) m_p1;
+#define BOOST_MOVE_MREF3 BOOST_MOVE_MREF2 BOOST_MOVE_MREF(P2) m_p2;
+#define BOOST_MOVE_MREF4 BOOST_MOVE_MREF3 BOOST_MOVE_MREF(P3) m_p3;
+#define BOOST_MOVE_MREF5 BOOST_MOVE_MREF4 BOOST_MOVE_MREF(P4) m_p4;
+#define BOOST_MOVE_MREF6 BOOST_MOVE_MREF5 BOOST_MOVE_MREF(P5) m_p5;
+#define BOOST_MOVE_MREF7 BOOST_MOVE_MREF6 BOOST_MOVE_MREF(P6) m_p6;
+#define BOOST_MOVE_MREF8 BOOST_MOVE_MREF7 BOOST_MOVE_MREF(P7) m_p7;
+#define BOOST_MOVE_MREF9 BOOST_MOVE_MREF8 BOOST_MOVE_MREF(P8) m_p8;
+
+//BOOST_MOVE_MREFQX
+#define BOOST_MOVE_MREFQ0
+#define BOOST_MOVE_MREFQ1                   BOOST_MOVE_MREFQ(Q0) m_q0;
+#define BOOST_MOVE_MREFQ2 BOOST_MOVE_MREFQ1 BOOST_MOVE_MREFQ(Q1) m_q1;
+#define BOOST_MOVE_MREFQ3 BOOST_MOVE_MREFQ2 BOOST_MOVE_MREFQ(Q2) m_q2;
+#define BOOST_MOVE_MREFQ4 BOOST_MOVE_MREFQ3 BOOST_MOVE_MREFQ(Q3) m_q3;
+#define BOOST_MOVE_MREFQ5 BOOST_MOVE_MREFQ4 BOOST_MOVE_MREFQ(Q4) m_q4;
+#define BOOST_MOVE_MREFQ6 BOOST_MOVE_MREFQ5 BOOST_MOVE_MREFQ(Q5) m_q5;
+#define BOOST_MOVE_MREFQ7 BOOST_MOVE_MREFQ6 BOOST_MOVE_MREFQ(Q6) m_q6;
+#define BOOST_MOVE_MREFQ8 BOOST_MOVE_MREFQ7 BOOST_MOVE_MREFQ(Q7) m_q7;
+#define BOOST_MOVE_MREFQ9 BOOST_MOVE_MREFQ8 BOOST_MOVE_MREFQ(Q8) m_q8;
+
+//BOOST_MOVE_MEMBX
+#define BOOST_MOVE_MEMB0
+#define BOOST_MOVE_MEMB1                  P0 m_p0;
+#define BOOST_MOVE_MEMB2 BOOST_MOVE_MEMB1 P1 m_p1;
+#define BOOST_MOVE_MEMB3 BOOST_MOVE_MEMB2 P2 m_p2;
+#define BOOST_MOVE_MEMB4 BOOST_MOVE_MEMB3 P3 m_p3;
+#define BOOST_MOVE_MEMB5 BOOST_MOVE_MEMB4 P4 m_p4;
+#define BOOST_MOVE_MEMB6 BOOST_MOVE_MEMB5 P5 m_p5;
+#define BOOST_MOVE_MEMB7 BOOST_MOVE_MEMB6 P6 m_p6;
+#define BOOST_MOVE_MEMB8 BOOST_MOVE_MEMB7 P7 m_p7;
+#define BOOST_MOVE_MEMB9 BOOST_MOVE_MEMB8 P8 m_p8;
+
+//BOOST_MOVE_MEMBQX
+#define BOOST_MOVE_MEMBQ0
+#define BOOST_MOVE_MEMBQ1                   Q0 m_q0;
+#define BOOST_MOVE_MEMBQ2 BOOST_MOVE_MEMBQ1 Q1 m_q1;
+#define BOOST_MOVE_MEMBQ3 BOOST_MOVE_MEMBQ2 Q2 m_q2;
+#define BOOST_MOVE_MEMBQ4 BOOST_MOVE_MEMBQ3 Q3 m_q3;
+#define BOOST_MOVE_MEMBQ5 BOOST_MOVE_MEMBQ4 Q4 m_q4;
+#define BOOST_MOVE_MEMBQ6 BOOST_MOVE_MEMBQ5 Q5 m_q5;
+#define BOOST_MOVE_MEMBQ7 BOOST_MOVE_MEMBQ6 Q6 m_q6;
+#define BOOST_MOVE_MEMBQ8 BOOST_MOVE_MEMBQ7 Q7 m_q7;
+#define BOOST_MOVE_MEMBQ9 BOOST_MOVE_MEMBQ8 Q8 m_q8;
+
+//BOOST_MOVE_TMPL_LTN
+#define BOOST_MOVE_TMPL_LT0
+#define BOOST_MOVE_TMPL_LT1 template<
+#define BOOST_MOVE_TMPL_LT2 BOOST_MOVE_TMPL_LT1
+#define BOOST_MOVE_TMPL_LT3 BOOST_MOVE_TMPL_LT1
+#define BOOST_MOVE_TMPL_LT4 BOOST_MOVE_TMPL_LT1
+#define BOOST_MOVE_TMPL_LT5 BOOST_MOVE_TMPL_LT1
+#define BOOST_MOVE_TMPL_LT6 BOOST_MOVE_TMPL_LT1
+#define BOOST_MOVE_TMPL_LT7 BOOST_MOVE_TMPL_LT1
+#define BOOST_MOVE_TMPL_LT8 BOOST_MOVE_TMPL_LT1
+#define BOOST_MOVE_TMPL_LT9 BOOST_MOVE_TMPL_LT1
+
+//BOOST_MOVE_LTN
+#define BOOST_MOVE_LT0
+#define BOOST_MOVE_LT1 <
+#define BOOST_MOVE_LT2 BOOST_MOVE_LT1
+#define BOOST_MOVE_LT3 BOOST_MOVE_LT1
+#define BOOST_MOVE_LT4 BOOST_MOVE_LT1
+#define BOOST_MOVE_LT5 BOOST_MOVE_LT1
+#define BOOST_MOVE_LT6 BOOST_MOVE_LT1
+#define BOOST_MOVE_LT7 BOOST_MOVE_LT1
+#define BOOST_MOVE_LT8 BOOST_MOVE_LT1
+#define BOOST_MOVE_LT9 BOOST_MOVE_LT1
+
+//BOOST_MOVE_GTN
+#define BOOST_MOVE_GT0
+#define BOOST_MOVE_GT1 >
+#define BOOST_MOVE_GT2 BOOST_MOVE_GT1
+#define BOOST_MOVE_GT3 BOOST_MOVE_GT1
+#define BOOST_MOVE_GT4 BOOST_MOVE_GT1
+#define BOOST_MOVE_GT5 BOOST_MOVE_GT1
+#define BOOST_MOVE_GT6 BOOST_MOVE_GT1
+#define BOOST_MOVE_GT7 BOOST_MOVE_GT1
+#define BOOST_MOVE_GT8 BOOST_MOVE_GT1
+#define BOOST_MOVE_GT9 BOOST_MOVE_GT1
+
+//BOOST_MOVE_LPN
+#define BOOST_MOVE_LP0
+#define BOOST_MOVE_LP1 (
+#define BOOST_MOVE_LP2 BOOST_MOVE_LP1
+#define BOOST_MOVE_LP3 BOOST_MOVE_LP1
+#define BOOST_MOVE_LP4 BOOST_MOVE_LP1
+#define BOOST_MOVE_LP5 BOOST_MOVE_LP1
+#define BOOST_MOVE_LP6 BOOST_MOVE_LP1
+#define BOOST_MOVE_LP7 BOOST_MOVE_LP1
+#define BOOST_MOVE_LP8 BOOST_MOVE_LP1
+#define BOOST_MOVE_LP9 BOOST_MOVE_LP1
+
+//BOOST_MOVE_RPN
+#define BOOST_MOVE_RP0
+#define BOOST_MOVE_RP1 )
+#define BOOST_MOVE_RP2 BOOST_MOVE_RP1
+#define BOOST_MOVE_RP3 BOOST_MOVE_RP1
+#define BOOST_MOVE_RP4 BOOST_MOVE_RP1
+#define BOOST_MOVE_RP5 BOOST_MOVE_RP1
+#define BOOST_MOVE_RP6 BOOST_MOVE_RP1
+#define BOOST_MOVE_RP7 BOOST_MOVE_RP1
+#define BOOST_MOVE_RP8 BOOST_MOVE_RP1
+#define BOOST_MOVE_RP9 BOOST_MOVE_RP1
+
+//BOOST_MOVE_IN
+#define BOOST_MOVE_I0
+#define BOOST_MOVE_I1 ,
+#define BOOST_MOVE_I2 BOOST_MOVE_I1
+#define BOOST_MOVE_I3 BOOST_MOVE_I1
+#define BOOST_MOVE_I4 BOOST_MOVE_I1
+#define BOOST_MOVE_I5 BOOST_MOVE_I1
+#define BOOST_MOVE_I6 BOOST_MOVE_I1
+#define BOOST_MOVE_I7 BOOST_MOVE_I1
+#define BOOST_MOVE_I8 BOOST_MOVE_I1
+#define BOOST_MOVE_I9 BOOST_MOVE_I1
+
+//BOOST_MOVE_BOOL
+# define BOOST_MOVE_BOOL(x)   BOOST_MOVE_BOOL_I(x)
+# define BOOST_MOVE_BOOL_I(x) BOOST_MOVE_BOOL##x
+# define BOOST_MOVE_BOOL0 0
+# define BOOST_MOVE_BOOL1 1
+# define BOOST_MOVE_BOOL2 1
+# define BOOST_MOVE_BOOL3 1
+# define BOOST_MOVE_BOOL4 1
+# define BOOST_MOVE_BOOL5 1
+# define BOOST_MOVE_BOOL6 1
+# define BOOST_MOVE_BOOL7 1
+# define BOOST_MOVE_BOOL8 1
+# define BOOST_MOVE_BOOL9 1
+
+//BOOST_MOVE_I_IF
+#define BOOST_MOVE_I_IF(x)    BOOST_MOVE_I_IF_I (BOOST_MOVE_BOOL(x))
+#define BOOST_MOVE_I_IF_I(x)  BOOST_MOVE_I_IF_I2(x)
+#define BOOST_MOVE_I_IF_I2(x) BOOST_MOVE_IF_I_##x
+#define BOOST_MOVE_IF_I_0
+#define BOOST_MOVE_IF_I_1 ,
+
+//BOOST_MOVE_IF
+#define BOOST_MOVE_IF(cond, t, f) BOOST_MOVE_IF_I(cond, t, f)
+#define BOOST_MOVE_IF_I(cond, t, f) BOOST_MOVE_IIF(BOOST_MOVE_BOOL(cond), t, f)
+
+#define BOOST_MOVE_IIF(bit, t, f)   BOOST_MOVE_IIF_I(bit, t, f)
+#define BOOST_MOVE_IIF_I(bit, t, f) BOOST_MOVE_IIF_##bit(t, f)
+#define BOOST_MOVE_IIF_0(t, f) f
+#define BOOST_MOVE_IIF_1(t, f) t
+
+/*
+#define BOOST_MOVE_IIF(bit, t, f) BOOST_MOVE_IIF_OO((bit, t, f))
+#define BOOST_MOVE_IIF_OO(par) BOOST_MOVE_IIF_I ## par
+#define BOOST_MOVE_IIF_I(bit, t, f) BOOST_MOVE_IIF_II(BOOST_MOVE_IIF_ ## bit(t, f))
+#define BOOST_MOVE_IIF_II(id) id
+#define BOOST_MOVE_IIF_0(t, f) f
+#define BOOST_MOVE_IIF_1(t, f) t
+*/
+
+//BOOST_MOVE_COLON
+#define BOOST_MOVE_COLON0
+#define BOOST_MOVE_COLON1 :
+#define BOOST_MOVE_COLON2 BOOST_MOVE_COLON1
+#define BOOST_MOVE_COLON3 BOOST_MOVE_COLON1
+#define BOOST_MOVE_COLON4 BOOST_MOVE_COLON1
+#define BOOST_MOVE_COLON5 BOOST_MOVE_COLON1
+#define BOOST_MOVE_COLON6 BOOST_MOVE_COLON1
+#define BOOST_MOVE_COLON7 BOOST_MOVE_COLON1
+#define BOOST_MOVE_COLON8 BOOST_MOVE_COLON1
+#define BOOST_MOVE_COLON9 BOOST_MOVE_COLON1
+
+//BOOST_MOVE_BITOR
+#define BOOST_MOVE_BITOR(x,y)    BOOST_MOVE_BITOR_I(x,y)
+#define BOOST_MOVE_BITOR_I(x,y)  BOOST_MOVE_BITOR##x##y
+#define BOOST_MOVE_BITOR00 0
+#define BOOST_MOVE_BITOR01 1
+#define BOOST_MOVE_BITOR10 1
+#define BOOST_MOVE_BITOR11 1
+
+//BOOST_MOVE_OR
+#define BOOST_MOVE_OR(x, y) BOOST_MOVE_OR_I(x, y)
+#define BOOST_MOVE_OR_I(x, y) BOOST_MOVE_BITOR(BOOST_MOVE_BOOL(x), BOOST_MOVE_BOOL(y))
+
+//BOOST_MOVE_BITAND
+#define BOOST_MOVE_BITAND(x,y)    BOOST_MOVE_BITAND_I(x,y)
+#define BOOST_MOVE_BITAND_I(x,y)  BOOST_MOVE_BITAND##x##y
+#define BOOST_MOVE_BITAND00 0
+#define BOOST_MOVE_BITAND01 0
+#define BOOST_MOVE_BITAND10 0
+#define BOOST_MOVE_BITAND11 1
+
+//BOOST_MOVE_AND
+#define BOOST_MOVE_AND(x, y) BOOST_MOVE_AND_I(x, y)
+#define BOOST_MOVE_AND_I(x, y) BOOST_MOVE_BITAND(BOOST_MOVE_BOOL(x), BOOST_MOVE_BOOL(y))
+
+//BOOST_MOVE_DEC
+#define BOOST_MOVE_DEC(x) BOOST_MOVE_DEC_I(x)
+#define BOOST_MOVE_DEC_I(x) BOOST_MOVE_DEC##x
+#define BOOST_MOVE_DEC1  0
+#define BOOST_MOVE_DEC2  1
+#define BOOST_MOVE_DEC3  2
+#define BOOST_MOVE_DEC4  3
+#define BOOST_MOVE_DEC5  4
+#define BOOST_MOVE_DEC6  5
+#define BOOST_MOVE_DEC7  6
+#define BOOST_MOVE_DEC8  7
+#define BOOST_MOVE_DEC9  8
+#define BOOST_MOVE_DEC10 9
+#define BOOST_MOVE_DEC11 10
+#define BOOST_MOVE_DEC12 11
+#define BOOST_MOVE_DEC13 12
+#define BOOST_MOVE_DEC14 13
+
+//BOOST_MOVE_SUB
+#define BOOST_MOVE_SUB(x, y) BOOST_MOVE_SUB_I(x,y)
+#define BOOST_MOVE_SUB_I(x, y) BOOST_MOVE_SUB##y(x)
+#define BOOST_MOVE_SUB0(x) x
+#define BOOST_MOVE_SUB1(x) BOOST_MOVE_DEC(x)
+#define BOOST_MOVE_SUB2(x) BOOST_MOVE_SUB1(BOOST_MOVE_DEC(x))
+#define BOOST_MOVE_SUB3(x) BOOST_MOVE_SUB2(BOOST_MOVE_DEC(x))
+#define BOOST_MOVE_SUB4(x) BOOST_MOVE_SUB3(BOOST_MOVE_DEC(x))
+#define BOOST_MOVE_SUB5(x) BOOST_MOVE_SUB4(BOOST_MOVE_DEC(x))
+#define BOOST_MOVE_SUB6(x) BOOST_MOVE_SUB5(BOOST_MOVE_DEC(x))
+#define BOOST_MOVE_SUB7(x) BOOST_MOVE_SUB6(BOOST_MOVE_DEC(x))
+#define BOOST_MOVE_SUB8(x) BOOST_MOVE_SUB7(BOOST_MOVE_DEC(x))
+#define BOOST_MOVE_SUB9(x) BOOST_MOVE_SUB8(BOOST_MOVE_DEC(x))
+#define BOOST_MOVE_SUB10(x) BOOST_MOVE_SUB9(BOOST_MOVE_DEC(x))
+#define BOOST_MOVE_SUB11(x) BOOST_MOVE_SUB10(BOOST_MOVE_DEC(x))
+#define BOOST_MOVE_SUB12(x) BOOST_MOVE_SUB11(BOOST_MOVE_DEC(x))
+#define BOOST_MOVE_SUB13(x) BOOST_MOVE_SUB12(BOOST_MOVE_DEC(x))
+#define BOOST_MOVE_SUB14(x) BOOST_MOVE_SUB13(BOOST_MOVE_DEC(x))
+
+//BOOST_MOVE_INC
+#define BOOST_MOVE_INC(x) BOOST_MOVE_INC_I(x)
+#define BOOST_MOVE_INC_I(x) BOOST_MOVE_INC##x
+#define BOOST_MOVE_INC0  1
+#define BOOST_MOVE_INC1  2
+#define BOOST_MOVE_INC2  3
+#define BOOST_MOVE_INC3  4
+#define BOOST_MOVE_INC4  5
+#define BOOST_MOVE_INC5  6
+#define BOOST_MOVE_INC6  7
+#define BOOST_MOVE_INC7  8
+#define BOOST_MOVE_INC8  9
+#define BOOST_MOVE_INC9  10
+#define BOOST_MOVE_INC10 11
+#define BOOST_MOVE_INC11 12
+#define BOOST_MOVE_INC12 13
+#define BOOST_MOVE_INC13 14
+
+//BOOST_MOVE_ADD
+#define BOOST_MOVE_ADD(x, y) BOOST_MOVE_ADD_I(x,y)
+#define BOOST_MOVE_ADD_I(x, y) BOOST_MOVE_ADD##y(x)
+#define BOOST_MOVE_ADD0(x) x
+#define BOOST_MOVE_ADD1(x) BOOST_MOVE_INC(x)
+#define BOOST_MOVE_ADD2(x) BOOST_MOVE_ADD1(BOOST_MOVE_INC(x))
+#define BOOST_MOVE_ADD3(x) BOOST_MOVE_ADD2(BOOST_MOVE_INC(x))
+#define BOOST_MOVE_ADD4(x) BOOST_MOVE_ADD3(BOOST_MOVE_INC(x))
+#define BOOST_MOVE_ADD5(x) BOOST_MOVE_ADD4(BOOST_MOVE_INC(x))
+#define BOOST_MOVE_ADD6(x) BOOST_MOVE_ADD5(BOOST_MOVE_INC(x))
+#define BOOST_MOVE_ADD7(x) BOOST_MOVE_ADD6(BOOST_MOVE_INC(x))
+#define BOOST_MOVE_ADD8(x) BOOST_MOVE_ADD7(BOOST_MOVE_INC(x))
+#define BOOST_MOVE_ADD9(x) BOOST_MOVE_ADD8(BOOST_MOVE_INC(x))
+#define BOOST_MOVE_ADD10(x) BOOST_MOVE_ADD9(BOOST_MOVE_INC(x))
+#define BOOST_MOVE_ADD11(x) BOOST_MOVE_ADD10(BOOST_MOVE_INC(x))
+#define BOOST_MOVE_ADD12(x) BOOST_MOVE_ADD11(BOOST_MOVE_INC(x))
+#define BOOST_MOVE_ADD13(x) BOOST_MOVE_ADD12(BOOST_MOVE_INC(x))
+
+//BOOST_MOVE_ITERATE_2TON
+#define BOOST_MOVE_ITERATE_2TO2(MACROFUNC)                                       MACROFUNC(2)
+#define BOOST_MOVE_ITERATE_2TO3(MACROFUNC)   BOOST_MOVE_ITERATE_2TO2(MACROFUNC)  MACROFUNC(3)
+#define BOOST_MOVE_ITERATE_2TO4(MACROFUNC)   BOOST_MOVE_ITERATE_2TO3(MACROFUNC)  MACROFUNC(4)
+#define BOOST_MOVE_ITERATE_2TO5(MACROFUNC)   BOOST_MOVE_ITERATE_2TO4(MACROFUNC)  MACROFUNC(5)
+#define BOOST_MOVE_ITERATE_2TO6(MACROFUNC)   BOOST_MOVE_ITERATE_2TO5(MACROFUNC)  MACROFUNC(6)
+#define BOOST_MOVE_ITERATE_2TO7(MACROFUNC)   BOOST_MOVE_ITERATE_2TO6(MACROFUNC)  MACROFUNC(7)
+#define BOOST_MOVE_ITERATE_2TO8(MACROFUNC)   BOOST_MOVE_ITERATE_2TO7(MACROFUNC)  MACROFUNC(8)
+#define BOOST_MOVE_ITERATE_2TO9(MACROFUNC)   BOOST_MOVE_ITERATE_2TO8(MACROFUNC)  MACROFUNC(9)
+
+//BOOST_MOVE_ITERATE_1TON
+#define BOOST_MOVE_ITERATE_1TO1(MACROFUNC)                                       MACROFUNC(1)
+#define BOOST_MOVE_ITERATE_1TO2(MACROFUNC)   BOOST_MOVE_ITERATE_1TO1(MACROFUNC)  MACROFUNC(2)
+#define BOOST_MOVE_ITERATE_1TO3(MACROFUNC)   BOOST_MOVE_ITERATE_1TO2(MACROFUNC)  MACROFUNC(3)
+#define BOOST_MOVE_ITERATE_1TO4(MACROFUNC)   BOOST_MOVE_ITERATE_1TO3(MACROFUNC)  MACROFUNC(4)
+#define BOOST_MOVE_ITERATE_1TO5(MACROFUNC)   BOOST_MOVE_ITERATE_1TO4(MACROFUNC)  MACROFUNC(5)
+#define BOOST_MOVE_ITERATE_1TO6(MACROFUNC)   BOOST_MOVE_ITERATE_1TO5(MACROFUNC)  MACROFUNC(6)
+#define BOOST_MOVE_ITERATE_1TO7(MACROFUNC)   BOOST_MOVE_ITERATE_1TO6(MACROFUNC)  MACROFUNC(7)
+#define BOOST_MOVE_ITERATE_1TO8(MACROFUNC)   BOOST_MOVE_ITERATE_1TO7(MACROFUNC)  MACROFUNC(8)
+#define BOOST_MOVE_ITERATE_1TO9(MACROFUNC)   BOOST_MOVE_ITERATE_1TO8(MACROFUNC)  MACROFUNC(9)
+
+//BOOST_MOVE_ITERATE_0TON
+#define BOOST_MOVE_ITERATE_0TO0(MACROFUNC)                                       MACROFUNC(0)
+#define BOOST_MOVE_ITERATE_0TO1(MACROFUNC)   BOOST_MOVE_ITERATE_0TO0(MACROFUNC)  MACROFUNC(1)
+#define BOOST_MOVE_ITERATE_0TO2(MACROFUNC)   BOOST_MOVE_ITERATE_0TO1(MACROFUNC)  MACROFUNC(2)
+#define BOOST_MOVE_ITERATE_0TO3(MACROFUNC)   BOOST_MOVE_ITERATE_0TO2(MACROFUNC)  MACROFUNC(3)
+#define BOOST_MOVE_ITERATE_0TO4(MACROFUNC)   BOOST_MOVE_ITERATE_0TO3(MACROFUNC)  MACROFUNC(4)
+#define BOOST_MOVE_ITERATE_0TO5(MACROFUNC)   BOOST_MOVE_ITERATE_0TO4(MACROFUNC)  MACROFUNC(5)
+#define BOOST_MOVE_ITERATE_0TO6(MACROFUNC)   BOOST_MOVE_ITERATE_0TO5(MACROFUNC)  MACROFUNC(6)
+#define BOOST_MOVE_ITERATE_0TO7(MACROFUNC)   BOOST_MOVE_ITERATE_0TO6(MACROFUNC)  MACROFUNC(7)
+#define BOOST_MOVE_ITERATE_0TO8(MACROFUNC)   BOOST_MOVE_ITERATE_0TO7(MACROFUNC)  MACROFUNC(8)
+#define BOOST_MOVE_ITERATE_0TO9(MACROFUNC)   BOOST_MOVE_ITERATE_0TO8(MACROFUNC)  MACROFUNC(9)
+
+//BOOST_MOVE_ITERATE_NTON
+#define BOOST_MOVE_ITERATE_1TO1(MACROFUNC)   MACROFUNC(1)
+#define BOOST_MOVE_ITERATE_2TO2(MACROFUNC)   MACROFUNC(2)
+#define BOOST_MOVE_ITERATE_3TO3(MACROFUNC)   MACROFUNC(3)
+#define BOOST_MOVE_ITERATE_4TO4(MACROFUNC)   MACROFUNC(4)
+#define BOOST_MOVE_ITERATE_5TO5(MACROFUNC)   MACROFUNC(5)
+#define BOOST_MOVE_ITERATE_6TO6(MACROFUNC)   MACROFUNC(6)
+#define BOOST_MOVE_ITERATE_7TO7(MACROFUNC)   MACROFUNC(7)
+#define BOOST_MOVE_ITERATE_8TO8(MACROFUNC)   MACROFUNC(8)
+#define BOOST_MOVE_ITERATE_9TO9(MACROFUNC)   MACROFUNC(9)
+
+//BOOST_MOVE_ITER2D_0TOMAX
+#define BOOST_MOVE_ITER2DLOW_0TOMAX0(MACROFUNC2D, M)                                                  MACROFUNC2D(M, 0)
+#define BOOST_MOVE_ITER2DLOW_0TOMAX1(MACROFUNC2D, M)  BOOST_MOVE_ITER2DLOW_0TOMAX0(MACROFUNC2D, M) MACROFUNC2D(M, 1)
+#define BOOST_MOVE_ITER2DLOW_0TOMAX2(MACROFUNC2D, M)  BOOST_MOVE_ITER2DLOW_0TOMAX1(MACROFUNC2D, M) MACROFUNC2D(M, 2)
+#define BOOST_MOVE_ITER2DLOW_0TOMAX3(MACROFUNC2D, M)  BOOST_MOVE_ITER2DLOW_0TOMAX2(MACROFUNC2D, M) MACROFUNC2D(M, 3)
+#define BOOST_MOVE_ITER2DLOW_0TOMAX4(MACROFUNC2D, M)  BOOST_MOVE_ITER2DLOW_0TOMAX3(MACROFUNC2D, M) MACROFUNC2D(M, 4)
+#define BOOST_MOVE_ITER2DLOW_0TOMAX5(MACROFUNC2D, M)  BOOST_MOVE_ITER2DLOW_0TOMAX4(MACROFUNC2D, M) MACROFUNC2D(M, 5)
+#define BOOST_MOVE_ITER2DLOW_0TOMAX6(MACROFUNC2D, M)  BOOST_MOVE_ITER2DLOW_0TOMAX5(MACROFUNC2D, M) MACROFUNC2D(M, 6)
+#define BOOST_MOVE_ITER2DLOW_0TOMAX7(MACROFUNC2D, M)  BOOST_MOVE_ITER2DLOW_0TOMAX6(MACROFUNC2D, M) MACROFUNC2D(M, 7)
+#define BOOST_MOVE_ITER2DLOW_0TOMAX8(MACROFUNC2D, M)  BOOST_MOVE_ITER2DLOW_0TOMAX7(MACROFUNC2D, M) MACROFUNC2D(M, 8)
+#define BOOST_MOVE_ITER2DLOW_0TOMAX9(MACROFUNC2D, M)  BOOST_MOVE_ITER2DLOW_0TOMAX8(MACROFUNC2D, M) MACROFUNC2D(M, 9)
+
+#define BOOST_MOVE_ITER2D_0TOMAX0(MAX, MACROFUNC2D)                                                   BOOST_MOVE_ITER2DLOW_0TOMAX##MAX(MACROFUNC2D, 0)
+#define BOOST_MOVE_ITER2D_0TOMAX1(MAX, MACROFUNC2D)   BOOST_MOVE_ITER2D_0TOMAX0(MAX, MACROFUNC2D)  BOOST_MOVE_ITER2DLOW_0TOMAX##MAX(MACROFUNC2D, 1)
+#define BOOST_MOVE_ITER2D_0TOMAX2(MAX, MACROFUNC2D)   BOOST_MOVE_ITER2D_0TOMAX1(MAX, MACROFUNC2D)  BOOST_MOVE_ITER2DLOW_0TOMAX##MAX(MACROFUNC2D, 2)
+#define BOOST_MOVE_ITER2D_0TOMAX3(MAX, MACROFUNC2D)   BOOST_MOVE_ITER2D_0TOMAX2(MAX, MACROFUNC2D)  BOOST_MOVE_ITER2DLOW_0TOMAX##MAX(MACROFUNC2D, 3)
+#define BOOST_MOVE_ITER2D_0TOMAX4(MAX, MACROFUNC2D)   BOOST_MOVE_ITER2D_0TOMAX3(MAX, MACROFUNC2D)  BOOST_MOVE_ITER2DLOW_0TOMAX##MAX(MACROFUNC2D, 4)
+#define BOOST_MOVE_ITER2D_0TOMAX5(MAX, MACROFUNC2D)   BOOST_MOVE_ITER2D_0TOMAX4(MAX, MACROFUNC2D)  BOOST_MOVE_ITER2DLOW_0TOMAX##MAX(MACROFUNC2D, 5)
+#define BOOST_MOVE_ITER2D_0TOMAX6(MAX, MACROFUNC2D)   BOOST_MOVE_ITER2D_0TOMAX5(MAX, MACROFUNC2D)  BOOST_MOVE_ITER2DLOW_0TOMAX##MAX(MACROFUNC2D, 6)
+#define BOOST_MOVE_ITER2D_0TOMAX7(MAX, MACROFUNC2D)   BOOST_MOVE_ITER2D_0TOMAX6(MAX, MACROFUNC2D)  BOOST_MOVE_ITER2DLOW_0TOMAX##MAX(MACROFUNC2D, 7)
+#define BOOST_MOVE_ITER2D_0TOMAX8(MAX, MACROFUNC2D)   BOOST_MOVE_ITER2D_0TOMAX7(MAX, MACROFUNC2D)  BOOST_MOVE_ITER2DLOW_0TOMAX##MAX(MACROFUNC2D, 8)
+#define BOOST_MOVE_ITER2D_0TOMAX9(MAX, MACROFUNC2D)   BOOST_MOVE_ITER2D_0TOMAX8(MAX, MACROFUNC2D)  BOOST_MOVE_ITER2DLOW_0TOMAX##MAX(MACROFUNC2D, 9)
+
+#define BOOST_MOVE_ITER2D_0TOMAX(MAX, MACROFUNC2D)    BOOST_MOVE_ITER2D_0TOMAX_I   (MAX, MACROFUNC2D)
+#define BOOST_MOVE_ITER2D_0TOMAX_I(MAX, MACROFUNC2D)  BOOST_MOVE_ITER2D_0TOMAX##MAX(MAX, MACROFUNC2D)
+
+
+
+
+//BOOST_MOVE_CAT
+#define BOOST_MOVE_CAT(a, b) BOOST_MOVE_CAT_I(a, b)
+#define BOOST_MOVE_CAT_I(a, b) a ## b
+//#    define BOOST_MOVE_CAT_I(a, b) BOOST_MOVE_CAT_II(~, a ## b)
+//#    define BOOST_MOVE_CAT_II(p, res) res
+
+#endif //#ifndef BOOST_MOVE_DETAIL_FWD_MACROS_HPP
diff --git a/include/boost/move/detail/iterator_to_raw_pointer.hpp b/include/boost/move/detail/iterator_to_raw_pointer.hpp
new file mode 100644
index 0000000..97ee3a6
--- /dev/null
+++ b/include/boost/move/detail/iterator_to_raw_pointer.hpp
@@ -0,0 +1,59 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2015. 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)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_MOVE_DETAIL_ITERATOR_TO_RAW_POINTER_HPP
+#define BOOST_MOVE_DETAIL_ITERATOR_TO_RAW_POINTER_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/iterator_traits.hpp>
+#include <boost/move/detail/to_raw_pointer.hpp>
+#include <boost/move/detail/pointer_element.hpp>
+
+namespace boost {
+namespace movelib {
+namespace detail {
+
+template <class T>
+inline T* iterator_to_pointer(T* i)
+{  return i; }
+
+template <class Iterator>
+inline typename boost::movelib::iterator_traits<Iterator>::pointer
+   iterator_to_pointer(const Iterator &i)
+{  return i.operator->();  }
+
+template <class Iterator>
+struct iterator_to_element_ptr
+{
+   typedef typename boost::movelib::iterator_traits<Iterator>::pointer  pointer;
+   typedef typename boost::movelib::pointer_element<pointer>::type      element_type;
+   typedef element_type* type;
+};
+
+}  //namespace detail {
+
+template <class Iterator>
+inline typename boost::movelib::detail::iterator_to_element_ptr<Iterator>::type
+   iterator_to_raw_pointer(const Iterator &i)
+{
+   return ::boost::movelib::to_raw_pointer
+      (  ::boost::movelib::detail::iterator_to_pointer(i)   );
+}
+
+}  //namespace movelib {
+}  //namespace boost {
+
+#endif   //#ifndef BOOST_MOVE_DETAIL_ITERATOR_TO_RAW_POINTER_HPP
diff --git a/include/boost/move/detail/iterator_traits.hpp b/include/boost/move/detail/iterator_traits.hpp
new file mode 100644
index 0000000..5ffcb2c
--- /dev/null
+++ b/include/boost/move/detail/iterator_traits.hpp
@@ -0,0 +1,77 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2014.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
+
+#ifndef BOOST_MOVE_DETAIL_ITERATOR_TRAITS_HPP
+#define BOOST_MOVE_DETAIL_ITERATOR_TRAITS_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <cstddef>
+#include <boost/move/detail/type_traits.hpp>
+
+#include <boost/move/detail/std_ns_begin.hpp>
+BOOST_MOVE_STD_NS_BEG
+
+struct input_iterator_tag;
+struct forward_iterator_tag;
+struct bidirectional_iterator_tag;
+struct random_access_iterator_tag;
+struct output_iterator_tag;
+
+BOOST_MOVE_STD_NS_END
+#include <boost/move/detail/std_ns_end.hpp>
+
+namespace boost{  namespace movelib{
+
+template<class Iterator>
+struct iterator_traits
+{
+   typedef typename Iterator::difference_type   difference_type;
+   typedef typename Iterator::value_type        value_type;
+   typedef typename Iterator::pointer           pointer;
+   typedef typename Iterator::reference         reference;
+   typedef typename Iterator::iterator_category iterator_category;
+   typedef typename boost::move_detail::make_unsigned<difference_type>::type size_type;
+};
+
+template<class T>
+struct iterator_traits<T*>
+{
+   typedef std::ptrdiff_t                    difference_type;
+   typedef T                                 value_type;
+   typedef T*                                pointer;
+   typedef T&                                reference;
+   typedef std::random_access_iterator_tag   iterator_category;
+   typedef typename boost::move_detail::make_unsigned<difference_type>::type size_type;
+};
+
+template<class T>
+struct iterator_traits<const T*>
+{
+   typedef std::ptrdiff_t                    difference_type;
+   typedef T                                 value_type;
+   typedef const T*                          pointer;
+   typedef const T&                          reference;
+   typedef std::random_access_iterator_tag   iterator_category;
+   typedef typename boost::move_detail::make_unsigned<difference_type>::type size_type;
+};
+
+}} //namespace boost {  namespace movelib{
+
+#endif //#ifndef BOOST_MOVE_DETAIL_ITERATOR_TRAITS_HPP
diff --git a/include/boost/move/detail/meta_utils.hpp b/include/boost/move/detail/meta_utils.hpp
new file mode 100644
index 0000000..e45394c
--- /dev/null
+++ b/include/boost/move/detail/meta_utils.hpp
@@ -0,0 +1,585 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2012-2015.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
+
+#ifndef BOOST_MOVE_DETAIL_META_UTILS_HPP
+#define BOOST_MOVE_DETAIL_META_UTILS_HPP
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/detail/workaround.hpp>  //forceinline
+#include <boost/move/detail/meta_utils_core.hpp>
+#include <cstddef>   //for std::size_t
+
+//Small meta-typetraits to support move
+
+namespace boost {
+
+//Forward declare boost::rv
+template <class T> class rv;
+
+namespace move_detail {
+
+//////////////////////////////////////
+//          is_different
+//////////////////////////////////////
+template<class T, class U>
+struct is_different
+{
+   static const bool value = !is_same<T, U>::value;
+};
+
+//////////////////////////////////////
+//             apply
+//////////////////////////////////////
+template<class F, class Param>
+struct apply
+{
+   typedef typename F::template apply<Param>::type type;
+};
+
+//////////////////////////////////////
+//             bool_
+//////////////////////////////////////
+
+template< bool C_ >
+struct bool_ : integral_constant<bool, C_>
+{
+     operator bool() const { return C_; }
+   bool operator()() const { return C_; }
+};
+
+typedef bool_<true>        true_;
+typedef bool_<false>       false_;
+
+//////////////////////////////////////
+//              nat
+//////////////////////////////////////
+struct nat{};
+
+//////////////////////////////////////
+//          yes_type/no_type
+//////////////////////////////////////
+typedef char yes_type;
+
+struct no_type
+{
+   char _[2];
+};
+
+//////////////////////////////////////
+//            natify
+//////////////////////////////////////
+template <class T> struct natify{};
+
+//////////////////////////////////////
+//          remove_reference
+//////////////////////////////////////
+template<class T>
+struct remove_reference
+{
+   typedef T type;
+};
+
+template<class T>
+struct remove_reference<T&>
+{
+   typedef T type;
+};
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+template<class T>
+struct remove_reference<T&&>
+{
+   typedef T type;
+};
+
+#else
+
+template<class T>
+struct remove_reference< rv<T> >
+{
+   typedef T type;
+};
+
+template<class T>
+struct remove_reference< rv<T> &>
+{
+   typedef T type;
+};
+
+template<class T>
+struct remove_reference< const rv<T> &>
+{
+   typedef T type;
+};
+
+#endif
+
+//////////////////////////////////////
+//             remove_pointer
+//////////////////////////////////////
+
+template< class T > struct remove_pointer                    { typedef T type;   };
+template< class T > struct remove_pointer<T*>                { typedef T type;   };
+template< class T > struct remove_pointer<T* const>          { typedef T type;   };
+template< class T > struct remove_pointer<T* volatile>       { typedef T type;   };
+template< class T > struct remove_pointer<T* const volatile> { typedef T type;   };
+
+//////////////////////////////////////
+//             add_pointer
+//////////////////////////////////////
+template< class T >
+struct add_pointer
+{
+   typedef typename remove_reference<T>::type* type;
+};
+
+//////////////////////////////////////
+//             add_const
+//////////////////////////////////////
+template<class T>
+struct add_const
+{
+   typedef const T type;
+};
+
+template<class T>
+struct add_const<T&>
+{
+   typedef const T& type;
+};
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+template<class T>
+struct add_const<T&&>
+{
+   typedef T&& type;
+};
+
+#endif
+
+//////////////////////////////////////
+//      add_lvalue_reference
+//////////////////////////////////////
+template<class T>
+struct add_lvalue_reference
+{  typedef T& type;  };
+
+template<class T> struct add_lvalue_reference<T&>                 {  typedef T& type;  };
+template<>        struct add_lvalue_reference<void>               {  typedef void type;   };
+template<>        struct add_lvalue_reference<const void>         {  typedef const void type;  };
+template<>        struct add_lvalue_reference<volatile void>      {  typedef volatile void type;   };
+template<>        struct add_lvalue_reference<const volatile void>{  typedef const volatile void type;   };
+
+template<class T>
+struct add_const_lvalue_reference
+{
+   typedef typename remove_reference<T>::type         t_unreferenced;
+   typedef typename add_const<t_unreferenced>::type   t_unreferenced_const;
+   typedef typename add_lvalue_reference
+      <t_unreferenced_const>::type                    type;
+};
+
+//////////////////////////////////////
+//             is_lvalue_reference
+//////////////////////////////////////
+template<class T>
+struct is_lvalue_reference
+{
+    static const bool value = false;
+};
+
+template<class T>
+struct is_lvalue_reference<T&>
+{
+    static const bool value = true;
+};
+
+
+//////////////////////////////////////
+//             identity
+//////////////////////////////////////
+template <class T>
+struct identity
+{
+   typedef T type;
+   typedef typename add_const_lvalue_reference<T>::type reference;
+   reference operator()(reference t)
+   {  return t;   }
+};
+
+//////////////////////////////////////
+//          is_class_or_union
+//////////////////////////////////////
+template<class T>
+struct is_class_or_union
+{
+   struct twochar { char dummy[2]; };
+   template <class U>
+   static char is_class_or_union_tester(void(U::*)(void));
+   template <class U>
+   static twochar is_class_or_union_tester(...);
+   static const bool value = sizeof(is_class_or_union_tester<T>(0)) == sizeof(char);
+};
+
+//////////////////////////////////////
+//             addressof
+//////////////////////////////////////
+template<class T>
+struct addr_impl_ref
+{
+   T & v_;
+   BOOST_MOVE_FORCEINLINE addr_impl_ref( T & v ): v_( v ) {}
+   BOOST_MOVE_FORCEINLINE operator T& () const { return v_; }
+
+   private:
+   addr_impl_ref & operator=(const addr_impl_ref &);
+};
+
+template<class T>
+struct addressof_impl
+{
+   BOOST_MOVE_FORCEINLINE static T * f( T & v, long )
+   {
+      return reinterpret_cast<T*>(
+         &const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
+   }
+
+   BOOST_MOVE_FORCEINLINE static T * f( T * v, int )
+   {  return v;  }
+};
+
+template<class T>
+BOOST_MOVE_FORCEINLINE T * addressof( T & v )
+{
+   return ::boost::move_detail::addressof_impl<T>::f
+      ( ::boost::move_detail::addr_impl_ref<T>( v ), 0 );
+}
+
+//////////////////////////////////////
+//          has_pointer_type
+//////////////////////////////////////
+template <class T>
+struct has_pointer_type
+{
+   struct two { char c[2]; };
+   template <class U> static two test(...);
+   template <class U> static char test(typename U::pointer* = 0);
+   static const bool value = sizeof(test<T>(0)) == 1;
+};
+
+//////////////////////////////////////
+//           is_convertible
+//////////////////////////////////////
+#if defined(_MSC_VER) && (_MSC_VER >= 1400)
+
+//use intrinsic since in MSVC
+//overaligned types can't go through ellipsis
+template <class T, class U>
+struct is_convertible
+{
+   static const bool value = __is_convertible_to(T, U);
+};
+
+#else
+
+template <class T, class U>
+class is_convertible
+{
+   typedef typename add_lvalue_reference<T>::type t_reference;
+   typedef char true_t;
+   class false_t { char dummy[2]; };
+   static false_t dispatch(...);
+   static true_t  dispatch(U);
+   static t_reference       trigger();
+   public:
+   static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
+};
+
+#endif
+
+template <class T, class U, bool IsSame = is_same<T, U>::value>
+struct is_same_or_convertible
+   : is_convertible<T, U>
+{};
+
+template <class T, class U>
+struct is_same_or_convertible<T, U, true>
+{
+   static const bool value = true;
+};
+
+template<
+      bool C
+    , typename F1
+    , typename F2
+    >
+struct eval_if_c
+    : if_c<C,F1,F2>::type
+{};
+
+template<
+      typename C
+    , typename T1
+    , typename T2
+    >
+struct eval_if
+    : if_<C,T1,T2>::type
+{};
+
+
+#if defined(BOOST_GCC) && (BOOST_GCC <= 40000)
+#define BOOST_MOVE_HELPERS_RETURN_SFINAE_BROKEN
+#endif
+
+template<class T, class U, class R = void>
+struct enable_if_convertible
+   : enable_if< is_convertible<T, U>, R>
+{};
+
+template<class T, class U, class R = void>
+struct disable_if_convertible
+   : disable_if< is_convertible<T, U>, R>
+{};
+
+template<class T, class U, class R = void>
+struct enable_if_same_or_convertible
+   : enable_if< is_same_or_convertible<T, U>, R>
+{};
+
+template<class T, class U, class R = void>
+struct disable_if_same_or_convertible
+   : disable_if< is_same_or_convertible<T, U>, R>
+{};
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                         and_
+//
+//////////////////////////////////////////////////////////////////////////////
+template<bool, class B = true_, class C = true_, class D = true_>
+struct and_impl
+   : and_impl<B::value, C, D>
+{};
+
+template<>
+struct and_impl<true, true_, true_, true_>
+{
+   static const bool value = true;
+};
+
+template<class B, class C, class D>
+struct and_impl<false, B, C, D>
+{
+   static const bool value = false;
+};
+
+template<class A, class B, class C = true_, class D = true_>
+struct and_
+   : and_impl<A::value, B, C, D>
+{};
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                            or_
+//
+//////////////////////////////////////////////////////////////////////////////
+template<bool, class B = false_, class C = false_, class D = false_>
+struct or_impl
+   : or_impl<B::value, C, D>
+{};
+
+template<>
+struct or_impl<false, false_, false_, false_>
+{
+   static const bool value = false;
+};
+
+template<class B, class C, class D>
+struct or_impl<true, B, C, D>
+{
+   static const bool value = true;
+};
+
+template<class A, class B, class C = false_, class D = false_>
+struct or_
+   : or_impl<A::value, B, C, D>
+{};
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                         not_
+//
+//////////////////////////////////////////////////////////////////////////////
+template<class T>
+struct not_
+{
+   static const bool value = !T::value;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// enable_if_and / disable_if_and / enable_if_or / disable_if_or
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template<class R, class A, class B, class C = true_, class D = true_>
+struct enable_if_and
+   : enable_if_c< and_<A, B, C, D>::value, R>
+{};
+
+template<class R, class A, class B, class C = true_, class D = true_>
+struct disable_if_and
+   : disable_if_c< and_<A, B, C, D>::value, R>
+{};
+
+template<class R, class A, class B, class C = false_, class D = false_>
+struct enable_if_or
+   : enable_if_c< or_<A, B, C, D>::value, R>
+{};
+
+template<class R, class A, class B, class C = false_, class D = false_>
+struct disable_if_or
+   : disable_if_c< or_<A, B, C, D>::value, R>
+{};
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                      has_move_emulation_enabled_impl
+//
+//////////////////////////////////////////////////////////////////////////////
+template<class T>
+struct has_move_emulation_enabled_impl
+   : is_convertible< T, ::boost::rv<T>& >
+{};
+
+template<class T>
+struct has_move_emulation_enabled_impl<T&>
+{  static const bool value = false;  };
+
+template<class T>
+struct has_move_emulation_enabled_impl< ::boost::rv<T> >
+{  static const bool value = false;  };
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                            is_rv_impl
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template <class T>
+struct is_rv_impl
+{  static const bool value = false;  };
+
+template <class T>
+struct is_rv_impl< rv<T> >
+{  static const bool value = true;  };
+
+template <class T>
+struct is_rv_impl< const rv<T> >
+{  static const bool value = true;  };
+
+// Code from Jeffrey Lee Hellrung, many thanks
+
+template< class T >
+struct is_rvalue_reference
+{  static const bool value = false;  };
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+template< class T >
+struct is_rvalue_reference< T&& >
+{  static const bool value = true;  };
+
+#else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+template< class T >
+struct is_rvalue_reference< boost::rv<T>& >
+{  static const bool value = true;  };
+
+template< class T >
+struct is_rvalue_reference< const boost::rv<T>& >
+{  static const bool value = true;  };
+
+#endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+template< class T >
+struct add_rvalue_reference
+{ typedef T&& type; };
+
+#else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+namespace detail_add_rvalue_reference
+{
+   template< class T
+            , bool emulation = has_move_emulation_enabled_impl<T>::value
+            , bool rv        = is_rv_impl<T>::value  >
+   struct add_rvalue_reference_impl { typedef T type; };
+
+   template< class T, bool emulation>
+   struct add_rvalue_reference_impl< T, emulation, true > { typedef T & type; };
+
+   template< class T, bool rv >
+   struct add_rvalue_reference_impl< T, true, rv > { typedef ::boost::rv<T>& type; };
+} // namespace detail_add_rvalue_reference
+
+template< class T >
+struct add_rvalue_reference
+   : detail_add_rvalue_reference::add_rvalue_reference_impl<T>
+{ };
+
+template< class T >
+struct add_rvalue_reference<T &>
+{  typedef T & type; };
+
+#endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+template< class T > struct remove_rvalue_reference { typedef T type; };
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+   template< class T > struct remove_rvalue_reference< T&& >                  { typedef T type; };
+#else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+   template< class T > struct remove_rvalue_reference< rv<T> >                { typedef T type; };
+   template< class T > struct remove_rvalue_reference< const rv<T> >          { typedef T type; };
+   template< class T > struct remove_rvalue_reference< volatile rv<T> >       { typedef T type; };
+   template< class T > struct remove_rvalue_reference< const volatile rv<T> > { typedef T type; };
+   template< class T > struct remove_rvalue_reference< rv<T>& >               { typedef T type; };
+   template< class T > struct remove_rvalue_reference< const rv<T>& >         { typedef T type; };
+   template< class T > struct remove_rvalue_reference< volatile rv<T>& >      { typedef T type; };
+   template< class T > struct remove_rvalue_reference< const volatile rv<T>& >{ typedef T type; };
+#endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+// Ideas from Boost.Move review, Jeffrey Lee Hellrung:
+//
+//- TypeTraits metafunctions is_lvalue_reference, add_lvalue_reference, and remove_lvalue_reference ?
+//  Perhaps add_reference and remove_reference can be modified so that they behave wrt emulated rvalue
+//  references the same as wrt real rvalue references, i.e., add_reference< rv<T>& > -> T& rather than
+//  rv<T>& (since T&& & -> T&).
+//
+//- Add'l TypeTraits has_[trivial_]move_{constructor,assign}...?
+//
+//- An as_lvalue(T& x) function, which amounts to an identity operation in C++0x, but strips emulated
+//  rvalue references in C++03.  This may be necessary to prevent "accidental moves".
+
+}  //namespace move_detail {
+}  //namespace boost {
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_MOVE_DETAIL_META_UTILS_HPP
diff --git a/include/boost/move/detail/meta_utils_core.hpp b/include/boost/move/detail/meta_utils_core.hpp
new file mode 100644
index 0000000..40dbb6e
--- /dev/null
+++ b/include/boost/move/detail/meta_utils_core.hpp
@@ -0,0 +1,132 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2015.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
+
+#ifndef BOOST_MOVE_DETAIL_META_UTILS_CORE_HPP
+#define BOOST_MOVE_DETAIL_META_UTILS_CORE_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+//Small meta-typetraits to support move
+
+namespace boost {
+namespace move_detail {
+
+//////////////////////////////////////
+//             if_c
+//////////////////////////////////////
+template<bool C, typename T1, typename T2>
+struct if_c
+{
+   typedef T1 type;
+};
+
+template<typename T1, typename T2>
+struct if_c<false,T1,T2>
+{
+   typedef T2 type;
+};
+
+//////////////////////////////////////
+//             if_
+//////////////////////////////////////
+template<typename T1, typename T2, typename T3>
+struct if_ : if_c<0 != T1::value, T2, T3>
+{};
+
+//////////////////////////////////////
+//          enable_if_c
+//////////////////////////////////////
+template <bool B, class T = void>
+struct enable_if_c
+{
+   typedef T type;
+};
+
+template <class T>
+struct enable_if_c<false, T> {};
+
+//////////////////////////////////////
+//           enable_if
+//////////////////////////////////////
+template <class Cond, class T = void>
+struct enable_if : enable_if_c<Cond::value, T> {};
+
+//////////////////////////////////////
+//          disable_if_c
+//////////////////////////////////////
+template <bool B, class T = void>
+struct disable_if_c
+   : enable_if_c<!B, T>
+{};
+
+//////////////////////////////////////
+//          disable_if
+//////////////////////////////////////
+template <class Cond, class T = void>
+struct disable_if : enable_if_c<!Cond::value, T> {};
+
+//////////////////////////////////////
+//          integral_constant
+//////////////////////////////////////
+template<class T, T v>
+struct integral_constant
+{
+   static const T value = v;
+   typedef T value_type;
+   typedef integral_constant<T, v> type;
+
+     operator T() const { return value; }
+   T operator()() const { return value; }
+};
+
+typedef integral_constant<bool, true >  true_type;
+typedef integral_constant<bool, false > false_type;
+
+
+//////////////////////////////////////
+//             is_same
+//////////////////////////////////////
+template<class T, class U>
+struct is_same
+{
+   static const bool value = false;
+};
+ 
+template<class T>
+struct is_same<T, T>
+{
+   static const bool value = true;
+};
+
+//////////////////////////////////////
+//        enable_if_same
+//////////////////////////////////////
+template <class T, class U, class R = void>
+struct enable_if_same : enable_if<is_same<T, U>, R> {};
+
+//////////////////////////////////////
+//        disable_if_same
+//////////////////////////////////////
+template <class T, class U, class R = void>
+struct disable_if_same : disable_if<is_same<T, U>, R> {};
+
+}  //namespace move_detail {
+}  //namespace boost {
+
+#endif //#ifndef BOOST_MOVE_DETAIL_META_UTILS_CORE_HPP
diff --git a/include/boost/move/detail/move_helpers.hpp b/include/boost/move/detail/move_helpers.hpp
new file mode 100644
index 0000000..1713844
--- /dev/null
+++ b/include/boost/move/detail/move_helpers.hpp
@@ -0,0 +1,256 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2010-2016.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_MOVE_MOVE_HELPERS_HPP
+#define BOOST_MOVE_MOVE_HELPERS_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/core.hpp>
+#include <boost/move/utility_core.hpp>
+#include <boost/move/detail/type_traits.hpp>
+
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+#define BOOST_MOVE_CATCH_CONST(U)  \
+   typename ::boost::move_detail::if_< ::boost::move_detail::is_class<U>, BOOST_CATCH_CONST_RLVALUE(U), const U &>::type
+#define BOOST_MOVE_CATCH_RVALUE(U)\
+   typename ::boost::move_detail::if_< ::boost::move_detail::is_class<U>, BOOST_RV_REF(U), ::boost::move_detail::nat>::type
+#define BOOST_MOVE_CATCH_FWD(U) BOOST_FWD_REF(U)
+#else
+#define BOOST_MOVE_CATCH_CONST(U)  const U &
+#define BOOST_MOVE_CATCH_RVALUE(U) U &&
+#define BOOST_MOVE_CATCH_FWD(U)    U &&
+#endif
+
+////////////////////////////////////////
+//
+// BOOST_MOVE_CONVERSION_AWARE_CATCH
+//
+////////////////////////////////////////
+
+#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+   template<class RETURN_VALUE, class BOOST_MOVE_TEMPL_PARAM, class TYPE>
+   struct boost_move_conversion_aware_catch_1
+      : public ::boost::move_detail::enable_if_and
+                        < RETURN_VALUE
+                        , ::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM>
+                        , ::boost::move_detail::is_class<TYPE>
+                        , ::boost::has_move_emulation_disabled<BOOST_MOVE_TEMPL_PARAM>
+                        >
+   {};
+
+   template<class RETURN_VALUE, class BOOST_MOVE_TEMPL_PARAM, class TYPE>
+   struct boost_move_conversion_aware_catch_2
+      : public ::boost::move_detail::disable_if_or
+                        < RETURN_VALUE
+                        , ::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM> 
+                        , ::boost::move_detail::is_rv_impl<BOOST_MOVE_TEMPL_PARAM>
+                        , ::boost::move_detail::and_
+                                    < ::boost::move_detail::is_rv_impl<BOOST_MOVE_TEMPL_PARAM>
+                                    , ::boost::move_detail::is_class<BOOST_MOVE_TEMPL_PARAM>
+                                    >
+                        >
+   {};
+
+   #define BOOST_MOVE_CONVERSION_AWARE_CATCH_COMMON(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\
+      BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_CONST(TYPE) x)\
+      {  return FWD_FUNCTION(static_cast<const TYPE&>(x)); }\
+      \
+      BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_RVALUE(TYPE) x) \
+      {  return FWD_FUNCTION(::boost::move(x));  }\
+      \
+      BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(TYPE &x)\
+      {  return FWD_FUNCTION(const_cast<const TYPE &>(x)); }\
+   //
+   #if defined(BOOST_MOVE_HELPERS_RETURN_SFINAE_BROKEN)
+      #define BOOST_MOVE_CONVERSION_AWARE_CATCH(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\
+         BOOST_MOVE_CONVERSION_AWARE_CATCH_COMMON(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\
+         \
+         template<class BOOST_MOVE_TEMPL_PARAM>\
+         BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u,\
+            typename boost_move_conversion_aware_catch_1< ::boost::move_detail::nat, BOOST_MOVE_TEMPL_PARAM, TYPE>::type* = 0)\
+         { return FWD_FUNCTION(u); }\
+         \
+         template<class BOOST_MOVE_TEMPL_PARAM>\
+         BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u,\
+            typename boost_move_conversion_aware_catch_2< ::boost::move_detail::nat, BOOST_MOVE_TEMPL_PARAM, TYPE>::type* = 0)\
+         {\
+            TYPE t((u));\
+            return FWD_FUNCTION(::boost::move(t));\
+         }\
+      //
+   #else
+      #define BOOST_MOVE_CONVERSION_AWARE_CATCH(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\
+         BOOST_MOVE_CONVERSION_AWARE_CATCH_COMMON(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\
+         \
+         template<class BOOST_MOVE_TEMPL_PARAM>\
+         BOOST_MOVE_FORCEINLINE typename boost_move_conversion_aware_catch_1<RETURN_VALUE, BOOST_MOVE_TEMPL_PARAM, TYPE>::type\
+            PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u)\
+         { return FWD_FUNCTION(u); }\
+         \
+         template<class BOOST_MOVE_TEMPL_PARAM>\
+         BOOST_MOVE_FORCEINLINE typename boost_move_conversion_aware_catch_2<RETURN_VALUE, BOOST_MOVE_TEMPL_PARAM, TYPE>::type\
+            PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u)\
+         {\
+            TYPE t((u));\
+            return FWD_FUNCTION(::boost::move(t));\
+         }\
+      //
+   #endif
+#elif (defined(_MSC_VER) && (_MSC_VER == 1600))
+
+   #define BOOST_MOVE_CONVERSION_AWARE_CATCH(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\
+      BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_CONST(TYPE) x)\
+      {  return FWD_FUNCTION(static_cast<const TYPE&>(x)); }\
+      \
+      BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_RVALUE(TYPE) x) \
+      {  return FWD_FUNCTION(::boost::move(x));  }\
+      \
+      template<class BOOST_MOVE_TEMPL_PARAM>\
+      BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c\
+                        < !::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM>::value\
+                        , RETURN_VALUE >::type\
+      PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u)\
+      {\
+         TYPE t((u));\
+         return FWD_FUNCTION(::boost::move(t));\
+      }\
+   //
+
+#else    //BOOST_NO_CXX11_RVALUE_REFERENCES
+
+   #define BOOST_MOVE_CONVERSION_AWARE_CATCH(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\
+      BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_CONST(TYPE) x)\
+      {  return FWD_FUNCTION(x); }\
+      \
+      BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_RVALUE(TYPE) x) \
+      {  return FWD_FUNCTION(::boost::move(x));  }\
+   //
+
+#endif   //BOOST_NO_CXX11_RVALUE_REFERENCES
+
+////////////////////////////////////////
+//
+// BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG
+//
+////////////////////////////////////////
+
+#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+   template<class RETURN_VALUE, class BOOST_MOVE_TEMPL_PARAM, class UNLESS_CONVERTIBLE_TO, class TYPE>
+   struct boost_move_conversion_aware_catch_1arg_1
+      : public ::boost::move_detail::enable_if_and
+                        < RETURN_VALUE
+                        , ::boost::move_detail::not_< ::boost::move_detail::is_same_or_convertible<BOOST_MOVE_TEMPL_PARAM, UNLESS_CONVERTIBLE_TO> >
+                        , ::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM>
+                        , ::boost::has_move_emulation_disabled<BOOST_MOVE_TEMPL_PARAM>
+                        >
+   {};
+
+   template<class RETURN_VALUE, class BOOST_MOVE_TEMPL_PARAM, class UNLESS_CONVERTIBLE_TO, class TYPE>
+   struct boost_move_conversion_aware_catch_1arg_2
+      : public ::boost::move_detail::disable_if_or
+                        < RETURN_VALUE
+                        , ::boost::move_detail::is_same_or_convertible< BOOST_MOVE_TEMPL_PARAM, UNLESS_CONVERTIBLE_TO>
+                        , ::boost::move_detail::is_rv_impl<BOOST_MOVE_TEMPL_PARAM>
+                        , ::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM>
+                        >
+   {};
+
+   #define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG_COMMON(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\
+      BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_CONST(TYPE) x)\
+      {  return FWD_FUNCTION(arg1, static_cast<const TYPE&>(x)); }\
+      \
+      BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_RVALUE(TYPE) x) \
+      {  return FWD_FUNCTION(arg1, ::boost::move(x));  }\
+      \
+      BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, TYPE &x)\
+      {  return FWD_FUNCTION(arg1, const_cast<const TYPE &>(x)); }\
+   //
+   #if defined(BOOST_MOVE_HELPERS_RETURN_SFINAE_BROKEN)
+      #define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\
+         BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG_COMMON(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\
+         \
+         template<class BOOST_MOVE_TEMPL_PARAM>\
+         BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u,\
+            typename boost_move_conversion_aware_catch_1arg_1<void, BOOST_MOVE_TEMPL_PARAM, UNLESS_CONVERTIBLE_TO, TYPE>::type* = 0)\
+         { return FWD_FUNCTION(arg1, u); }\
+         \
+         template<class BOOST_MOVE_TEMPL_PARAM>\
+         BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u,\
+            typename boost_move_conversion_aware_catch_1arg_2<void, BOOST_MOVE_TEMPL_PARAM, UNLESS_CONVERTIBLE_TO, TYPE>::type* = 0)\
+         {\
+            TYPE t((u));\
+            return FWD_FUNCTION(arg1, ::boost::move(t));\
+         }\
+      //
+   #else
+      #define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\
+         BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG_COMMON(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\
+         \
+         template<class BOOST_MOVE_TEMPL_PARAM>\
+         BOOST_MOVE_FORCEINLINE typename boost_move_conversion_aware_catch_1arg_1<RETURN_VALUE, BOOST_MOVE_TEMPL_PARAM, UNLESS_CONVERTIBLE_TO, TYPE>::type\
+            PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\
+         { return FWD_FUNCTION(arg1, u); }\
+         \
+         template<class BOOST_MOVE_TEMPL_PARAM>\
+         BOOST_MOVE_FORCEINLINE typename boost_move_conversion_aware_catch_1arg_2<RETURN_VALUE, BOOST_MOVE_TEMPL_PARAM, UNLESS_CONVERTIBLE_TO, TYPE>::type\
+            PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\
+         {\
+            TYPE t((u));\
+            return FWD_FUNCTION(arg1, ::boost::move(t));\
+         }\
+      //
+   #endif
+
+#elif (defined(_MSC_VER) && (_MSC_VER == 1600))
+
+   #define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\
+      BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_CONST(TYPE) x)\
+      {  return FWD_FUNCTION(arg1, static_cast<const TYPE&>(x)); }\
+      \
+      BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_RVALUE(TYPE) x) \
+      {  return FWD_FUNCTION(arg1, ::boost::move(x));  }\
+      \
+      template<class BOOST_MOVE_TEMPL_PARAM>\
+      BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::disable_if_or\
+                        < RETURN_VALUE \
+                        , ::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM> \
+                        , ::boost::move_detail::is_same_or_convertible<BOOST_MOVE_TEMPL_PARAM, UNLESS_CONVERTIBLE_TO> \
+                        >::type\
+      PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\
+      {\
+         TYPE t((u));\
+         return FWD_FUNCTION(arg1, ::boost::move(t));\
+      }\
+   //
+
+#else
+
+   #define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\
+      BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_CONST(TYPE) x)\
+      {  return FWD_FUNCTION(arg1, static_cast<const TYPE&>(x)); }\
+      \
+      BOOST_MOVE_FORCEINLINE RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_RVALUE(TYPE) x) \
+      {  return FWD_FUNCTION(arg1, ::boost::move(x));  }\
+   //
+
+#endif
+
+#endif //#ifndef BOOST_MOVE_MOVE_HELPERS_HPP
diff --git a/include/boost/move/detail/placement_new.hpp b/include/boost/move/detail/placement_new.hpp
new file mode 100644
index 0000000..69d3332
--- /dev/null
+++ b/include/boost/move/detail/placement_new.hpp
@@ -0,0 +1,30 @@
+#ifndef BOOST_MOVE_DETAIL_PLACEMENT_NEW_HPP
+#define BOOST_MOVE_DETAIL_PLACEMENT_NEW_HPP
+///////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2015. 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)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+struct boost_move_new_t{};
+
+//avoid including <new>
+inline void *operator new(std::size_t, void *p, boost_move_new_t)
+{  return p;  }
+
+inline void operator delete(void *, void *, boost_move_new_t)
+{}
+
+#endif   //BOOST_MOVE_DETAIL_PLACEMENT_NEW_HPP
diff --git a/include/boost/move/detail/pointer_element.hpp b/include/boost/move/detail/pointer_element.hpp
new file mode 100644
index 0000000..ecdd608
--- /dev/null
+++ b/include/boost/move/detail/pointer_element.hpp
@@ -0,0 +1,168 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2017. 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_MOVE_DETAIL_POINTER_ELEMENT_HPP
+#define BOOST_MOVE_DETAIL_POINTER_ELEMENT_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#ifndef BOOST_MOVE_DETAIL_WORKAROUND_HPP
+#include <boost/move/detail/workaround.hpp>
+#endif   //BOOST_MOVE_DETAIL_WORKAROUND_HPP
+
+namespace boost {
+namespace movelib {
+namespace detail{
+
+//////////////////////
+//struct first_param
+//////////////////////
+
+template <typename T> struct first_param
+{  typedef void type;   };
+
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+   template <template <typename, typename...> class TemplateClass, typename T, typename... Args>
+   struct first_param< TemplateClass<T, Args...> >
+   {
+      typedef T type;
+   };
+
+#else //C++03 compilers
+
+   template < template  //0arg
+               <class
+               > class TemplateClass, class T
+            >
+   struct first_param
+      < TemplateClass<T> >
+   {  typedef T type;   };
+
+   template < template  //1arg
+               <class,class
+               > class TemplateClass, class T
+            , class P0>
+   struct first_param
+      < TemplateClass<T, P0> >
+   {  typedef T type;   };
+
+   template < template  //2arg
+               <class,class,class
+               > class TemplateClass, class T
+            , class P0, class P1>
+   struct first_param
+      < TemplateClass<T, P0, P1> >
+   {  typedef T type;   };
+
+   template < template  //3arg
+               <class,class,class,class
+               > class TemplateClass, class T
+            , class P0, class P1, class P2>
+   struct first_param
+      < TemplateClass<T, P0, P1, P2> >
+   {  typedef T type;   };
+
+   template < template  //4arg
+               <class,class,class,class,class
+               > class TemplateClass, class T
+            , class P0, class P1, class P2, class P3>
+   struct first_param
+      < TemplateClass<T, P0, P1, P2, P3> >
+   {  typedef T type;   };
+
+   template < template  //5arg
+               <class,class,class,class,class,class
+               > class TemplateClass, class T
+            , class P0, class P1, class P2, class P3, class P4>
+   struct first_param
+      < TemplateClass<T, P0, P1, P2, P3, P4> >
+   {  typedef T type;   };
+
+   template < template  //6arg
+               <class,class,class,class,class,class,class
+               > class TemplateClass, class T
+            , class P0, class P1, class P2, class P3, class P4, class P5>
+   struct first_param
+      < TemplateClass<T, P0, P1, P2, P3, P4, P5> >
+   {  typedef T type;   };
+
+   template < template  //7arg
+               <class,class,class,class,class,class,class,class
+               > class TemplateClass, class T
+            , class P0, class P1, class P2, class P3, class P4, class P5, class P6>
+   struct first_param
+      < TemplateClass<T, P0, P1, P2, P3, P4, P5, P6> >
+   {  typedef T type;   };
+
+   template < template  //8arg
+               <class,class,class,class,class,class,class,class,class
+               > class TemplateClass, class T
+            , class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7>
+   struct first_param
+      < TemplateClass<T, P0, P1, P2, P3, P4, P5, P6, P7> >
+   {  typedef T type;   };
+
+   template < template  //9arg
+               <class,class,class,class,class,class,class,class,class,class
+               > class TemplateClass, class T
+            , class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
+   struct first_param
+      < TemplateClass<T, P0, P1, P2, P3, P4, P5, P6, P7, P8> >
+   {  typedef T type;   };
+
+#endif   //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+template <typename T>
+struct has_internal_pointer_element
+{
+   template <typename X>
+   static char test(int, typename X::element_type*);
+
+   template <typename X>
+   static int test(...);
+
+   static const bool value = (1 == sizeof(test<T>(0, 0)));
+};
+
+template<class Ptr, bool = has_internal_pointer_element<Ptr>::value>
+struct pointer_element_impl
+{
+   typedef typename Ptr::element_type type;
+};
+
+template<class Ptr>
+struct pointer_element_impl<Ptr, false>
+{
+   typedef typename boost::movelib::detail::first_param<Ptr>::type type;
+};
+
+}  //namespace detail{
+
+template <typename Ptr>
+struct pointer_element
+{
+   typedef typename ::boost::movelib::detail::pointer_element_impl<Ptr>::type type;
+};
+
+template <typename T>
+struct pointer_element<T*>
+{  typedef T type; };
+
+}  //namespace movelib {
+}  //namespace boost {
+
+#endif // defined(BOOST_MOVE_DETAIL_POINTER_ELEMENT_HPP)
diff --git a/include/boost/move/detail/reverse_iterator.hpp b/include/boost/move/detail/reverse_iterator.hpp
new file mode 100644
index 0000000..73f59ce
--- /dev/null
+++ b/include/boost/move/detail/reverse_iterator.hpp
@@ -0,0 +1,171 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2014-2014
+//
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_MOVE_DETAIL_REVERSE_ITERATOR_HPP
+#define BOOST_MOVE_DETAIL_REVERSE_ITERATOR_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/detail/iterator_traits.hpp>
+#include <boost/move/detail/meta_utils.hpp>
+
+namespace boost {
+namespace movelib {
+
+template<class It>
+class reverse_iterator
+{
+   public:
+   typedef typename boost::movelib::iterator_traits<It>::pointer             pointer;
+   typedef typename boost::movelib::iterator_traits<It>::reference           reference;
+   typedef typename boost::movelib::iterator_traits<It>::difference_type     difference_type;
+   typedef typename boost::movelib::iterator_traits<It>::iterator_category   iterator_category;
+   typedef typename boost::movelib::iterator_traits<It>::value_type          value_type;
+
+
+   typedef It iterator_type;
+
+   reverse_iterator()
+      : m_current()  //Value initialization to achieve "null iterators" (N3644)
+   {}
+
+   explicit reverse_iterator(It r)
+      : m_current(r)
+   {}
+
+   reverse_iterator(const reverse_iterator& r)
+      : m_current(r.base())
+   {}
+
+   template<class OtherIt>
+   reverse_iterator( const reverse_iterator<OtherIt>& r
+                   , typename boost::move_detail::enable_if_convertible<OtherIt, It>::type* =0
+                   )
+      : m_current(r.base())
+   {}
+
+   reverse_iterator & operator=( const reverse_iterator& r)
+   {  m_current = r.base();   return *this;  }
+
+   template<class OtherIt>
+   typename boost::move_detail::enable_if_convertible<OtherIt, It, reverse_iterator &>::type
+         operator=( const reverse_iterator<OtherIt>& r)
+   {  m_current = r.base();   return *this;  }
+
+   It base() const
+   {  return m_current;  }
+
+   reference operator*() const
+   {
+      It temp(m_current);
+      --temp;
+      reference r = *temp;
+      return r;
+   }
+
+   pointer operator->() const
+   {
+      It temp(m_current);
+      --temp;
+      return iterator_arrow_result(temp);
+   }
+
+   reference operator[](difference_type off) const
+   {
+      return this->m_current[-off - 1];
+   }
+
+   reverse_iterator& operator++()
+   {
+      --m_current;
+      return *this;
+   }
+
+   reverse_iterator operator++(int)
+   {
+      reverse_iterator temp((*this));
+      --m_current;
+      return temp;
+   }
+
+   reverse_iterator& operator--()
+   {
+      ++m_current;
+      return *this;
+   }
+
+   reverse_iterator operator--(int)
+   {
+      reverse_iterator temp((*this));
+      ++m_current;
+      return temp;
+   }
+
+   friend bool operator==(const reverse_iterator& l, const reverse_iterator& r)
+   {  return l.m_current == r.m_current;  }
+
+   friend bool operator!=(const reverse_iterator& l, const reverse_iterator& r)
+   {  return l.m_current != r.m_current;  }
+
+   friend bool operator<(const reverse_iterator& l, const reverse_iterator& r)
+   {  return l.m_current > r.m_current;  }
+
+   friend bool operator<=(const reverse_iterator& l, const reverse_iterator& r)
+   {  return l.m_current >= r.m_current;  }
+
+   friend bool operator>(const reverse_iterator& l, const reverse_iterator& r)
+   {  return l.m_current < r.m_current;  }
+
+   friend bool operator>=(const reverse_iterator& l, const reverse_iterator& r)
+   {  return l.m_current <= r.m_current;  }
+
+   reverse_iterator& operator+=(difference_type off)
+   {  m_current -= off; return *this;  }
+
+   reverse_iterator& operator-=(difference_type off)
+   {  m_current += off; return *this;  }
+
+   friend reverse_iterator operator+(reverse_iterator l, difference_type off)
+   {  return (l += off);  }
+
+   friend reverse_iterator operator+(difference_type off, reverse_iterator r)
+   {  return (r += off);   }
+
+   friend reverse_iterator operator-(reverse_iterator l, difference_type off)
+   {  return (l-= off);  }
+
+   friend difference_type operator-(const reverse_iterator& l, const reverse_iterator& r)
+   {  return r.m_current - l.m_current;  }
+
+   private:
+   It m_current;   // the wrapped iterator
+};
+
+template< class Iterator >
+reverse_iterator<Iterator> make_reverse_iterator( Iterator i )
+{
+    return reverse_iterator<Iterator>(i);
+}
+
+} //namespace movelib {
+} //namespace boost {
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif //BOOST_MOVE_DETAIL_REVERSE_ITERATOR_HPP
diff --git a/include/boost/move/detail/std_ns_begin.hpp b/include/boost/move/detail/std_ns_begin.hpp
new file mode 100644
index 0000000..a768e61
--- /dev/null
+++ b/include/boost/move/detail/std_ns_begin.hpp
@@ -0,0 +1,30 @@
+#//////////////////////////////////////////////////////////////////////////////
+#//
+#// (C) Copyright Ion Gaztanaga 2015-2015.
+#// 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)
+#//
+#// See http://www.boost.org/libs/move for documentation.
+#//
+#//////////////////////////////////////////////////////////////////////////////
+#
+#if defined(_LIBCPP_VERSION)
+   #if defined(__clang__)
+      #define BOOST_MOVE_STD_NS_GCC_DIAGNOSTIC_PUSH
+      #pragma GCC diagnostic push
+      #pragma GCC diagnostic ignored "-Wc++11-extensions"
+   #endif
+   #define BOOST_MOVE_STD_NS_BEG _LIBCPP_BEGIN_NAMESPACE_STD
+   #define BOOST_MOVE_STD_NS_END _LIBCPP_END_NAMESPACE_STD
+#elif defined(BOOST_GNU_STDLIB) && defined(_GLIBCXX_BEGIN_NAMESPACE_VERSION)  //GCC >= 4.6
+   #define BOOST_MOVE_STD_NS_BEG namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION
+   #define BOOST_MOVE_STD_NS_END _GLIBCXX_END_NAMESPACE_VERSION  } // namespace
+#elif defined(BOOST_GNU_STDLIB) && defined(_GLIBCXX_BEGIN_NAMESPACE)  //GCC >= 4.2
+   #define BOOST_MOVE_STD_NS_BEG _GLIBCXX_BEGIN_NAMESPACE(std)
+   #define BOOST_MOVE_STD_NS_END _GLIBCXX_END_NAMESPACE
+#else
+   #define BOOST_MOVE_STD_NS_BEG namespace std{
+   #define BOOST_MOVE_STD_NS_END }
+#endif
+
diff --git a/include/boost/move/detail/std_ns_end.hpp b/include/boost/move/detail/std_ns_end.hpp
new file mode 100644
index 0000000..0975059
--- /dev/null
+++ b/include/boost/move/detail/std_ns_end.hpp
@@ -0,0 +1,14 @@
+#//////////////////////////////////////////////////////////////////////////////
+#//
+#// (C) Copyright Ion Gaztanaga 2015-2015.
+#// 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)
+#//
+#// See http://www.boost.org/libs/move for documentation.
+#//
+#//////////////////////////////////////////////////////////////////////////////
+#ifdef BOOST_MOVE_STD_NS_GCC_DIAGNOSTIC_PUSH
+   #pragma GCC diagnostic pop
+   #undef BOOST_MOVE_STD_NS_GCC_DIAGNOSTIC_PUSH
+#endif   //BOOST_MOVE_STD_NS_GCC_DIAGNOSTIC_PUSH
diff --git a/include/boost/move/detail/to_raw_pointer.hpp b/include/boost/move/detail/to_raw_pointer.hpp
new file mode 100644
index 0000000..7e89beb
--- /dev/null
+++ b/include/boost/move/detail/to_raw_pointer.hpp
@@ -0,0 +1,45 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga  2017-2017
+//
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_MOVE_DETAIL_TO_RAW_POINTER_HPP
+#define BOOST_MOVE_DETAIL_TO_RAW_POINTER_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/detail/workaround.hpp>
+#include <boost/move/detail/pointer_element.hpp>
+
+namespace boost {
+namespace movelib {
+
+template <class T>
+BOOST_MOVE_FORCEINLINE T* to_raw_pointer(T* p)
+{  return p; }
+
+template <class Pointer>
+BOOST_MOVE_FORCEINLINE typename boost::movelib::pointer_element<Pointer>::type*
+to_raw_pointer(const Pointer &p)
+{  return ::boost::movelib::to_raw_pointer(p.operator->());  }
+
+} //namespace movelib
+} //namespace boost
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif //BOOST_MOVE_DETAIL_TO_RAW_POINTER_HPP
diff --git a/include/boost/move/detail/type_traits.hpp b/include/boost/move/detail/type_traits.hpp
new file mode 100644
index 0000000..a3326d0
--- /dev/null
+++ b/include/boost/move/detail/type_traits.hpp
@@ -0,0 +1,1086 @@
+//////////////////////////////////////////////////////////////////////////////
+// (C) Copyright John Maddock 2000.
+// (C) Copyright Ion Gaztanaga 2005-2015.
+//
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+// The alignment and Type traits implementation comes from
+// John Maddock's TypeTraits library.
+//
+// Some other tricks come from Howard Hinnant's papers and StackOverflow replies
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_MOVE_DETAIL_TYPE_TRAITS_HPP
+#define BOOST_MOVE_DETAIL_TYPE_TRAITS_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/detail/workaround.hpp>
+
+// move/detail
+#include <boost/move/detail/meta_utils.hpp>
+// other
+#include <boost/assert.hpp>
+#include <boost/static_assert.hpp>
+// std
+#include <cstddef>
+
+//Use of Boost.TypeTraits leads to long preprocessed source code due to
+//MPL dependencies. We'll use intrinsics directly and make or own
+//simplified version of TypeTraits.
+//If someday Boost.TypeTraits dependencies are minimized, we should
+//revisit this file redirecting code to Boost.TypeTraits traits.
+
+//These traits don't care about volatile, reference or other checks
+//made by Boost.TypeTraits because no volatile or reference types
+//can be hold in Boost.Containers. This helps to avoid any Boost.TypeTraits
+//dependency.
+
+// Helper macros for builtin compiler support.
+// If your compiler has builtin support for any of the following
+// traits concepts, then redefine the appropriate macros to pick
+// up on the compiler support:
+//
+// (these should largely ignore cv-qualifiers)
+// BOOST_MOVE_IS_POD(T) should evaluate to true if T is a POD type
+// BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) should evaluate to true if "T x;" has no effect
+// BOOST_MOVE_HAS_TRIVIAL_COPY(T) should evaluate to true if T(t) <==> memcpy
+// (Note: this trait does not guarantee T is copy constructible, the copy constructor could be deleted but still be trivial)
+// BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) should evaluate to true if T(boost::move(t)) <==> memcpy
+// BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) should evaluate to true if t = u <==> memcpy
+// (Note: this trait does not guarantee T is assignable , the copy assignmen could be deleted but still be trivial)
+// BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T) should evaluate to true if t = boost::move(u) <==> memcpy
+// BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) should evaluate to true if ~T() has no effect
+// BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) should evaluate to true if "T x;" can not throw
+// BOOST_MOVE_HAS_NOTHROW_COPY(T) should evaluate to true if T(t) can not throw
+// BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) should evaluate to true if t = u can not throw
+// BOOST_MOVE_IS_ENUM(T) should evaluate to true it t is a union type.
+//
+// The following can also be defined: when detected our implementation is greatly simplified.
+//
+// BOOST_ALIGNMENT_OF(T) should evaluate to the alignment requirements of type T.
+
+#if defined(__MSL_CPP__) && (__MSL_CPP__ >= 0x8000)
+    // Metrowerks compiler is acquiring intrinsic type traits support
+    // post version 8.  We hook into the published interface to pick up
+    // user defined specializations as well as compiler intrinsics as
+    // and when they become available:
+#   include <msl_utility>
+#   define BOOST_MOVE_IS_UNION(T) BOOST_STD_EXTENSION_NAMESPACE::is_union<T>::value
+#   define BOOST_MOVE_IS_POD(T) BOOST_STD_EXTENSION_NAMESPACE::is_POD<T>::value
+#   define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_default_ctor<T>::value
+#   define BOOST_MOVE_HAS_TRIVIAL_COPY(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_copy_ctor<T>::value
+#   define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_assignment<T>::value
+#   define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_dtor<T>::value
+#endif
+
+#if (defined(BOOST_MSVC) && defined(BOOST_MSVC_FULL_VER) && (BOOST_MSVC_FULL_VER >=140050215))\
+         || (defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1500))
+#   define BOOST_MOVE_IS_UNION(T) __is_union(T)
+#   define BOOST_MOVE_IS_POD(T)                    (__is_pod(T) && __has_trivial_constructor(T))
+#   define BOOST_MOVE_IS_EMPTY(T)                  __is_empty(T)
+#   define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T)   __has_trivial_constructor(T)
+#   define BOOST_MOVE_HAS_TRIVIAL_COPY(T)          (__has_trivial_copy(T)|| ::boost::move_detail::is_pod<T>::value)
+#   define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T)        (__has_trivial_assign(T) || ::boost::move_detail::is_pod<T>::value)
+#   define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T)    (__has_trivial_destructor(T) || ::boost::move_detail::is_pod<T>::value)
+#   define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T)   (__has_nothrow_constructor(T) || ::boost::move_detail::is_trivially_default_constructible<T>::value)
+#   define BOOST_MOVE_HAS_NOTHROW_COPY(T)          (__has_nothrow_copy(T) || ::boost::move_detail::is_trivially_copy_constructible<T>::value)
+#   define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T)        (__has_nothrow_assign(T) || ::boost::move_detail::is_trivially_copy_assignable<T>::value)
+
+#   define BOOST_MOVE_IS_ENUM(T) __is_enum(T)
+#   if defined(_MSC_VER) && (_MSC_VER >= 1700)
+#       define BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T)   (__has_trivial_move_constructor(T) || ::boost::move_detail::is_pod<T>::value)
+#       define BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T)        (__has_trivial_move_assign(T) || ::boost::move_detail::is_pod<T>::value)
+#   endif
+#endif
+
+#if defined(BOOST_CLANG) && defined(__has_feature)
+
+#   if __has_feature(is_union)
+#     define BOOST_MOVE_IS_UNION(T) __is_union(T)
+#   endif
+#   if (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20080306 && __GLIBCXX__ != 20080519)) && __has_feature(is_pod)
+#     define BOOST_MOVE_IS_POD(T) __is_pod(T)
+#   endif
+#   if (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20080306 && __GLIBCXX__ != 20080519)) && __has_feature(is_empty)
+#     define BOOST_MOVE_IS_EMPTY(T) __is_empty(T)
+#   endif
+#   if __has_feature(has_trivial_constructor)
+#     define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T)
+#   endif
+#   if __has_feature(has_trivial_copy)
+#     define BOOST_MOVE_HAS_TRIVIAL_COPY(T) __has_trivial_copy(T)
+#   endif
+#   if __has_feature(has_trivial_assign)
+#     define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T) )
+#   endif
+#   if __has_feature(has_trivial_destructor)
+#     define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T)
+#   endif
+#   if __has_feature(has_nothrow_constructor)
+#     define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) __has_nothrow_constructor(T)
+#   endif
+#   if __has_feature(has_nothrow_copy)
+#     define BOOST_MOVE_HAS_NOTHROW_COPY(T) (__has_nothrow_copy(T))
+#   endif
+#   if __has_feature(is_nothrow_copy_assignable)
+#     define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T))
+#   endif
+#   if __has_feature(is_enum)
+#     define BOOST_MOVE_IS_ENUM(T) __is_enum(T)
+#   endif
+#   if __has_feature(has_trivial_move_constructor)
+#     define BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) __has_trivial_move_constructor(T)
+#   endif
+#   if __has_feature(has_trivial_move_assign)
+#     define BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T) __has_trivial_move_assign(T)
+#   endif
+#   define BOOST_MOVE_ALIGNMENT_OF(T) __alignof(T)
+#endif
+
+#if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3) && !defined(__GCCXML__))) && !defined(BOOST_CLANG)
+
+#ifdef BOOST_INTEL
+#  define BOOST_MOVE_INTEL_TT_OPTS || ::boost::move_detail::is_pod<T>::value
+#else
+#  define BOOST_MOVE_INTEL_TT_OPTS
+#endif
+
+#   define BOOST_MOVE_IS_UNION(T) __is_union(T)
+#   define BOOST_MOVE_IS_POD(T) __is_pod(T)
+#   define BOOST_MOVE_IS_EMPTY(T) __is_empty(T)
+#   define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) ((__has_trivial_constructor(T) BOOST_MOVE_INTEL_TT_OPTS))
+#   define BOOST_MOVE_HAS_TRIVIAL_COPY(T) ((__has_trivial_copy(T) BOOST_MOVE_INTEL_TT_OPTS))
+#   define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) ((__has_trivial_assign(T) BOOST_MOVE_INTEL_TT_OPTS) )
+#   define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T) BOOST_MOVE_INTEL_TT_OPTS)
+#   define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_constructor(T) BOOST_MOVE_INTEL_TT_OPTS)
+#   define BOOST_MOVE_HAS_NOTHROW_COPY(T) ((__has_nothrow_copy(T) BOOST_MOVE_INTEL_TT_OPTS))
+#   define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) ((__has_nothrow_assign(T) BOOST_MOVE_INTEL_TT_OPTS))
+
+#   define BOOST_MOVE_IS_ENUM(T) __is_enum(T)
+#   if (!defined(unix) && !defined(__unix__)) || defined(__LP64__)
+      // GCC sometimes lies about alignment requirements
+      // of type double on 32-bit unix platforms, use the
+      // old implementation instead in that case:
+#     define BOOST_MOVE_ALIGNMENT_OF(T) __alignof__(T)
+#   endif
+#endif
+
+#if defined(__ghs__) && (__GHS_VERSION_NUMBER >= 600)
+
+#   define BOOST_MOVE_IS_UNION(T) __is_union(T)
+#   define BOOST_MOVE_IS_POD(T) __is_pod(T)
+#   define BOOST_MOVE_IS_EMPTY(T) __is_empty(T)
+#   define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T)
+#   define BOOST_MOVE_HAS_TRIVIAL_COPY(T) (__has_trivial_copy(T))
+#   define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T))
+#   define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T)
+#   define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) __has_nothrow_constructor(T)
+#   define BOOST_MOVE_HAS_NOTHROW_COPY(T) (__has_nothrow_copy(T))
+#   define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T))
+
+#   define BOOST_MOVE_IS_ENUM(T) __is_enum(T)
+#   define BOOST_MOVE_ALIGNMENT_OF(T) __alignof__(T)
+#endif
+
+# if defined(__CODEGEARC__)
+#   define BOOST_MOVE_IS_UNION(T) __is_union(T)
+#   define BOOST_MOVE_IS_POD(T) __is_pod(T)
+#   define BOOST_MOVE_IS_EMPTY(T) __is_empty(T)
+#   define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) (__has_trivial_default_constructor(T))
+#   define BOOST_MOVE_HAS_TRIVIAL_COPY(T) (__has_trivial_copy_constructor(T))
+#   define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T))
+#   define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T))
+#   define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_default_constructor(T))
+#   define BOOST_MOVE_HAS_NOTHROW_COPY(T) (__has_nothrow_copy_constructor(T))
+#   define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T))
+
+#   define BOOST_MOVE_IS_ENUM(T) __is_enum(T)
+#   define BOOST_MOVE_ALIGNMENT_OF(T) alignof(T)
+
+#endif
+
+//Fallback definitions
+
+#ifdef BOOST_MOVE_IS_UNION
+   #define BOOST_MOVE_IS_UNION_IMPL(T) BOOST_MOVE_IS_UNION(T)
+#else
+   #define BOOST_MOVE_IS_UNION_IMPL(T) false
+#endif
+
+#ifdef BOOST_MOVE_IS_POD
+   //in some compilers the intrinsic is limited to class types so add scalar and void
+   #define BOOST_MOVE_IS_POD_IMPL(T) (::boost::move_detail::is_scalar<T>::value ||\
+                                      ::boost::move_detail::is_void<T>::value   ||\
+                                       BOOST_MOVE_IS_POD(T))
+#else
+   #define BOOST_MOVE_IS_POD_IMPL(T) \
+      (::boost::move_detail::is_scalar<T>::value || ::boost::move_detail::is_void<T>::value)
+#endif
+
+#ifdef BOOST_MOVE_IS_EMPTY
+   #define BOOST_MOVE_IS_EMPTY_IMPL(T) BOOST_MOVE_IS_EMPTY(T)
+#else
+   #define BOOST_MOVE_IS_EMPTY_IMPL(T)    ::boost::move_detail::is_empty_nonintrinsic<T>::value
+#endif
+
+#ifdef BOOST_MOVE_HAS_TRIVIAL_COPY
+   #define BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)   ::boost::move_detail::is_pod<T>::value ||\
+                                                          (::boost::move_detail::is_copy_constructible<T>::value &&\
+                                                           BOOST_MOVE_HAS_TRIVIAL_COPY(T))
+#else
+   #define BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)   ::boost::move_detail::is_pod<T>::value
+#endif
+
+#ifdef BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR
+   #define BOOST_MOVE_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE(T)  BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T)
+#else
+   #define BOOST_MOVE_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE(T)  ::boost::move_detail::is_pod<T>::value
+#endif
+
+#ifdef BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR
+   #define BOOST_MOVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE(T)   BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T)
+#else
+   #define BOOST_MOVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE(T)   ::boost::move_detail::is_pod<T>::value
+#endif
+
+#ifdef BOOST_MOVE_HAS_TRIVIAL_ASSIGN
+   #define BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T) ::boost::move_detail::is_pod<T>::value ||\
+                                                      ( ::boost::move_detail::is_copy_assignable<T>::value &&\
+                                                         BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T))
+#else
+   #define BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T) ::boost::move_detail::is_pod<T>::value
+#endif
+
+#ifdef BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN
+   #define BOOST_MOVE_IS_TRIVIALLY_MOVE_ASSIGNABLE(T)  BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T)
+#else
+   #define BOOST_MOVE_IS_TRIVIALLY_MOVE_ASSIGNABLE(T)  ::boost::move_detail::is_pod<T>::value
+#endif
+
+#ifdef BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR
+   #define BOOST_MOVE_IS_TRIVIALLY_DESTRUCTIBLE(T)   BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T)
+#else
+   #define BOOST_MOVE_IS_TRIVIALLY_DESTRUCTIBLE(T)   ::boost::move_detail::is_pod<T>::value
+#endif
+
+#ifdef BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR
+   #define BOOST_MOVE_IS_NOTHROW_DEFAULT_CONSTRUCTIBLE(T)  BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T)
+#else
+   #define BOOST_MOVE_IS_NOTHROW_DEFAULT_CONSTRUCTIBLE(T)  ::boost::move_detail::is_pod<T>::value
+#endif
+
+#ifdef BOOST_MOVE_HAS_NOTHROW_COPY
+   #define BOOST_MOVE_IS_NOTHROW_COPY_CONSTRUCTIBLE(T)   BOOST_MOVE_HAS_NOTHROW_COPY(T)
+#else
+   #define BOOST_MOVE_IS_NOTHROW_COPY_CONSTRUCTIBLE(T)   ::boost::move_detail::is_pod<T>::value
+#endif
+
+#ifdef BOOST_MOVE_HAS_NOTHROW_MOVE
+   #define BOOST_MOVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE(T)   BOOST_MOVE_HAS_NOTHROW_MOVE(T)
+#else
+   #define BOOST_MOVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE(T)   ::boost::move_detail::is_pod<T>::value
+#endif
+
+#ifdef BOOST_MOVE_HAS_NOTHROW_ASSIGN
+   #define BOOST_MOVE_IS_NOTHROW_COPY_ASSIGNABLE(T) BOOST_MOVE_HAS_NOTHROW_ASSIGN(T)
+#else
+   #define BOOST_MOVE_IS_NOTHROW_COPY_ASSIGNABLE(T) ::boost::move_detail::is_pod<T>::value
+#endif
+
+#ifdef BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN
+   #define BOOST_MOVE_IS_NOTHROW_MOVE_ASSIGNABLE(T) BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T)
+#else
+   #define BOOST_MOVE_IS_NOTHROW_MOVE_ASSIGNABLE(T) ::boost::move_detail::is_pod<T>::value
+#endif
+
+#ifdef BOOST_MOVE_IS_ENUM
+   #define BOOST_MOVE_IS_ENUM_IMPL(T)   BOOST_MOVE_IS_ENUM(T)
+#else
+   #define BOOST_MOVE_IS_ENUM_IMPL(T)   ::boost::move_detail::is_enum_nonintrinsic<T>::value
+#endif
+
+namespace boost {
+namespace move_detail {
+
+//////////////////////////
+//    is_reference
+//////////////////////////
+template<class T>
+struct is_reference
+{  static const bool value = false; };
+
+template<class T>
+struct is_reference<T&>
+{  static const bool value = true; };
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+template<class T>
+struct is_reference<T&&>
+{  static const bool value = true; };
+#endif
+
+//////////////////////////
+//    is_pointer
+//////////////////////////
+template<class T>
+struct is_pointer
+{  static const bool value = false; };
+
+template<class T>
+struct is_pointer<T*>
+{  static const bool value = true; };
+
+//////////////////////////
+//       is_const
+//////////////////////////
+template<class T>
+struct is_const
+{  static const bool value = false; };
+
+template<class T>
+struct is_const<const T>
+{  static const bool value = true; };
+
+//////////////////////////
+//       unvoid_ref
+//////////////////////////
+template <typename T> struct unvoid_ref : add_lvalue_reference<T>{};
+template <> struct unvoid_ref<void>                { typedef unvoid_ref & type; };
+template <> struct unvoid_ref<const void>          { typedef unvoid_ref & type; };
+template <> struct unvoid_ref<volatile void>       { typedef unvoid_ref & type; };
+template <> struct unvoid_ref<const volatile void> { typedef unvoid_ref & type; };
+
+template <typename T>
+struct add_reference : add_lvalue_reference<T>
+{};
+
+//////////////////////////
+//    add_const_reference
+//////////////////////////
+template <class T>
+struct add_const_reference
+{  typedef const T &type;   };
+
+template <class T>
+struct add_const_reference<T&>
+{  typedef T& type;   };
+
+//////////////////////////
+//    add_const_if_c
+//////////////////////////
+template<class T, bool Add>
+struct add_const_if_c
+   : if_c<Add, typename add_const<T>::type, T>
+{};
+
+//////////////////////////
+//    remove_const
+//////////////////////////
+template<class T>
+struct remove_const
+{  typedef T type;   };
+
+template<class T>
+struct remove_const< const T>
+{  typedef T type;   };
+
+//////////////////////////
+//    remove_cv
+//////////////////////////
+template<typename T> struct remove_cv                    {  typedef T type;   };
+template<typename T> struct remove_cv<const T>           {  typedef T type;   };
+template<typename T> struct remove_cv<const volatile T>  {  typedef T type;   };
+template<typename T> struct remove_cv<volatile T>        {  typedef T type;   };
+
+//////////////////////////
+//    make_unsigned
+//////////////////////////
+template <class T>
+struct make_unsigned_impl                                         {  typedef T type;   };
+template <> struct make_unsigned_impl<signed char>                {  typedef unsigned char  type; };
+template <> struct make_unsigned_impl<signed short>               {  typedef unsigned short type; };
+template <> struct make_unsigned_impl<signed int>                 {  typedef unsigned int   type; };
+template <> struct make_unsigned_impl<signed long>                {  typedef unsigned long  type; };
+#ifdef BOOST_HAS_LONG_LONG
+template <> struct make_unsigned_impl< ::boost::long_long_type >  {  typedef ::boost::ulong_long_type type; };
+#endif
+
+template <class T>
+struct make_unsigned
+   : make_unsigned_impl<typename remove_cv<T>::type>
+{};
+
+//////////////////////////
+//    is_floating_point
+//////////////////////////
+template<class T> struct is_floating_point_cv               {  static const bool value = false; };
+template<>        struct is_floating_point_cv<float>        {  static const bool value = true; };
+template<>        struct is_floating_point_cv<double>       {  static const bool value = true; };
+template<>        struct is_floating_point_cv<long double>  {  static const bool value = true; };
+
+template<class T>
+struct is_floating_point
+   : is_floating_point_cv<typename remove_cv<T>::type>
+{};
+
+//////////////////////////
+//    is_integral
+//////////////////////////
+template<class T> struct is_integral_cv                    {  static const bool value = false; };
+template<> struct is_integral_cv<                     bool>{  static const bool value = true; };
+template<> struct is_integral_cv<                     char>{  static const bool value = true; };
+template<> struct is_integral_cv<            unsigned char>{  static const bool value = true; };
+template<> struct is_integral_cv<              signed char>{  static const bool value = true; };
+#ifndef BOOST_NO_CXX11_CHAR16_T
+template<> struct is_integral_cv<                 char16_t>{  static const bool value = true; };
+#endif
+#ifndef BOOST_NO_CXX11_CHAR32_T
+template<> struct is_integral_cv<                 char32_t>{  static const bool value = true; };
+#endif
+#ifndef BOOST_NO_INTRINSIC_WCHAR_T
+template<> struct is_integral_cv<                  wchar_t>{  static const bool value = true; };
+#endif
+template<> struct is_integral_cv<                    short>{  static const bool value = true; };
+template<> struct is_integral_cv<           unsigned short>{  static const bool value = true; };
+template<> struct is_integral_cv<                      int>{  static const bool value = true; };
+template<> struct is_integral_cv<             unsigned int>{  static const bool value = true; };
+template<> struct is_integral_cv<                     long>{  static const bool value = true; };
+template<> struct is_integral_cv<            unsigned long>{  static const bool value = true; };
+#ifdef BOOST_HAS_LONG_LONG
+template<> struct is_integral_cv< ::boost:: long_long_type>{  static const bool value = true; };
+template<> struct is_integral_cv< ::boost::ulong_long_type>{  static const bool value = true; };
+#endif
+
+template<class T>
+struct is_integral
+   : public is_integral_cv<typename remove_cv<T>::type>
+{};
+
+//////////////////////////////////////
+//          remove_all_extents
+//////////////////////////////////////
+template <class T>
+struct remove_all_extents
+{  typedef T type;};
+
+template <class T>
+struct remove_all_extents<T[]>
+{  typedef typename remove_all_extents<T>::type type; };
+
+template <class T, std::size_t N>
+struct remove_all_extents<T[N]>
+{  typedef typename remove_all_extents<T>::type type;};
+
+//////////////////////////
+//    is_scalar
+//////////////////////////
+template<class T>
+struct is_scalar
+{  static const bool value = is_integral<T>::value || is_floating_point<T>::value; };
+
+//////////////////////////
+//       is_void
+//////////////////////////
+template<class T>
+struct is_void_cv
+{  static const bool value = false; };
+
+template<>
+struct is_void_cv<void>
+{  static const bool value = true; };
+
+template<class T>
+struct is_void
+   : is_void_cv<typename remove_cv<T>::type>
+{};
+
+//////////////////////////////////////
+//          is_array
+//////////////////////////////////////
+template<class T>
+struct is_array
+{  static const bool value = false; };
+
+template<class T>
+struct is_array<T[]>
+{  static const bool value = true;  };
+
+template<class T, std::size_t N>
+struct is_array<T[N]>
+{  static const bool value = true;  };
+
+//////////////////////////////////////
+//           is_member_pointer
+//////////////////////////////////////
+template <class T>         struct is_member_pointer_cv         {  static const bool value = false; };
+template <class T, class U>struct is_member_pointer_cv<T U::*> {  static const bool value = true; };
+
+template <class T>
+struct is_member_pointer
+    : is_member_pointer_cv<typename remove_cv<T>::type>
+{};
+
+//////////////////////////////////////
+//          is_nullptr_t
+//////////////////////////////////////
+template <class T>
+struct is_nullptr_t_cv
+{  static const bool value = false; };
+
+#if !defined(BOOST_NO_CXX11_NULLPTR)
+template <>
+struct is_nullptr_t_cv
+   #if !defined(BOOST_NO_CXX11_DECLTYPE)
+   <decltype(nullptr)>
+   #else
+   <std::nullptr_t>
+   #endif
+{  static const bool value = true; };
+#endif
+
+template <class T>
+struct is_nullptr_t
+   : is_nullptr_t_cv<typename remove_cv<T>::type>
+{};
+
+//////////////////////////////////////
+//          is_function
+//////////////////////////////////////
+//Inspired by libc++, thanks to Howard Hinnant
+//For a function to pointer an lvalue of function type T can be implicitly converted to a prvalue
+//pointer to that function. This does not apply to non-static member functions because lvalues
+//that refer to non-static member functions do not exist.
+template <class T>
+struct is_reference_convertible_to_pointer
+{
+   struct twochar { char dummy[2]; };
+   template <class U> static char    test(U*);
+   template <class U> static twochar test(...);
+   static T& source();
+   static const bool value = sizeof(char) == sizeof(test<T>(source()));
+};
+//Filter out:
+// - class types that might have implicit conversions
+// - void (to avoid forming a reference to void later)
+// - references (e.g.: filtering reference to functions)
+// - nullptr_t (convertible to pointer)
+template < class T
+         , bool Filter = is_class_or_union<T>::value  ||
+                         is_void<T>::value            ||
+                         is_reference<T>::value       ||
+                         is_nullptr_t<T>::value       >
+struct is_function_impl
+{  static const bool value = is_reference_convertible_to_pointer<T>::value; };
+
+template <class T>
+struct is_function_impl<T, true>
+{  static const bool value = false; };
+
+template <class T>
+struct is_function
+   : is_function_impl<T>
+{};
+
+//////////////////////////////////////
+//       is_union
+//////////////////////////////////////
+template<class T>
+struct is_union_noextents_cv
+{  static const bool value = BOOST_MOVE_IS_UNION_IMPL(T); };
+
+template<class T>
+struct is_union
+   : is_union_noextents_cv<typename remove_cv<typename remove_all_extents<T>::type>::type>
+{};
+
+//////////////////////////////////////
+//             is_class
+//////////////////////////////////////
+template <class T>
+struct is_class
+{
+   static const bool value = is_class_or_union<T>::value && ! is_union<T>::value;
+};
+
+
+//////////////////////////////////////
+//             is_arithmetic
+//////////////////////////////////////
+template <class T>
+struct is_arithmetic
+{
+   static const bool value = is_floating_point<T>::value ||
+                             is_integral<T>::value;
+};
+
+//////////////////////////////////////
+//    is_member_function_pointer
+//////////////////////////////////////
+template <class T>
+struct is_member_function_pointer_cv
+{
+   static const bool value = false;
+};
+
+template <class T, class C>
+struct is_member_function_pointer_cv<T C::*>
+   : is_function<T>
+{};
+
+template <class T>
+struct is_member_function_pointer
+    : is_member_function_pointer_cv<typename remove_cv<T>::type>
+{};
+
+//////////////////////////////////////
+//             is_enum
+//////////////////////////////////////
+#if !defined(BOOST_MOVE_IS_ENUM)
+//Based on (http://howardhinnant.github.io/TypeHiearchy.pdf)
+template <class T>
+struct is_enum_nonintrinsic
+{
+   static const bool value =  !is_arithmetic<T>::value     &&
+                              !is_reference<T>::value      &&
+                              !is_class_or_union<T>::value &&
+                              !is_array<T>::value          &&
+                              !is_void<T>::value           &&
+                              !is_nullptr_t<T>::value      &&
+                              !is_member_pointer<T>::value &&
+                              !is_pointer<T>::value        &&
+                              !is_function<T>::value;
+};
+#endif
+
+template <class T>
+struct is_enum
+{  static const bool value = BOOST_MOVE_IS_ENUM_IMPL(T);  };
+
+//////////////////////////////////////
+//       is_pod
+//////////////////////////////////////
+template<class T>
+struct is_pod_noextents_cv  //for non-c++11 compilers, a safe fallback
+{  static const bool value = BOOST_MOVE_IS_POD_IMPL(T); };
+
+template<class T>
+struct is_pod
+   : is_pod_noextents_cv<typename remove_cv<typename remove_all_extents<T>::type>::type>
+{};
+
+//////////////////////////////////////
+//             is_empty
+//////////////////////////////////////
+#if !defined(BOOST_MOVE_IS_EMPTY)
+
+template <typename T>
+struct empty_helper_t1 : public T
+{
+   empty_helper_t1();  // hh compiler bug workaround
+   int i[256];
+   private:
+
+   empty_helper_t1(const empty_helper_t1&);
+   empty_helper_t1& operator=(const empty_helper_t1&);
+};
+
+struct empty_helper_t2 { int i[256]; };
+
+template <typename T, bool IsClass = is_class<T>::value >
+struct is_empty_nonintrinsic
+{
+   static const bool value = false;
+};
+
+template <typename T>
+struct is_empty_nonintrinsic<T, true>
+{
+   static const bool value = sizeof(empty_helper_t1<T>) == sizeof(empty_helper_t2);
+};
+#endif
+
+template <class T>
+struct is_empty
+{  static const bool value = BOOST_MOVE_IS_EMPTY_IMPL(T);  };
+
+
+template<class T>
+struct has_boost_move_no_copy_constructor_or_assign_type
+{
+   template <class U>
+   static yes_type test(typename U::boost_move_no_copy_constructor_or_assign*);
+
+   template <class U>
+   static no_type test(...);
+
+   static const bool value = sizeof(test<T>(0)) == sizeof(yes_type);
+};
+
+//////////////////////////////////////
+//       is_copy_constructible
+//////////////////////////////////////
+#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_NO_CXX11_DECLTYPE) \
+   && !defined(BOOST_INTEL_CXX_VERSION) && \
+      !(defined(BOOST_MSVC) && _MSC_VER == 1800)
+#define BOOST_MOVE_TT_CXX11_IS_COPY_CONSTRUCTIBLE
+#endif
+
+template<class T>
+struct is_copy_constructible
+{
+   // Intel compiler has problems with SFINAE for copy constructors and deleted functions:
+   //
+   // error: function *function_name* cannot be referenced -- it is a deleted function
+   // static yes_type test(U&, decltype(U(boost::declval<U&>()))* = 0);
+   //                                                        ^ 
+   // MSVC 12.0 (Visual 2013) has problems when the copy constructor has been deleted. See:
+   // https://connect.microsoft.com/VisualStudio/feedback/details/800328/std-is-copy-constructible-is-broken
+   #if defined(BOOST_MOVE_TT_CXX11_IS_COPY_CONSTRUCTIBLE)
+      template<class U> static typename add_reference<U>::type source();
+      static no_type test(...);
+      #ifdef BOOST_NO_CXX11_DECLTYPE
+         template <class U>
+         static yes_type test(U&, bool_<sizeof(U(source<U>()))>* = 0);
+      #else
+         template <class U>
+         static yes_type test(U&, decltype(U(source<U>()))* = 0);
+      #endif
+      static const bool value = sizeof(test(source<T>())) == sizeof(yes_type);
+   #else
+   static const bool value = !has_boost_move_no_copy_constructor_or_assign_type<T>::value;
+   #endif
+};
+
+
+//////////////////////////////////////
+//       is_copy_assignable
+//////////////////////////////////////
+#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_NO_CXX11_DECLTYPE) \
+   && !defined(BOOST_INTEL_CXX_VERSION) && \
+      !(defined(BOOST_MSVC) && _MSC_VER == 1800)
+#define BOOST_MOVE_TT_CXX11_IS_COPY_ASSIGNABLE
+#endif
+
+template <class T>
+struct is_copy_assignable
+{
+// Intel compiler has problems with SFINAE for copy constructors and deleted functions:
+//
+// error: function *function_name* cannot be referenced -- it is a deleted function
+// static boost::type_traits::yes_type test(T1&, decltype(T1(boost::declval<T1&>()))* = 0);
+//                                                        ^ 
+//
+// MSVC 12.0 (Visual 2013) has problems when the copy constructor has been deleted. See:
+// https://connect.microsoft.com/VisualStudio/feedback/details/800328/std-is-copy-constructible-is-broken
+#if defined(BOOST_MOVE_TT_CXX11_IS_COPY_ASSIGNABLE)
+   typedef char yes_type;
+   struct no_type { char dummy[2]; };
+   
+   template <class U>   static typename add_reference<U>::type source();
+   template <class U>   static decltype(source<U&>() = source<const U&>(), yes_type() ) test(int);
+   template <class>     static no_type test(...);
+
+   static const bool value = sizeof(test<T>(0)) == sizeof(yes_type);
+#else
+   static const bool value = !has_boost_move_no_copy_constructor_or_assign_type<T>::value;
+#endif
+};
+
+//////////////////////////////////////
+//       is_trivially_destructible
+//////////////////////////////////////
+template<class T>
+struct is_trivially_destructible
+{  static const bool value = BOOST_MOVE_IS_TRIVIALLY_DESTRUCTIBLE(T); };
+
+//////////////////////////////////////
+//       is_trivially_default_constructible
+//////////////////////////////////////
+template<class T>
+struct is_trivially_default_constructible
+{  static const bool value = BOOST_MOVE_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE(T); };
+
+//////////////////////////////////////
+//       is_trivially_copy_constructible
+//////////////////////////////////////
+template<class T>
+struct is_trivially_copy_constructible
+{
+   //In several compilers BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE return true even with
+   //deleted copy constructors so make sure the type is copy constructible.
+   static const bool value = BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T);
+};
+
+//////////////////////////////////////
+//       is_trivially_move_constructible
+//////////////////////////////////////
+template<class T>
+struct is_trivially_move_constructible
+{ static const bool value = BOOST_MOVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE(T); };
+
+//////////////////////////////////////
+//       is_trivially_copy_assignable
+//////////////////////////////////////
+template<class T>
+struct is_trivially_copy_assignable
+{
+   //In several compilers BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE return true even with
+   //deleted copy constructors so make sure the type is copy constructible.
+   static const bool value = BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T);
+};                             
+
+//////////////////////////////////////
+//       is_trivially_move_assignable
+//////////////////////////////////////
+template<class T>
+struct is_trivially_move_assignable
+{  static const bool value = BOOST_MOVE_IS_TRIVIALLY_MOVE_ASSIGNABLE(T);  };
+
+//////////////////////////////////////
+//       is_nothrow_default_constructible
+//////////////////////////////////////
+template<class T>
+struct is_nothrow_default_constructible
+   : is_pod<T>
+{  static const bool value = BOOST_MOVE_IS_NOTHROW_DEFAULT_CONSTRUCTIBLE(T);  };
+
+//////////////////////////////////////
+//    is_nothrow_copy_constructible
+//////////////////////////////////////
+template<class T>
+struct is_nothrow_copy_constructible
+{  static const bool value = BOOST_MOVE_IS_NOTHROW_COPY_CONSTRUCTIBLE(T);  };
+
+//////////////////////////////////////
+//    is_nothrow_move_constructible
+//////////////////////////////////////
+template<class T>
+struct is_nothrow_move_constructible
+{  static const bool value = BOOST_MOVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE(T);  };
+
+//////////////////////////////////////
+//       is_nothrow_copy_assignable
+//////////////////////////////////////
+template<class T>
+struct is_nothrow_copy_assignable
+{  static const bool value = BOOST_MOVE_IS_NOTHROW_COPY_ASSIGNABLE(T);  };
+
+//////////////////////////////////////
+//    is_nothrow_move_assignable
+//////////////////////////////////////
+template<class T>
+struct is_nothrow_move_assignable
+{  static const bool value = BOOST_MOVE_IS_NOTHROW_MOVE_ASSIGNABLE(T);  };
+
+//////////////////////////////////////
+//    is_nothrow_swappable
+//////////////////////////////////////
+template<class T>
+struct is_nothrow_swappable
+{
+   static const bool value = is_empty<T>::value || is_pod<T>::value;
+};
+
+//////////////////////////////////////
+//       alignment_of
+//////////////////////////////////////
+template <typename T>
+struct alignment_of_hack
+{
+   T t1;
+   char c;
+   T t2;
+   alignment_of_hack();
+};
+
+template <unsigned A, unsigned S>
+struct alignment_logic
+{  static const std::size_t value = A < S ? A : S; };
+
+template< typename T >
+struct alignment_of_impl
+#if defined(BOOST_MSVC) && (BOOST_MSVC >= 1400)
+    // With MSVC both the native __alignof operator
+    // and our own logic gets things wrong from time to time :-(
+    // Using a combination of the two seems to make the most of a bad job:
+   : alignment_logic< sizeof(alignment_of_hack<T>) - 2*sizeof(T), __alignof(T)>
+{};
+#elif !defined(BOOST_MOVE_ALIGNMENT_OF)
+   : alignment_logic< sizeof(alignment_of_hack<T>) - 2*sizeof(T), sizeof(T)>
+{};
+#else
+{  static const std::size_t value = BOOST_MOVE_ALIGNMENT_OF(T);  };
+#endif
+
+template< typename T >
+struct alignment_of
+   : alignment_of_impl<T>
+{};
+
+class alignment_dummy;
+typedef void (*function_ptr)();
+typedef int (alignment_dummy::*member_ptr);
+typedef int (alignment_dummy::*member_function_ptr)();
+struct alignment_struct
+{  long double dummy[4];  };
+
+/////////////////////////////
+//    max_align_t
+/////////////////////////////
+//This is not standard, but should work with all compilers
+union max_align
+{
+   char        char_;
+   short       short_;
+   int         int_;
+   long        long_;
+   #ifdef BOOST_HAS_LONG_LONG
+   ::boost::long_long_type   long_long_;
+   #endif
+   float       float_;
+   double      double_;
+   void *      void_ptr_;
+   long double long_double_[4];
+   alignment_dummy *unknown_class_ptr_;
+   function_ptr function_ptr_;
+   member_function_ptr member_function_ptr_;
+   alignment_struct alignment_struct_;
+};
+
+typedef union max_align max_align_t;
+
+/////////////////////////////
+//    aligned_storage
+/////////////////////////////
+
+#if !defined(BOOST_NO_ALIGNMENT)
+
+template<std::size_t Len, std::size_t Align>
+struct aligned_struct;
+
+#define BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(A)\
+template<std::size_t Len>\
+struct BOOST_ALIGNMENT(A) aligned_struct<Len, A>\
+{\
+   char data[Len];\
+};\
+//
+
+//Up to 4K alignment (typical page size)
+BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x1)
+BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x2)
+BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x4)
+BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x8)
+BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x10)
+BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x20)
+BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x40)
+BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x80)
+BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x100)
+BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x200)
+BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x400)
+BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x800)
+BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x1000)
+
+#undef BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT
+
+// Workaround for bogus [-Wignored-attributes] warning on GCC 6.x/7.x: don't use a type that "directly" carries the alignment attribute.
+// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82270
+template<std::size_t Len, std::size_t Align>
+union aligned_struct_wrapper
+{
+   aligned_struct<Len, Align> aligner;
+   char data[sizeof(aligned_struct<Len, Align>)];
+};
+
+template<std::size_t Len, std::size_t Align>
+struct aligned_storage_impl
+{
+   typedef aligned_struct_wrapper<Len, Align> type;
+};
+
+#else //BOOST_NO_ALIGNMENT
+
+template<class T, std::size_t Len>
+union aligned_union
+{   
+   T aligner;
+   char data[Len];
+};
+
+template<std::size_t Len, std::size_t Align, class T, bool Ok>
+struct aligned_next;
+
+template<std::size_t Len, std::size_t Align, class T>
+struct aligned_next<Len, Align, T, true>
+{
+   BOOST_STATIC_ASSERT((alignment_of<T>::value == Align));
+   typedef aligned_union<T, Len> type;
+};
+
+//End of search defaults to max_align_t
+template<std::size_t Len, std::size_t Align>
+struct aligned_next<Len, Align, max_align_t, false>
+{   typedef aligned_union<max_align_t, Len> type;   };
+
+//Now define a search list through types
+#define BOOST_MOVE_ALIGNED_NEXT_STEP(TYPE, NEXT_TYPE)\
+   template<std::size_t Len, std::size_t Align>\
+   struct aligned_next<Len, Align, TYPE, false>\
+      : aligned_next<Len, Align, NEXT_TYPE, Align == alignment_of<NEXT_TYPE>::value>\
+   {};\
+   //
+   BOOST_MOVE_ALIGNED_NEXT_STEP(long double, max_align_t)
+   BOOST_MOVE_ALIGNED_NEXT_STEP(double, long double)
+   #ifdef BOOST_HAS_LONG_LONG
+      BOOST_MOVE_ALIGNED_NEXT_STEP(::boost::long_long_type, double)
+      BOOST_MOVE_ALIGNED_NEXT_STEP(long, ::boost::long_long_type)
+   #else
+      BOOST_MOVE_ALIGNED_NEXT_STEP(long, double)
+   #endif
+   BOOST_MOVE_ALIGNED_NEXT_STEP(int, long)
+   BOOST_MOVE_ALIGNED_NEXT_STEP(short, int)
+   BOOST_MOVE_ALIGNED_NEXT_STEP(char, short)
+#undef BOOST_MOVE_ALIGNED_NEXT_STEP
+
+template<std::size_t Len, std::size_t Align>
+struct aligned_storage_impl
+   : aligned_next<Len, Align, char, Align == alignment_of<char>::value>
+{};
+
+#endif
+
+template<std::size_t Len, std::size_t Align = alignment_of<max_align_t>::value>
+struct aligned_storage
+{
+   //Sanity checks for input parameters
+   BOOST_STATIC_ASSERT(Align > 0);
+
+   //Sanity checks for output type
+   typedef typename aligned_storage_impl<Len ? Len : 1, Align>::type type;
+   static const std::size_t value = alignment_of<type>::value;
+   BOOST_STATIC_ASSERT(value >= Align);
+   BOOST_STATIC_ASSERT((value % Align) == 0);
+
+   //Just in case someone instantiates aligned_storage
+   //instead of aligned_storage::type (typical error).
+   private:
+   aligned_storage();
+};
+
+}  //namespace move_detail {
+}  //namespace boost {
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif   //#ifndef BOOST_MOVE_DETAIL_TYPE_TRAITS_HPP
diff --git a/include/boost/move/detail/unique_ptr_meta_utils.hpp b/include/boost/move/detail/unique_ptr_meta_utils.hpp
new file mode 100644
index 0000000..e11124d
--- /dev/null
+++ b/include/boost/move/detail/unique_ptr_meta_utils.hpp
@@ -0,0 +1,591 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2012-2012.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
+
+#ifndef BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP
+#define BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <cstddef>   //for std::size_t
+
+//Small meta-typetraits to support move
+
+namespace boost {
+
+namespace movelib {
+
+template <class T>
+struct default_delete;
+
+}  //namespace movelib {
+
+#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+//Forward declare boost::rv
+template <class T> class rv;
+#endif
+
+namespace move_upmu {
+
+//////////////////////////////////////
+//              nat
+//////////////////////////////////////
+struct nat{};
+
+//////////////////////////////////////
+//            natify
+//////////////////////////////////////
+template <class T> struct natify{};
+
+//////////////////////////////////////
+//             if_c
+//////////////////////////////////////
+template<bool C, typename T1, typename T2>
+struct if_c
+{
+   typedef T1 type;
+};
+
+template<typename T1, typename T2>
+struct if_c<false,T1,T2>
+{
+   typedef T2 type;
+};
+
+//////////////////////////////////////
+//             if_
+//////////////////////////////////////
+template<typename T1, typename T2, typename T3>
+struct if_ : if_c<0 != T1::value, T2, T3>
+{};
+
+//enable_if_
+template <bool B, class T = nat>
+struct enable_if_c
+{
+   typedef T type;
+};
+
+//////////////////////////////////////
+//          enable_if_c
+//////////////////////////////////////
+template <class T>
+struct enable_if_c<false, T> {};
+
+//////////////////////////////////////
+//           enable_if
+//////////////////////////////////////
+template <class Cond, class T = nat>
+struct enable_if : public enable_if_c<Cond::value, T> {};
+
+//////////////////////////////////////
+//          remove_reference
+//////////////////////////////////////
+template<class T>
+struct remove_reference
+{
+   typedef T type;
+};
+
+template<class T>
+struct remove_reference<T&>
+{
+   typedef T type;
+};
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+template<class T>
+struct remove_reference<T&&>
+{
+   typedef T type;
+};
+
+#else
+
+template<class T>
+struct remove_reference< rv<T> >
+{
+   typedef T type;
+};
+
+template<class T>
+struct remove_reference< rv<T> &>
+{
+   typedef T type;
+};
+
+template<class T>
+struct remove_reference< const rv<T> &>
+{
+   typedef T type;
+};
+
+
+#endif
+
+//////////////////////////////////////
+//             remove_const
+//////////////////////////////////////
+template< class T >
+struct remove_const
+{
+   typedef T type;
+};
+
+template< class T >
+struct remove_const<const T>
+{
+   typedef T type;
+};
+
+//////////////////////////////////////
+//             remove_volatile
+//////////////////////////////////////
+template< class T >
+struct remove_volatile
+{
+   typedef T type;
+};
+
+template< class T >
+struct remove_volatile<volatile T>
+{
+   typedef T type;
+};
+
+//////////////////////////////////////
+//             remove_cv
+//////////////////////////////////////
+template< class T >
+struct remove_cv
+{
+    typedef typename remove_volatile
+      <typename remove_const<T>::type>::type type;
+};
+
+//////////////////////////////////////
+//          remove_extent
+//////////////////////////////////////
+template<class T>
+struct remove_extent
+{
+   typedef T type;
+};
+ 
+template<class T>
+struct remove_extent<T[]>
+{
+   typedef T type;
+};
+ 
+template<class T, std::size_t N>
+struct remove_extent<T[N]>
+{
+   typedef T type;
+};
+
+//////////////////////////////////////
+//             extent
+//////////////////////////////////////
+
+template<class T, unsigned N = 0>
+struct extent
+{
+   static const std::size_t value = 0;
+};
+ 
+template<class T>
+struct extent<T[], 0> 
+{
+   static const std::size_t value = 0;
+};
+
+template<class T, unsigned N>
+struct extent<T[], N>
+{
+   static const std::size_t value = extent<T, N-1>::value;
+};
+
+template<class T, std::size_t N>
+struct extent<T[N], 0> 
+{
+   static const std::size_t value = N;
+};
+ 
+template<class T, std::size_t I, unsigned N>
+struct extent<T[I], N>
+{
+   static const std::size_t value = extent<T, N-1>::value;
+};
+
+//////////////////////////////////////
+//      add_lvalue_reference
+//////////////////////////////////////
+template<class T>
+struct add_lvalue_reference
+{
+   typedef T& type;
+};
+
+template<class T>
+struct add_lvalue_reference<T&>
+{
+   typedef T& type;
+};
+
+template<>
+struct add_lvalue_reference<void>
+{
+   typedef void type;
+};
+
+template<>
+struct add_lvalue_reference<const void>
+{
+   typedef const void type;
+};
+
+template<>
+struct add_lvalue_reference<volatile void>
+{
+   typedef volatile void type;
+};
+
+template<>
+struct add_lvalue_reference<const volatile void>
+{
+   typedef const volatile void type;
+};
+
+template<class T>
+struct add_const_lvalue_reference
+{
+   typedef typename remove_reference<T>::type   t_unreferenced;
+   typedef const t_unreferenced                 t_unreferenced_const;
+   typedef typename add_lvalue_reference
+      <t_unreferenced_const>::type              type;
+};
+
+//////////////////////////////////////
+//             is_same
+//////////////////////////////////////
+template<class T, class U>
+struct is_same
+{
+   static const bool value = false;
+};
+ 
+template<class T>
+struct is_same<T, T>
+{
+   static const bool value = true;
+};
+
+//////////////////////////////////////
+//             is_pointer
+//////////////////////////////////////
+template< class T >
+struct is_pointer
+{
+    static const bool value = false;
+};
+
+template< class T >
+struct is_pointer<T*>
+{
+    static const bool value = true;
+};
+
+//////////////////////////////////////
+//             is_reference
+//////////////////////////////////////
+template< class T >
+struct is_reference
+{
+    static const bool value = false;
+};
+
+template< class T >
+struct is_reference<T&>
+{
+    static const bool value = true;
+};
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+template< class T >
+struct is_reference<T&&>
+{
+    static const bool value = true;
+};
+
+#endif
+
+//////////////////////////////////////
+//             is_lvalue_reference
+//////////////////////////////////////
+template<class T>
+struct is_lvalue_reference
+{
+    static const bool value = false;
+};
+
+template<class T>
+struct is_lvalue_reference<T&>
+{
+    static const bool value = true;
+};
+
+//////////////////////////////////////
+//          is_array
+//////////////////////////////////////
+template<class T>
+struct is_array
+{
+   static const bool value = false;
+};
+ 
+template<class T>
+struct is_array<T[]>
+{
+   static const bool value = true;
+};
+ 
+template<class T, std::size_t N>
+struct is_array<T[N]>
+{
+   static const bool value = true;
+};
+
+//////////////////////////////////////
+//          has_pointer_type
+//////////////////////////////////////
+template <class T>
+struct has_pointer_type
+{
+   struct two { char c[2]; };
+   template <class U> static two test(...);
+   template <class U> static char test(typename U::pointer* = 0);
+   static const bool value = sizeof(test<T>(0)) == 1;
+};
+
+//////////////////////////////////////
+//             pointer_type
+//////////////////////////////////////
+template <class T, class D, bool = has_pointer_type<D>::value>
+struct pointer_type_imp
+{
+    typedef typename D::pointer type;
+};
+
+template <class T, class D>
+struct pointer_type_imp<T, D, false>
+{
+    typedef T* type;
+};
+
+template <class T, class D>
+struct pointer_type
+{
+    typedef typename pointer_type_imp
+      <typename remove_extent<T>::type, typename remove_reference<D>::type>::type type;
+};
+
+//////////////////////////////////////
+//           is_convertible
+//////////////////////////////////////
+#if defined(_MSC_VER) && (_MSC_VER >= 1400)
+
+//use intrinsic since in MSVC
+//overaligned types can't go through ellipsis
+template <class T, class U>
+struct is_convertible
+{
+   static const bool value = __is_convertible_to(T, U);
+};
+
+#else
+
+template <class T, class U>
+class is_convertible
+{
+   typedef typename add_lvalue_reference<T>::type t_reference;
+   typedef char true_t;
+   class false_t { char dummy[2]; };
+   static false_t dispatch(...);
+   static true_t  dispatch(U);
+   static t_reference       trigger();
+   public:
+   static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
+};
+
+#endif
+
+//////////////////////////////////////
+//       is_unary_function
+//////////////////////////////////////
+#if defined(BOOST_MSVC) || defined(__BORLANDC_)
+#define BOOST_MOVE_TT_DECL __cdecl
+#else
+#define BOOST_MOVE_TT_DECL
+#endif
+
+#if defined(_MSC_EXTENSIONS) && !defined(__BORLAND__) && !defined(_WIN64) && !defined(_M_ARM) && !defined(_M_ARM64) && !defined(UNDER_CE)
+#define BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
+#endif
+
+template <typename T>
+struct is_unary_function_impl
+{  static const bool value = false; };
+
+// avoid duplicate definitions of is_unary_function_impl
+#ifndef BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
+
+template <typename R>
+struct is_unary_function_impl<R (*)()>
+{  static const bool value = true;  };
+
+template <typename R>
+struct is_unary_function_impl<R (*)(...)>
+{  static const bool value = true;  };
+
+#else // BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
+
+template <typename R>
+struct is_unary_function_impl<R (__stdcall*)()>
+{  static const bool value = true;  };
+
+#ifndef _MANAGED
+
+template <typename R>
+struct is_unary_function_impl<R (__fastcall*)()>
+{  static const bool value = true;  };
+
+#endif
+
+template <typename R>
+struct is_unary_function_impl<R (__cdecl*)()>
+{  static const bool value = true;  };
+
+template <typename R>
+struct is_unary_function_impl<R (__cdecl*)(...)>
+{  static const bool value = true;  };
+
+#endif
+
+// avoid duplicate definitions of is_unary_function_impl
+#ifndef BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
+
+template <typename R, class T0>
+struct is_unary_function_impl<R (*)(T0)>
+{  static const bool value = true;  };
+
+template <typename R, class T0>
+struct is_unary_function_impl<R (*)(T0...)>
+{  static const bool value = true;  };
+
+#else // BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
+
+template <typename R, class T0>
+struct is_unary_function_impl<R (__stdcall*)(T0)>
+{  static const bool value = true;  };
+
+#ifndef _MANAGED
+
+template <typename R, class T0>
+struct is_unary_function_impl<R (__fastcall*)(T0)>
+{  static const bool value = true;  };
+
+#endif
+
+template <typename R, class T0>
+struct is_unary_function_impl<R (__cdecl*)(T0)>
+{  static const bool value = true;  };
+
+template <typename R, class T0>
+struct is_unary_function_impl<R (__cdecl*)(T0...)>
+{  static const bool value = true;  };
+
+#endif
+
+template <typename T>
+struct is_unary_function_impl<T&>
+{  static const bool value = false; };
+
+template<typename T>
+struct is_unary_function
+{  static const bool value = is_unary_function_impl<T>::value;   };
+
+//////////////////////////////////////
+//       has_virtual_destructor
+//////////////////////////////////////
+#if (defined(BOOST_MSVC) && defined(BOOST_MSVC_FULL_VER) && (BOOST_MSVC_FULL_VER >=140050215))\
+         || (defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1500))
+#  define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
+#elif defined(BOOST_CLANG) && defined(__has_feature)
+#  if __has_feature(has_virtual_destructor)
+#     define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
+#  endif
+#elif defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3) && !defined(__GCCXML__))) && !defined(BOOST_CLANG)
+#  define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
+#elif defined(__ghs__) && (__GHS_VERSION_NUMBER >= 600)
+#  define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
+#elif defined(__CODEGEARC__)
+#  define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
+#endif
+
+#ifdef BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR
+   template<class T>
+   struct has_virtual_destructor{   static const bool value = BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T);  };
+#else
+   //If no intrinsic is available you trust the programmer knows what is doing
+   template<class T>
+   struct has_virtual_destructor{   static const bool value = true;  };
+#endif
+
+//////////////////////////////////////
+//       missing_virtual_destructor
+//////////////////////////////////////
+
+template< class T, class U
+        , bool enable =  is_convertible< U*, T*>::value &&
+                        !is_array<T>::value &&
+                        !is_same<typename remove_cv<T>::type, void>::value &&
+                        !is_same<typename remove_cv<U>::type, typename remove_cv<T>::type>::value
+        >
+struct missing_virtual_destructor_default_delete
+{  static const bool value = !has_virtual_destructor<T>::value;  };
+
+template<class T, class U>
+struct missing_virtual_destructor_default_delete<T, U, false>
+{  static const bool value = false;  };
+
+template<class Deleter, class U>
+struct missing_virtual_destructor
+{  static const bool value = false;  };
+
+template<class T, class U>
+struct missing_virtual_destructor< ::boost::movelib::default_delete<T>, U >
+   : missing_virtual_destructor_default_delete<T, U>
+{};
+
+}  //namespace move_upmu {
+}  //namespace boost {
+
+#endif //#ifndef BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP
diff --git a/include/boost/move/detail/workaround.hpp b/include/boost/move/detail/workaround.hpp
new file mode 100644
index 0000000..1d16f24
--- /dev/null
+++ b/include/boost/move/detail/workaround.hpp
@@ -0,0 +1,69 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2014. 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)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_MOVE_DETAIL_WORKAROUND_HPP
+#define BOOST_MOVE_DETAIL_WORKAROUND_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#if    !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+   #define BOOST_MOVE_PERFECT_FORWARDING
+#endif
+
+#if defined(__has_feature)
+   #define BOOST_MOVE_HAS_FEATURE __has_feature
+#else
+   #define BOOST_MOVE_HAS_FEATURE(x) 0
+#endif
+
+#if BOOST_MOVE_HAS_FEATURE(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
+   #define BOOST_MOVE_ADDRESS_SANITIZER_ON
+#endif
+
+//Macros for documentation purposes. For code, expands to the argument
+#define BOOST_MOVE_IMPDEF(TYPE) TYPE
+#define BOOST_MOVE_SEEDOC(TYPE) TYPE
+#define BOOST_MOVE_DOC0PTR(TYPE) TYPE
+#define BOOST_MOVE_DOC1ST(TYPE1, TYPE2) TYPE2
+#define BOOST_MOVE_I ,
+#define BOOST_MOVE_DOCIGN(T1) T1
+
+#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 5) && !defined(__clang__)
+   //Pre-standard rvalue binding rules
+   #define BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+#elif defined(_MSC_VER) && (_MSC_VER == 1600)
+   //Standard rvalue binding rules but with some bugs
+   #define BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG
+   #define BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG
+#elif defined(_MSC_VER) && (_MSC_VER == 1700)
+   #define BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG
+#endif
+
+#if defined(BOOST_MOVE_DISABLE_FORCEINLINE)
+   #define BOOST_MOVE_FORCEINLINE inline
+#elif defined(BOOST_MOVE_FORCEINLINE_IS_BOOST_FORCELINE)
+   #define BOOST_MOVE_FORCEINLINE BOOST_FORCEINLINE
+#elif defined(BOOST_MSVC) && defined(_DEBUG)
+   //"__forceinline" and MSVC seems to have some bugs in debug mode
+   #define BOOST_MOVE_FORCEINLINE inline
+#elif defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && (__GNUC_MINOR__ < 5)))
+   //Older GCCs have problems with forceinline
+   #define BOOST_MOVE_FORCEINLINE inline
+#else
+   #define BOOST_MOVE_FORCEINLINE BOOST_FORCEINLINE
+#endif
+
+#endif   //#ifndef BOOST_MOVE_DETAIL_WORKAROUND_HPP
diff --git a/include/boost/move/iterator.hpp b/include/boost/move/iterator.hpp
new file mode 100644
index 0000000..f36df23
--- /dev/null
+++ b/include/boost/move/iterator.hpp
@@ -0,0 +1,311 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2012-2012.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
+
+#ifndef BOOST_MOVE_ITERATOR_HPP
+#define BOOST_MOVE_ITERATOR_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/detail/workaround.hpp>  //forceinline
+#include <boost/move/detail/iterator_traits.hpp>
+#include <boost/move/utility_core.hpp>
+
+namespace boost {
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                            move_iterator
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! Class template move_iterator is an iterator adaptor with the same behavior
+//! as the underlying iterator except that its dereference operator implicitly
+//! converts the value returned by the underlying iterator's dereference operator
+//! to an rvalue reference. Some generic algorithms can be called with move
+//! iterators to replace copying with moving.
+template <class It>
+class move_iterator
+{
+   public:
+   typedef It                                                              iterator_type;
+   typedef typename boost::movelib::iterator_traits<iterator_type>::value_type        value_type;
+   #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
+   typedef value_type &&                                                   reference;
+   #else
+   typedef typename ::boost::move_detail::if_
+      < ::boost::has_move_emulation_enabled<value_type>
+      , ::boost::rv<value_type>&
+      , value_type & >::type                                               reference;
+   #endif
+   typedef It                                                              pointer;
+   typedef typename boost::movelib::iterator_traits<iterator_type>::difference_type   difference_type;
+   typedef typename boost::movelib::iterator_traits<iterator_type>::iterator_category iterator_category;
+
+   BOOST_MOVE_FORCEINLINE move_iterator()
+      : m_it()
+   {}
+
+   BOOST_MOVE_FORCEINLINE explicit move_iterator(const It &i)
+      :  m_it(i)
+   {}
+
+   template <class U>
+   BOOST_MOVE_FORCEINLINE move_iterator(const move_iterator<U>& u)
+      :  m_it(u.m_it)
+   {}
+
+   BOOST_MOVE_FORCEINLINE reference operator*() const
+   {
+      #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
+      return *m_it;
+      #else
+      return ::boost::move(*m_it);
+      #endif
+   }
+
+   BOOST_MOVE_FORCEINLINE pointer   operator->() const
+   {  return m_it;   }
+
+   BOOST_MOVE_FORCEINLINE move_iterator& operator++()
+   {  ++m_it; return *this;   }
+
+   BOOST_MOVE_FORCEINLINE move_iterator<iterator_type>  operator++(int)
+   {  move_iterator<iterator_type> tmp(*this); ++(*this); return tmp;   }
+
+   BOOST_MOVE_FORCEINLINE move_iterator& operator--()
+   {  --m_it; return *this;   }
+
+   BOOST_MOVE_FORCEINLINE move_iterator<iterator_type>  operator--(int)
+   {  move_iterator<iterator_type> tmp(*this); --(*this); return tmp;   }
+
+   move_iterator<iterator_type>  operator+ (difference_type n) const
+   {  return move_iterator<iterator_type>(m_it + n);  }
+
+   BOOST_MOVE_FORCEINLINE move_iterator& operator+=(difference_type n)
+   {  m_it += n; return *this;   }
+
+   BOOST_MOVE_FORCEINLINE move_iterator<iterator_type>  operator- (difference_type n) const
+   {  return move_iterator<iterator_type>(m_it - n);  }
+
+   BOOST_MOVE_FORCEINLINE move_iterator& operator-=(difference_type n)
+   {  m_it -= n; return *this;   }
+
+   BOOST_MOVE_FORCEINLINE reference operator[](difference_type n) const
+   {
+      #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
+      return m_it[n];
+      #else
+      return ::boost::move(m_it[n]);
+      #endif
+   }
+
+   BOOST_MOVE_FORCEINLINE friend bool operator==(const move_iterator& x, const move_iterator& y)
+   {  return x.m_it == y.m_it;  }
+
+   BOOST_MOVE_FORCEINLINE friend bool operator!=(const move_iterator& x, const move_iterator& y)
+   {  return x.m_it != y.m_it;  }
+
+   BOOST_MOVE_FORCEINLINE friend bool operator< (const move_iterator& x, const move_iterator& y)
+   {  return x.m_it < y.m_it;   }
+
+   BOOST_MOVE_FORCEINLINE friend bool operator<=(const move_iterator& x, const move_iterator& y)
+   {  return x.m_it <= y.m_it;  }
+
+   BOOST_MOVE_FORCEINLINE friend bool operator> (const move_iterator& x, const move_iterator& y)
+   {  return x.m_it > y.m_it;  }
+
+   BOOST_MOVE_FORCEINLINE friend bool operator>=(const move_iterator& x, const move_iterator& y)
+   {  return x.m_it >= y.m_it;  }
+
+   BOOST_MOVE_FORCEINLINE friend difference_type operator-(const move_iterator& x, const move_iterator& y)
+   {  return x.m_it - y.m_it;   }
+
+   BOOST_MOVE_FORCEINLINE friend move_iterator operator+(difference_type n, const move_iterator& x)
+   {  return move_iterator(x.m_it + n);   }
+
+   private:
+   It m_it;
+};
+
+//is_move_iterator
+namespace move_detail {
+
+template <class I>
+struct is_move_iterator
+{
+   static const bool value = false;
+};
+
+template <class I>
+struct is_move_iterator< ::boost::move_iterator<I> >
+{
+   static const bool value = true;
+};
+
+}  //namespace move_detail {
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                            move_iterator
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//!
+//! <b>Returns</b>: move_iterator<It>(i).
+template<class It>
+inline move_iterator<It> make_move_iterator(const It &it)
+{  return move_iterator<It>(it); }
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                         back_move_insert_iterator
+//
+//////////////////////////////////////////////////////////////////////////////
+
+
+//! A move insert iterator that move constructs elements at the
+//! back of a container
+template <typename C> // C models Container
+class back_move_insert_iterator
+{
+   C* container_m;
+
+   public:
+   typedef C                           container_type;
+   typedef typename C::value_type      value_type;
+   typedef typename C::reference       reference;
+   typedef typename C::pointer         pointer;
+   typedef typename C::difference_type difference_type;
+   typedef std::output_iterator_tag    iterator_category;
+
+   explicit back_move_insert_iterator(C& x) : container_m(&x) { }
+
+   back_move_insert_iterator& operator=(reference x)
+   { container_m->push_back(boost::move(x)); return *this; }
+
+   back_move_insert_iterator& operator=(BOOST_RV_REF(value_type) x)
+   {  reference rx = x; return this->operator=(rx);  }
+
+   back_move_insert_iterator& operator*()     { return *this; }
+   back_move_insert_iterator& operator++()    { return *this; }
+   back_move_insert_iterator& operator++(int) { return *this; }
+};
+
+//!
+//! <b>Returns</b>: back_move_insert_iterator<C>(x).
+template <typename C> // C models Container
+inline back_move_insert_iterator<C> back_move_inserter(C& x)
+{
+   return back_move_insert_iterator<C>(x);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                         front_move_insert_iterator
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! A move insert iterator that move constructs elements int the
+//! front of a container
+template <typename C> // C models Container
+class front_move_insert_iterator
+{
+   C* container_m;
+
+public:
+   typedef C                           container_type;
+   typedef typename C::value_type      value_type;
+   typedef typename C::reference       reference;
+   typedef typename C::pointer         pointer;
+   typedef typename C::difference_type difference_type;
+   typedef std::output_iterator_tag    iterator_category;
+
+   explicit front_move_insert_iterator(C& x) : container_m(&x) { }
+
+   front_move_insert_iterator& operator=(reference x)
+   { container_m->push_front(boost::move(x)); return *this; }
+
+   front_move_insert_iterator& operator=(BOOST_RV_REF(value_type) x)
+   {  reference rx = x; return this->operator=(rx);  }
+
+   front_move_insert_iterator& operator*()     { return *this; }
+   front_move_insert_iterator& operator++()    { return *this; }
+   front_move_insert_iterator& operator++(int) { return *this; }
+};
+
+//!
+//! <b>Returns</b>: front_move_insert_iterator<C>(x).
+template <typename C> // C models Container
+inline front_move_insert_iterator<C> front_move_inserter(C& x)
+{
+   return front_move_insert_iterator<C>(x);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                         insert_move_iterator
+//
+//////////////////////////////////////////////////////////////////////////////
+template <typename C> // C models Container
+class move_insert_iterator
+{
+   C* container_m;
+   typename C::iterator pos_;
+
+   public:
+   typedef C                           container_type;
+   typedef typename C::value_type      value_type;
+   typedef typename C::reference       reference;
+   typedef typename C::pointer         pointer;
+   typedef typename C::difference_type difference_type;
+   typedef std::output_iterator_tag    iterator_category;
+
+   explicit move_insert_iterator(C& x, typename C::iterator pos)
+      : container_m(&x), pos_(pos)
+   {}
+
+   move_insert_iterator& operator=(reference x)
+   {
+      pos_ = container_m->insert(pos_, ::boost::move(x));
+      ++pos_;
+      return *this;
+   }
+
+   move_insert_iterator& operator=(BOOST_RV_REF(value_type) x)
+   {  reference rx = x; return this->operator=(rx);  }
+
+   move_insert_iterator& operator*()     { return *this; }
+   move_insert_iterator& operator++()    { return *this; }
+   move_insert_iterator& operator++(int) { return *this; }
+};
+
+//!
+//! <b>Returns</b>: move_insert_iterator<C>(x, it).
+template <typename C> // C models Container
+inline move_insert_iterator<C> move_inserter(C& x, typename C::iterator it)
+{
+   return move_insert_iterator<C>(x, it);
+}
+
+}  //namespace boost {
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_MOVE_ITERATOR_HPP
diff --git a/include/boost/move/make_unique.hpp b/include/boost/move/make_unique.hpp
new file mode 100644
index 0000000..ef106db
--- /dev/null
+++ b/include/boost/move/make_unique.hpp
@@ -0,0 +1,238 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2006-2014. 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_MOVE_MAKE_UNIQUE_HPP_INCLUDED
+#define BOOST_MOVE_MAKE_UNIQUE_HPP_INCLUDED
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/detail/workaround.hpp>
+#include <boost/move/utility_core.hpp>
+#include <boost/move/unique_ptr.hpp>
+#include <cstddef>   //for std::size_t
+#include <boost/move/detail/unique_ptr_meta_utils.hpp>
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+#  include <boost/move/detail/fwd_macros.hpp>
+#endif
+
+//!\file
+//! Defines "make_unique" functions, which are factories to create instances
+//! of unique_ptr depending on the passed arguments.
+//!
+//! This header can be a bit heavyweight in C++03 compilers due to the use of the
+//! preprocessor library, that's why it's a a separate header from <tt>unique_ptr.hpp</tt>
+ 
+#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+namespace std {   //no namespace versioning in clang+libc++
+
+struct nothrow_t;
+
+}  //namespace std {
+
+namespace boost{
+namespace move_upmu {
+
+//Compile time switch between
+//single element, unknown bound array
+//and known bound array
+template<class T>
+struct unique_ptr_if
+{
+   typedef ::boost::movelib::unique_ptr<T> t_is_not_array;
+};
+
+template<class T>
+struct unique_ptr_if<T[]>
+{
+   typedef ::boost::movelib::unique_ptr<T[]> t_is_array_of_unknown_bound;
+};
+
+template<class T, std::size_t N>
+struct unique_ptr_if<T[N]>
+{
+   typedef void t_is_array_of_known_bound;
+};
+
+template <int Dummy = 0>
+struct nothrow_holder
+{
+   static std::nothrow_t *pnothrow;   
+};
+
+template <int Dummy>
+std::nothrow_t *nothrow_holder<Dummy>::pnothrow = 
+   reinterpret_cast<std::nothrow_t *>(0x1234);  //Avoid reference to null errors in sanitizers
+
+}  //namespace move_upmu {
+}  //namespace boost{
+
+#endif   //!defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+namespace boost{
+namespace movelib {
+
+#if defined(BOOST_MOVE_DOXYGEN_INVOKED) || !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is not an array.
+//!
+//! <b>Returns</b>: <tt>unique_ptr<T>(new T(std::forward<Args>(args)...))</tt>.
+template<class T, class... Args>
+inline BOOST_MOVE_DOC1ST(unique_ptr<T>, 
+   typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array)
+      make_unique(BOOST_FWD_REF(Args)... args)
+{  return unique_ptr<T>(new T(::boost::forward<Args>(args)...));  }
+
+//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is not an array.
+//!
+//! <b>Returns</b>: <tt>unique_ptr<T>(new T(std::nothrow)(std::forward<Args>(args)...))</tt>.
+template<class T, class... Args>
+inline BOOST_MOVE_DOC1ST(unique_ptr<T>, 
+   typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array)
+      make_unique_nothrow(BOOST_FWD_REF(Args)... args)
+{  return unique_ptr<T>(new (*boost::move_upmu::nothrow_holder<>::pnothrow)T(::boost::forward<Args>(args)...));  }
+
+#else
+   #define BOOST_MOVE_MAKE_UNIQUE_CODE(N)\
+      template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N>\
+      typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array\
+         make_unique( BOOST_MOVE_UREF##N)\
+      {  return unique_ptr<T>( new T( BOOST_MOVE_FWD##N ) );  }\
+      \
+      template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N>\
+      typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array\
+         make_unique_nothrow( BOOST_MOVE_UREF##N)\
+      {  return unique_ptr<T>( new (*boost::move_upmu::nothrow_holder<>::pnothrow)T ( BOOST_MOVE_FWD##N ) );  }\
+      //
+   BOOST_MOVE_ITERATE_0TO9(BOOST_MOVE_MAKE_UNIQUE_CODE)
+   #undef BOOST_MOVE_MAKE_UNIQUE_CODE
+
+#endif
+
+//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is not an array.
+//!
+//! <b>Returns</b>: <tt>unique_ptr<T>(new T)</tt> (default initialization)
+template<class T>
+inline BOOST_MOVE_DOC1ST(unique_ptr<T>, 
+   typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array)
+      make_unique_definit()
+{
+    return unique_ptr<T>(new T);
+}
+
+//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is not an array.
+//!
+//! <b>Returns</b>: <tt>unique_ptr<T>(new T(std::nothrow)</tt> (default initialization)
+template<class T>
+inline BOOST_MOVE_DOC1ST(unique_ptr<T>, 
+   typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array)
+      make_unique_nothrow_definit()
+{
+    return unique_ptr<T>(new (*boost::move_upmu::nothrow_holder<>::pnothrow)T);
+}
+
+//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is an array of 
+//!   unknown bound.
+//!
+//! <b>Returns</b>: <tt>unique_ptr<T>(new remove_extent_t<T>[n]())</tt> (value initialization)
+template<class T>
+inline BOOST_MOVE_DOC1ST(unique_ptr<T>, 
+   typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_unknown_bound)
+      make_unique(std::size_t n)
+{
+    typedef typename ::boost::move_upmu::remove_extent<T>::type U;
+    return unique_ptr<T>(new U[n]());
+}
+
+//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is an array of 
+//!   unknown bound.
+//!
+//! <b>Returns</b>: <tt>unique_ptr<T>(new (std::nothrow)remove_extent_t<T>[n]())</tt> (value initialization)
+template<class T>
+inline BOOST_MOVE_DOC1ST(unique_ptr<T>, 
+   typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_unknown_bound)
+      make_unique_nothrow(std::size_t n)
+{
+    typedef typename ::boost::move_upmu::remove_extent<T>::type U;
+    return unique_ptr<T>(new (*boost::move_upmu::nothrow_holder<>::pnothrow)U[n]());
+}
+
+//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is an array of 
+//!   unknown bound.
+//!
+//! <b>Returns</b>: <tt>unique_ptr<T>(new remove_extent_t<T>[n])</tt> (default initialization)
+template<class T>
+inline BOOST_MOVE_DOC1ST(unique_ptr<T>, 
+   typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_unknown_bound)
+      make_unique_definit(std::size_t n)
+{
+    typedef typename ::boost::move_upmu::remove_extent<T>::type U;
+    return unique_ptr<T>(new U[n]);
+}
+
+//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is an array of 
+//!   unknown bound.
+//!
+//! <b>Returns</b>: <tt>unique_ptr<T>(new (std::nothrow)remove_extent_t<T>[n])</tt> (default initialization)
+template<class T>
+inline BOOST_MOVE_DOC1ST(unique_ptr<T>, 
+   typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_unknown_bound)
+      make_unique_nothrow_definit(std::size_t n)
+{
+    typedef typename ::boost::move_upmu::remove_extent<T>::type U;
+    return unique_ptr<T>(new (*boost::move_upmu::nothrow_holder<>::pnothrow) U[n]);
+}
+
+#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
+
+//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is
+//!   an array of known bound.
+template<class T, class... Args>
+inline BOOST_MOVE_DOC1ST(unspecified, 
+   typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_known_bound)
+      make_unique(BOOST_FWD_REF(Args) ...) = delete;
+
+//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is
+//!   an array of known bound.
+template<class T, class... Args>
+inline BOOST_MOVE_DOC1ST(unspecified, 
+   typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_known_bound)
+      make_unique_definit(BOOST_FWD_REF(Args) ...) = delete;
+
+//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is
+//!   an array of known bound.
+template<class T, class... Args>
+inline BOOST_MOVE_DOC1ST(unspecified, 
+   typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_known_bound)
+      make_unique_nothrow(BOOST_FWD_REF(Args) ...) = delete;
+
+//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is
+//!   an array of known bound.
+template<class T, class... Args>
+inline BOOST_MOVE_DOC1ST(unspecified, 
+   typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_known_bound)
+      make_unique_nothrow_definit(BOOST_FWD_REF(Args) ...) = delete;
+
+#endif
+
+}  //namespace movelib {
+
+}  //namespace boost{
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif   //#ifndef BOOST_MOVE_MAKE_UNIQUE_HPP_INCLUDED
diff --git a/include/boost/move/move.hpp b/include/boost/move/move.hpp
new file mode 100644
index 0000000..62dddbc
--- /dev/null
+++ b/include/boost/move/move.hpp
@@ -0,0 +1,35 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright David Abrahams, Vicente Botet 2009.
+// (C) Copyright Ion Gaztanaga 2009-2012.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
+//! A general library header that includes
+//! the rest of top-level headers.
+
+#ifndef BOOST_MOVE_MOVE_HPP
+#define BOOST_MOVE_MOVE_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/move/iterator.hpp>
+#include <boost/move/traits.hpp>
+#include <boost/move/algorithm.hpp>
+#include <boost/move/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_MOVE_MOVE_HPP
diff --git a/include/boost/move/traits.hpp b/include/boost/move/traits.hpp
new file mode 100644
index 0000000..b48b8f6
--- /dev/null
+++ b/include/boost/move/traits.hpp
@@ -0,0 +1,77 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009-2012.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
+
+#ifndef BOOST_MOVE_TRAITS_HPP
+#define BOOST_MOVE_TRAITS_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/config_begin.hpp>
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+#include <boost/move/core.hpp>
+#endif
+#include <boost/move/detail/meta_utils.hpp>
+#include <boost/move/detail/type_traits.hpp>
+
+namespace boost {
+
+//! If this trait yields to true
+//! (<i>has_trivial_destructor_after_move &lt;T&gt;::value == true</i>)
+//! means that if T is used as argument of a move construction/assignment,
+//! there is no need to call T's destructor.
+//! This optimization tipically is used to improve containers' performance.
+//!
+//! By default this trait is true if the type has trivial destructor,
+//! every class should specialize this trait if it wants to improve performance
+//! when inserted in containers.
+template <class T>
+struct has_trivial_destructor_after_move
+   : ::boost::move_detail::is_trivially_destructible<T>
+{};
+
+//! By default this traits returns
+//! <pre>boost::is_nothrow_move_constructible<T>::value && boost::is_nothrow_move_assignable<T>::value </pre>.
+//! Classes with non-throwing move constructor
+//! and assignment can specialize this trait to obtain some performance improvements.
+template <class T>
+struct has_nothrow_move
+{
+   static const bool value = boost::move_detail::is_nothrow_move_constructible<T>::value &&
+                             boost::move_detail::is_nothrow_move_assignable<T>::value;
+};
+
+namespace move_detail {
+
+template <class T>
+struct is_nothrow_move_constructible_or_uncopyable
+{
+   //The standard requires is_nothrow_move_constructible for move_if_noexcept
+   //but a user (usually in C++03) might specialize has_nothrow_move which includes it
+   static const bool value = is_nothrow_move_constructible<T>::value ||
+                             has_nothrow_move<T>::value ||
+                            !is_copy_constructible<T>::value;
+};
+
+}  //move_detail {
+}  //namespace boost {
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_MOVE_TRAITS_HPP
diff --git a/include/boost/move/unique_ptr.hpp b/include/boost/move/unique_ptr.hpp
new file mode 100644
index 0000000..2d794e8
--- /dev/null
+++ b/include/boost/move/unique_ptr.hpp
@@ -0,0 +1,871 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2014. 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_MOVE_UNIQUE_PTR_HPP_INCLUDED
+#define BOOST_MOVE_UNIQUE_PTR_HPP_INCLUDED
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/detail/workaround.hpp>  //forceinline
+#include <boost/move/detail/unique_ptr_meta_utils.hpp>
+#include <boost/move/default_delete.hpp>
+#include <boost/move/utility_core.hpp>
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/assert.hpp>
+
+#include <cstddef>   //For std::nullptr_t and std::size_t
+
+//!\file
+//! Describes the smart pointer unique_ptr, a drop-in replacement for std::unique_ptr,
+//! usable also from C++03 compilers.
+//!
+//! Main differences from std::unique_ptr to avoid heavy dependencies,
+//! specially in C++03 compilers:
+//!   - <tt>operator < </tt> uses pointer <tt>operator < </tt>instead of <tt>std::less<common_type></tt>. 
+//!      This avoids dependencies on <tt>std::common_type</tt> and <tt>std::less</tt>
+//!      (<tt><type_traits>/<functional></tt> headers). In C++03 this avoid pulling Boost.Typeof and other
+//!      cascading dependencies. As in all Boost platforms <tt>operator <</tt> on raw pointers and
+//!      other smart pointers provides strict weak ordering in practice this should not be a problem for users.
+//!   - assignable from literal 0 for compilers without nullptr
+//!   - <tt>unique_ptr<T[]></tt> is constructible and assignable from <tt>unique_ptr<U[]></tt> if
+//!      cv-less T and cv-less U are the same type and T is more CV qualified than U.
+
+namespace boost{
+// @cond
+namespace move_upd {
+
+////////////////////////////////////////////
+//          deleter types
+////////////////////////////////////////////
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+template <class T>
+class is_noncopyable
+{
+   typedef char true_t;
+   class false_t { char dummy[2]; };
+   template<class U> static false_t dispatch(...);
+   template<class U> static true_t  dispatch(typename U::boost_move_no_copy_constructor_or_assign*);
+   public:
+   static const bool value = sizeof(dispatch<T>(0)) == sizeof(true_t);
+};
+#endif   //defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+template <class D>
+struct deleter_types
+{
+   typedef typename bmupmu::add_lvalue_reference<D>::type            del_ref;
+   typedef typename bmupmu::add_const_lvalue_reference<D>::type      del_cref;
+   #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+   typedef typename bmupmu::if_c
+      < bmupmu::is_lvalue_reference<D>::value, D, del_cref >::type   deleter_arg_type1;
+   typedef typename bmupmu::remove_reference<D>::type &&             deleter_arg_type2;
+   #else
+   typedef typename bmupmu::if_c
+      < is_noncopyable<D>::value, bmupmu::nat, del_cref>::type       non_ref_deleter_arg1;
+   typedef typename bmupmu::if_c< bmupmu::is_lvalue_reference<D>::value
+                       , D, non_ref_deleter_arg1 >::type          deleter_arg_type1;
+   typedef ::boost::rv<D> &                                       deleter_arg_type2;
+   #endif
+};
+
+////////////////////////////////////////////
+//          unique_ptr_data
+////////////////////////////////////////////
+template <class P, class D, bool = bmupmu::is_unary_function<D>::value || bmupmu::is_reference<D>::value >
+struct unique_ptr_data
+{
+   typedef typename deleter_types<D>::deleter_arg_type1  deleter_arg_type1;
+   typedef typename deleter_types<D>::del_ref            del_ref;
+   typedef typename deleter_types<D>::del_cref           del_cref;
+
+   BOOST_MOVE_FORCEINLINE unique_ptr_data() BOOST_NOEXCEPT
+      : m_p(), d()
+   {}
+
+   BOOST_MOVE_FORCEINLINE explicit unique_ptr_data(P p) BOOST_NOEXCEPT
+      : m_p(p), d()
+   {}
+
+   BOOST_MOVE_FORCEINLINE unique_ptr_data(P p, deleter_arg_type1 d1) BOOST_NOEXCEPT
+      : m_p(p), d(d1)
+   {}
+
+   template <class U>
+   BOOST_MOVE_FORCEINLINE unique_ptr_data(P p, BOOST_FWD_REF(U) d1) BOOST_NOEXCEPT
+      : m_p(p), d(::boost::forward<U>(d1))
+   {}
+
+   BOOST_MOVE_FORCEINLINE del_ref deleter()       { return d; }
+   BOOST_MOVE_FORCEINLINE del_cref deleter() const{ return d; }
+
+   P m_p;
+   D d;
+
+   private:
+   unique_ptr_data& operator=(const unique_ptr_data&);
+   unique_ptr_data(const unique_ptr_data&);
+};
+
+template <class P, class D>
+struct unique_ptr_data<P, D, false>
+   : private D
+{
+   typedef typename deleter_types<D>::deleter_arg_type1  deleter_arg_type1;
+   typedef typename deleter_types<D>::del_ref            del_ref;
+   typedef typename deleter_types<D>::del_cref           del_cref;
+
+   BOOST_MOVE_FORCEINLINE unique_ptr_data() BOOST_NOEXCEPT
+      : D(), m_p()
+   {}
+
+   BOOST_MOVE_FORCEINLINE explicit unique_ptr_data(P p) BOOST_NOEXCEPT
+      : D(), m_p(p)
+   {}
+
+   BOOST_MOVE_FORCEINLINE unique_ptr_data(P p, deleter_arg_type1 d1) BOOST_NOEXCEPT
+      : D(d1), m_p(p)
+   {}
+
+   template <class U>
+   BOOST_MOVE_FORCEINLINE unique_ptr_data(P p, BOOST_FWD_REF(U) d) BOOST_NOEXCEPT
+      : D(::boost::forward<U>(d)), m_p(p)
+   {}
+
+   BOOST_MOVE_FORCEINLINE del_ref deleter()        BOOST_NOEXCEPT   {  return static_cast<del_ref>(*this);   }
+   BOOST_MOVE_FORCEINLINE del_cref deleter() const BOOST_NOEXCEPT   {  return static_cast<del_cref>(*this);  }
+
+   P m_p;
+
+   private:
+   unique_ptr_data& operator=(const unique_ptr_data&);
+   unique_ptr_data(const unique_ptr_data&);
+};
+
+////////////////////////////////////////////
+//          is_unique_ptr_convertible
+////////////////////////////////////////////
+
+//Although non-standard, we avoid using pointer_traits
+//to avoid heavy dependencies
+template <typename T>
+struct get_element_type
+{
+   struct DefaultWrap { typedef bmupmu::natify<T> element_type; };
+   template <typename X>   static char test(int, typename X::element_type*);
+   template <typename X>   static int test(...);
+   static const bool value = (1 == sizeof(test<T>(0, 0)));
+   typedef typename bmupmu::if_c<value, T, DefaultWrap>::type::element_type type;
+};
+
+template<class T>
+struct get_element_type<T*>
+{
+   typedef T type;
+};
+
+template<class T>
+struct get_cvelement
+   : bmupmu::remove_cv<typename get_element_type<T>::type>
+{};
+
+template <class P1, class P2>
+struct is_same_cvelement_and_convertible
+{
+   typedef typename bmupmu::remove_reference<P1>::type arg1;
+   typedef typename bmupmu::remove_reference<P2>::type arg2;
+   static const bool same_cvless =
+      bmupmu::is_same<typename get_cvelement<arg1>::type,typename get_cvelement<arg2>::type>::value;
+   static const bool value = same_cvless && bmupmu::is_convertible<arg1, arg2>::value;
+};
+
+template<bool IsArray, class FromPointer, class ThisPointer>
+struct is_unique_ptr_convertible
+   : is_same_cvelement_and_convertible<FromPointer, ThisPointer>
+{};
+
+template<class FromPointer, class ThisPointer>
+struct is_unique_ptr_convertible<false, FromPointer, ThisPointer>
+   : bmupmu::is_convertible<FromPointer, ThisPointer>
+{};
+
+////////////////////////////////////////
+////     enable_up_moveconv_assign
+////////////////////////////////////////
+
+template<class T, class FromPointer, class ThisPointer, class Type = bmupmu::nat>
+struct enable_up_ptr
+   : bmupmu::enable_if_c< is_unique_ptr_convertible
+      < bmupmu::is_array<T>::value, FromPointer, ThisPointer>::value, Type>
+{};
+
+////////////////////////////////////////
+////     enable_up_moveconv_assign
+////////////////////////////////////////
+
+template<class T, class D, class U, class E>
+struct unique_moveconvert_assignable
+{
+   static const bool t_is_array = bmupmu::is_array<T>::value;
+   static const bool value =
+      t_is_array == bmupmu::is_array<U>::value &&
+      bmupmu::extent<T>::value == bmupmu::extent<U>::value &&
+      is_unique_ptr_convertible
+         < t_is_array
+         , typename bmupmu::pointer_type<U, E>::type, typename bmupmu::pointer_type<T, D>::type
+         >::value;
+};
+
+template<class T, class D, class U, class E, std::size_t N>
+struct unique_moveconvert_assignable<T[], D, U[N], E>
+   : unique_moveconvert_assignable<T[], D, U[], E>
+{};
+
+template<class T, class D, class U, class E, class Type = bmupmu::nat>
+struct enable_up_moveconv_assign
+   : bmupmu::enable_if_c<unique_moveconvert_assignable<T, D, U, E>::value, Type>
+{};
+
+////////////////////////////////////////
+////     enable_up_moveconv_constr
+////////////////////////////////////////
+
+template<class D, class E, bool IsReference = bmupmu::is_reference<D>::value>
+struct unique_deleter_is_initializable
+   : bmupmu::is_same<D, E>
+{};
+
+template <class T, class U>
+class is_rvalue_convertible
+{
+   #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+   typedef typename bmupmu::remove_reference<T>::type&& t_from;
+   #else
+   typedef typename bmupmu::if_c
+      < ::boost::has_move_emulation_enabled<T>::value && !bmupmu::is_reference<T>::value
+      , ::boost::rv<T>&
+      , typename bmupmu::add_lvalue_reference<T>::type
+      >::type t_from;
+   #endif
+
+   typedef char true_t;
+   class false_t { char dummy[2]; };
+   static false_t dispatch(...);
+   static true_t  dispatch(U);
+   static t_from trigger();
+   public:
+   static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
+};
+
+template<class D, class E>
+struct unique_deleter_is_initializable<D, E, false>
+{
+   #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+   //Clang has some problems with is_rvalue_convertible with non-copyable types
+   //so use intrinsic if available
+   #if defined(BOOST_CLANG)
+      #if __has_feature(is_convertible_to)
+      static const bool value = __is_convertible_to(E, D);
+      #else
+      static const bool value = is_rvalue_convertible<E, D>::value;
+      #endif
+   #else
+   static const bool value = is_rvalue_convertible<E, D>::value;
+   #endif
+
+   #else //!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+   //No hope for compilers with move emulation for now. In several compilers is_convertible
+   // leads to errors, so just move the Deleter and see if the conversion works
+   static const bool value = true;  /*is_rvalue_convertible<E, D>::value*/
+   #endif
+};
+
+template<class T, class D, class U, class E, class Type = bmupmu::nat>
+struct enable_up_moveconv_constr
+   : bmupmu::enable_if_c
+      < unique_moveconvert_assignable<T, D, U, E>::value && unique_deleter_is_initializable<D, E>::value
+      , Type>
+{};
+
+}  //namespace move_upd {
+// @endcond
+
+namespace movelib {
+
+//! A unique pointer is an object that owns another object and
+//! manages that other object through a pointer.
+//! 
+//! More precisely, a unique pointer is an object u that stores a pointer to a second object p and will dispose
+//! of p when u is itself destroyed (e.g., when leaving block scope). In this context, u is said to own p.
+//! 
+//! The mechanism by which u disposes of p is known as p's associated deleter, a function object whose correct
+//! invocation results in p's appropriate disposition (typically its deletion).
+//! 
+//! Let the notation u.p denote the pointer stored by u, and let u.d denote the associated deleter. Upon request,
+//! u can reset (replace) u.p and u.d with another pointer and deleter, but must properly dispose of its owned
+//! object via the associated deleter before such replacement is considered completed.
+//! 
+//! Additionally, u can, upon request, transfer ownership to another unique pointer u2. Upon completion of
+//! such a transfer, the following postconditions hold:
+//!   - u2.p is equal to the pre-transfer u.p,
+//!   - u.p is equal to nullptr, and
+//!   - if the pre-transfer u.d maintained state, such state has been transferred to u2.d.
+//! 
+//! As in the case of a reset, u2 must properly dispose of its pre-transfer owned object via the pre-transfer
+//! associated deleter before the ownership transfer is considered complete.
+//! 
+//! Each object of a type U instantiated from the unique_ptr template specified in this subclause has the strict
+//! ownership semantics, specified above, of a unique pointer. In partial satisfaction of these semantics, each
+//! such U is MoveConstructible and MoveAssignable, but is not CopyConstructible nor CopyAssignable.
+//! The template parameter T of unique_ptr may be an incomplete type.
+//! 
+//! The uses of unique_ptr include providing exception safety for dynamically allocated memory, passing
+//! ownership of dynamically allocated memory to a function, and returning dynamically allocated memory from
+//! a function.
+//!
+//! If T is an array type (e.g. unique_ptr<MyType[]>) the interface is slightly altered:
+//!   - Pointers to types derived from T are rejected by the constructors, and by reset.
+//!   - The observers <tt>operator*</tt> and <tt>operator-></tt> are not provided.
+//!   - The indexing observer <tt>operator[]</tt> is provided.
+//!
+//! \tparam T Provides the type of the stored pointer.
+//! \tparam D The deleter type:
+//!   -  The default type for the template parameter D is default_delete. A client-supplied template argument
+//!      D shall be a function object type, lvalue-reference to function, or lvalue-reference to function object type
+//!      for which, given a value d of type D and a value ptr of type unique_ptr<T, D>::pointer, the expression
+//!      d(ptr) is valid and has the effect of disposing of the pointer as appropriate for that deleter.
+//!   -  If the deleter's type D is not a reference type, D shall satisfy the requirements of Destructible.
+//!   -  If the type <tt>remove_reference<D>::type::pointer</tt> exists, it shall satisfy the requirements of NullablePointer.
+template <class T, class D = default_delete<T> >
+class unique_ptr
+{
+   #if defined(BOOST_MOVE_DOXYGEN_INVOKED)
+   public:
+   unique_ptr(const unique_ptr&) = delete;
+   unique_ptr& operator=(const unique_ptr&) = delete;
+   private:
+   #else
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(unique_ptr)
+
+   typedef bmupmu::pointer_type<T, D >                            pointer_type_obtainer;
+   typedef bmupd::unique_ptr_data
+      <typename pointer_type_obtainer::type, D>                data_type;
+   typedef typename bmupd::deleter_types<D>::deleter_arg_type1 deleter_arg_type1;
+   typedef typename bmupd::deleter_types<D>::deleter_arg_type2 deleter_arg_type2;
+   data_type m_data;
+   #endif
+
+   public:
+   //! If the type <tt>remove_reference<D>::type::pointer</tt> exists, then it shall be a
+   //! synonym for <tt>remove_reference<D>::type::pointer</tt>. Otherwise it shall be a
+   //! synonym for T*.
+   typedef typename BOOST_MOVE_SEEDOC(pointer_type_obtainer::type) pointer;
+   //! If T is an array type, then element_type is equal to T. Otherwise, if T is a type
+   //! in the form U[], element_type is equal to U.
+   typedef typename BOOST_MOVE_SEEDOC(bmupmu::remove_extent<T>::type) element_type;
+   typedef D deleter_type;
+
+   //! <b>Requires</b>: D shall satisfy the requirements of DefaultConstructible, and
+   //!   that construction shall not throw an exception.
+   //!
+   //! <b>Effects</b>: Constructs a unique_ptr object that owns nothing, value-initializing the
+   //!   stored pointer and the stored deleter.
+   //!
+   //! <b>Postconditions</b>: <tt>get() == nullptr</tt>. <tt>get_deleter()</tt> returns a reference to the stored deleter.
+   //!
+   //! <b>Remarks</b>: If this constructor is instantiated with a pointer type or reference type
+   //!   for the template argument D, the program is ill-formed.   
+   BOOST_MOVE_FORCEINLINE BOOST_CONSTEXPR unique_ptr() BOOST_NOEXCEPT
+      : m_data()
+   {
+      //If this constructor is instantiated with a pointer type or reference type
+      //for the template argument D, the program is ill-formed.
+      BOOST_STATIC_ASSERT(!bmupmu::is_pointer<D>::value);
+      BOOST_STATIC_ASSERT(!bmupmu::is_reference<D>::value);
+   }
+
+   //! <b>Effects</b>: Same as <tt>unique_ptr()</tt> (default constructor).
+   //! 
+   BOOST_MOVE_FORCEINLINE BOOST_CONSTEXPR unique_ptr(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
+      : m_data()
+   {
+      //If this constructor is instantiated with a pointer type or reference type
+      //for the template argument D, the program is ill-formed.
+      BOOST_STATIC_ASSERT(!bmupmu::is_pointer<D>::value);
+      BOOST_STATIC_ASSERT(!bmupmu::is_reference<D>::value);
+   }
+
+   //! <b>Requires</b>: D shall satisfy the requirements of DefaultConstructible, and
+   //!   that construction shall not throw an exception.
+   //!
+   //! <b>Effects</b>: Constructs a unique_ptr which owns p, initializing the stored pointer 
+   //!   with p and value initializing the stored deleter.
+   //!
+   //! <b>Postconditions</b>: <tt>get() == p</tt>. <tt>get_deleter()</tt> returns a reference to the stored deleter.
+   //!
+   //! <b>Remarks</b>: If this constructor is instantiated with a pointer type or reference type
+   //!   for the template argument D, the program is ill-formed.
+   //!   This constructor shall not participate in overload resolution unless:
+   //!      - If T is not an array type and Pointer is implicitly convertible to pointer.
+   //!      - If T is an array type and Pointer is a more CV qualified pointer to element_type.
+   template<class Pointer>
+   BOOST_MOVE_FORCEINLINE explicit unique_ptr(Pointer p
+      BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_up_ptr<T BOOST_MOVE_I Pointer BOOST_MOVE_I pointer>::type* =0)
+                 ) BOOST_NOEXCEPT
+      : m_data(p)
+   {
+      //If T is not an array type, element_type_t<Pointer> derives from T
+      //it uses the default deleter and T has no virtual destructor, then you have a problem
+      BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor
+                            <D, typename bmupd::get_element_type<Pointer>::type>::value ));
+      //If this constructor is instantiated with a pointer type or reference type
+      //for the template argument D, the program is ill-formed.
+      BOOST_STATIC_ASSERT(!bmupmu::is_pointer<D>::value);
+      BOOST_STATIC_ASSERT(!bmupmu::is_reference<D>::value);
+   }
+
+   //!The signature of this constructor depends upon whether D is a reference type.
+   //!   - If D is non-reference type A, then the signature is <tt>unique_ptr(pointer p, const A& d)</tt>.
+   //!   - If D is an lvalue-reference type A&, then the signature is <tt>unique_ptr(pointer p, A& d)</tt>.
+   //!   - If D is an lvalue-reference type const A&, then the signature is <tt>unique_ptr(pointer p, const A& d)</tt>.
+   //!
+   //!
+   //! <b>Requires</b>: Either
+   //!   - D is not an lvalue-reference type and d is an lvalue or const rvalue. 
+   //!         D shall satisfy the requirements of CopyConstructible, and the copy constructor of D
+   //!         shall not throw an exception. This unique_ptr will hold a copy of d.
+   //!   - D is an lvalue-reference type and d is an lvalue. the type which D references need not be CopyConstructible nor
+   //!      MoveConstructible. This unique_ptr will hold a D which refers to the lvalue d.
+   //!
+   //! <b>Effects</b>: Constructs a unique_ptr object which owns p, initializing the stored pointer with p and
+   //!   initializing the deleter as described above.
+   //! 
+   //! <b>Postconditions</b>: <tt>get() == p</tt>. <tt>get_deleter()</tt> returns a reference to the stored deleter. If D is a
+   //!   reference type then <tt>get_deleter()</tt> returns a reference to the lvalue d.
+   //!
+   //! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
+   //!      - If T is not an array type and Pointer is implicitly convertible to pointer.
+   //!      - If T is an array type and Pointer is a more CV qualified pointer to element_type.
+   template<class Pointer>
+   BOOST_MOVE_FORCEINLINE unique_ptr(Pointer p, BOOST_MOVE_SEEDOC(deleter_arg_type1) d1
+      BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_up_ptr<T BOOST_MOVE_I Pointer BOOST_MOVE_I pointer>::type* =0)
+              ) BOOST_NOEXCEPT
+      : m_data(p, d1)
+   {
+      //If T is not an array type, element_type_t<Pointer> derives from T
+      //it uses the default deleter and T has no virtual destructor, then you have a problem
+      BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor
+                            <D, typename bmupd::get_element_type<Pointer>::type>::value ));
+   }
+
+   //! <b>Effects</b>: Same effects as <tt>template<class Pointer> unique_ptr(Pointer p, deleter_arg_type1 d1)</tt>
+   //!   and additionally <tt>get() == nullptr</tt>
+   BOOST_MOVE_FORCEINLINE unique_ptr(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), BOOST_MOVE_SEEDOC(deleter_arg_type1) d1) BOOST_NOEXCEPT
+      : m_data(pointer(), d1)
+   {}
+
+   //! The signature of this constructor depends upon whether D is a reference type.
+   //!   - If D is non-reference type A, then the signature is <tt>unique_ptr(pointer p, A&& d)</tt>.
+   //!   - If D is an lvalue-reference type A&, then the signature is <tt>unique_ptr(pointer p, A&& d)</tt>.
+   //!   - If D is an lvalue-reference type const A&, then the signature is <tt>unique_ptr(pointer p, const A&& d)</tt>.
+   //!
+   //! <b>Requires</b>: Either
+   //!   - D is not an lvalue-reference type and d is a non-const rvalue. D
+   //!      shall satisfy the requirements of MoveConstructible, and the move constructor
+   //!      of D shall not throw an exception. This unique_ptr will hold a value move constructed from d.
+   //!   - D is an lvalue-reference type and d is an rvalue, the program is ill-formed.
+   //!
+   //! <b>Effects</b>: Constructs a unique_ptr object which owns p, initializing the stored pointer with p and
+   //!   initializing the deleter as described above.
+   //! 
+   //! <b>Postconditions</b>: <tt>get() == p</tt>. <tt>get_deleter()</tt> returns a reference to the stored deleter. If D is a
+   //!   reference type then <tt>get_deleter()</tt> returns a reference to the lvalue d.
+   //!
+   //! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
+   //!      - If T is not an array type and Pointer is implicitly convertible to pointer.
+   //!      - If T is an array type and Pointer is a more CV qualified pointer to element_type.
+   template<class Pointer>
+   BOOST_MOVE_FORCEINLINE unique_ptr(Pointer p, BOOST_MOVE_SEEDOC(deleter_arg_type2) d2
+      BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_up_ptr<T BOOST_MOVE_I Pointer BOOST_MOVE_I pointer>::type* =0)
+             ) BOOST_NOEXCEPT
+      : m_data(p, ::boost::move(d2))
+   {
+      //If T is not an array type, element_type_t<Pointer> derives from T
+      //it uses the default deleter and T has no virtual destructor, then you have a problem
+      BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor
+                            <D, typename bmupd::get_element_type<Pointer>::type>::value ));
+   }
+
+   //! <b>Effects</b>: Same effects as <tt>template<class Pointer> unique_ptr(Pointer p, deleter_arg_type2 d2)</tt>
+   //!   and additionally <tt>get() == nullptr</tt>
+   BOOST_MOVE_FORCEINLINE unique_ptr(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), BOOST_MOVE_SEEDOC(deleter_arg_type2) d2) BOOST_NOEXCEPT
+      : m_data(pointer(), ::boost::move(d2))
+   {}
+
+   //! <b>Requires</b>: If D is not a reference type, D shall satisfy the requirements of MoveConstructible.
+   //! Construction of the deleter from an rvalue of type D shall not throw an exception.
+   //! 
+   //! <b>Effects</b>: Constructs a unique_ptr by transferring ownership from u to *this. If D is a reference type,
+   //! this deleter is copy constructed from u's deleter; otherwise, this deleter is move constructed from u's
+   //! deleter.
+   //! 
+   //! <b>Postconditions</b>: <tt>get()</tt> yields the value u.get() yielded before the construction. <tt>get_deleter()</tt>
+   //! returns a reference to the stored deleter that was constructed from u.get_deleter(). If D is a
+   //! reference type then <tt>get_deleter()</tt> and <tt>u.get_deleter()</tt> both reference the same lvalue deleter.
+   BOOST_MOVE_FORCEINLINE unique_ptr(BOOST_RV_REF(unique_ptr) u) BOOST_NOEXCEPT
+      : m_data(u.release(), ::boost::move_if_not_lvalue_reference<D>(u.get_deleter()))
+   {}
+
+   //! <b>Requires</b>: If E is not a reference type, construction of the deleter from an rvalue of type E shall be
+   //!   well formed and shall not throw an exception. Otherwise, E is a reference type and construction of the
+   //!   deleter from an lvalue of type E shall be well formed and shall not throw an exception.
+   //!
+   //! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
+   //!   - <tt>unique_ptr<U, E>::pointer</tt> is implicitly convertible to pointer,
+   //!   - U is not an array type, and
+   //!   - either D is a reference type and E is the same type as D, or D is not a reference type and E is
+   //!      implicitly convertible to D.
+   //!
+   //! <b>Effects</b>: Constructs a unique_ptr by transferring ownership from u to *this. If E is a reference type,
+   //!   this deleter is copy constructed from u's deleter; otherwise, this deleter is move constructed from u's deleter.
+   //!
+   //! <b>Postconditions</b>: <tt>get()</tt> yields the value <tt>u.get()</tt> yielded before the construction. <tt>get_deleter()</tt>
+   //!   returns a reference to the stored deleter that was constructed from <tt>u.get_deleter()</tt>.
+   template <class U, class E>
+   BOOST_MOVE_FORCEINLINE unique_ptr( BOOST_RV_REF_BEG_IF_CXX11 unique_ptr<U, E> BOOST_RV_REF_END_IF_CXX11 u
+      BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_up_moveconv_constr<T BOOST_MOVE_I D BOOST_MOVE_I U BOOST_MOVE_I E>::type* =0)
+      ) BOOST_NOEXCEPT
+      : m_data(u.release(), ::boost::move_if_not_lvalue_reference<E>(u.get_deleter()))
+   {
+      //If T is not an array type, U derives from T
+      //it uses the default deleter and T has no virtual destructor, then you have a problem
+      BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor
+                            <D, typename unique_ptr<U, E>::pointer>::value ));
+   }
+
+   //! <b>Requires</b>: The expression <tt>get_deleter()(get())</tt> shall be well formed, shall have well-defined behavior,
+   //!   and shall not throw exceptions.
+   //!
+   //! <b>Effects</b>: If <tt>get() == nullpt1r</tt> there are no effects. Otherwise <tt>get_deleter()(get())</tt>.
+   //!
+   //! <b>Note</b>: The use of default_delete requires T to be a complete type
+   ~unique_ptr()
+   {  if(m_data.m_p) m_data.deleter()(m_data.m_p);   }
+
+   //! <b>Requires</b>: If D is not a reference type, D shall satisfy the requirements of MoveAssignable
+   //!   and assignment of the deleter from an rvalue of type D shall not throw an exception. Otherwise, D
+   //!   is a reference type; <tt>remove_reference<D>::type</tt> shall satisfy the CopyAssignable requirements and
+   //!   assignment of the deleter from an lvalue of type D shall not throw an exception.
+   //!
+   //! <b>Effects</b>: Transfers ownership from u to *this as if by calling <tt>reset(u.release())</tt> followed
+   //!   by <tt>get_deleter() = std::forward<D>(u.get_deleter())</tt>.
+   //!
+   //! <b>Returns</b>: *this.
+   unique_ptr& operator=(BOOST_RV_REF(unique_ptr) u) BOOST_NOEXCEPT
+   {
+      this->reset(u.release());
+      m_data.deleter() = ::boost::move_if_not_lvalue_reference<D>(u.get_deleter());
+      return *this;
+   }
+
+   //! <b>Requires</b>: If E is not a reference type, assignment of the deleter from an rvalue of type E shall be
+   //!   well-formed and shall not throw an exception. Otherwise, E is a reference type and assignment of the
+   //!   deleter from an lvalue of type E shall be well-formed and shall not throw an exception.
+   //!
+   //! <b>Remarks</b>: This operator shall not participate in overload resolution unless:
+   //!   - <tt>unique_ptr<U, E>::pointer</tt> is implicitly convertible to pointer and
+   //!   - U is not an array type.
+   //!
+   //! <b>Effects</b>: Transfers ownership from u to *this as if by calling <tt>reset(u.release())</tt> followed by
+   //!   <tt>get_deleter() = std::forward<E>(u.get_deleter())</tt>.
+   //!
+   //! <b>Returns</b>: *this.
+   template <class U, class E>
+   BOOST_MOVE_DOC1ST(unique_ptr&, typename bmupd::enable_up_moveconv_assign
+         <T BOOST_MOVE_I D BOOST_MOVE_I U BOOST_MOVE_I E BOOST_MOVE_I unique_ptr &>::type)
+      operator=(BOOST_RV_REF_BEG unique_ptr<U, E> BOOST_RV_REF_END u) BOOST_NOEXCEPT
+   {
+      this->reset(u.release());
+      m_data.deleter() = ::boost::move_if_not_lvalue_reference<E>(u.get_deleter());
+      return *this;
+   }
+
+   //! <b>Effects</b>: <tt>reset()</tt>.
+   //!
+   //! <b>Postcondition</b>: <tt>get() == nullptr</tt>
+   //!
+   //! <b>Returns</b>: *this.
+   unique_ptr& operator=(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
+   {  this->reset(); return *this;  }
+
+   //! <b>Requires</b>: <tt>get() != nullptr</tt>.
+   //!
+   //! <b>Returns</b>: <tt>*get()</tt>.
+   //!
+   //! <b>Remarks</b: If T is an array type, the program is ill-formed.
+   BOOST_MOVE_DOC1ST(element_type&, typename bmupmu::add_lvalue_reference<element_type>::type)
+      operator*() const BOOST_NOEXCEPT
+   {
+      BOOST_STATIC_ASSERT((!bmupmu::is_array<T>::value));
+      return *m_data.m_p;
+   }
+
+   //! <b>Requires</b>: i < the number of elements in the array to which the stored pointer points.
+   //!
+   //! <b>Returns</b>: <tt>get()[i]</tt>.
+   //!
+   //! <b>Remarks</b: If T is not an array type, the program is ill-formed.
+   BOOST_MOVE_FORCEINLINE BOOST_MOVE_DOC1ST(element_type&, typename bmupmu::add_lvalue_reference<element_type>::type)
+      operator[](std::size_t i) const BOOST_NOEXCEPT
+   {
+      BOOST_ASSERT( bmupmu::extent<T>::value == 0 || i < bmupmu::extent<T>::value );
+      BOOST_ASSERT(m_data.m_p);
+      return m_data.m_p[i];
+   }
+
+   //! <b>Requires</b>: <tt>get() != nullptr</tt>.
+   //!
+   //! <b>Returns</b>: <tt>get()</tt>.
+   //!
+   //! <b>Note</b>: use typically requires that T be a complete type.
+   //!
+   //! <b>Remarks</b: If T is an array type, the program is ill-formed.
+   BOOST_MOVE_FORCEINLINE pointer operator->() const BOOST_NOEXCEPT
+   {
+      BOOST_STATIC_ASSERT((!bmupmu::is_array<T>::value));
+      BOOST_ASSERT(m_data.m_p);
+      return m_data.m_p;
+   }
+
+   //! <b>Returns</b>: The stored pointer.
+   //!
+   BOOST_MOVE_FORCEINLINE pointer get() const BOOST_NOEXCEPT
+   {  return m_data.m_p;  }
+
+   //! <b>Returns</b>: A reference to the stored deleter.
+   //!
+   BOOST_MOVE_FORCEINLINE BOOST_MOVE_DOC1ST(D&, typename bmupmu::add_lvalue_reference<D>::type)
+      get_deleter() BOOST_NOEXCEPT
+   {  return m_data.deleter();  }   
+
+   //! <b>Returns</b>: A reference to the stored deleter.
+   //!
+   BOOST_MOVE_FORCEINLINE BOOST_MOVE_DOC1ST(const D&, typename bmupmu::add_const_lvalue_reference<D>::type)
+      get_deleter() const BOOST_NOEXCEPT
+   {  return m_data.deleter();  }
+
+   #ifdef BOOST_MOVE_DOXYGEN_INVOKED
+   //! <b>Returns</b>: Returns: get() != nullptr.
+   //!
+   BOOST_MOVE_FORCEINLINE explicit operator bool
+   #else
+   BOOST_MOVE_FORCEINLINE operator bmupd::explicit_bool_arg
+   #endif
+      ()const BOOST_NOEXCEPT
+   {
+      return m_data.m_p
+         ? &bmupd::bool_conversion::for_bool
+         : bmupd::explicit_bool_arg(0);
+   }
+
+   //! <b>Postcondition</b>: <tt>get() == nullptr</tt>.
+   //!
+   //! <b>Returns</b>: The value <tt>get()</tt> had at the start of the call to release.   
+   BOOST_MOVE_FORCEINLINE pointer release() BOOST_NOEXCEPT
+   {
+      const pointer tmp = m_data.m_p;
+      m_data.m_p = pointer();
+      return tmp;
+   }
+
+   //! <b>Requires</b>: The expression <tt>get_deleter()(get())</tt> shall be well formed, shall have well-defined behavior,
+   //!   and shall not throw exceptions.
+   //!
+   //! <b>Effects</b>: assigns p to the stored pointer, and then if the old value of the stored pointer, old_p, was not
+   //!   equal to nullptr, calls <tt>get_deleter()(old_p)</tt>. Note: The order of these operations is significant
+   //!   because the call to <tt>get_deleter()</tt> may destroy *this.
+   //!
+   //! <b>Postconditions</b>: <tt>get() == p</tt>. Note: The postcondition does not hold if the call to <tt>get_deleter()</tt>
+   //!   destroys *this since <tt>this->get()</tt> is no longer a valid expression.
+   //!
+   //! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
+   //!      - If T is not an array type and Pointer is implicitly convertible to pointer.
+   //!      - If T is an array type and Pointer is a more CV qualified pointer to element_type.
+   template<class Pointer>
+   BOOST_MOVE_DOC1ST(void, typename bmupd::enable_up_ptr<T BOOST_MOVE_I Pointer BOOST_MOVE_I pointer BOOST_MOVE_I void>::type)
+      reset(Pointer p) BOOST_NOEXCEPT
+   {
+      //If T is not an array type, element_type_t<Pointer> derives from T
+      //it uses the default deleter and T has no virtual destructor, then you have a problem
+      BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor
+                            <D, typename bmupd::get_element_type<Pointer>::type>::value ));
+      pointer tmp = m_data.m_p;
+      m_data.m_p = p;
+      if(tmp) m_data.deleter()(tmp);
+   }
+
+   //! <b>Requires</b>: The expression <tt>get_deleter()(get())</tt> shall be well formed, shall have well-defined behavior,
+   //!   and shall not throw exceptions.
+   //!
+   //! <b>Effects</b>: assigns nullptr to the stored pointer, and then if the old value of the stored pointer, old_p, was not
+   //!   equal to nullptr, calls <tt>get_deleter()(old_p)</tt>. Note: The order of these operations is significant
+   //!   because the call to <tt>get_deleter()</tt> may destroy *this.
+   //!
+   //! <b>Postconditions</b>: <tt>get() == p</tt>. Note: The postcondition does not hold if the call to <tt>get_deleter()</tt>
+   //!   destroys *this since <tt>this->get()</tt> is no longer a valid expression.
+   void reset() BOOST_NOEXCEPT
+   {  this->reset(pointer());  }
+
+   //! <b>Effects</b>: Same as <tt>reset()</tt>
+   //! 
+   void reset(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
+   {  this->reset(); }
+
+   //! <b>Requires</b>: <tt>get_deleter()</tt> shall be swappable and shall not throw an exception under swap.
+   //!
+   //! <b>Effects</b>: Invokes swap on the stored pointers and on the stored deleters of *this and u.
+   void swap(unique_ptr& u) BOOST_NOEXCEPT
+   {
+      ::boost::adl_move_swap(m_data.m_p, u.m_data.m_p);
+      ::boost::adl_move_swap(m_data.deleter(), u.m_data.deleter());
+   }
+};
+
+//! <b>Effects</b>: Calls <tt>x.swap(y)</tt>.
+//!
+template <class T, class D>
+BOOST_MOVE_FORCEINLINE void swap(unique_ptr<T, D> &x, unique_ptr<T, D> &y) BOOST_NOEXCEPT
+{  x.swap(y); }
+
+//! <b>Returns</b>: <tt>x.get() == y.get()</tt>.
+//!
+template <class T1, class D1, class T2, class D2>
+BOOST_MOVE_FORCEINLINE bool operator==(const unique_ptr<T1, D1> &x, const unique_ptr<T2, D2> &y)
+{  return x.get() == y.get(); }
+
+//! <b>Returns</b>: <tt>x.get() != y.get()</tt>.
+//!
+template <class T1, class D1, class T2, class D2>
+BOOST_MOVE_FORCEINLINE bool operator!=(const unique_ptr<T1, D1> &x, const unique_ptr<T2, D2> &y)
+{  return x.get() != y.get(); }
+
+//! <b>Returns</b>: x.get() < y.get().
+//!
+//! <b>Remarks</b>: This comparison shall induce a
+//!   strict weak ordering betwen pointers.
+template <class T1, class D1, class T2, class D2>
+BOOST_MOVE_FORCEINLINE bool operator<(const unique_ptr<T1, D1> &x, const unique_ptr<T2, D2> &y)
+{  return x.get() < y.get();  }
+
+//! <b>Returns</b>: !(y < x).
+//!
+template <class T1, class D1, class T2, class D2>
+BOOST_MOVE_FORCEINLINE bool operator<=(const unique_ptr<T1, D1> &x, const unique_ptr<T2, D2> &y)
+{  return !(y < x);  }
+
+//! <b>Returns</b>: y < x.
+//!
+template <class T1, class D1, class T2, class D2>
+BOOST_MOVE_FORCEINLINE bool operator>(const unique_ptr<T1, D1> &x, const unique_ptr<T2, D2> &y)
+{  return y < x;  }
+
+//! <b>Returns</b>:!(x < y).
+//!
+template <class T1, class D1, class T2, class D2>
+BOOST_MOVE_FORCEINLINE bool operator>=(const unique_ptr<T1, D1> &x, const unique_ptr<T2, D2> &y)
+{  return !(x < y);  }
+
+//! <b>Returns</b>:!x.
+//!
+template <class T, class D>
+BOOST_MOVE_FORCEINLINE bool operator==(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
+{  return !x;  }
+
+//! <b>Returns</b>:!x.
+//!
+template <class T, class D>
+BOOST_MOVE_FORCEINLINE bool operator==(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x) BOOST_NOEXCEPT
+{  return !x;  }
+
+//! <b>Returns</b>: (bool)x.
+//!
+template <class T, class D>
+BOOST_MOVE_FORCEINLINE bool operator!=(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
+{  return !!x;  }
+
+//! <b>Returns</b>: (bool)x.
+//!
+template <class T, class D>
+BOOST_MOVE_FORCEINLINE bool operator!=(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x) BOOST_NOEXCEPT
+{  return !!x;  }
+
+//! <b>Requires</b>: <tt>operator </tt> shall induce a strict weak ordering on unique_ptr<T, D>::pointer values.
+//!
+//! <b>Returns</b>: Returns <tt>x.get() < pointer()</tt>.
+template <class T, class D>
+BOOST_MOVE_FORCEINLINE bool operator<(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type))
+{  return x.get() < typename unique_ptr<T, D>::pointer();  }
+
+//! <b>Requires</b>: <tt>operator </tt> shall induce a strict weak ordering on unique_ptr<T, D>::pointer values.
+//!
+//! <b>Returns</b>: Returns <tt>pointer() < x.get()</tt>.
+template <class T, class D>
+BOOST_MOVE_FORCEINLINE bool operator<(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x)
+{  return typename unique_ptr<T, D>::pointer() < x.get();  }
+
+//! <b>Returns</b>: <tt>nullptr < x</tt>.
+//!
+template <class T, class D>
+BOOST_MOVE_FORCEINLINE bool operator>(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type))
+{  return x.get() > typename unique_ptr<T, D>::pointer();  }
+
+//! <b>Returns</b>: <tt>x < nullptr</tt>.
+//!
+template <class T, class D>
+BOOST_MOVE_FORCEINLINE bool operator>(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x)
+{  return typename unique_ptr<T, D>::pointer() > x.get();  }
+
+//! <b>Returns</b>: <tt>!(nullptr < x)</tt>.
+//!
+template <class T, class D>
+BOOST_MOVE_FORCEINLINE bool operator<=(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type))
+{  return !(bmupd::nullptr_type() < x);  }
+
+//! <b>Returns</b>: <tt>!(x < nullptr)</tt>.
+//!
+template <class T, class D>
+BOOST_MOVE_FORCEINLINE bool operator<=(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x)
+{  return !(x < bmupd::nullptr_type());  }
+
+//! <b>Returns</b>: <tt>!(x < nullptr)</tt>.
+//!
+template <class T, class D>
+BOOST_MOVE_FORCEINLINE bool operator>=(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type))
+{  return !(x < bmupd::nullptr_type());  }
+
+//! <b>Returns</b>: <tt>!(nullptr < x)</tt>.
+//!
+template <class T, class D>
+BOOST_MOVE_FORCEINLINE bool operator>=(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x)
+{  return !(bmupd::nullptr_type() < x);  }
+
+}  //namespace movelib {
+}  //namespace boost{
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif   //#ifndef BOOST_MOVE_UNIQUE_PTR_HPP_INCLUDED
diff --git a/include/boost/move/utility.hpp b/include/boost/move/utility.hpp
new file mode 100644
index 0000000..28de793
--- /dev/null
+++ b/include/boost/move/utility.hpp
@@ -0,0 +1,150 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2012-2012.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
+//! This header includes core utilities from <tt><boost/move/utility_core.hpp></tt> and defines
+//! some more advanced utilities such as:
+
+#ifndef BOOST_MOVE_MOVE_UTILITY_HPP
+#define BOOST_MOVE_MOVE_UTILITY_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/detail/workaround.hpp>  //forceinline
+#include <boost/move/utility_core.hpp>
+#include <boost/move/traits.hpp>
+
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+   namespace boost {
+
+   //////////////////////////////////////////////////////////////////////////////
+   //
+   //                            move_if_noexcept()
+   //
+   //////////////////////////////////////////////////////////////////////////////
+
+   template <class T>
+   BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c
+      < enable_move_utility_emulation<T>::value && !has_move_emulation_enabled<T>::value
+      , typename ::boost::move_detail::add_const<T>::type &
+      >::type
+         move_if_noexcept(T& x) BOOST_NOEXCEPT
+   {
+      return x;
+   }
+
+   template <class T>
+   BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c
+      < enable_move_utility_emulation<T>::value && has_move_emulation_enabled<T>::value
+            && ::boost::move_detail::is_nothrow_move_constructible_or_uncopyable<T>::value, rv<T>&>::type
+         move_if_noexcept(T& x) BOOST_NOEXCEPT
+   {
+      return *static_cast<rv<T>* >(::boost::move_detail::addressof(x));
+   }
+
+   template <class T>
+   BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c
+      < enable_move_utility_emulation<T>::value && has_move_emulation_enabled<T>::value
+            && ::boost::move_detail::is_nothrow_move_constructible_or_uncopyable<T>::value
+      , rv<T>&
+      >::type
+         move_if_noexcept(rv<T>& x) BOOST_NOEXCEPT
+   {
+      return x;
+   }
+
+   template <class T>
+   BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c
+      < enable_move_utility_emulation<T>::value && has_move_emulation_enabled<T>::value
+            && !::boost::move_detail::is_nothrow_move_constructible_or_uncopyable<T>::value
+      , typename ::boost::move_detail::add_const<T>::type &
+      >::type
+         move_if_noexcept(T& x) BOOST_NOEXCEPT
+   {
+      return x;
+   }
+
+   template <class T>
+   BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c
+      < enable_move_utility_emulation<T>::value && has_move_emulation_enabled<T>::value
+            && !::boost::move_detail::is_nothrow_move_constructible_or_uncopyable<T>::value
+      , typename ::boost::move_detail::add_const<T>::type &
+      >::type
+         move_if_noexcept(rv<T>& x) BOOST_NOEXCEPT
+   {
+      return x;
+   }
+
+   }  //namespace boost
+
+#else    //#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+   #if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)
+      #include <utility>
+
+      namespace boost{
+
+      using ::std::move_if_noexcept;
+
+      }  //namespace boost
+
+   #else //!BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE
+
+      namespace boost {
+
+      //////////////////////////////////////////////////////////////////////////////
+      //
+      //                            move_if_noexcept()
+      //
+      //////////////////////////////////////////////////////////////////////////////
+      #if defined(BOOST_MOVE_DOXYGEN_INVOKED)
+         //! This function provides a way to convert a reference into a rvalue reference
+         //! in compilers with rvalue references. For other compilers converts T & into
+         //! <i>::boost::rv<T> &</i> so that move emulation is activated. Reference
+         //! would be converted to rvalue reference only if input type is nothrow move
+         //! constructible or if it has no copy constructor. In all other cases const
+         //! reference would be returned
+         template <class T>
+         rvalue_reference_or_const_lvalue_reference move_if_noexcept(input_reference) noexcept;
+
+      #else //BOOST_MOVE_DOXYGEN_INVOKED
+
+         template <class T>
+         BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c
+            < ::boost::move_detail::is_nothrow_move_constructible_or_uncopyable<T>::value, T&&>::type
+               move_if_noexcept(T& x) BOOST_NOEXCEPT
+         {  return ::boost::move(x);   }
+
+         template <class T>
+         BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_c
+            < !::boost::move_detail::is_nothrow_move_constructible_or_uncopyable<T>::value, const T&>::type
+               move_if_noexcept(T& x) BOOST_NOEXCEPT
+         {  return x;  }
+
+      #endif //BOOST_MOVE_DOXYGEN_INVOKED
+
+      }  //namespace boost {
+
+   #endif   //#if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)
+
+#endif   //BOOST_NO_CXX11_RVALUE_REFERENCES
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_MOVE_MOVE_UTILITY_HPP
diff --git a/include/boost/move/utility_core.hpp b/include/boost/move/utility_core.hpp
new file mode 100644
index 0000000..55042a9
--- /dev/null
+++ b/include/boost/move/utility_core.hpp
@@ -0,0 +1,318 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2012-2012.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
+//! This header defines core utilities to ease the development
+//! of move-aware functions. This header minimizes dependencies
+//! from other libraries.
+
+#ifndef BOOST_MOVE_MOVE_UTILITY_CORE_HPP
+#define BOOST_MOVE_MOVE_UTILITY_CORE_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/detail/workaround.hpp>  //forceinline
+#include <boost/move/core.hpp>
+#include <boost/move/detail/meta_utils.hpp>
+#include <boost/static_assert.hpp>
+
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+   namespace boost {
+
+   template<class T>
+   struct enable_move_utility_emulation
+   {
+      static const bool value = true;
+   };
+    
+   //////////////////////////////////////////////////////////////////////////////
+   //
+   //                            move()
+   //
+   //////////////////////////////////////////////////////////////////////////////
+
+   template <class T>
+   BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_and
+      < T &
+      , enable_move_utility_emulation<T>
+      , has_move_emulation_disabled<T>
+      >::type
+         move(T& x) BOOST_NOEXCEPT
+   {
+      return x;
+   }
+
+   template <class T>
+   BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_and
+      < rv<T>&
+      , enable_move_utility_emulation<T>
+      , has_move_emulation_enabled<T>
+      >::type
+         move(T& x) BOOST_NOEXCEPT
+   {
+      return *BOOST_MOVE_TO_RV_CAST(::boost::rv<T>*, ::boost::move_detail::addressof(x) );
+   }
+
+   template <class T>
+   BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_and
+      < rv<T>&
+      , enable_move_utility_emulation<T>
+      , has_move_emulation_enabled<T>
+      >::type
+         move(rv<T>& x) BOOST_NOEXCEPT
+   {
+      return x;
+   }
+
+   //////////////////////////////////////////////////////////////////////////////
+   //
+   //                            forward()
+   //
+   //////////////////////////////////////////////////////////////////////////////
+
+   template <class T>
+   BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_and
+      < T &
+      , enable_move_utility_emulation<T>
+      , ::boost::move_detail::is_rv<T>
+      >::type
+         forward(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
+   {
+      return const_cast<T&>(x);
+   }
+
+   template <class T>
+   BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_and
+      < const T &
+      , enable_move_utility_emulation<T>
+      , ::boost::move_detail::is_not_rv<T>
+      >::type
+         forward(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
+   {
+      return x;
+   }
+
+   //////////////////////////////////////////////////////////////////////////////
+   //
+   //                        move_if_not_lvalue_reference()
+   //
+   //////////////////////////////////////////////////////////////////////////////
+
+   template <class T>
+   BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_and
+      < T &
+      , enable_move_utility_emulation<T>
+      , ::boost::move_detail::is_rv<T>
+      >::type
+         move_if_not_lvalue_reference(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
+   {
+      return const_cast<T&>(x);
+   }
+
+   template <class T>
+   BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_and
+      < typename ::boost::move_detail::add_lvalue_reference<T>::type
+      , enable_move_utility_emulation<T>
+      , ::boost::move_detail::is_not_rv<T>
+      , ::boost::move_detail::or_
+         < ::boost::move_detail::is_lvalue_reference<T>
+         , has_move_emulation_disabled<T>
+         >
+      >::type
+         move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type &x) BOOST_NOEXCEPT
+   {
+      return x;
+   }
+
+   template <class T>
+   BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::enable_if_and
+      < rv<T>&
+      , enable_move_utility_emulation<T>
+      , ::boost::move_detail::is_not_rv<T>
+      , ::boost::move_detail::and_
+         < ::boost::move_detail::not_< ::boost::move_detail::is_lvalue_reference<T> >
+         , has_move_emulation_enabled<T>
+         >
+      >::type
+         move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type &x) BOOST_NOEXCEPT
+   {
+      return move(x);
+   }
+
+   }  //namespace boost
+
+#else    //#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+   #if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)
+      #include <utility>
+
+      namespace boost{
+
+      using ::std::move;
+      using ::std::forward;
+
+      }  //namespace boost
+
+   #else //!BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE
+
+      namespace boost {
+
+      //! This trait's internal boolean `value` is false in compilers with rvalue references
+      //! and true in compilers without rvalue references.
+      //!
+      //! A user can specialize this trait for a type T to false to SFINAE out `move` and `forward`
+      //! so that the user can define a different move emulation for that type in namespace boost
+      //! (e.g. another Boost library for its types) and avoid any overload ambiguity.
+      template<class T>
+      struct enable_move_utility_emulation
+      {
+         static const bool value = false;
+      };
+
+      //////////////////////////////////////////////////////////////////////////////
+      //
+      //                                  move
+      //
+      //////////////////////////////////////////////////////////////////////////////
+
+      #if defined(BOOST_MOVE_DOXYGEN_INVOKED)
+         //! This function provides a way to convert a reference into a rvalue reference
+         //! in compilers with rvalue references. For other compilers if `T` is Boost.Move
+         //! enabled type then it converts `T&` into <tt>::boost::rv<T> &</tt> so that
+         //! move emulation is activated, else it returns `T &`.
+         template <class T>
+         rvalue_reference move(input_reference) noexcept;
+
+      #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
+
+         //Old move approach, lvalues could bind to rvalue references
+         template <class T>
+         BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::remove_reference<T>::type && move(T&& t) BOOST_NOEXCEPT
+         {  return t;   }
+
+      #else //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+
+         template <class T>
+         BOOST_MOVE_FORCEINLINE typename ::boost::move_detail::remove_reference<T>::type && move(T&& t) BOOST_NOEXCEPT
+         { return static_cast<typename ::boost::move_detail::remove_reference<T>::type &&>(t); }
+
+      #endif   //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+
+      //////////////////////////////////////////////////////////////////////////////
+      //
+      //                                  forward
+      //
+      //////////////////////////////////////////////////////////////////////////////
+
+
+      #if defined(BOOST_MOVE_DOXYGEN_INVOKED)
+         //! This function provides limited form of forwarding that is usually enough for
+         //! in-place construction and avoids the exponential overloading for
+         //! achieve the limited forwarding in C++03.
+         //!
+         //! For compilers with rvalue references this function provides perfect forwarding.
+         //!
+         //! Otherwise:
+         //! * If input_reference binds to const ::boost::rv<T> & then it output_reference is
+         //!   ::boost::rv<T> &
+         //!
+         //! * Else, output_reference is equal to input_reference.
+         template <class T> output_reference forward(input_reference) noexcept;
+      #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
+
+         //Old move approach, lvalues could bind to rvalue references
+
+         template <class T>
+         BOOST_MOVE_FORCEINLINE T&& forward(typename ::boost::move_detail::identity<T>::type&& t) BOOST_NOEXCEPT
+         {  return t;   }
+
+      #else //Old move
+
+         template <class T>
+         BOOST_MOVE_FORCEINLINE T&& forward(typename ::boost::move_detail::remove_reference<T>::type& t) BOOST_NOEXCEPT
+         {  return static_cast<T&&>(t);   }
+
+         template <class T>
+         BOOST_MOVE_FORCEINLINE T&& forward(typename ::boost::move_detail::remove_reference<T>::type&& t) BOOST_NOEXCEPT
+         {
+            //"boost::forward<T> error: 'T' is a lvalue reference, can't forward as rvalue.";
+            BOOST_STATIC_ASSERT(!boost::move_detail::is_lvalue_reference<T>::value);
+            return static_cast<T&&>(t);
+         }
+
+      #endif   //BOOST_MOVE_DOXYGEN_INVOKED
+
+      //////////////////////////////////////////////////////////////////////////////
+      //
+      //                         move_if_not_lvalue_reference
+      //
+      //////////////////////////////////////////////////////////////////////////////
+
+
+      #if defined(BOOST_MOVE_DOXYGEN_INVOKED)
+         //! <b>Effects</b>: Calls `boost::move` if `input_reference` is not a lvalue reference.
+         //!   Otherwise returns the reference
+         template <class T> output_reference move_if_not_lvalue_reference(input_reference) noexcept;
+      #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
+
+         //Old move approach, lvalues could bind to rvalue references
+
+         template <class T>
+         BOOST_MOVE_FORCEINLINE T&& move_if_not_lvalue_reference(typename ::boost::move_detail::identity<T>::type&& t) BOOST_NOEXCEPT
+         {  return t;   }
+
+      #else //Old move
+
+         template <class T>
+         BOOST_MOVE_FORCEINLINE T&& move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type& t) BOOST_NOEXCEPT
+         {  return static_cast<T&&>(t);   }
+
+         template <class T>
+         BOOST_MOVE_FORCEINLINE T&& move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type&& t) BOOST_NOEXCEPT
+         {
+            //"boost::forward<T> error: 'T' is a lvalue reference, can't forward as rvalue.";
+            BOOST_STATIC_ASSERT(!boost::move_detail::is_lvalue_reference<T>::value);
+            return static_cast<T&&>(t);
+         }
+
+      #endif   //BOOST_MOVE_DOXYGEN_INVOKED
+
+      }  //namespace boost {
+
+   #endif   //#if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)
+
+#endif   //BOOST_NO_CXX11_RVALUE_REFERENCES
+
+#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+namespace boost{
+namespace move_detail{
+
+template <typename T>
+typename boost::move_detail::add_rvalue_reference<T>::type declval();
+
+}  //namespace move_detail{
+}  //namespace boost{
+
+#endif   //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_MOVE_MOVE_UTILITY_CORE_HPP
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..cb02a37
--- /dev/null
+++ b/index.html
@@ -0,0 +1,14 @@
+<!--
+Copyright 2005-2011 Ion Gaztanaga
+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)
+-->
+<html>
+<head>
+   <meta http-equiv="refresh" content="0; URL=../../doc/html/move.html">
+</head>
+<body>
+Automatic redirection failed, please go to
+<a href="../../doc/html/move.html">../../doc/html/move.html</a>
+</body>
+</html>
diff --git a/meta/libraries.json b/meta/libraries.json
new file mode 100644
index 0000000..1bc20a8
--- /dev/null
+++ b/meta/libraries.json
@@ -0,0 +1,14 @@
+{
+    "key": "move",
+    "name": "Move",
+    "authors": [
+        "Ion Gazta\u00f1aga"
+    ],
+    "description": "Portable move semantics for C++03 and C++11 compilers.",
+    "category": [
+        "Emulation"
+    ],
+    "maintainers": [
+        "Ion Gaztanaga <igaztanaga -at- gmail.com>"
+    ]
+}
diff --git a/proj/vc7ide/Move.sln b/proj/vc7ide/Move.sln
new file mode 100644
index 0000000..7b77580
--- /dev/null
+++ b/proj/vc7ide/Move.sln
@@ -0,0 +1,303 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "copy_elision_test_test", "copy_elision_test.vcproj", "{C8AD2618-79EB-8612-42FE-2A3AC9667A13}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_how_works", "doc_how_works.vcproj", "{C7C2F583-4FE2-1862-BF87-BA26D31A7995}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "conversion_test", "conversion_test.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "back_move_inserter_test", "back_move_inserter_test.vcproj", "{C8AD2618-79EB-8612-42FE-2A3AC9667A13}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "construct_forward_test", "construct_forward_test.vcproj", "{C8AD2618-79EB-8612-42FE-2A3AC9667A13}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "copy_move_optimization_test", "copy_move_optimization.vcproj", "{C8AD2618-79EB-8612-42FE-2A3AC9667A13}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_clone_ptr", "doc_clone_ptr.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_construct_forward", "doc_construct_forward.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_file_descriptor", "doc_file_descriptor.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_move_algorithms", "doc_move_algorithms.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_move_inserter", "doc_move_inserter.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_move_iterator", "doc_move_iterator.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "move_algorithm_test", "move_algorithm.vcproj", "{C8AD2618-79EB-8612-42FE-2A3AC9667A13}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "move_iterator_test", "move_iterator_test.vcproj", "{C8AD2618-79EB-8612-42FE-2A3AC9667A13}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "move_test", "move_test.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_move_return", "doc_move_return.vcproj", "{7C1462C8-D532-4B8E-F2F6-E3A2A796D912}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "move_if_noexcept_test", "move_if_noexcept_test.vcproj", "{CD57C283-1862-42FE-BF87-B96D3A2A7912}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unique_ptr_default_deleter_test", "unique_ptr_default_deleter.vcproj", "{C57C25A3-4620-FE08-F8B7-AB673D762B60}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unique_ptr_functions_test", "unique_ptr_functions.vcproj", "{C57C25A3-4620-FE08-F8B7-AB673D762B60}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unique_ptr_assign_test", "unique_ptr_assign_test.vcproj", "{C57C28A3-4FE0-6208-BF87-B2B61D3A7674}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unique_ptr_ctordtor_test", "unique_ptr_ctordtor_test.vcproj", "{C57C28A3-4FE0-6208-BF87-B2B61D3A7676}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unique_ptr_modifiers_test", "unique_ptr_modifiers_test.vcproj", "{C57C28A3-4FE0-6208-BF87-B2B61D3A7673}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unique_ptr_movector_test", "unique_ptr_movector_test.vcproj", "{C57C28A3-4FE0-6208-BF87-B2B61D3A7672}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unique_ptr_nullptr_test", "unique_ptr_nullptr_test.vcproj", "{C57C28A3-4FE0-6208-BF87-B2B61D3A7671}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unique_ptr_observers_test", "unique_ptr_observers_test.vcproj", "{C57C28A3-4FE0-6208-BF87-B2B61D3A7670}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unique_ptr_types_test", "unique_ptr_types_test.vcproj", "{C57C28A3-4FE0-6208-BF87-B2B61D3A7675}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "adl_move_swap", "adl_move_swap.vcproj", "{CD2617A8-79EB-6172-2CE4-26617AA3AC93}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "type_traits", "type_traits.vcproj", "{D7C28A23-8621-FE05-BF87-3C7B6176BD02}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bench_sort", "bench_sort.vcproj", "{CD2617A8-6217-9EB7-24CE-6C9AA035376A}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bench_merge", "bench_merge.vcproj", "{CD2617A8-6217-9EB7-24CE-6C9AA035376A}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "adaptive_sort_test", "adaptive_sort_test.vcproj", "{CD617A28-6217-B79E-4CE2-6BA035379A6A}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "adaptive_merge_test", "adaptive_merge_test.vcproj", "{CD617A28-6217-B79E-4CE2-6BA035379A6A}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_template_assign", "doc_template_assign.vcproj", "{7460CA18-D532-E4F8-F1F2-3A796D2A91E2}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "inplace_merge_test", "inplace_merge_test.vcproj", "{CD617C28-62B7-CE9E-0000-000000000000}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "algo_test", "algo_test.vcproj", "{C8AD2618-79EB-8612-42FE-2A3AC9667A13}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_movelib", "move.vcproj", "{F6BAFC51-6BBD-2EC3-B204-9A67C31325A3}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Global
+	GlobalSection(SolutionConfiguration) = preSolution
+		Debug = Debug
+		Release = Release
+	EndGlobalSection
+	GlobalSection(ProjectDependencies) = postSolution
+	EndGlobalSection
+	GlobalSection(ProjectConfiguration) = postSolution
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.ActiveCfg = Debug|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.Build.0 = Debug|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.ActiveCfg = Release|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.Build.0 = Release|Win32
+		{C7C2F583-4FE2-1862-BF87-BA26D31A7995}.Debug.ActiveCfg = Debug|Win32
+		{C7C2F583-4FE2-1862-BF87-BA26D31A7995}.Debug.Build.0 = Debug|Win32
+		{C7C2F583-4FE2-1862-BF87-BA26D31A7995}.Release.ActiveCfg = Release|Win32
+		{C7C2F583-4FE2-1862-BF87-BA26D31A7995}.Release.Build.0 = Release|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = Debug|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.Build.0 = Debug|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.ActiveCfg = Release|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.Build.0 = Release|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.ActiveCfg = Debug|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.Build.0 = Debug|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.ActiveCfg = Release|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.Build.0 = Release|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.ActiveCfg = Debug|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.Build.0 = Debug|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.ActiveCfg = Release|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.Build.0 = Release|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.ActiveCfg = Debug|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.Build.0 = Debug|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.ActiveCfg = Release|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.Build.0 = Release|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = Debug|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.Build.0 = Debug|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.ActiveCfg = Release|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.Build.0 = Release|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = Debug|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.Build.0 = Debug|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.ActiveCfg = Release|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.Build.0 = Release|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = Debug|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.Build.0 = Debug|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.ActiveCfg = Release|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.Build.0 = Release|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = Debug|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.Build.0 = Debug|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.ActiveCfg = Release|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.Build.0 = Release|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = Debug|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.Build.0 = Debug|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.ActiveCfg = Release|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.Build.0 = Release|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = Debug|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.Build.0 = Debug|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.ActiveCfg = Release|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.Build.0 = Release|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.ActiveCfg = Debug|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.Build.0 = Debug|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.ActiveCfg = Release|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.Build.0 = Release|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.ActiveCfg = Debug|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.Build.0 = Debug|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.ActiveCfg = Release|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.Build.0 = Release|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = Debug|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.Build.0 = Debug|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.ActiveCfg = Release|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.Build.0 = Release|Win32
+		{7C1462C8-D532-4B8E-F2F6-E3A2A796D912}.Debug.ActiveCfg = Debug|Win32
+		{7C1462C8-D532-4B8E-F2F6-E3A2A796D912}.Debug.Build.0 = Debug|Win32
+		{7C1462C8-D532-4B8E-F2F6-E3A2A796D912}.Release.ActiveCfg = Release|Win32
+		{7C1462C8-D532-4B8E-F2F6-E3A2A796D912}.Release.Build.0 = Release|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.ActiveCfg = Debug|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Debug.Build.0 = Debug|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.ActiveCfg = Release|Win32
+		{CD57C283-1862-42FE-BF87-B96D3A2A7912}.Release.Build.0 = Release|Win32
+		{C57C25A3-4620-FE08-F8B7-AB673D762B60}.Debug.ActiveCfg = Debug|Win32
+		{C57C25A3-4620-FE08-F8B7-AB673D762B60}.Debug.Build.0 = Debug|Win32
+		{C57C25A3-4620-FE08-F8B7-AB673D762B60}.Release.ActiveCfg = Release|Win32
+		{C57C25A3-4620-FE08-F8B7-AB673D762B60}.Release.Build.0 = Release|Win32
+		{C57C25A3-4620-FE08-F8B7-AB673D762B60}.Debug.ActiveCfg = Debug|Win32
+		{C57C25A3-4620-FE08-F8B7-AB673D762B60}.Debug.Build.0 = Debug|Win32
+		{C57C25A3-4620-FE08-F8B7-AB673D762B60}.Release.ActiveCfg = Release|Win32
+		{C57C25A3-4620-FE08-F8B7-AB673D762B60}.Release.Build.0 = Release|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7674}.Debug.ActiveCfg = Debug|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7674}.Debug.Build.0 = Debug|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7674}.Release.ActiveCfg = Release|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7674}.Release.Build.0 = Release|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7676}.Debug.ActiveCfg = Debug|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7676}.Debug.Build.0 = Debug|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7676}.Release.ActiveCfg = Release|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7676}.Release.Build.0 = Release|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7673}.Debug.ActiveCfg = Debug|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7673}.Debug.Build.0 = Debug|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7673}.Release.ActiveCfg = Release|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7673}.Release.Build.0 = Release|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7672}.Debug.ActiveCfg = Debug|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7672}.Debug.Build.0 = Debug|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7672}.Release.ActiveCfg = Release|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7672}.Release.Build.0 = Release|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7671}.Debug.ActiveCfg = Debug|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7671}.Debug.Build.0 = Debug|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7671}.Release.ActiveCfg = Release|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7671}.Release.Build.0 = Release|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7670}.Debug.ActiveCfg = Debug|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7670}.Debug.Build.0 = Debug|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7670}.Release.ActiveCfg = Release|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7670}.Release.Build.0 = Release|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7675}.Debug.ActiveCfg = Debug|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7675}.Debug.Build.0 = Debug|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7675}.Release.ActiveCfg = Release|Win32
+		{C57C28A3-4FE0-6208-BF87-B2B61D3A7675}.Release.Build.0 = Release|Win32
+		{CD2617A8-79EB-6172-2CE4-26617AA3AC93}.Debug.ActiveCfg = Debug|Win32
+		{CD2617A8-79EB-6172-2CE4-26617AA3AC93}.Debug.Build.0 = Debug|Win32
+		{CD2617A8-79EB-6172-2CE4-26617AA3AC93}.Release.ActiveCfg = Release|Win32
+		{CD2617A8-79EB-6172-2CE4-26617AA3AC93}.Release.Build.0 = Release|Win32
+		{D7C28A23-8621-FE05-BF87-3C7B6176BD02}.Debug.ActiveCfg = Debug|Win32
+		{D7C28A23-8621-FE05-BF87-3C7B6176BD02}.Debug.Build.0 = Debug|Win32
+		{D7C28A23-8621-FE05-BF87-3C7B6176BD02}.Release.ActiveCfg = Release|Win32
+		{D7C28A23-8621-FE05-BF87-3C7B6176BD02}.Release.Build.0 = Release|Win32
+		{CD2617A8-6217-9EB7-24CE-6C9AA035376A}.Debug.ActiveCfg = Debug|Win32
+		{CD2617A8-6217-9EB7-24CE-6C9AA035376A}.Debug.Build.0 = Debug|Win32
+		{CD2617A8-6217-9EB7-24CE-6C9AA035376A}.Release.ActiveCfg = Release|Win32
+		{CD2617A8-6217-9EB7-24CE-6C9AA035376A}.Release.Build.0 = Release|Win32
+		{CD2617A8-6217-9EB7-24CE-6C9AA035376A}.Debug.ActiveCfg = Debug|Win32
+		{CD2617A8-6217-9EB7-24CE-6C9AA035376A}.Debug.Build.0 = Debug|Win32
+		{CD2617A8-6217-9EB7-24CE-6C9AA035376A}.Release.ActiveCfg = Release|Win32
+		{CD2617A8-6217-9EB7-24CE-6C9AA035376A}.Release.Build.0 = Release|Win32
+		{CD617A28-6217-B79E-4CE2-6BA035379A6A}.Debug.ActiveCfg = Debug|Win32
+		{CD617A28-6217-B79E-4CE2-6BA035379A6A}.Debug.Build.0 = Debug|Win32
+		{CD617A28-6217-B79E-4CE2-6BA035379A6A}.Release.ActiveCfg = Release|Win32
+		{CD617A28-6217-B79E-4CE2-6BA035379A6A}.Release.Build.0 = Release|Win32
+		{CD617A28-6217-B79E-4CE2-6BA035379A6A}.Debug.ActiveCfg = Debug|Win32
+		{CD617A28-6217-B79E-4CE2-6BA035379A6A}.Debug.Build.0 = Debug|Win32
+		{CD617A28-6217-B79E-4CE2-6BA035379A6A}.Release.ActiveCfg = Release|Win32
+		{CD617A28-6217-B79E-4CE2-6BA035379A6A}.Release.Build.0 = Release|Win32
+		{7460CA18-D532-E4F8-F1F2-3A796D2A91E2}.Debug.ActiveCfg = Debug|Win32
+		{7460CA18-D532-E4F8-F1F2-3A796D2A91E2}.Debug.Build.0 = Debug|Win32
+		{7460CA18-D532-E4F8-F1F2-3A796D2A91E2}.Release.ActiveCfg = Release|Win32
+		{7460CA18-D532-E4F8-F1F2-3A796D2A91E2}.Release.Build.0 = Release|Win32
+		{CD617C28-62B7-CE9E-0000-000000000000}.Debug.ActiveCfg = Debug|Win32
+		{CD617C28-62B7-CE9E-0000-000000000000}.Debug.Build.0 = Debug|Win32
+		{CD617C28-62B7-CE9E-0000-000000000000}.Release.ActiveCfg = Release|Win32
+		{CD617C28-62B7-CE9E-0000-000000000000}.Release.Build.0 = Release|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.ActiveCfg = Debug|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Debug.Build.0 = Debug|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.ActiveCfg = Release|Win32
+		{C8AD2618-79EB-8612-42FE-2A3AC9667A13}.Release.Build.0 = Release|Win32
+		{F6BAFC51-6BBD-2EC3-B204-9A67C31325A3}.Debug.ActiveCfg = Debug|Win32
+		{F6BAFC51-6BBD-2EC3-B204-9A67C31325A3}.Debug.Build.0 = Debug|Win32
+		{F6BAFC51-6BBD-2EC3-B204-9A67C31325A3}.Release.ActiveCfg = Release|Win32
+		{F6BAFC51-6BBD-2EC3-B204-9A67C31325A3}.Release.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+	EndGlobalSection
+	GlobalSection(ExtensibilityAddIns) = postSolution
+	EndGlobalSection
+EndGlobal
diff --git a/proj/vc7ide/adaptive_merge_test.vcproj b/proj/vc7ide/adaptive_merge_test.vcproj
new file mode 100644
index 0000000..516f1b1
--- /dev/null
+++ b/proj/vc7ide/adaptive_merge_test.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="adaptive_merge_test"
+	ProjectGUID="{CD617A28-6217-B79E-4CE2-6BA035379A6A}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/adaptive_merge_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/adaptive_merge_test_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/adaptive_merge_test.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/adaptive_merge_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/adaptive_merge_test.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{163D8753-0546-A605-5C56-3B0FEAD7A52A}">
+			<File
+				RelativePath="..\..\test\adaptive_merge_test.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/adaptive_sort_test.vcproj b/proj/vc7ide/adaptive_sort_test.vcproj
new file mode 100644
index 0000000..7600c88
--- /dev/null
+++ b/proj/vc7ide/adaptive_sort_test.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="adaptive_sort_test"
+	ProjectGUID="{CD617A28-6217-B79E-4CE2-6BA035379A6A}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/adaptive_sort_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/adaptive_sort_test_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/adaptive_sort_test.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/adaptive_sort_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/adaptive_sort_test.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{163D8753-0546-A605-5C56-3B0FEAD7A52A}">
+			<File
+				RelativePath="..\..\test\adaptive_sort_test.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/adl_move_swap.vcproj b/proj/vc7ide/adl_move_swap.vcproj
new file mode 100644
index 0000000..4c57491
--- /dev/null
+++ b/proj/vc7ide/adl_move_swap.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="adl_move_swap"
+	ProjectGUID="{CD2617A8-79EB-6172-2CE4-26617AA3AC93}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/move_adl_move_swap"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/move_iterator_test_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/move_adl_move_swap.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/move_adl_move_swap"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/move_adl_move_swap.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{163D8753-4026-0A65-5C56-2BA532AD7FEF}">
+			<File
+				RelativePath="..\..\test\adl_move_swap.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/algo_test.vcproj b/proj/vc7ide/algo_test.vcproj
new file mode 100644
index 0000000..e228f8f
--- /dev/null
+++ b/proj/vc7ide/algo_test.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="algo_test"
+	ProjectGUID="{C8AD2618-79EB-8612-42FE-2A3AC9667A13}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/algo_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/algo_test_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/algo_test.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/algo_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/algo_test.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{818563C3-6640-0A65-55CB-202E5BAD7FAF}">
+			<File
+				RelativePath="..\..\test\algo_test.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/back_move_inserter_test.vcproj b/proj/vc7ide/back_move_inserter_test.vcproj
new file mode 100644
index 0000000..17a751f
--- /dev/null
+++ b/proj/vc7ide/back_move_inserter_test.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="back_move_inserter_test"
+	ProjectGUID="{C8AD2618-79EB-8612-42FE-2A3AC9667A13}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/back_move_inserter_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/back_move_inserter_test_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/back_move_inserter_test.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/back_move_inserter_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/back_move_inserter_test.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{818563C3-6640-0A65-55CB-202E5BAD7FAF}">
+			<File
+				RelativePath="..\..\test\back_move_inserter.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/bench_merge.vcproj b/proj/vc7ide/bench_merge.vcproj
new file mode 100644
index 0000000..a64bb63
--- /dev/null
+++ b/proj/vc7ide/bench_merge.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="bench_merge"
+	ProjectGUID="{CD2617A8-6217-9EB7-24CE-6C9AA035376A}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/bench_merge"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/bench_merge_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/bench_merge.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/bench_merge"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/bench_merge.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{1D875633-A605-0546-5C56-3A5FEAD72B0A}">
+			<File
+				RelativePath="..\..\test\bench_merge.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/bench_sort.vcproj b/proj/vc7ide/bench_sort.vcproj
new file mode 100644
index 0000000..0b630fd
--- /dev/null
+++ b/proj/vc7ide/bench_sort.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="bench_sort"
+	ProjectGUID="{CD2617A8-6217-9EB7-24CE-6C9AA035376A}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/bench_sort"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/bench_sort_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/bench_sort.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/bench_sort"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/bench_sort.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{1D875633-A605-0546-5C56-3A5FEAD72B0A}">
+			<File
+				RelativePath="..\..\test\bench_sort.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/construct_forward_test.vcproj b/proj/vc7ide/construct_forward_test.vcproj
new file mode 100644
index 0000000..0f44a59
--- /dev/null
+++ b/proj/vc7ide/construct_forward_test.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="construct_forward_test"
+	ProjectGUID="{C8AD2618-79EB-8612-42FE-2A3AC9667A13}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/construct_forward_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/construct_forward_test_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/construct_forward_test.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/construct_forward_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/construct_forward_test.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{818563C3-6640-0A65-55CB-202E5BAD7FAF}">
+			<File
+				RelativePath="..\..\test\construct_forward.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/conversion_test.vcproj b/proj/vc7ide/conversion_test.vcproj
new file mode 100644
index 0000000..215b0ea
--- /dev/null
+++ b/proj/vc7ide/conversion_test.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="conversion_test"
+	ProjectGUID="{CD57C283-1862-42FE-BF87-B96D3A2A7912}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/conversion_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/conversion_test_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/conversion_test.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/conversion_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/conversion_test.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{93828A70-7DE8-BD78-4B31-6551E0ACE5FA}">
+			<File
+				RelativePath="..\..\test\conversion_test.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/copy_elision_test.vcproj b/proj/vc7ide/copy_elision_test.vcproj
new file mode 100644
index 0000000..9a31cd7
--- /dev/null
+++ b/proj/vc7ide/copy_elision_test.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="copy_elision_test_test"
+	ProjectGUID="{C8AD2618-79EB-8612-42FE-2A3AC9667A13}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/copy_elision_test_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/copy_elision_test_test_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/copy_elision_test_test.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/copy_elision_test_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/copy_elision_test_test.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{818563C3-6640-0A65-55CB-202E5BAD7FAF}">
+			<File
+				RelativePath="..\..\test\copy_elision_test.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/copy_move_optimization.vcproj b/proj/vc7ide/copy_move_optimization.vcproj
new file mode 100644
index 0000000..13ef1a4
--- /dev/null
+++ b/proj/vc7ide/copy_move_optimization.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="copy_move_optimization_test"
+	ProjectGUID="{C8AD2618-79EB-8612-42FE-2A3AC9667A13}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/copy_move_optimization_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/copy_move_optimization_test_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/copy_move_optimization_test.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/copy_move_optimization_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/copy_move_optimization_test.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{818563C3-6640-0A65-55CB-202E5BAD7FAF}">
+			<File
+				RelativePath="..\..\test\copy_move_optimization.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/doc_clone_ptr.vcproj b/proj/vc7ide/doc_clone_ptr.vcproj
new file mode 100644
index 0000000..1021375
--- /dev/null
+++ b/proj/vc7ide/doc_clone_ptr.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="doc_clone_ptr"
+	ProjectGUID="{CD57C283-1862-42FE-BF87-B96D3A2A7912}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/doc_clone_ptr"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/doc_clone_ptr_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/doc_clone_ptr.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/doc_clone_ptr"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/doc_clone_ptr.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{34957FC1-7BC5-1646-05A6-27542AA2A2FF}">
+			<File
+				RelativePath="..\..\example\doc_clone_ptr.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/doc_construct_forward.vcproj b/proj/vc7ide/doc_construct_forward.vcproj
new file mode 100644
index 0000000..439e4ea
--- /dev/null
+++ b/proj/vc7ide/doc_construct_forward.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="doc_construct_forward"
+	ProjectGUID="{CD57C283-1862-42FE-BF87-B96D3A2A7912}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/doc_construct_forward"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/doc_construct_forward_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/doc_construct_forward.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/doc_construct_forward"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/doc_construct_forward.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{34957FC1-7BC5-1646-05A6-27542AA2A2FF}">
+			<File
+				RelativePath="..\..\example\doc_construct_forward.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/doc_file_descriptor.vcproj b/proj/vc7ide/doc_file_descriptor.vcproj
new file mode 100644
index 0000000..1fe67ee
--- /dev/null
+++ b/proj/vc7ide/doc_file_descriptor.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="doc_file_descriptor"
+	ProjectGUID="{CD57C283-1862-42FE-BF87-B96D3A2A7912}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/doc_file_descriptor"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/doc_file_descriptor_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/doc_file_descriptor.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/doc_file_descriptor"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/doc_file_descriptor.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{34957FC1-7BC5-1646-05A6-27542AA2A2FF}">
+			<File
+				RelativePath="..\..\example\doc_file_descriptor.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/doc_how_works.vcproj b/proj/vc7ide/doc_how_works.vcproj
new file mode 100644
index 0000000..5f4bbdbb
--- /dev/null
+++ b/proj/vc7ide/doc_how_works.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="doc_how_works"
+	ProjectGUID="{C7C2F583-4FE2-1862-BF87-BA26D31A7995}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/doc_how_works"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/doc_how_works_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/doc_how_works.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/doc_how_works"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/doc_how_works.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{34957FC1-7BC5-05A6-1646-2A25472AA2FF}">
+			<File
+				RelativePath="..\..\example\doc_how_works.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/doc_move_algorithms.vcproj b/proj/vc7ide/doc_move_algorithms.vcproj
new file mode 100644
index 0000000..b2f3dfc
--- /dev/null
+++ b/proj/vc7ide/doc_move_algorithms.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="doc_move_algorithms"
+	ProjectGUID="{CD57C283-1862-42FE-BF87-B96D3A2A7912}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/doc_move_algorithms"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/doc_move_algorithms_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/doc_move_algorithms.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/doc_move_algorithms"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/doc_move_algorithms.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{34957FC1-7BC5-1646-05A6-27542AA2A2FF}">
+			<File
+				RelativePath="..\..\example\doc_move_algorithms.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/doc_move_inserter.vcproj b/proj/vc7ide/doc_move_inserter.vcproj
new file mode 100644
index 0000000..b0160b9
--- /dev/null
+++ b/proj/vc7ide/doc_move_inserter.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="doc_move_inserter"
+	ProjectGUID="{CD57C283-1862-42FE-BF87-B96D3A2A7912}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/doc_move_inserter"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/doc_move_inserter_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/doc_move_inserter.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/doc_move_inserter"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/doc_move_inserter.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{34957FC1-7BC5-1646-05A6-27542AA2A2FF}">
+			<File
+				RelativePath="..\..\example\doc_move_inserter.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/doc_move_iterator.vcproj b/proj/vc7ide/doc_move_iterator.vcproj
new file mode 100644
index 0000000..342b2ea
--- /dev/null
+++ b/proj/vc7ide/doc_move_iterator.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="doc_move_iterator"
+	ProjectGUID="{CD57C283-1862-42FE-BF87-B96D3A2A7912}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/doc_move_iterator"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/doc_move_iterator_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/doc_move_iterator.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/doc_move_iterator"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/doc_move_iterator.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{34957FC1-7BC5-1646-05A6-27542AA2A2FF}">
+			<File
+				RelativePath="..\..\example\doc_move_iterator.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/doc_move_return.vcproj b/proj/vc7ide/doc_move_return.vcproj
new file mode 100644
index 0000000..eeedd94
--- /dev/null
+++ b/proj/vc7ide/doc_move_return.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="doc_move_return"
+	ProjectGUID="{7C1462C8-D532-4B8E-F2F6-E3A2A796D912}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/doc_move_return"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/doc_move_return_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/doc_move_return.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/doc_move_return"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/doc_move_return.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{475F3C87-6465-7BC5-05A6-2454C0A2A2CF}">
+			<File
+				RelativePath="..\..\example\doc_move_return.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/doc_template_assign.vcproj b/proj/vc7ide/doc_template_assign.vcproj
new file mode 100644
index 0000000..c37cb13
--- /dev/null
+++ b/proj/vc7ide/doc_template_assign.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="doc_template_assign"
+	ProjectGUID="{7460CA18-D532-E4F8-F1F2-3A796D2A91E2}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/doc_template_assign"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/doc_template_assign_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/doc_template_assign.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/doc_template_assign"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/doc_template_assign.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{475F3C87-6465-7BC5-05A6-2454C0A2A2CF}">
+			<File
+				RelativePath="..\..\example\doc_template_assign.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/inplace_merge_test.vcproj b/proj/vc7ide/inplace_merge_test.vcproj
new file mode 100644
index 0000000..682b772
--- /dev/null
+++ b/proj/vc7ide/inplace_merge_test.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="inplace_merge_test"
+	ProjectGUID="{CD617C28-62B7-CE9E-0000-000000000000}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/inplace_merge_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/inplace_merge_test_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/inplace_merge_test.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/inplace_merge_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/inplace_merge_test.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{870D8633-604305-5C-5C56-3BAD7A55FE7A}">
+			<File
+				RelativePath="..\..\test\inplace_merge_test.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/move.vcproj b/proj/vc7ide/move.vcproj
new file mode 100644
index 0000000..e060606
--- /dev/null
+++ b/proj/vc7ide/move.vcproj
@@ -0,0 +1,312 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="_movelib"
+	ProjectGUID="{F6BAFC51-6BBD-2EC3-B204-9A67C31325A3}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32"
+			IntermediateDirectory="Debug"
+			ConfigurationType="4"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="$(OutDir)/d.lib"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32"
+			IntermediateDirectory="Release"
+			ConfigurationType="4"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				RuntimeLibrary="2"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLibrarianTool"
+				OutputFile="$(OutDir)/move.lib"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="move"
+			Filter="">
+			<File
+				RelativePath="..\..\..\..\boost\move\adl_move_swap.hpp">
+			</File>
+			<File
+				RelativePath="..\..\..\..\boost\move\algorithm.hpp">
+			</File>
+			<File
+				RelativePath="..\..\..\..\boost\move\core.hpp">
+			</File>
+			<File
+				RelativePath="..\..\..\..\boost\move\default_delete.hpp">
+			</File>
+			<File
+				RelativePath="..\..\..\..\boost\move\iterator.hpp">
+			</File>
+			<File
+				RelativePath="..\..\..\..\boost\move\make_unique.hpp">
+			</File>
+			<File
+				RelativePath="..\..\..\..\boost\move\move.hpp">
+			</File>
+			<File
+				RelativePath="..\..\..\..\boost\move\traits.hpp">
+			</File>
+			<File
+				RelativePath="..\..\..\..\boost\move\unique_ptr.hpp">
+			</File>
+			<File
+				RelativePath="..\..\..\..\boost\move\utility.hpp">
+			</File>
+			<File
+				RelativePath="..\..\..\..\boost\move\utility_core.hpp">
+			</File>
+			<Filter
+				Name="detail"
+				Filter="">
+				<File
+					RelativePath="..\..\..\..\boost\move\detail\config_begin.hpp">
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\move\detail\config_end.hpp">
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\move\detail\destruct_n.hpp">
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\move\detail\fwd_macros.hpp">
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\move\detail\iterator_to_raw_pointer.hpp">
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\move\detail\iterator_traits.hpp">
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\move\detail\meta_utils.hpp">
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\move\detail\meta_utils_core.hpp">
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\move\detail\move_helpers.hpp">
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\move\detail\placement_new.hpp">
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\move\detail\pointer_element.hpp">
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\move\detail\reverse_iterator.hpp">
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\move\detail\std_ns_begin.hpp">
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\move\detail\std_ns_end.hpp">
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\move\detail\to_raw_pointer.hpp">
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\move\detail\type_traits.hpp">
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\move\detail\unique_ptr_meta_utils.hpp">
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\move\detail\workaround.hpp">
+				</File>
+			</Filter>
+			<Filter
+				Name="algo"
+				Filter="">
+				<File
+					RelativePath="..\..\..\..\boost\move\algo\adaptive_merge.hpp">
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\move\algo\adaptive_sort.hpp">
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\move\algo\move.hpp">
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\move\algo\predicate.hpp">
+				</File>
+				<File
+					RelativePath="..\..\..\..\boost\move\algo\unique.hpp">
+				</File>
+				<Filter
+					Name="detail"
+					Filter="">
+					<File
+						RelativePath="..\..\..\..\boost\move\algo\detail\adaptive_sort_merge.hpp">
+					</File>
+					<File
+						RelativePath="..\..\..\..\boost\move\algo\detail\basic_op.hpp">
+					</File>
+					<File
+						RelativePath="..\..\..\..\boost\move\algo\detail\heap_sort.hpp">
+					</File>
+					<File
+						RelativePath="..\..\..\..\boost\move\algo\detail\insertion_sort.hpp">
+					</File>
+					<File
+						RelativePath="..\..\..\..\boost\move\algo\detail\merge.hpp">
+					</File>
+					<File
+						RelativePath="..\..\..\..\boost\move\algo\detail\merge_sort.hpp">
+					</File>
+					<File
+						RelativePath="..\..\..\..\boost\move\algo\detail\pdqsort.hpp">
+					</File>
+					<File
+						RelativePath="..\..\..\..\boost\move\algo\detail\set_difference.hpp">
+					</File>
+				</Filter>
+			</Filter>
+		</Filter>
+		<Filter
+			Name="doc"
+			Filter="">
+			<File
+				RelativePath="..\..\doc\Jamfile.v2">
+			</File>
+			<File
+				RelativePath="..\..\doc\move.qbk">
+			</File>
+		</Filter>
+		<Filter
+			Name="example"
+			Filter="">
+			<File
+				RelativePath="..\..\example\copymovable.hpp">
+			</File>
+			<File
+				RelativePath="..\..\example\doc_clone_ptr.cpp">
+			</File>
+			<File
+				RelativePath="..\..\example\doc_construct_forward.cpp">
+			</File>
+			<File
+				RelativePath="..\..\example\doc_file_descriptor.cpp">
+			</File>
+			<File
+				RelativePath="..\..\example\doc_how_works.cpp">
+			</File>
+			<File
+				RelativePath="..\..\example\doc_move_algorithms.cpp">
+			</File>
+			<File
+				RelativePath="..\..\example\doc_move_inserter.cpp">
+			</File>
+			<File
+				RelativePath="..\..\example\doc_move_iterator.cpp">
+			</File>
+			<File
+				RelativePath="..\..\example\doc_move_return.cpp">
+			</File>
+			<File
+				RelativePath="..\..\example\doc_template_assign.cpp">
+			</File>
+			<File
+				RelativePath="..\..\example\Jamfile.v2">
+			</File>
+			<File
+				RelativePath="..\..\example\movable.hpp">
+			</File>
+		</Filter>
+		<Filter
+			Name="test"
+			Filter="">
+			<File
+				RelativePath="..\..\test\Jamfile.v2">
+			</File>
+			<File
+				RelativePath="..\..\test\order_type.hpp">
+			</File>
+			<File
+				RelativePath="..\..\test\random_shuffle.hpp">
+			</File>
+			<File
+				RelativePath="..\..\test\unique_ptr_test_utils_beg.hpp">
+			</File>
+			<File
+				RelativePath="..\..\test\unique_ptr_test_utils_end.hpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/move_algorithm.vcproj b/proj/vc7ide/move_algorithm.vcproj
new file mode 100644
index 0000000..33d4e5e
--- /dev/null
+++ b/proj/vc7ide/move_algorithm.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="move_algorithm_test"
+	ProjectGUID="{C8AD2618-79EB-8612-42FE-2A3AC9667A13}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/move_algorithm_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/move_algorithm_test_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/move_algorithm_test.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/move_algorithm_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/move_algorithm_test.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{818563C3-6640-0A65-55CB-202E5BAD7FAF}">
+			<File
+				RelativePath="..\..\test\move_algorithm.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/move_if_noexcept_test.vcproj b/proj/vc7ide/move_if_noexcept_test.vcproj
new file mode 100644
index 0000000..4265c32
--- /dev/null
+++ b/proj/vc7ide/move_if_noexcept_test.vcproj
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="move_if_noexcept_test"
+	ProjectGUID="{CD57C283-1862-42FE-BF87-B96D3A2A7912}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/move_if_noexcept_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/move_if_noexcept_test_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/move_if_noexcept_test.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/move_if_noexcept_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/move_if_noexcept_test.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{7EA34951-57AC-6216-05A6-20A754202AFF}">
+			<File
+				RelativePath="..\..\test\move_if_noexcept.cpp">
+			</File>
+		</Filter>
+
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/move_iterator_test.vcproj b/proj/vc7ide/move_iterator_test.vcproj
new file mode 100644
index 0000000..49355ee
--- /dev/null
+++ b/proj/vc7ide/move_iterator_test.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="move_iterator_test"
+	ProjectGUID="{C8AD2618-79EB-8612-42FE-2A3AC9667A13}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/move_iterator_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/move_iterator_test_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/move_iterator_test.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/move_iterator_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/move_iterator_test.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{818563C3-6640-0A65-55CB-202E5BAD7FAF}">
+			<File
+				RelativePath="..\..\test\move_iterator.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/move_test.vcproj b/proj/vc7ide/move_test.vcproj
new file mode 100644
index 0000000..347ce13
--- /dev/null
+++ b/proj/vc7ide/move_test.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="move_test"
+	ProjectGUID="{CD57C283-1862-42FE-BF87-B96D3A2A7912}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/move_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/move_test_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/move_test.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/move_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/move_test.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{34957FC1-7BC5-1646-05A6-27542AA2A2FF}">
+			<File
+				RelativePath="..\..\test\move.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/type_traits.vcproj b/proj/vc7ide/type_traits.vcproj
new file mode 100644
index 0000000..daa696a
--- /dev/null
+++ b/proj/vc7ide/type_traits.vcproj
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="type_traits"
+	ProjectGUID="{D7C28A23-8621-FE05-BF87-3C7B6176BD02}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/type_traits"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/unique_ptr_types_test_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/type_traits.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/type_traits"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/type_traits.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{43465AE1-5F7A-33E6-5A6C-3202CE43A275}">
+			<File
+				RelativePath="..\..\test\type_traits.cpp">
+			</File>
+		</Filter>
+
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/unique_ptr_assign_test.vcproj b/proj/vc7ide/unique_ptr_assign_test.vcproj
new file mode 100644
index 0000000..941d51e
--- /dev/null
+++ b/proj/vc7ide/unique_ptr_assign_test.vcproj
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="unique_ptr_assign_test"
+	ProjectGUID="{C57C28A3-4FE0-6208-BF87-B2B61D3A7674}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/unique_ptr_assign_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/unique_ptr_assign_test_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/unique_ptr_assign_test.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/unique_ptr_assign_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/unique_ptr_assign_test.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{7E3495A1-163E-57AC-5A6C-3A2754202BF4}">
+			<File
+				RelativePath="..\..\test\unique_ptr_assign.cpp">
+			</File>
+		</Filter>
+
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/unique_ptr_ctordtor_test.vcproj b/proj/vc7ide/unique_ptr_ctordtor_test.vcproj
new file mode 100644
index 0000000..50bec36
--- /dev/null
+++ b/proj/vc7ide/unique_ptr_ctordtor_test.vcproj
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="unique_ptr_ctordtor_test"
+	ProjectGUID="{C57C28A3-4FE0-6208-BF87-B2B61D3A7676}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/unique_ptr_ctordtor_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/unique_ptr_ctordtor_test_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/unique_ptr_ctordtor_test.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/unique_ptr_ctordtor_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/unique_ptr_ctordtor_test.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{7E3495A1-163E-57AC-5A6C-3A2754202BF6}">
+			<File
+				RelativePath="..\..\test\unique_ptr_ctordtor.cpp">
+			</File>
+		</Filter>
+
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/unique_ptr_default_deleter.vcproj b/proj/vc7ide/unique_ptr_default_deleter.vcproj
new file mode 100644
index 0000000..23ac752
--- /dev/null
+++ b/proj/vc7ide/unique_ptr_default_deleter.vcproj
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="unique_ptr_default_deleter_test"
+	ProjectGUID="{C57C25A3-4620-FE08-F8B7-AB673D762B60}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/unique_ptr_default_deleter_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/unique_ptr_default_deleter_test_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/unique_ptr_default_deleter_test.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/unique_ptr_default_deleter_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/unique_ptr_default_deleter_test.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{73495AA1-5A6C-3E57-16AC-542F7F2242B9}">
+			<File
+				RelativePath="..\..\test\unique_ptr_default_deleter.cpp">
+			</File>
+		</Filter>
+
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/unique_ptr_functions.vcproj b/proj/vc7ide/unique_ptr_functions.vcproj
new file mode 100644
index 0000000..4917faa
--- /dev/null
+++ b/proj/vc7ide/unique_ptr_functions.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="unique_ptr_functions_test"
+	ProjectGUID="{C57C25A3-4620-FE08-F8B7-AB673D762B60}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/unique_ptr_functions_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/unique_ptr_functions_test_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/unique_ptr_functions_test.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/unique_ptr_functions_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/unique_ptr_functions_test.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{73495AA1-5A6C-3E57-16AC-542F7F2242B9}">
+			<File
+				RelativePath="..\..\test\unique_ptr_functions.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/unique_ptr_modifiers_test.vcproj b/proj/vc7ide/unique_ptr_modifiers_test.vcproj
new file mode 100644
index 0000000..120d483
--- /dev/null
+++ b/proj/vc7ide/unique_ptr_modifiers_test.vcproj
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="unique_ptr_modifiers_test"
+	ProjectGUID="{C57C28A3-4FE0-6208-BF87-B2B61D3A7673}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/unique_ptr_modifiers_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/unique_ptr_modifiers_test_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/unique_ptr_modifiers_test.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/unique_ptr_modifiers_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/unique_ptr_modifiers_test.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{7E3495A1-163E-57AC-5A6C-3A2754202BF3}">
+			<File
+				RelativePath="..\..\test\unique_ptr_modifiers.cpp">
+			</File>
+		</Filter>
+
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/unique_ptr_movector_test.vcproj b/proj/vc7ide/unique_ptr_movector_test.vcproj
new file mode 100644
index 0000000..6c79449
--- /dev/null
+++ b/proj/vc7ide/unique_ptr_movector_test.vcproj
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="unique_ptr_movector_test"
+	ProjectGUID="{C57C28A3-4FE0-6208-BF87-B2B61D3A7672}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/unique_ptr_movector_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/unique_ptr_movector_test_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/unique_ptr_movector_test.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/unique_ptr_movector_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/unique_ptr_movector_test.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{7E3495A1-163E-57AC-5A6C-3A2754202BF2}">
+			<File
+				RelativePath="..\..\test\unique_ptr_movector.cpp">
+			</File>
+		</Filter>
+
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/unique_ptr_nullptr_test.vcproj b/proj/vc7ide/unique_ptr_nullptr_test.vcproj
new file mode 100644
index 0000000..1ff8e57
--- /dev/null
+++ b/proj/vc7ide/unique_ptr_nullptr_test.vcproj
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="unique_ptr_nullptr_test"
+	ProjectGUID="{C57C28A3-4FE0-6208-BF87-B2B61D3A7671}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/unique_ptr_nullptr_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/unique_ptr_nullptr_test_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/unique_ptr_nullptr_test.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/unique_ptr_nullptr_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/unique_ptr_nullptr_test.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{7E3495A1-163E-57AC-5A6C-3A2754202BF1}">
+			<File
+				RelativePath="..\..\test\unique_ptr_nullptr.cpp">
+			</File>
+		</Filter>
+
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/unique_ptr_observers_test.vcproj b/proj/vc7ide/unique_ptr_observers_test.vcproj
new file mode 100644
index 0000000..abfbf87
--- /dev/null
+++ b/proj/vc7ide/unique_ptr_observers_test.vcproj
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="unique_ptr_observers_test"
+	ProjectGUID="{C57C28A3-4FE0-6208-BF87-B2B61D3A7670}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/unique_ptr_observers_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/unique_ptr_observers_test_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/unique_ptr_observers_test.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/unique_ptr_observers_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/unique_ptr_observers_test.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{7E3495A1-163E-57AC-5A6C-3A2754202BF0}">
+			<File
+				RelativePath="..\..\test\unique_ptr_observers.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/proj/vc7ide/unique_ptr_types_test.vcproj b/proj/vc7ide/unique_ptr_types_test.vcproj
new file mode 100644
index 0000000..9b35a18
--- /dev/null
+++ b/proj/vc7ide/unique_ptr_types_test.vcproj
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="unique_ptr_types_test"
+	ProjectGUID="{C57C28A3-4FE0-6208-BF87-B2B61D3A7675}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="../../Bin/Win32/Debug"
+			IntermediateDirectory="Debug/unique_ptr_types_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				DisableLanguageExtensions="FALSE"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/unique_ptr_types_test_d.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/unique_ptr_types_test.pdb"
+				SubSystem="1"
+				TargetMachine="1"
+				FixedBaseAddress="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="../../Bin/Win32/Release"
+			IntermediateDirectory="Release/unique_ptr_types_test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="../../../.."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
+				RuntimeLibrary="2"
+				TreatWChar_tAsBuiltInType="TRUE"
+				ForceConformanceInForLoopScope="FALSE"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="0"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="winmm.lib"
+				OutputFile="$(OutDir)/unique_ptr_types_test.exe"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="../../../../stage/lib"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{7E3495A1-163E-57AC-5A6C-3A2754202BF5}">
+			<File
+				RelativePath="..\..\test\unique_ptr_types.cpp">
+			</File>
+		</Filter>
+
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
new file mode 100644
index 0000000..472517b
--- /dev/null
+++ b/test/Jamfile.v2
@@ -0,0 +1,29 @@
+##############################################################################
+##
+## (C) Copyright Ion Gaztanaga 2008-2009 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)
+##
+##
+##############################################################################
+
+import testing ;
+
+rule test_all
+{
+   local all_rules = ;
+
+   for local fileb in [ glob *.cpp ]
+   {
+      all_rules += [ run $(fileb) /boost/timer//boost_timer
+      :  # additional args
+      :  # test-files
+      :  # requirements
+      ] ;
+   }
+
+   return $(all_rules) ;
+}
+
+test-suite move_test : [ test_all r ] ;
+ 
diff --git a/test/adaptive_merge_test.cpp b/test/adaptive_merge_test.cpp
new file mode 100644
index 0000000..9522625
--- /dev/null
+++ b/test/adaptive_merge_test.cpp
@@ -0,0 +1,80 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2016.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <cstdlib>   //std::srand
+#include <iostream>  //std::cout
+
+#include <boost/config.hpp>
+
+#include <boost/move/unique_ptr.hpp>
+#include <boost/move/algo/detail/merge_sort.hpp>
+
+#include "order_type.hpp"
+#include "random_shuffle.hpp"
+
+#include <boost/move/algo/adaptive_merge.hpp>
+#include <boost/move/core.hpp>
+
+
+template<class T>
+bool test_random_shuffled(std::size_t const element_count, std::size_t const num_keys, std::size_t const num_iter)
+{
+   boost::movelib::unique_ptr<T[]> elements(new T[element_count]);
+   boost::movelib::unique_ptr<std::size_t[]> key_reps(new std::size_t[num_keys ? num_keys : element_count]);
+   std::cout << "- - N: " << element_count << ", Keys: " << num_keys << ", It: " << num_iter << " \n";
+
+   //Initialize keys
+   for(std::size_t  i=0; i < element_count; ++i){
+      std::size_t  key = num_keys ? (i % num_keys) : i;
+      elements[i].key=key;
+   }
+
+   std::srand(0);
+
+   for (std::size_t i = 0; i != num_iter; ++i)
+   {
+      ::random_shuffle(elements.get(), elements.get() + element_count);
+      for(std::size_t i = 0; i < (num_keys ? num_keys : element_count); ++i){
+         key_reps[i]=0;
+      }
+      for(std::size_t i = 0; i < element_count; ++i){
+         elements[i].val = key_reps[elements[i].key]++;
+      }
+
+      boost::movelib::unique_ptr<char[]> buf(new char [sizeof(T)*(element_count-element_count/2)]);
+
+      std::size_t const split = std::size_t(std::rand()) % element_count;
+      boost::movelib::merge_sort(elements.get(), elements.get()+split, order_type_less(), (T*)buf.get());
+      boost::movelib::merge_sort(elements.get()+split, elements.get()+element_count, order_type_less(), (T*)buf.get());
+      
+      boost::movelib::adaptive_merge(elements.get(), elements.get()+split, elements.get()+element_count, order_type_less());
+
+      if (!is_order_type_ordered(elements.get(), element_count))
+      {
+         std::cout <<  "\n ERROR\n";
+         throw int(0);
+      }
+   }
+   return true;
+}
+
+int main()
+{
+   const std::size_t NIter = 100;
+   test_random_shuffled<order_move_type>(10001, 3,    NIter);
+   test_random_shuffled<order_move_type>(10001, 65,   NIter);
+   test_random_shuffled<order_move_type>(10001, 101,  NIter);
+   test_random_shuffled<order_move_type>(10001, 1023, NIter);
+   test_random_shuffled<order_move_type>(10001, 4095, NIter);
+   test_random_shuffled<order_move_type>(10001, 0,    NIter);
+
+   return 0;
+}
diff --git a/test/adaptive_sort_test.cpp b/test/adaptive_sort_test.cpp
new file mode 100644
index 0000000..686b4bd
--- /dev/null
+++ b/test/adaptive_sort_test.cpp
@@ -0,0 +1,73 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2016.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <cstdlib>   //std::srand
+#include <iostream>  //std::cout
+
+#include <boost/config.hpp>
+
+#include <boost/move/unique_ptr.hpp>
+#include <boost/container/vector.hpp>
+
+#include "order_type.hpp"
+#include "random_shuffle.hpp"
+
+#include <boost/move/algo/adaptive_sort.hpp>
+#include <boost/move/core.hpp>
+
+template<class T>
+bool test_random_shuffled(std::size_t const element_count, std::size_t const num_keys, std::size_t const num_iter)
+{
+   boost::movelib::unique_ptr<T[]> elements(new T[element_count]);
+   boost::movelib::unique_ptr<std::size_t[]> key_reps(new std::size_t[num_keys ? num_keys : element_count]);
+   std::cout << "- - N: " << element_count << ", Keys: " << num_keys << ", It: " << num_iter << " \n";
+
+   //Initialize keys
+   for(std::size_t  i=0; i < element_count; ++i){
+      std::size_t  key = num_keys ? (i % num_keys) : i;
+      elements[i].key=key;
+   }
+
+   std::srand(0);
+
+   for (std::size_t i = 0; i != num_iter; ++i)
+   {
+      ::random_shuffle(elements.get(), elements.get() + element_count);
+      for(std::size_t i = 0; i < (num_keys ? num_keys : element_count); ++i){
+         key_reps[i]=0;
+      }
+      for(std::size_t i = 0; i < element_count; ++i){
+         elements[i].val = key_reps[elements[i].key]++;
+      }
+
+      boost::movelib::adaptive_sort(elements.get(), elements.get()+element_count, order_type_less());
+
+      if (!is_order_type_ordered(elements.get(), element_count))
+      {
+         std::cout <<  "\n ERROR\n";
+         throw int(0);
+      }
+   }
+   return true;
+}
+
+int main()
+{
+   const std::size_t NIter = 100;
+   test_random_shuffled<order_move_type>(10001, 3,   NIter);
+   test_random_shuffled<order_move_type>(10001, 65,   NIter);
+   test_random_shuffled<order_move_type>(10001, 101,  NIter);
+   test_random_shuffled<order_move_type>(10001, 1023, NIter);
+   test_random_shuffled<order_move_type>(10001, 4095, NIter);
+   test_random_shuffled<order_move_type>(10001, 0,    NIter);
+
+   return 0;
+}
diff --git a/test/adl_move_swap.cpp b/test/adl_move_swap.cpp
new file mode 100644
index 0000000..200c6cb
--- /dev/null
+++ b/test/adl_move_swap.cpp
@@ -0,0 +1,169 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2014.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/move/core.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+class swap_stats
+{
+   public:
+   static void reset_stats()
+   {
+      member_swap_calls = 0;
+      friend_swap_calls = 0;
+      move_cnstor_calls = 0;
+      move_assign_calls = 0;
+      copy_cnstor_calls = 0;
+      copy_assign_calls = 0;
+   }
+
+   static unsigned int member_swap_calls;
+   static unsigned int friend_swap_calls;
+   static unsigned int move_cnstor_calls;
+   static unsigned int move_assign_calls;
+   static unsigned int copy_cnstor_calls;
+   static unsigned int copy_assign_calls;
+};
+
+unsigned int swap_stats::member_swap_calls = 0;
+unsigned int swap_stats::friend_swap_calls = 0;
+unsigned int swap_stats::move_cnstor_calls = 0;
+unsigned int swap_stats::move_assign_calls = 0;
+unsigned int swap_stats::copy_cnstor_calls = 0;
+unsigned int swap_stats::copy_assign_calls = 0;
+
+class movable : public swap_stats
+{
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(movable)
+   public:
+   movable()                                 {}
+   movable(BOOST_RV_REF(movable))            { ++move_cnstor_calls; }
+   movable & operator=(BOOST_RV_REF(movable)){ ++move_assign_calls; return *this; }
+   friend void swap(movable &, movable &)    { ++friend_swap_calls; }
+};
+
+class movable_swap_member : public swap_stats
+{
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(movable_swap_member)
+   public:
+   movable_swap_member()                                             {}
+   movable_swap_member(BOOST_RV_REF(movable_swap_member))            { ++move_cnstor_calls; }
+   movable_swap_member & operator=(BOOST_RV_REF(movable_swap_member)){ ++move_assign_calls; return *this; }
+   void swap(movable_swap_member &)                                  { ++member_swap_calls; }
+   friend void swap(movable_swap_member &, movable_swap_member &)    { ++friend_swap_calls; }
+};
+
+class copyable : public swap_stats
+{
+   public:
+   copyable()                                {}
+   copyable(const copyable &)                { ++copy_cnstor_calls; }
+   copyable & operator=(const copyable&)     { ++copy_assign_calls; return *this; }
+   void swap(copyable &)                     { ++member_swap_calls; }
+   friend void swap(copyable &, copyable &)  { ++friend_swap_calls; }
+};
+
+class no_swap : public swap_stats
+{
+   private: unsigned m_state;
+   public:
+   explicit no_swap(unsigned i): m_state(i){}
+   no_swap(const no_swap &x)               { m_state = x.m_state; ++copy_cnstor_calls; }
+   no_swap & operator=(const no_swap& x)   { m_state = x.m_state; ++copy_assign_calls; return *this; }
+   void swap(no_swap &)                    { ++member_swap_calls; }
+   friend bool operator==(const no_swap &x, const no_swap &y) {  return x.m_state == y.m_state; }
+   friend bool operator!=(const no_swap &x, const no_swap &y) {  return !(x==y); }
+};
+
+
+int main()
+{
+   {  //movable
+      movable x, y;
+      swap_stats::reset_stats();
+      ::boost::adl_move_swap(x, y);
+      #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+      //In non rvalue reference compilers,
+      //movable classes with no swap() member uses
+      //boost::move() to implement swap.
+      BOOST_TEST(swap_stats::friend_swap_calls == 0);
+      BOOST_TEST(swap_stats::member_swap_calls == 0);
+      BOOST_TEST(swap_stats::member_swap_calls == 0);
+      BOOST_TEST(swap_stats::move_cnstor_calls == 1);
+      BOOST_TEST(swap_stats::move_assign_calls == 2);
+      BOOST_TEST(swap_stats::copy_cnstor_calls == 0);
+      BOOST_TEST(swap_stats::copy_assign_calls == 0);
+      #else
+      //In compilers with rvalue references, this should call friend swap via ADL
+      BOOST_TEST(swap_stats::friend_swap_calls == 1);
+      BOOST_TEST(swap_stats::member_swap_calls == 0);
+      BOOST_TEST(swap_stats::member_swap_calls == 0);
+      BOOST_TEST(swap_stats::move_cnstor_calls == 0);
+      BOOST_TEST(swap_stats::move_assign_calls == 0);
+      BOOST_TEST(swap_stats::copy_cnstor_calls == 0);
+      BOOST_TEST(swap_stats::copy_assign_calls == 0);
+      #endif
+   }
+   {  //movable_swap_member
+      movable_swap_member x, y;
+      swap_stats::reset_stats();
+      ::boost::adl_move_swap(x, y);
+      #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+      //In non rvalue reference compilers,
+      //movable classes with no swap() member uses
+      //boost::move() to implement swap.
+      BOOST_TEST(swap_stats::friend_swap_calls == 0);
+      BOOST_TEST(swap_stats::member_swap_calls == 1);
+      BOOST_TEST(swap_stats::move_cnstor_calls == 0);
+      BOOST_TEST(swap_stats::move_assign_calls == 0);
+      BOOST_TEST(swap_stats::copy_cnstor_calls == 0);
+      BOOST_TEST(swap_stats::copy_assign_calls == 0);
+      #else
+      //In compilers with rvalue references, this should call friend swap via ADL
+      BOOST_TEST(swap_stats::friend_swap_calls == 1);
+      BOOST_TEST(swap_stats::member_swap_calls == 0);
+      BOOST_TEST(swap_stats::move_cnstor_calls == 0);
+      BOOST_TEST(swap_stats::move_assign_calls == 0);
+      BOOST_TEST(swap_stats::copy_cnstor_calls == 0);
+      BOOST_TEST(swap_stats::copy_assign_calls == 0);
+      #endif
+   }
+   {  //copyable
+      copyable x, y;
+      swap_stats::reset_stats();
+      ::boost::adl_move_swap(x, y);
+      //This should call friend swap via ADL
+      BOOST_TEST(swap_stats::friend_swap_calls == 1);
+      BOOST_TEST(swap_stats::member_swap_calls == 0);
+      BOOST_TEST(swap_stats::move_cnstor_calls == 0);
+      BOOST_TEST(swap_stats::move_assign_calls == 0);
+      BOOST_TEST(swap_stats::copy_cnstor_calls == 0);
+      BOOST_TEST(swap_stats::copy_assign_calls == 0);
+   }
+   {  //no_swap
+      no_swap x(1), y(2), x_back(x), y_back(y);
+      swap_stats::reset_stats();
+      ::boost::adl_move_swap(x, y);
+      //This should call std::swap which uses copies
+      BOOST_TEST(swap_stats::friend_swap_calls == 0);
+      BOOST_TEST(swap_stats::member_swap_calls == 0);
+      BOOST_TEST(swap_stats::move_cnstor_calls == 0);
+      BOOST_TEST(swap_stats::move_assign_calls == 0);
+      BOOST_TEST(swap_stats::copy_cnstor_calls == 1);
+      BOOST_TEST(swap_stats::copy_assign_calls == 2);
+      BOOST_TEST(x == y_back);
+      BOOST_TEST(y == x_back);
+      BOOST_TEST(x != y);
+   }
+   return ::boost::report_errors();
+}
+#include <boost/move/detail/config_end.hpp>
diff --git a/test/algo_test.cpp b/test/algo_test.cpp
new file mode 100644
index 0000000..d4652e2
--- /dev/null
+++ b/test/algo_test.cpp
@@ -0,0 +1,953 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2007-2017.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/move/algo/detail/set_difference.hpp>
+#include "order_type.hpp"
+#include <boost/core/lightweight_test.hpp>
+#include <cstddef>
+/*
+///////////////////////////////////
+//
+//      set_difference
+//
+///////////////////////////////////
+void test_set_difference_normal()
+{
+   order_perf_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_perf_type range1[4];
+   range1[0].key = 0u;
+   range1[0].val = 1u;
+   range1[1].key = 1u;
+   range1[1].val = 1u;
+   range1[2].key = 3u;
+   range1[2].val = 1u;
+   range1[3].key = 4u;
+   range1[3].val = 1u;
+
+   order_perf_type out[20];
+   out[2].key = 998;
+   out[2].val = 999;
+   boost::movelib::set_difference(range1, range1+4, range2, range2+10, out, order_type_less());
+   BOOST_TEST(out[0].key == 1u);
+   BOOST_TEST(out[0].val == 1u);
+   BOOST_TEST(out[1].key == 3u);
+   BOOST_TEST(out[1].val == 1u);
+   BOOST_TEST(out[2].key == 998);
+   BOOST_TEST(out[2].val == 999);
+}
+
+void test_set_difference_range1_repeated()
+{
+   order_perf_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_perf_type range1[4];
+   range1[0].key = 0u;
+   range1[0].val = 1u;
+   range1[1].key = 2u;
+   range1[1].val = 1u;
+   range1[2].key = 4u;
+   range1[2].val = 1u;
+   range1[3].key = 6u;
+   range1[3].val = 1u;
+
+   order_perf_type out[20];
+   out[0].key = 998;
+   out[0].val = 999;
+   boost::movelib::set_difference(range1, range1+4, range2, range2+10, out, order_type_less());
+   BOOST_TEST(out[0].key == 998);
+   BOOST_TEST(out[0].val == 999);
+}
+
+void test_set_difference_range1_unique()
+{
+   order_perf_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_perf_type range1[4];
+   range1[0].key = 1u;
+   range1[0].val = 1u;
+   range1[1].key = 3u;
+   range1[1].val = 1u;
+   range1[2].key = 5u;
+   range1[2].val = 1u;
+   range1[3].key = 7u;
+   range1[3].val = 1u;
+
+   order_perf_type out[20];
+   out[4].key = 998;
+   out[4].val = 999;
+   boost::movelib::set_difference(range1, range1+4, range2, range2+10, out, order_type_less());
+   BOOST_TEST(out[0].key == 1u);
+   BOOST_TEST(out[0].val == 1u);
+   BOOST_TEST(out[1].key == 3u);
+   BOOST_TEST(out[1].val == 1u);
+   BOOST_TEST(out[2].key == 5u);
+   BOOST_TEST(out[3].val == 1u);
+   BOOST_TEST(out[3].key == 7u);
+   BOOST_TEST(out[3].val == 1u);
+   BOOST_TEST(out[4].key == 998);
+   BOOST_TEST(out[4].val == 999);
+}
+*/
+
+///////////////////////////////////
+//
+//      set_difference
+//
+///////////////////////////////////
+void test_set_difference_normal()
+{
+   order_perf_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_perf_type range1[5];
+   range1[0].key = 0u;
+   range1[0].val = 1u;
+   range1[1].key = 1u;
+   range1[1].val = 1u;
+   range1[2].key = 1u;
+   range1[2].val = 2u;
+   range1[3].key = 3u;
+   range1[3].val = 1u;
+   range1[4].key = 4u;
+   range1[4].val = 1u;
+
+   order_perf_type out[20];
+   out[3].key = 998;
+   out[3].val = 999;
+   order_perf_type *r =
+      boost::movelib::set_difference(range1, range1+5, range2, range2+10, out, order_type_less());
+   BOOST_TEST(&out[3] == r);
+   BOOST_TEST(out[0].key == 1u);
+   BOOST_TEST(out[0].val == 1u);
+   BOOST_TEST(out[1].key == 1u);
+   BOOST_TEST(out[1].val == 2u);
+   BOOST_TEST(out[2].key == 3u);
+   BOOST_TEST(out[2].val == 1u);
+   BOOST_TEST(out[3].key == 998);
+   BOOST_TEST(out[3].val == 999);
+}
+
+void test_set_difference_range1_repeated()
+{
+   order_perf_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_perf_type range1[5];
+   range1[0].key = 0u;
+   range1[0].val = 1u;
+   range1[1].key = 2u;
+   range1[1].val = 1u;
+   range1[2].key = 2u;
+   range1[2].val = 2u;
+   range1[3].key = 4u;
+   range1[3].val = 1u;
+   range1[4].key = 6u;
+   range1[4].val = 1u;
+
+   order_perf_type out[20];
+   out[0].key = 998;
+   out[0].val = 999;
+   order_perf_type *r =
+      boost::movelib::set_difference(range1, range1+5, range2, range2+10, out, order_type_less());
+   BOOST_TEST(&out[1] == r);
+   BOOST_TEST(out[0].key == 2);
+   BOOST_TEST(out[0].val == 2);
+}
+
+void test_set_difference_range1_unique()
+{
+   order_perf_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_perf_type range1[5];
+   range1[0].key = 1u;
+   range1[0].val = 1u;
+   range1[1].key = 3u;
+   range1[1].val = 1u;
+   range1[2].key = 5u;
+   range1[2].val = 1u;
+   range1[3].key = 7u;
+   range1[3].val = 1u;
+   range1[4].key = 7u;
+   range1[4].val = 2u;
+
+   order_perf_type out[20];
+   out[5].key = 998;
+   out[5].val = 999;
+   order_perf_type *r =
+      boost::movelib::set_difference(range1, range1+5, range2, range2+10, out, order_type_less());
+   BOOST_TEST(&out[5] == r);
+   BOOST_TEST(out[0].key == 1u);
+   BOOST_TEST(out[0].val == 1u);
+   BOOST_TEST(out[1].key == 3u);
+   BOOST_TEST(out[1].val == 1u);
+   BOOST_TEST(out[2].key == 5u);
+   BOOST_TEST(out[2].val == 1u);
+   BOOST_TEST(out[3].key == 7u);
+   BOOST_TEST(out[3].val == 1u);
+   BOOST_TEST(out[4].key == 7u);
+   BOOST_TEST(out[4].val == 2u);
+   BOOST_TEST(out[5].key == 998);
+   BOOST_TEST(out[5].val == 999);
+}
+
+/*
+///////////////////////////////////
+//
+//      inplace_set_difference
+//
+///////////////////////////////////
+void test_inplace_set_difference_normal()
+{
+   order_move_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_move_type range1[4];
+   range1[0].key = 0u;
+   range1[0].val = 1u;
+   range1[1].key = 1u;
+   range1[1].val = 1u;
+   range1[2].key = 3u;
+   range1[2].val = 1u;
+   range1[3].key = 4u;
+   range1[3].val = 1u;
+
+   order_move_type *ret = boost::movelib::inplace_set_difference(range1, range1+4, range2, range2+10, order_type_less());
+   BOOST_TEST(ret == range1+2);
+   BOOST_TEST(range1[0].key == 1u);
+   BOOST_TEST(range1[0].val == 1u);
+   BOOST_TEST(range1[1].key == 3u);
+   BOOST_TEST(range1[1].val == 1u);
+   BOOST_TEST(range1[2].key == order_move_type::moved_assign_mark);
+   BOOST_TEST(range1[2].val == order_move_type::moved_assign_mark);
+}
+
+void test_inplace_set_difference_range1_repeated()
+{
+   order_move_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_move_type range1[5];
+   range1[0].key = 0u;
+   range1[0].val = 1u;
+   range1[1].key = 2u;
+   range1[1].val = 1u;
+   range1[2].key = 4u;
+   range1[2].val = 1u;
+   range1[3].key = 6u;
+   range1[3].val = 1u;
+   range1[4].key = order_move_type::moved_assign_mark;
+   range1[4].val = order_move_type::moved_assign_mark;
+
+   order_move_type *ret = boost::movelib::inplace_set_difference(range1, range1+4, range2, range2+10, order_type_less());
+   BOOST_TEST(ret == range1+0);
+   BOOST_TEST(range1[0].key == 0u);
+   BOOST_TEST(range1[0].val == 1u);
+   BOOST_TEST(range1[1].key == 2u);
+   BOOST_TEST(range1[1].val == 1u);
+   BOOST_TEST(range1[2].key == 4u);
+   BOOST_TEST(range1[3].val == 1u);
+   BOOST_TEST(range1[3].key == 6u);
+   BOOST_TEST(range1[3].val == 1u);
+   BOOST_TEST(range1[4].key == order_move_type::moved_assign_mark);
+   BOOST_TEST(range1[4].val == order_move_type::moved_assign_mark);
+}
+
+void test_inplace_set_difference_range1_unique()
+{
+   order_move_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_move_type range1[5];
+   range1[0].key = 1u;
+   range1[0].val = 1u;
+   range1[1].key = 3u;
+   range1[1].val = 1u;
+   range1[2].key = 5u;
+   range1[2].val = 1u;
+   range1[3].key = 7u;
+   range1[3].val = 1u;
+   range1[4].key = order_move_type::moved_assign_mark;
+   range1[4].val = order_move_type::moved_assign_mark;
+
+   order_move_type *ret = boost::movelib::inplace_set_difference(range1, range1+4, range2, range2+10, order_type_less());
+   BOOST_TEST(ret == range1+4);
+   BOOST_TEST(range1[0].key == 1u);
+   BOOST_TEST(range1[0].val == 1u);
+   BOOST_TEST(range1[1].key == 3u);
+   BOOST_TEST(range1[1].val == 1u);
+   BOOST_TEST(range1[2].key == 5u);
+   BOOST_TEST(range1[3].val == 1u);
+   BOOST_TEST(range1[3].key == 7u);
+   BOOST_TEST(range1[3].val == 1u);
+   BOOST_TEST(range1[4].key == order_move_type::moved_assign_mark);
+   BOOST_TEST(range1[4].val == order_move_type::moved_assign_mark);
+}
+
+void test_inplace_set_difference_range1_unique_long()
+{
+   order_move_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_move_type range1[11];
+   for(std::size_t i = 0; i != sizeof(range1)/sizeof(*range1); ++i){
+      range1[i].key = i*2+1;
+      range1[i].val = 1u;
+   }
+
+   order_move_type *ret = boost::movelib::inplace_set_difference(range1, range1+11, range2, range2+10, order_type_less());
+   BOOST_TEST(ret == range1+11);
+   for(std::size_t i = 0; i != sizeof(range1)/sizeof(*range1); ++i){
+      BOOST_TEST(range1[i].key == i*2+1);
+      BOOST_TEST(range1[i].val == 1u);
+   }
+}
+
+void test_inplace_set_difference_range1_same_start()
+{
+   order_move_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_move_type range1[5];
+   range1[0].key = 0u;
+   range1[0].val = 1u;
+   range1[1].key = 2u;
+   range1[1].val = 1u;
+   range1[2].key = 4u;
+   range1[2].val = 1u;
+   range1[3].key = 5u;
+   range1[3].val = 1u;
+   range1[4].key = 7u;
+   range1[4].val = 1u;
+
+   order_move_type *ret = boost::movelib::inplace_set_difference(range1, range1+5, range2, range2+10, order_type_less());
+   BOOST_TEST(ret == range1+2);
+   BOOST_TEST(range1[0].key == 5u);
+   BOOST_TEST(range1[0].val == 1u);
+   BOOST_TEST(range1[1].key == 7u);
+   BOOST_TEST(range1[1].val == 1u);
+}
+
+void test_inplace_set_difference_range1_same_end()
+{
+   order_move_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_move_type range1[5];
+   range1[0].key = 1u;
+   range1[0].val = 1u;
+   range1[1].key = 3u;
+   range1[1].val = 1u;
+   range1[2].key = 4u;
+   range1[2].val = 1u;
+   range1[3].key = 6u;
+   range1[3].val = 1u;
+   range1[4].key = 8u;
+   range1[4].val = 1u;
+
+   order_move_type *ret = boost::movelib::inplace_set_difference(range1, range1+5, range2, range2+10, order_type_less());
+   BOOST_TEST(ret == range1+2);
+   BOOST_TEST(range1[0].key == 1u);
+   BOOST_TEST(range1[0].val == 1u);
+   BOOST_TEST(range1[1].key == 3u);
+   BOOST_TEST(range1[1].val == 1u);
+   BOOST_TEST(range1[2].key == 4u);
+   BOOST_TEST(range1[2].val == 1u);
+   BOOST_TEST(range1[3].key == 6u);
+   BOOST_TEST(range1[3].val == 1u);
+}
+*/
+
+///////////////////////////////////
+//
+//      inplace_set_difference
+//
+///////////////////////////////////
+void test_inplace_set_difference_normal()
+{
+   order_move_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_move_type range1[4];
+   range1[0].key = 0u;
+   range1[0].val = 1u;
+   range1[1].key = 1u;
+   range1[1].val = 1u;
+   range1[2].key = 3u;
+   range1[2].val = 1u;
+   range1[3].key = 4u;
+   range1[3].val = 1u;
+
+   order_move_type *ret = boost::movelib::inplace_set_difference(range1, range1+4, range2, range2+10, order_type_less());
+   BOOST_TEST(ret == range1+2);
+   BOOST_TEST(range1[0].key == 1u);
+   BOOST_TEST(range1[0].val == 1u);
+   BOOST_TEST(range1[1].key == 3u);
+   BOOST_TEST(range1[1].val == 1u);
+   BOOST_TEST(range1[2].key == order_move_type::moved_assign_mark);
+   BOOST_TEST(range1[2].val == order_move_type::moved_assign_mark);
+}
+
+void test_inplace_set_difference_range1_repeated()
+{
+   order_move_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_move_type range1[5];
+   range1[0].key = 0u;
+   range1[0].val = 1u;
+   range1[1].key = 2u;
+   range1[1].val = 1u;
+   range1[2].key = 4u;
+   range1[2].val = 1u;
+   range1[3].key = 6u;
+   range1[3].val = 1u;
+   range1[4].key = order_move_type::moved_assign_mark;
+   range1[4].val = order_move_type::moved_assign_mark;
+
+   order_move_type *ret = boost::movelib::inplace_set_difference(range1, range1+4, range2, range2+10, order_type_less());
+   BOOST_TEST(ret == range1+0);
+   BOOST_TEST(range1[0].key == 0u);
+   BOOST_TEST(range1[0].val == 1u);
+   BOOST_TEST(range1[1].key == 2u);
+   BOOST_TEST(range1[1].val == 1u);
+   BOOST_TEST(range1[2].key == 4u);
+   BOOST_TEST(range1[3].val == 1u);
+   BOOST_TEST(range1[3].key == 6u);
+   BOOST_TEST(range1[3].val == 1u);
+   BOOST_TEST(range1[4].key == order_move_type::moved_assign_mark);
+   BOOST_TEST(range1[4].val == order_move_type::moved_assign_mark);
+}
+
+void test_inplace_set_difference_range1_unique()
+{
+   order_move_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_move_type range1[5];
+   range1[0].key = 1u;
+   range1[0].val = 1u;
+   range1[1].key = 3u;
+   range1[1].val = 1u;
+   range1[2].key = 5u;
+   range1[2].val = 1u;
+   range1[3].key = 7u;
+   range1[3].val = 1u;
+   range1[4].key = order_move_type::moved_assign_mark;
+   range1[4].val = order_move_type::moved_assign_mark;
+
+   order_move_type *ret = boost::movelib::inplace_set_difference(range1, range1+4, range2, range2+10, order_type_less());
+   BOOST_TEST(ret == range1+4);
+   BOOST_TEST(range1[0].key == 1u);
+   BOOST_TEST(range1[0].val == 1u);
+   BOOST_TEST(range1[1].key == 3u);
+   BOOST_TEST(range1[1].val == 1u);
+   BOOST_TEST(range1[2].key == 5u);
+   BOOST_TEST(range1[3].val == 1u);
+   BOOST_TEST(range1[3].key == 7u);
+   BOOST_TEST(range1[3].val == 1u);
+   BOOST_TEST(range1[4].key == order_move_type::moved_assign_mark);
+   BOOST_TEST(range1[4].val == order_move_type::moved_assign_mark);
+}
+
+void test_inplace_set_difference_range1_unique_long()
+{
+   order_move_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_move_type range1[11];
+   for(std::size_t i = 0; i != sizeof(range1)/sizeof(*range1); ++i){
+      range1[i].key = i*2+1;
+      range1[i].val = 1u;
+   }
+
+   order_move_type *ret = boost::movelib::inplace_set_difference(range1, range1+11, range2, range2+10, order_type_less());
+   BOOST_TEST(ret == range1+11);
+   for(std::size_t i = 0; i != sizeof(range1)/sizeof(*range1); ++i){
+      BOOST_TEST(range1[i].key == i*2+1);
+      BOOST_TEST(range1[i].val == 1u);
+   }
+}
+
+void test_inplace_set_difference_range1_same_start()
+{
+   order_move_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_move_type range1[5];
+   range1[0].key = 0u;
+   range1[0].val = 1u;
+   range1[1].key = 2u;
+   range1[1].val = 1u;
+   range1[2].key = 4u;
+   range1[2].val = 1u;
+   range1[3].key = 5u;
+   range1[3].val = 1u;
+   range1[4].key = 7u;
+   range1[4].val = 1u;
+
+   order_move_type *ret = boost::movelib::inplace_set_difference(range1, range1+5, range2, range2+10, order_type_less());
+   BOOST_TEST(ret == range1+2);
+   BOOST_TEST(range1[0].key == 5u);
+   BOOST_TEST(range1[0].val == 1u);
+   BOOST_TEST(range1[1].key == 7u);
+   BOOST_TEST(range1[1].val == 1u);
+}
+
+void test_inplace_set_difference_range1_same_end()
+{
+   order_move_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_move_type range1[5];
+   range1[0].key = 1u;
+   range1[0].val = 1u;
+   range1[1].key = 3u;
+   range1[1].val = 1u;
+   range1[2].key = 4u;
+   range1[2].val = 1u;
+   range1[3].key = 6u;
+   range1[3].val = 1u;
+   range1[4].key = 8u;
+   range1[4].val = 1u;
+
+   order_move_type *ret = boost::movelib::inplace_set_difference(range1, range1+5, range2, range2+10, order_type_less());
+   BOOST_TEST(ret == range1+2);
+   BOOST_TEST(range1[0].key == 1u);
+   BOOST_TEST(range1[0].val == 1u);
+   BOOST_TEST(range1[1].key == 3u);
+   BOOST_TEST(range1[1].val == 1u);
+   BOOST_TEST(range1[2].key == 4u);
+   BOOST_TEST(range1[2].val == 1u);
+   BOOST_TEST(range1[3].key == 6u);
+   BOOST_TEST(range1[3].val == 1u);
+}
+
+
+///////////////////////////////////
+//
+//      set_unique_difference
+//
+///////////////////////////////////
+void test_set_unique_difference_normal()
+{
+   order_perf_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_perf_type range1[10];
+   range1[0].key = 0u;
+   range1[0].val = 1u;
+   range1[1].key = 1u;
+   range1[1].val = 1u;
+   range1[2].key = 1u;
+   range1[2].val = 2u;
+   range1[3].key = 3u;
+   range1[3].val = 1u;
+   range1[4].key = 4u;
+   range1[4].val = 1u;
+   range1[5].key = 4u;
+   range1[5].val = 2u;
+   range1[6].key = 21u;
+   range1[6].val = 1u;
+   range1[7].key = 21u;
+   range1[7].val = 2u;
+   range1[8].key = 23u;
+   range1[8].val = 1u;
+   range1[9].key = 23u;
+   range1[9].val = 2u;
+
+   order_perf_type out[20];
+   out[4].key = 998;
+   out[4].val = 999;
+   order_perf_type * r =
+      boost::movelib::set_unique_difference(range1, range1+10, range2, range2+10, out, order_type_less());
+   BOOST_TEST(&out[4] == r);
+   BOOST_TEST(out[0].key == 1u);
+   BOOST_TEST(out[0].val == 1u);
+   BOOST_TEST(out[1].key == 3u);
+   BOOST_TEST(out[1].val == 1u);
+   BOOST_TEST(out[2].key == 21u);
+   BOOST_TEST(out[2].val == 1u);
+   BOOST_TEST(out[3].key == 23u);
+   BOOST_TEST(out[3].val == 1u);
+   BOOST_TEST(out[4].key == 998);
+   BOOST_TEST(out[4].val == 999);
+}
+
+void test_set_unique_difference_range1_repeated()
+{
+   order_perf_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_perf_type range1[11];
+   range1[0].key = 0u;
+   range1[0].val = 1u;
+   range1[1].key = 0u;
+   range1[1].val = 2u;
+   range1[2].key = 0u;
+   range1[2].val = 2u;
+   range1[3].key = 2u;
+   range1[3].val = 1u;
+   range1[4].key = 2u;
+   range1[4].val = 2u;
+   range1[5].key = 4u;
+   range1[5].val = 1u;
+   range1[6].key = 6u;
+   range1[6].val = 1u;
+   range1[7].key = 6u;
+   range1[7].val = 2u;
+   range1[8].key = 6u;
+   range1[8].val = 3u;
+   range1[9].key = 6u;
+   range1[9].val = 4u;
+   range1[10].key = 6u;
+   range1[10].val = 5u;
+
+   order_perf_type out[20];
+   out[0].key = 998;
+   out[0].val = 999;
+   order_perf_type * r =
+      boost::movelib::set_unique_difference(range1, range1+11, range2, range2+10, out, order_type_less());
+   BOOST_TEST(&out[0] == r);
+   BOOST_TEST(out[0].key == 998);
+   BOOST_TEST(out[0].val == 999);
+}
+
+void test_set_unique_difference_range1_unique()
+{
+   order_perf_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_perf_type range1[7];
+   range1[0].key = 1u;
+   range1[0].val = 1u;
+   range1[1].key = 3u;
+   range1[1].val = 1u;
+   range1[2].key = 3u;
+   range1[2].val = 2u;
+   range1[3].key = 5u;
+   range1[3].val = 1u;
+   range1[4].key = 7u;
+   range1[4].val = 1u;
+   range1[5].key = 7u;
+   range1[5].val = 2u;
+   range1[6].key = 7u;
+   range1[6].val = 3u;
+
+   order_perf_type out[20];
+   out[4].key = 998;
+   out[4].val = 999;
+   order_perf_type * r =
+      boost::movelib::set_unique_difference(range1, range1+7, range2, range2+10, out, order_type_less());
+   BOOST_TEST(&out[4] == r);
+   BOOST_TEST(out[0].key == 1u);
+   BOOST_TEST(out[0].val == 1u);
+   BOOST_TEST(out[1].key == 3u);
+   BOOST_TEST(out[1].val == 1u);
+   BOOST_TEST(out[2].key == 5u);
+   BOOST_TEST(out[2].val == 1u);
+   BOOST_TEST(out[3].key == 7u);
+   BOOST_TEST(out[3].val == 1u);
+   BOOST_TEST(out[4].key == 998);
+   BOOST_TEST(out[4].val == 999);
+}
+
+///////////////////////////////////
+//
+//      inplace_set_unique_difference
+//
+///////////////////////////////////
+void test_inplace_set_unique_difference_normal()
+{
+   order_move_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_move_type range1[4];
+   range1[0].key = 0u;
+   range1[0].val = 1u;
+   range1[1].key = 1u;
+   range1[1].val = 1u;
+   range1[2].key = 3u;
+   range1[2].val = 1u;
+   range1[3].key = 4u;
+   range1[3].val = 1u;
+
+   order_move_type *ret = boost::movelib::inplace_set_unique_difference(range1, range1+4, range2, range2+10, order_type_less());
+   BOOST_TEST(ret == range1+2);
+   BOOST_TEST(range1[0].key == 1u);
+   BOOST_TEST(range1[0].val == 1u);
+   BOOST_TEST(range1[1].key == 3u);
+   BOOST_TEST(range1[1].val == 1u);
+   BOOST_TEST(range1[2].key == order_move_type::moved_assign_mark);
+   BOOST_TEST(range1[2].val == order_move_type::moved_assign_mark);
+}
+
+void test_inplace_set_unique_difference_range1_repeated()
+{
+   order_move_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_move_type range1[5];
+   range1[0].key = 0u;
+   range1[0].val = 1u;
+   range1[1].key = 2u;
+   range1[1].val = 1u;
+   range1[2].key = 4u;
+   range1[2].val = 1u;
+   range1[3].key = 6u;
+   range1[3].val = 1u;
+   range1[4].key = order_move_type::moved_assign_mark;
+   range1[4].val = order_move_type::moved_assign_mark;
+
+   order_move_type *ret = boost::movelib::inplace_set_unique_difference(range1, range1+4, range2, range2+10, order_type_less());
+   BOOST_TEST(ret == range1+0);
+   BOOST_TEST(range1[0].key == 0u);
+   BOOST_TEST(range1[0].val == 1u);
+   BOOST_TEST(range1[1].key == 2u);
+   BOOST_TEST(range1[1].val == 1u);
+   BOOST_TEST(range1[2].key == 4u);
+   BOOST_TEST(range1[3].val == 1u);
+   BOOST_TEST(range1[3].key == 6u);
+   BOOST_TEST(range1[3].val == 1u);
+   BOOST_TEST(range1[4].key == order_move_type::moved_assign_mark);
+   BOOST_TEST(range1[4].val == order_move_type::moved_assign_mark);
+}
+
+void test_inplace_set_unique_difference_range1_unique()
+{
+   order_move_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_move_type range1[9];
+   range1[0].key = 1u;
+   range1[0].val = 1u;
+   range1[1].key = 1u;
+   range1[1].val = 2u;
+   range1[2].key = 3u;
+   range1[2].val = 1u;
+   range1[3].key = 3u;
+   range1[3].val = 2u;
+   range1[4].key = 5u;
+   range1[4].val = 1u;
+   range1[5].key = 7u;
+   range1[5].val = 1u;
+   range1[6].key = 7u;
+   range1[6].val = 2u;
+   range1[7].key = 7u;
+   range1[7].val = 3u;
+   range1[8].val = 3u;
+   range1[8].key = order_move_type::moved_assign_mark;
+   range1[8].val = order_move_type::moved_assign_mark;
+
+   order_move_type *ret =
+      boost::movelib::inplace_set_unique_difference(range1, range1+8, range2, range2+10, order_type_less());
+   BOOST_TEST(ret == range1+4);
+   BOOST_TEST(range1[0].key == 1u);
+   BOOST_TEST(range1[0].val == 1u);
+   BOOST_TEST(range1[1].key == 3u);
+   BOOST_TEST(range1[1].val == 1u);
+   BOOST_TEST(range1[2].key == 5u);
+   BOOST_TEST(range1[3].val == 1u);
+   BOOST_TEST(range1[3].key == 7u);
+   BOOST_TEST(range1[3].val == 1u);
+}
+
+void test_inplace_set_unique_difference_range1_unique_long()
+{
+   order_move_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_move_type range1[22];
+   for(std::size_t i = 0; i != sizeof(range1)/sizeof(*range1); ++i){
+      range1[i].key = (i/2)*2+1;
+      range1[i].val = i%2;
+   }
+
+   order_move_type *ret =
+      boost::movelib::inplace_set_unique_difference(range1, range1+22, range2, range2+10, order_type_less());
+   BOOST_TEST(ret == range1+11);
+   for(std::size_t i = 0; i != 11; ++i){
+      BOOST_TEST(range1[i].key == i*2+1);
+      BOOST_TEST(range1[i].val == 0u);
+   }
+}
+
+void test_inplace_set_unique_difference_range1_same_start()
+{
+   order_move_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_move_type range1[6];
+   range1[0].key = 0u;
+   range1[0].val = 1u;
+   range1[1].key = 2u;
+   range1[1].val = 1u;
+   range1[2].key = 4u;
+   range1[2].val = 1u;
+   range1[3].key = 4u;
+   range1[3].val = 2u;
+   range1[4].key = 5u;
+   range1[4].val = 1u;
+   range1[5].key = 7u;
+   range1[5].val = 1u;
+
+   order_move_type *ret =
+      boost::movelib::inplace_set_unique_difference(range1, range1+6, range2, range2+10, order_type_less());
+   BOOST_TEST(ret == range1+2);
+   BOOST_TEST(range1[0].key == 5u);
+   BOOST_TEST(range1[0].val == 1u);
+   BOOST_TEST(range1[1].key == 7u);
+   BOOST_TEST(range1[1].val == 1u);
+}
+
+void test_inplace_set_unique_difference_range1_same_end()
+{
+   order_move_type range2[10];
+   for(std::size_t i = 0; i != sizeof(range2)/sizeof(*range2); ++i){
+      range2[i].key = i*2;
+      range2[i].val = 0u;
+   }
+
+   order_move_type range1[8];
+   range1[0].key = 1u;
+   range1[0].val = 1u;
+   range1[1].key = 3u;
+   range1[1].val = 1u;
+   range1[2].key = 4u;
+   range1[2].val = 1u;
+   range1[3].key = 4u;
+   range1[3].val = 2u;
+   range1[4].key = 6u;
+   range1[4].val = 1u;
+   range1[5].key = 8u;
+   range1[5].val = 1u;
+   range1[6].key = 8u;
+   range1[6].val = 2u;
+   range1[7].key = 8u;
+   range1[7].val = 3u;
+
+   order_move_type *ret =
+      boost::movelib::inplace_set_unique_difference(range1, range1+8, range2, range2+10, order_type_less());
+   BOOST_TEST(ret == range1+2);
+   BOOST_TEST(range1[0].key == 1u);
+   BOOST_TEST(range1[0].val == 1u);
+   BOOST_TEST(range1[1].key == 3u);
+   BOOST_TEST(range1[1].val == 1u);
+}
+
+int main()
+{
+   //set_difference
+   test_set_difference_normal();
+   test_set_difference_range1_repeated();
+   test_set_difference_range1_unique();
+   //inplace_set_difference
+   test_inplace_set_difference_normal();
+   test_inplace_set_difference_range1_repeated();
+   test_inplace_set_difference_range1_unique();
+   test_inplace_set_difference_range1_unique_long();
+   test_inplace_set_difference_range1_same_start();
+   test_inplace_set_difference_range1_same_end();
+   //set_unique_difference
+   test_set_unique_difference_normal();
+   test_set_unique_difference_range1_repeated();
+   test_set_unique_difference_range1_unique();
+   //inplace_set_unique_difference
+   test_inplace_set_unique_difference_normal();
+   test_inplace_set_unique_difference_range1_repeated();
+   test_inplace_set_unique_difference_range1_unique();
+   test_inplace_set_unique_difference_range1_unique_long();
+   test_inplace_set_unique_difference_range1_same_start();
+   test_inplace_set_unique_difference_range1_same_end();
+
+   return boost::report_errors();
+}
diff --git a/test/back_move_inserter.cpp b/test/back_move_inserter.cpp
new file mode 100644
index 0000000..6fc4829
--- /dev/null
+++ b/test/back_move_inserter.cpp
@@ -0,0 +1,80 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2009.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/move/detail/config_begin.hpp>
+// move
+#include <boost/move/algorithm.hpp>
+#include <boost/move/iterator.hpp>
+// container
+#include <boost/container/deque.hpp>
+#include <boost/container/list.hpp>
+#include <boost/container/stable_vector.hpp>
+#include "../example/movable.hpp"
+
+template<class Container>
+int move_test()
+{
+   bool use_move_iterator = false;
+   bool done = false;
+   while(!done){
+      //Default construct 10 movable objects
+      Container v(10);
+
+      //Test default constructed value
+      if(v.begin()->moved()){
+         return 1;
+      }
+
+      //Move values
+      Container v2;
+      if(use_move_iterator){
+         ::boost::copy_or_move( boost::make_move_iterator(v.begin())
+                              , boost::make_move_iterator(v.end())
+                              , boost::back_move_inserter(v2));
+      }
+      else{
+         std::copy(v.begin(), v.end(), boost::back_move_inserter(v2));
+      }
+
+      //Test values have been moved
+      if(!v.begin()->moved()){
+         return 1;
+      }
+
+      if(v2.size() != 10){
+         return 1;
+      }
+
+      if(v2.begin()->moved()){
+         return 1;
+      }
+      done = use_move_iterator;
+      use_move_iterator = true;
+   }
+   return 0;
+}
+
+int main()
+{
+   namespace bc = ::boost::container;
+
+   if(move_test< bc::vector<movable> >()){
+      return 1;
+   }
+   if(move_test< bc::list<movable> >()){
+      return 1;
+   }
+   if(move_test< bc::stable_vector<movable> >()){
+      return 1;
+   }
+   return 0;
+}
+
+#include <boost/move/detail/config_end.hpp>
diff --git a/test/bench_merge.cpp b/test/bench_merge.cpp
new file mode 100644
index 0000000..5f69018
--- /dev/null
+++ b/test/bench_merge.cpp
@@ -0,0 +1,274 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2016.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <algorithm> //std::inplace_merge
+#include <cstdio>    //std::printf
+#include <iostream>  //std::cout
+
+#include <boost/config.hpp>
+
+#include <boost/move/unique_ptr.hpp>
+#include <boost/timer/timer.hpp>
+
+#include "order_type.hpp"
+#include "random_shuffle.hpp"
+
+using boost::timer::cpu_timer;
+using boost::timer::cpu_times;
+using boost::timer::nanosecond_type;
+
+//#define BOOST_MOVE_ADAPTIVE_SORT_STATS
+//#define BOOST_MOVE_ADAPTIVE_SORT_STATS_LEVEL 2
+void print_stats(const char *str, boost::ulong_long_type element_count)
+{
+   std::printf("%sCmp:%8.04f Cpy:%9.04f\n", str, double(order_perf_type::num_compare)/element_count, double(order_perf_type::num_copy)/element_count );
+}
+
+#include <boost/move/algo/adaptive_merge.hpp>
+#include <boost/move/algo/detail/merge.hpp>
+#include <boost/move/core.hpp>
+
+template<class T, class Compare>
+std::size_t generate_elements(T elements[], std::size_t element_count, std::size_t key_reps[], std::size_t key_len, Compare comp)
+{
+   std::srand(0);
+   for(std::size_t i = 0; i < (key_len ? key_len : element_count); ++i){
+      key_reps[i]=0;
+   }
+   for(std::size_t  i=0; i < element_count; ++i){
+      std::size_t  key = key_len ? (i % key_len) : i;
+      elements[i].key=key;
+   }
+   ::random_shuffle(elements, elements + element_count);
+   ::random_shuffle(elements, elements + element_count);
+   ::random_shuffle(elements, elements + element_count);
+   for(std::size_t i = 0; i < element_count; ++i){
+      elements[i].val = key_reps[elements[i].key]++;
+   }
+   std::size_t split_count = element_count/2;
+   std::stable_sort(elements, elements+split_count, comp);
+   std::stable_sort(elements+split_count, elements+element_count, comp);
+   return split_count;
+}
+
+
+
+template<class T, class Compare>
+void adaptive_merge_buffered(T *elements, T *mid, T *last, Compare comp, std::size_t BufLen)
+{
+   boost::movelib::unique_ptr<char[]> mem(new char[sizeof(T)*BufLen]);
+   boost::movelib::adaptive_merge(elements, mid, last, comp, reinterpret_cast<T*>(mem.get()), BufLen);
+}
+
+enum AlgoType
+{
+   StdMerge,
+   AdaptiveMerge,
+   SqrtHAdaptiveMerge,
+   SqrtAdaptiveMerge,
+   Sqrt2AdaptiveMerge,
+   QuartAdaptiveMerge,
+   StdInplaceMerge,
+   MaxMerge
+};
+
+const char *AlgoNames [] = { "StdMerge        "
+                           , "AdaptMerge      "
+                           , "SqrtHAdaptMerge "
+                           , "SqrtAdaptMerge  "
+                           , "Sqrt2AdaptMerge "
+                           , "QuartAdaptMerge "
+                           , "StdInplaceMerge "
+                           };
+
+BOOST_STATIC_ASSERT((sizeof(AlgoNames)/sizeof(*AlgoNames)) == MaxMerge);
+
+template<class T>
+bool measure_algo(T *elements, std::size_t key_reps[], std::size_t element_count, std::size_t key_len, unsigned alg, nanosecond_type &prev_clock)
+{
+   std::size_t const split_pos = generate_elements(elements, element_count, key_reps, key_len, order_type_less());
+
+   std::printf("%s ", AlgoNames[alg]);
+   order_perf_type::num_compare=0;
+   order_perf_type::num_copy=0;
+   order_perf_type::num_elements = element_count;
+   cpu_timer timer;
+   timer.resume();
+   switch(alg)
+   {
+      case StdMerge:
+         std::inplace_merge(elements, elements+split_pos, elements+element_count, order_type_less());
+      break;
+      case AdaptiveMerge:
+         boost::movelib::adaptive_merge(elements, elements+split_pos, elements+element_count, order_type_less());
+      break;
+      case SqrtHAdaptiveMerge:
+         adaptive_merge_buffered( elements, elements+split_pos, elements+element_count, order_type_less()
+                            , boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count)/2+1);
+      break;
+      case SqrtAdaptiveMerge:
+         adaptive_merge_buffered( elements, elements+split_pos, elements+element_count, order_type_less()
+                            , boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count));
+      break;
+      case Sqrt2AdaptiveMerge:
+         adaptive_merge_buffered( elements, elements+split_pos, elements+element_count, order_type_less()
+                            , 2*boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count));
+      break;
+      case QuartAdaptiveMerge:
+         adaptive_merge_buffered( elements, elements+split_pos, elements+element_count, order_type_less()
+                            , (element_count-1)/4+1);
+      break;
+      case StdInplaceMerge:
+         boost::movelib::merge_bufferless_ONlogN(elements, elements+split_pos, elements+element_count, order_type_less());
+      break;
+   }
+   timer.stop();
+
+   if(order_perf_type::num_elements == element_count){
+      std::printf(" Tmp Ok ");
+   } else{
+      std::printf(" Tmp KO ");
+   }
+   nanosecond_type new_clock = timer.elapsed().wall;
+
+   //std::cout << "Cmp:" << order_perf_type::num_compare << " Cpy:" << order_perf_type::num_copy;   //for old compilers without ll size argument
+   std::printf("Cmp:%8.04f Cpy:%9.04f", double(order_perf_type::num_compare)/element_count, double(order_perf_type::num_copy)/element_count );
+
+   double time = double(new_clock);
+
+   const char *units = "ns";
+   if(time >= 1000000000.0){
+      time /= 1000000000.0;
+      units = " s";
+   }
+   else if(time >= 1000000.0){
+      time /= 1000000.0;
+      units = "ms";
+   }
+   else if(time >= 1000.0){
+      time /= 1000.0;
+      units = "us";
+   }
+
+   std::printf(" %6.02f%s (%6.02f)\n"
+              , time
+              , units
+              , prev_clock ? double(new_clock)/double(prev_clock): 1.0);
+   prev_clock = new_clock;
+   bool res = is_order_type_ordered(elements, element_count, true);
+   return res;
+}
+
+template<class T>
+bool measure_all(std::size_t L, std::size_t NK)
+{
+   boost::movelib::unique_ptr<T[]> pdata(new T[L]);
+   boost::movelib::unique_ptr<std::size_t[]> pkeys(new std::size_t[NK ? NK : L]);
+   T *A              = pdata.get();
+   std::size_t *Keys = pkeys.get();
+   std::printf("\n - - N: %u, NK: %u - -\n", (unsigned)L, (unsigned)NK);
+
+   nanosecond_type prev_clock = 0;
+   nanosecond_type back_clock;
+   bool res = true;
+   res = res && measure_algo(A,Keys,L,NK,StdMerge, prev_clock);
+   back_clock = prev_clock;
+   //
+   prev_clock = back_clock;
+   res = res && measure_algo(A,Keys,L,NK,QuartAdaptiveMerge, prev_clock);
+   //
+   prev_clock = back_clock;
+   res = res && measure_algo(A,Keys,L,NK,Sqrt2AdaptiveMerge, prev_clock);
+   //
+   prev_clock = back_clock;
+   res = res && measure_algo(A,Keys,L,NK,SqrtAdaptiveMerge, prev_clock);
+   //
+   prev_clock = back_clock;
+   res = res && measure_algo(A,Keys,L,NK,SqrtHAdaptiveMerge, prev_clock);
+   //
+   prev_clock = back_clock;
+   res = res && measure_algo(A,Keys,L,NK,AdaptiveMerge, prev_clock);
+   //
+   prev_clock = back_clock;
+   res = res && measure_algo(A,Keys,L,NK,StdInplaceMerge, prev_clock);
+   //
+   if(!res)
+      throw int(0);
+   return res;
+}
+
+//Undef it to run the long test
+#define BENCH_MERGE_SHORT
+#define BENCH_SORT_UNIQUE_VALUES
+
+int main()
+{
+   try{
+   #ifndef BENCH_SORT_UNIQUE_VALUES
+   measure_all<order_perf_type>(101,1);
+   measure_all<order_perf_type>(101,7);
+   measure_all<order_perf_type>(101,31);
+   #endif
+   measure_all<order_perf_type>(101,0);
+
+   //
+   #ifndef BENCH_SORT_UNIQUE_VALUES
+   measure_all<order_perf_type>(1101,1);
+   measure_all<order_perf_type>(1001,7);
+   measure_all<order_perf_type>(1001,31);
+   measure_all<order_perf_type>(1001,127);
+   measure_all<order_perf_type>(1001,511);
+   #endif
+   measure_all<order_perf_type>(1001,0);
+   //
+   #ifndef BENCH_MERGE_SHORT
+   #ifndef BENCH_SORT_UNIQUE_VALUES
+   measure_all<order_perf_type>(10001,65);
+   measure_all<order_perf_type>(10001,255);
+   measure_all<order_perf_type>(10001,1023);
+   measure_all<order_perf_type>(10001,4095);
+   #endif
+   measure_all<order_perf_type>(10001,0);
+
+   //
+   #ifndef BENCH_SORT_UNIQUE_VALUES
+   measure_all<order_perf_type>(100001,511);
+   measure_all<order_perf_type>(100001,2047);
+   measure_all<order_perf_type>(100001,8191);
+   measure_all<order_perf_type>(100001,32767);
+   #endif
+   measure_all<order_perf_type>(100001,0);
+
+   //
+   #ifdef NDEBUG
+   #ifndef BENCH_SORT_UNIQUE_VALUES
+   measure_all<order_perf_type>(1000001,1);
+   measure_all<order_perf_type>(1000001,1024);
+   measure_all<order_perf_type>(1000001,32768);
+   measure_all<order_perf_type>(1000001,524287);
+   #endif
+   measure_all<order_perf_type>(1000001,0);
+   measure_all<order_perf_type>(3000001,0);
+   measure_all<order_perf_type>(5000001,0);
+   #endif   //NDEBUG
+
+   #endif   //#ifndef BENCH_MERGE_SHORT
+
+   //measure_all<order_perf_type>(100000001,0);
+   }
+   catch(...)
+   {
+      return 1;
+   }
+
+   return 0;
+}
+
diff --git a/test/bench_sort.cpp b/test/bench_sort.cpp
new file mode 100644
index 0000000..6544976
--- /dev/null
+++ b/test/bench_sort.cpp
@@ -0,0 +1,313 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2016.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#include <cstdlib>   //std::srand
+#include <algorithm> //std::stable_sort, std::make|sort_heap, std::random_shuffle
+#include <cstdio>    //std::printf
+#include <iostream>  //std::cout
+
+#include <boost/config.hpp>
+
+#include <boost/move/unique_ptr.hpp>
+#include <boost/timer/timer.hpp>
+
+using boost::timer::cpu_timer;
+using boost::timer::cpu_times;
+using boost::timer::nanosecond_type;
+
+#include "order_type.hpp"
+#include "random_shuffle.hpp"
+
+//#define BOOST_MOVE_ADAPTIVE_SORT_STATS
+//#define BOOST_MOVE_ADAPTIVE_SORT_INVARIANTS
+void print_stats(const char *str, boost::ulong_long_type element_count)
+{
+   std::printf("%sCmp:%7.03f Cpy:%8.03f\n", str, double(order_perf_type::num_compare)/element_count, double(order_perf_type::num_copy)/element_count );
+}
+
+
+#include <boost/move/algo/adaptive_sort.hpp>
+#include <boost/move/algo/detail/merge_sort.hpp>
+#include <boost/move/algo/detail/pdqsort.hpp>
+#include <boost/move/algo/detail/heap_sort.hpp>
+#include <boost/move/core.hpp>
+
+template<class T>
+void generate_elements(T elements[], std::size_t element_count, std::size_t key_reps[], std::size_t key_len)
+{
+   std::srand(0);
+   for(std::size_t i = 0; i < (key_len ? key_len : element_count); ++i){
+      key_reps[i]=0;
+   }
+   for(std::size_t  i=0; i < element_count; ++i){
+      std::size_t  key = key_len ? (i % key_len) : i;
+      elements[i].key=key;
+   }
+   ::random_shuffle(elements, elements + element_count);
+   ::random_shuffle(elements, elements + element_count);
+   ::random_shuffle(elements, elements + element_count);
+   for(std::size_t i = 0; i < element_count; ++i){
+      elements[i].val = key_reps[elements[i].key]++;
+   }
+}
+
+template<class T, class Compare>
+void adaptive_sort_buffered(T *elements, std::size_t element_count, Compare comp, std::size_t BufLen)
+{
+   boost::movelib::unique_ptr<char[]> mem(new char[sizeof(T)*BufLen]);
+   boost::movelib::adaptive_sort(elements, elements + element_count, comp, reinterpret_cast<T*>(mem.get()), BufLen);
+}
+
+template<class T, class Compare>
+void merge_sort_buffered(T *elements, std::size_t element_count, Compare comp)
+{
+   boost::movelib::unique_ptr<char[]> mem(new char[sizeof(T)*((element_count+1)/2)]);
+   boost::movelib::merge_sort(elements, elements + element_count, comp, reinterpret_cast<T*>(mem.get()));
+}
+
+enum AlgoType
+{
+   MergeSort,
+   StableSort,
+   PdQsort,
+   StdSort,
+   AdaptiveSort,
+   SqrtHAdaptiveSort,
+   SqrtAdaptiveSort,
+   Sqrt2AdaptiveSort,
+   QuartAdaptiveSort,
+   InplaceStableSort,
+   SlowStableSort,
+   HeapSort,
+   MaxSort
+};
+
+const char *AlgoNames [] = { "MergeSort      "
+                           , "StableSort     "
+                           , "PdQsort        "
+                           , "StdSort        "
+                           , "AdaptSort      "
+                           , "SqrtHAdaptSort "
+                           , "SqrtAdaptSort  "
+                           , "Sqrt2AdaptSort "
+                           , "QuartAdaptSort "
+                           , "InplStableSort "
+                           , "SlowSort       "
+                           , "HeapSort       "
+                           };
+
+BOOST_STATIC_ASSERT((sizeof(AlgoNames)/sizeof(*AlgoNames)) == MaxSort);
+
+template<class T>
+bool measure_algo(T *elements, std::size_t key_reps[], std::size_t element_count, std::size_t key_len, unsigned alg, nanosecond_type &prev_clock)
+{
+   generate_elements(elements, element_count, key_reps, key_len);
+
+   std::printf("%s ", AlgoNames[alg]);
+   order_perf_type::num_compare=0;
+   order_perf_type::num_copy=0;
+   order_perf_type::num_elements = element_count;
+   cpu_timer timer;
+   timer.resume();
+   switch(alg)
+   {
+      case MergeSort:
+         merge_sort_buffered(elements, element_count, order_type_less());
+      break;
+      case StableSort:
+         std::stable_sort(elements,elements+element_count,order_type_less());
+      break;
+      case PdQsort:
+         boost::movelib::pdqsort(elements,elements+element_count,order_type_less());
+      break;
+      case StdSort:
+         std::sort(elements,elements+element_count,order_type_less());
+      break;
+      case AdaptiveSort:
+         boost::movelib::adaptive_sort(elements, elements+element_count, order_type_less());
+      break;
+      case SqrtHAdaptiveSort:
+         adaptive_sort_buffered( elements, element_count, order_type_less()
+                            , boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count)/2+1);
+      break;
+      case SqrtAdaptiveSort:
+         adaptive_sort_buffered( elements, element_count, order_type_less()
+                            , boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count));
+      break;
+      case Sqrt2AdaptiveSort:
+         adaptive_sort_buffered( elements, element_count, order_type_less()
+                            , 2*boost::movelib::detail_adaptive::ceil_sqrt_multiple(element_count));
+      break;
+      case QuartAdaptiveSort:
+         adaptive_sort_buffered( elements, element_count, order_type_less()
+                            , (element_count-1)/4+1);
+      break;
+      case InplaceStableSort:
+         boost::movelib::inplace_stable_sort(elements, elements+element_count, order_type_less());
+      break;
+      case SlowStableSort:
+         boost::movelib::detail_adaptive::slow_stable_sort(elements, elements+element_count, order_type_less());
+      break;
+      case HeapSort:
+         boost::movelib::heap_sort(elements, elements+element_count, order_type_less());
+         boost::movelib::heap_sort((order_move_type*)0, (order_move_type*)0, order_type_less());
+
+      break;
+   }
+   timer.stop();
+
+   if(order_perf_type::num_elements == element_count){
+      std::printf(" Tmp Ok ");
+   } else{
+      std::printf(" Tmp KO ");
+   }
+   nanosecond_type new_clock = timer.elapsed().wall;
+
+   //std::cout << "Cmp:" << order_perf_type::num_compare << " Cpy:" << order_perf_type::num_copy;   //for old compilers without ll size argument
+   std::printf("Cmp:%7.03f Cpy:%8.03f", double(order_perf_type::num_compare)/element_count, double(order_perf_type::num_copy)/element_count );
+
+   double time = double(new_clock);
+
+   const char *units = "ns";
+   if(time >= 1000000000.0){
+      time /= 1000000000.0;
+      units = " s";
+   }
+   else if(time >= 1000000.0){
+      time /= 1000000.0;
+      units = "ms";
+   }
+   else if(time >= 1000.0){
+      time /= 1000.0;
+      units = "us";
+   }
+
+   std::printf(" %6.02f%s (%6.02f)\n"
+              , time
+              , units
+              , prev_clock ? double(new_clock)/double(prev_clock): 1.0);
+   prev_clock = new_clock;
+   bool res = is_order_type_ordered(elements, element_count, alg != HeapSort && alg != PdQsort && alg != StdSort);
+   return res;
+}
+
+template<class T>
+bool measure_all(std::size_t L, std::size_t NK)
+{
+   boost::movelib::unique_ptr<T[]> pdata(new T[L]);
+   boost::movelib::unique_ptr<std::size_t[]> pkeys(new std::size_t[NK ? NK : L]);
+   T *A              = pdata.get();
+   std::size_t *Keys = pkeys.get();
+   std::printf("\n - - N: %u, NK: %u - -\n", (unsigned)L, (unsigned)NK);
+
+   nanosecond_type prev_clock = 0;
+   nanosecond_type back_clock;
+   bool res = true;
+   res = res && measure_algo(A,Keys,L,NK,MergeSort, prev_clock);
+   back_clock = prev_clock;
+   //
+   prev_clock = back_clock;
+   res = res && measure_algo(A,Keys,L,NK,StableSort, prev_clock);
+   //
+   prev_clock = back_clock;
+   res = res && measure_algo(A,Keys,L,NK,PdQsort, prev_clock);
+   //
+   prev_clock = back_clock;
+   res = res && measure_algo(A,Keys,L,NK,StdSort, prev_clock);
+   //
+   prev_clock = back_clock;
+   res = res && measure_algo(A,Keys,L,NK,HeapSort, prev_clock);
+   //
+   prev_clock = back_clock;
+   res = res && measure_algo(A,Keys,L,NK,QuartAdaptiveSort, prev_clock);
+   //
+   prev_clock = back_clock;
+   res = res && measure_algo(A,Keys,L,NK,Sqrt2AdaptiveSort, prev_clock);
+   //
+   prev_clock = back_clock;
+   res = res && measure_algo(A,Keys,L,NK,SqrtAdaptiveSort, prev_clock);
+   //
+   prev_clock = back_clock;
+   res = res && measure_algo(A,Keys,L,NK,SqrtHAdaptiveSort, prev_clock);
+   //
+   prev_clock = back_clock;
+   res = res && measure_algo(A,Keys,L,NK,AdaptiveSort, prev_clock);
+   //
+   prev_clock = back_clock;
+   res = res && measure_algo(A,Keys,L,NK,InplaceStableSort, prev_clock);
+   //
+   //prev_clock = back_clock;
+   //res = res && measure_algo(A,Keys,L,NK,SlowStableSort, prev_clock);
+   //
+   if(!res)
+      throw int(0);
+   return res;
+}
+
+//Undef it to run the long test
+#define BENCH_SORT_SHORT
+#define BENCH_SORT_UNIQUE_VALUES
+
+int main()
+{
+   #ifndef BENCH_SORT_UNIQUE_VALUES
+   measure_all<order_perf_type>(101,1);
+   measure_all<order_perf_type>(101,7);
+   measure_all<order_perf_type>(101,31);
+   #endif
+   measure_all<order_perf_type>(101,0);
+
+   //
+   #ifndef BENCH_SORT_UNIQUE_VALUES
+   measure_all<order_perf_type>(1101,1);
+   measure_all<order_perf_type>(1001,7);
+   measure_all<order_perf_type>(1001,31);
+   measure_all<order_perf_type>(1001,127);
+   measure_all<order_perf_type>(1001,511);
+   #endif
+   measure_all<order_perf_type>(1001,0);
+   //
+   #ifndef BENCH_SORT_SHORT
+   #ifndef BENCH_SORT_UNIQUE_VALUES
+   measure_all<order_perf_type>(10001,65);
+   measure_all<order_perf_type>(10001,255);
+   measure_all<order_perf_type>(10001,1023);
+   measure_all<order_perf_type>(10001,4095);
+   #endif
+   measure_all<order_perf_type>(10001,0);
+
+   //
+   #ifndef BENCH_SORT_UNIQUE_VALUES
+   measure_all<order_perf_type>(100001,511);
+   measure_all<order_perf_type>(100001,2047);
+   measure_all<order_perf_type>(100001,8191);
+   measure_all<order_perf_type>(100001,32767);
+   #endif
+   measure_all<order_perf_type>(100001,0);
+
+   //
+   #ifdef NDEBUG
+   #ifndef BENCH_SORT_UNIQUE_VALUES
+   measure_all<order_perf_type>(1000001,1);
+   measure_all<order_perf_type>(1000001,1024);
+   measure_all<order_perf_type>(1000001,32768);
+   measure_all<order_perf_type>(1000001,524287);
+   #endif
+   measure_all<order_perf_type>(1000001,0);
+   measure_all<order_perf_type>(1500001,0);
+   #endif   //NDEBUG
+
+   #endif   //#ifndef BENCH_SORT_SHORT
+
+   //measure_all<order_perf_type>(100000001,0);
+
+   return 0;
+}
diff --git a/test/construct_forward.cpp b/test/construct_forward.cpp
new file mode 100644
index 0000000..87c9a80
--- /dev/null
+++ b/test/construct_forward.cpp
@@ -0,0 +1,117 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2009-2012.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/utility_core.hpp>
+#include <boost/utility/enable_if.hpp>
+#include "../example/movable.hpp"
+#include "../example/copymovable.hpp"
+#include <cstdio>
+
+class non_movable
+{
+   public:
+   non_movable()
+   {}
+};
+
+template<class MaybeRvalue>
+void catch_test(BOOST_RV_REF(MaybeRvalue) x
+               #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+               ,typename ::boost::enable_if< ::boost::has_move_emulation_enabled<MaybeRvalue> >::type* = 0
+               #endif   //BOOST_NO_CXX11_RVALUE_REFERENCES
+               )
+{  (void)x;}
+
+template<class MaybeRvalue>
+void catch_test(BOOST_COPY_ASSIGN_REF(MaybeRvalue) x
+               #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+               ,typename ::boost::enable_if< ::boost::has_move_emulation_enabled<MaybeRvalue> >::type* = 0
+               #endif   //BOOST_NO_CXX11_RVALUE_REFERENCES
+               )
+
+{  (void)x;}
+
+template<class MaybeRvalue>
+void catch_test(MaybeRvalue &x
+               #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+               ,typename ::boost::enable_if< ::boost::has_move_emulation_enabled<MaybeRvalue> >::type* = 0
+               #endif   //BOOST_NO_CXX11_RVALUE_REFERENCES
+               )
+{  (void)x;}
+
+               #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+template<class MaybeRvalue>
+void catch_test(const MaybeRvalue& x
+               ,typename ::boost::disable_if< ::boost::has_move_emulation_enabled<MaybeRvalue> >::type* = 0
+               )
+{  (void)x;}
+               #endif   //BOOST_NO_CXX11_RVALUE_REFERENCES
+
+movable create_movable()
+{  return movable(); }
+
+copy_movable create_copy_movable()
+{  return copy_movable(); }
+
+non_movable create_non_movable()
+{  return non_movable(); }
+
+
+void catch_test()
+{
+   movable m;
+   const movable constm;
+   catch_test<movable>(boost::move(m));
+   #ifdef BOOST_CATCH_CONST_RLVALUE
+   catch_test<movable>(create_movable());
+   #endif
+   catch_test<movable>(m);
+   catch_test<movable>(constm);
+   copy_movable cm;
+   const copy_movable constcm;
+   catch_test<copy_movable>(boost::move(cm));
+   catch_test<copy_movable>(create_copy_movable());
+   catch_test<copy_movable>(cm);
+   catch_test<copy_movable>(constcm);
+   non_movable nm;
+   const non_movable constnm;
+   catch_test<non_movable>(boost::move(nm));
+   catch_test<non_movable>(create_non_movable());
+   catch_test<non_movable>(nm);
+   catch_test<non_movable>(constnm);
+}
+
+template<class MaybeMovableOnly, class MaybeRvalue>
+void function_construct(BOOST_FWD_REF(MaybeRvalue) x)
+{
+   //Moves in case Convertible is boost::rv<movable> copies otherwise
+   //For C++0x perfect forwarding
+   MaybeMovableOnly m(boost::forward<MaybeRvalue>(x));
+}
+
+void forward_test()
+{
+   movable m;
+   function_construct<movable>(boost::move(m));
+//   non_movable nm;
+//   function_construct<non_movable>(boost::move(nm));
+//   const non_movable cnm;
+//   function_construct<non_movable>(cnm);
+}
+
+int main()
+{
+   catch_test();
+   forward_test();
+   return 0;
+}
+
+#include <boost/move/detail/config_end.hpp>
diff --git a/test/conversion_test.cpp b/test/conversion_test.cpp
new file mode 100644
index 0000000..8e901f8
--- /dev/null
+++ b/test/conversion_test.cpp
@@ -0,0 +1,414 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2010-2012.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/move/utility_core.hpp>
+#include <boost/move/detail/meta_utils.hpp>
+#include <cassert>
+#include <new>
+#include <boost/move/detail/move_helpers.hpp>
+
+
+enum ConstructionType { Copied, Moved, Other };
+
+class conversion_source
+{
+   public:
+   conversion_source(){}
+   operator int() const { return 0; }
+};
+
+class conversion_target
+{
+   ConstructionType c_type_;
+   public:
+   conversion_target(conversion_source)
+      { c_type_ = Other; }
+   conversion_target()
+      { c_type_ = Other; }
+   conversion_target(const conversion_target &)
+      { c_type_ = Copied; }
+   ConstructionType construction_type() const
+      { return c_type_; }
+};
+
+
+class conversion_target_copymovable
+{
+   ConstructionType c_type_;
+   BOOST_COPYABLE_AND_MOVABLE(conversion_target_copymovable)
+   public:
+   conversion_target_copymovable()
+      { c_type_ = Other; }
+   conversion_target_copymovable(conversion_source)
+      { c_type_ = Other; }
+   conversion_target_copymovable(const conversion_target_copymovable &)
+      { c_type_ = Copied; }
+   conversion_target_copymovable(BOOST_RV_REF(conversion_target_copymovable) )
+      { c_type_ = Moved; }
+   conversion_target_copymovable &operator=(BOOST_RV_REF(conversion_target_copymovable) )
+      { c_type_ = Moved; return *this; }
+   conversion_target_copymovable &operator=(BOOST_COPY_ASSIGN_REF(conversion_target_copymovable) )
+      { c_type_ = Copied; return *this; }
+   ConstructionType construction_type() const
+      {  return c_type_; }
+};
+
+class conversion_target_movable
+{
+   ConstructionType c_type_;
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(conversion_target_movable)
+   public:
+   conversion_target_movable()
+      { c_type_ = Other; }
+   conversion_target_movable(conversion_source)
+      { c_type_ = Other; }
+   conversion_target_movable(BOOST_RV_REF(conversion_target_movable) )
+      { c_type_ = Moved; }
+   conversion_target_movable &operator=(BOOST_RV_REF(conversion_target_movable) )
+      { c_type_ = Moved; return *this; }
+   ConstructionType construction_type() const
+      {  return c_type_; }
+};
+
+
+template<class T>
+class container
+{
+   T *storage_;
+   public:
+   struct const_iterator{};
+   struct iterator : const_iterator{};
+   container()
+      : storage_(0)
+   {}
+
+   ~container()
+   {  delete storage_; }
+
+   container(const container &c)
+      : storage_(c.storage_ ? new T(*c.storage_) : 0)
+   {}
+
+   container &operator=(const container &c)
+   {
+      if(storage_){
+         delete storage_;
+         storage_ = 0;
+      }
+      storage_ = c.storage_ ? new T(*c.storage_) : 0;
+      return *this;
+   }
+
+   BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back)
+
+   BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator)
+
+   template <class Iterator>
+   iterator insert(Iterator, Iterator){ return iterator(); }
+
+   ConstructionType construction_type() const
+   {  return construction_type_impl
+         (typename ::boost::move_detail::integral_constant<bool, ::boost::move_detail::is_class_or_union<T>::value>());
+   }
+
+   ConstructionType construction_type_impl(::boost::move_detail::true_type) const
+     {  return storage_->construction_type(); }
+
+   ConstructionType construction_type_impl(::boost::move_detail::false_type) const
+     {  return Copied; }
+
+   iterator begin() const { return iterator(); }
+   
+   private:
+   template<class U>
+    void priv_construct(BOOST_MOVE_CATCH_FWD(U) x)
+   {
+      if(storage_){
+         delete storage_;
+         storage_ = 0;
+      }
+      storage_ = new T(::boost::forward<U>(x));
+   }
+
+   template<class U>
+   void priv_push_back(BOOST_MOVE_CATCH_FWD(U) x)
+   {  priv_construct(::boost::forward<U>(x));   }
+
+   template<class U>
+   iterator priv_insert(const_iterator, BOOST_MOVE_CATCH_FWD(U) x)
+   {  priv_construct(::boost::forward<U>(x));   return iterator();   }
+};
+
+class recursive_container
+{
+   BOOST_COPYABLE_AND_MOVABLE(recursive_container)
+   public:
+   recursive_container()
+   {}
+
+   recursive_container(const recursive_container &c)
+      : container_(c.container_)
+   {}
+
+   recursive_container(BOOST_RV_REF(recursive_container) c)
+      : container_(::boost::move(c.container_))
+   {}
+
+   recursive_container & operator =(BOOST_COPY_ASSIGN_REF(recursive_container) c)
+   {
+      container_= c.container_;
+      return *this;
+   }
+
+   recursive_container & operator =(BOOST_RV_REF(recursive_container) c)
+   {
+      container_= ::boost::move(c.container_);
+      return *this;
+   }
+
+   container<recursive_container> container_;
+   friend bool operator< (const recursive_container &a, const recursive_container &b)
+   {  return &a < &b;   }
+};
+
+
+int main()
+{
+   conversion_target_movable a;
+   conversion_target_movable b(::boost::move(a));
+   {
+      container<conversion_target> c;
+      {
+         conversion_target x;
+         c.push_back(x);
+         assert(c.construction_type() == Copied);
+         c.insert(c.begin(), x);
+         assert(c.construction_type() == Copied);
+      }
+      {
+         const conversion_target x;
+         c.push_back(x);
+         assert(c.construction_type() == Copied);
+         c.insert(c.begin(), x);
+         assert(c.construction_type() == Copied);
+      }
+      {
+         c.push_back(conversion_target());
+         assert(c.construction_type() == Copied);
+         c.insert(c.begin(), conversion_target());
+         assert(c.construction_type() == Copied);
+      }
+      {
+         conversion_source x;
+         c.push_back(x);
+         assert(c.construction_type() == Copied);
+         c.insert(c.begin(), x);
+         assert(c.construction_type() == Copied);
+      }
+      {
+         const conversion_source x;
+         c.push_back(x);
+         assert(c.construction_type() == Copied);
+         c.insert(c.begin(), x);
+         assert(c.construction_type() == Copied);
+      }
+      {
+         c.push_back(conversion_source());
+         assert(c.construction_type() == Copied);
+         c.insert(c.begin(), conversion_source());
+         assert(c.construction_type() == Copied);
+      }
+   }
+
+   {
+      container<conversion_target_copymovable> c;
+      {
+         conversion_target_copymovable x;
+         c.push_back(x);
+         assert(c.construction_type() == Copied);
+         c.insert(c.begin(), x);
+         assert(c.construction_type() == Copied);
+      }
+      {
+         const conversion_target_copymovable x;
+         c.push_back(x);
+         assert(c.construction_type() == Copied);
+         c.insert(c.begin(), x);
+         assert(c.construction_type() == Copied);
+      }
+      {
+         c.push_back(conversion_target_copymovable());
+         assert(c.construction_type() == Moved);
+         c.insert(c.begin(), conversion_target_copymovable());
+         assert(c.construction_type() == Moved);
+      }
+      {
+         conversion_source x;
+         c.push_back(x);
+         assert(c.construction_type() == Moved);
+         c.insert(c.begin(), x);
+         assert(c.construction_type() == Moved);
+      }
+      {
+         const conversion_source x;
+         c.push_back(x);
+         assert(c.construction_type() == Moved);
+         c.insert(c.begin(), x);
+         assert(c.construction_type() == Moved);
+      }
+      {
+         c.push_back(conversion_source());
+         assert(c.construction_type() == Moved);
+         c.insert(c.begin(), conversion_source());
+         assert(c.construction_type() == Moved);
+      }
+   }
+   {
+      container<conversion_target_movable> c;
+      //This should not compile
+      //{
+      //   conversion_target_movable x;
+      //   c.push_back(x);
+      //   assert(c.construction_type() == Copied);
+      //}
+      //{
+      //   const conversion_target_movable x;
+      //   c.push_back(x);
+      //   assert(c.construction_type() == Copied);
+      //}
+      {
+         c.push_back(conversion_target_movable());
+         assert(c.construction_type() == Moved);
+         c.insert(c.begin(), conversion_target_movable());
+         assert(c.construction_type() == Moved);
+      }
+      {
+         conversion_source x;
+         c.push_back(x);
+         assert(c.construction_type() == Moved);
+         c.insert(c.begin(), x);
+         assert(c.construction_type() == Moved);
+      }
+      {
+         const conversion_source x;
+         c.push_back(x);
+         assert(c.construction_type() == Moved);
+         c.insert(c.begin(), x);
+         assert(c.construction_type() == Moved);
+      }
+      {
+         c.push_back(conversion_source());
+         assert(c.construction_type() == Moved);
+         c.insert(c.begin(), conversion_source());
+         assert(c.construction_type() == Moved);
+      }
+   }
+   {
+      container<int> c;
+      {
+         int x = 0;
+         c.push_back(x);
+         assert(c.construction_type() == Copied);
+         c.insert(c.begin(), c.construction_type());
+         assert(c.construction_type() == Copied);
+      }
+      {
+         const int x = 0;
+         c.push_back(x);
+         assert(c.construction_type() == Copied);
+         c.insert(c.begin(), x);
+         assert(c.construction_type() == Copied);
+      }
+      {
+         c.push_back(int(0));
+         assert(c.construction_type() == Copied);
+         c.insert(c.begin(), int(0));
+         assert(c.construction_type() == Copied);
+      }
+      {
+         conversion_source x;
+         c.push_back(x);
+         assert(c.construction_type() == Copied);
+         c.insert(c.begin(), x);
+         assert(c.construction_type() == Copied);
+      }
+
+      {
+         const conversion_source x;
+         c.push_back(x);
+         assert(c.construction_type() == Copied);
+         c.insert(c.begin(), x);
+         assert(c.construction_type() == Copied);
+      }
+      {
+         c.push_back(conversion_source());
+         assert(c.construction_type() == Copied);
+         c.insert(c.begin(), conversion_source());
+         assert(c.construction_type() == Copied);
+      }
+      //c.insert(c.begin(), c.begin());
+   }
+
+   {
+      container<int> c;
+      {
+         int x = 0;
+         c.push_back(x);
+         assert(c.construction_type() == Copied);
+         c.insert(c.begin(), c.construction_type());
+         assert(c.construction_type() == Copied);
+      }
+      {
+         const int x = 0;
+         c.push_back(x);
+         assert(c.construction_type() == Copied);
+         c.insert(c.begin(), x);
+         assert(c.construction_type() == Copied);
+      }
+      {
+         c.push_back(int(0));
+         assert(c.construction_type() == Copied);
+         c.insert(c.begin(), int(0));
+         assert(c.construction_type() == Copied);
+      }
+      {
+         conversion_source x;
+         c.push_back(x);
+         assert(c.construction_type() == Copied);
+         c.insert(c.begin(), x);
+         assert(c.construction_type() == Copied);
+      }
+
+      {
+         const conversion_source x;
+         c.push_back(x);
+         assert(c.construction_type() == Copied);
+         c.insert(c.begin(), x);
+         assert(c.construction_type() == Copied);
+      }
+      {
+         c.push_back(conversion_source());
+         assert(c.construction_type() == Copied);
+         c.insert(c.begin(), conversion_source());
+         assert(c.construction_type() == Copied);
+      }
+      c.insert(c.begin(), c.begin());
+   }
+
+   {
+      recursive_container c;
+      recursive_container internal;
+      c.container_.insert(c.container_.begin(), recursive_container());
+      c.container_.insert(c.container_.begin(), internal);
+      c.container_.insert(c.container_.begin(), c.container_.begin());
+   }
+
+   return 0;
+}
diff --git a/test/copy_elision_test.cpp b/test/copy_elision_test.cpp
new file mode 100644
index 0000000..39123e1
--- /dev/null
+++ b/test/copy_elision_test.cpp
@@ -0,0 +1,177 @@
+// Copyright David Abrahams 2009. 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 <boost/move/detail/config_begin.hpp>
+#include <iostream>
+#include <boost/core/lightweight_test.hpp>
+
+#ifdef NO_MOVE
+# undef BOOST_COPY_ASSIGN_REF
+# define BOOST_COPY_ASSIGN_REF(X) X const&
+# undef BOOST_COPYABLE_AND_MOVABLE
+# define BOOST_COPYABLE_AND_MOVABLE(X)
+# define MOVE(x) (x)
+#else
+#include <boost/move/utility_core.hpp>
+# define MOVE(x) boost::move(x)
+#endif
+
+struct X
+{
+    X() : id(instances++)
+    {
+        std::cout << "X" << id << ": construct\n";
+    }
+    
+    X(X const& rhs) : id(instances++)
+    {
+        std::cout << "X" << id << ": <- " << "X" << rhs.id << ": **copy**\n";
+        ++copies;
+    }
+
+    // This particular test doesn't exercise assignment, but for
+    // completeness:
+    X& operator=(BOOST_COPY_ASSIGN_REF(X) rhs)
+    {
+        std::cout << "X" << id << ": <- " << "X" << rhs.id << ": assign\n";
+        return *this;
+    }
+
+#ifndef NO_MOVE
+    X& operator=(BOOST_RV_REF(X) rhs)
+    {
+        std::cout << "X" << id << ": <- " << "X" << rhs.id << ": move assign\n";
+        return *this;
+    }
+    
+    X(BOOST_RV_REF(X) rhs) : id(instances++)
+    {
+        std::cout << "X" << id << ": <- " << "X" << rhs.id << ": ..move construct..\n";
+        ++copies;
+    }
+#endif 
+
+    ~X() { std::cout << "X" << id << ": destroy\n"; }
+
+    unsigned id;
+    
+    static unsigned copies;
+    static unsigned instances;
+
+    BOOST_COPYABLE_AND_MOVABLE(X)
+};
+
+unsigned X::copies = 0;
+unsigned X::instances = 0;
+
+#define CHECK_COPIES( stmt, min, max, comment )                         \
+{                                                                       \
+    unsigned const old_copies = X::copies;                              \
+                                                                        \
+    std::cout << "\n" comment "\n" #stmt "\n===========\n";             \
+    {                                                                   \
+        stmt;                                                           \
+    }                                                                   \
+    unsigned const n = X::copies - old_copies;                          \
+    volatile unsigned const minv(min), maxv(max);                       \
+    BOOST_TEST(n <= maxv);                                              \
+    if (n > maxv)                                                       \
+        std::cout << "*** max is too low or compiler is buggy ***\n";   \
+    BOOST_TEST(n >= minv);                                              \
+    if (n < minv)                                                       \
+        std::cout << "*** min is too high or compiler is buggy ***\n";  \
+                                                                        \
+    std::cout << "-----------\n"                                        \
+              << n << "/" << max                                        \
+              << " possible copies/moves made\n"                        \
+              << max - n << "/" << max - min                            \
+              << " possible elisions performed\n\n";                    \
+                                                                        \
+    if (n > minv)                                                       \
+        std::cout << "*** " << n - min                                  \
+                  << " possible elisions missed! ***\n";                \
+}
+
+struct trace
+{
+    trace(char const* name)
+        : m_name(name)
+    {
+        std::cout << "->: " << m_name << "\n";
+    }
+    
+    ~trace()
+    {
+        std::cout << "<-: " << m_name << "\n";
+    }
+    
+    char const* m_name;
+};
+
+void sink(X)
+{
+  trace t("sink");
+}
+
+X nrvo_source()
+{
+    trace t("nrvo_source");
+    X a;
+    return a;
+}
+
+X urvo_source()
+{
+    trace t("urvo_source");
+    return X();
+}
+
+X identity(X a)
+{
+    trace t("identity");
+    return a;
+}
+
+X lvalue_;
+X& lvalue()
+{
+    return lvalue_;
+}
+typedef X rvalue;
+
+X ternary( bool y )
+{
+    X a, b;
+    return MOVE(y?a:b);
+}
+
+int main(int argc, char* argv[])
+{
+   (void)argv;
+    // Double parens prevent "most vexing parse"
+    CHECK_COPIES( X a(( lvalue() )), 1U, 1U, "Direct initialization from lvalue");
+    CHECK_COPIES( X a(( rvalue() )), 0U, 1U, "Direct initialization from rvalue");
+    
+    CHECK_COPIES( X a = lvalue(), 1U, 1U, "Copy initialization from lvalue" );
+    CHECK_COPIES( X a = rvalue(), 0U, 1U, "Copy initialization from rvalue" );
+
+    CHECK_COPIES( sink( lvalue() ), 1U, 1U, "Pass lvalue by value" );
+    CHECK_COPIES( sink( rvalue() ), 0U, 1U, "Pass rvalue by value" );
+
+    CHECK_COPIES( nrvo_source(), 0U, 1U, "Named return value optimization (NRVO)" );
+    CHECK_COPIES( urvo_source(), 0U, 1U, "Unnamed return value optimization (URVO)" );
+
+    // Just to prove these things compose properly
+    CHECK_COPIES( X a(urvo_source()), 0U, 2U, "Return value used as ctor arg" );
+    
+    // Expect to miss one possible elision here
+    CHECK_COPIES( identity( rvalue() ), 0U, 2U, "Return rvalue passed by value" );
+
+    // Expect to miss an elision in at least one of the following lines
+    CHECK_COPIES( X a = ternary( argc == 1000 ), 0U, 2U, "Return result of ternary operation" );
+    CHECK_COPIES( X a = ternary( argc != 1000 ), 0U, 2U, "Return result of ternary operation again" );
+    return boost::report_errors();
+}
+
+#include <boost/move/detail/config_end.hpp>
diff --git a/test/copy_move_optimization.cpp b/test/copy_move_optimization.cpp
new file mode 100644
index 0000000..06d1847
--- /dev/null
+++ b/test/copy_move_optimization.cpp
@@ -0,0 +1,107 @@
+//We need to declare:
+//
+//2 conversions: rv<T> & and const rv<T> &
+//1 rv<T> & constructor: move constructor
+//1 const rv<T> & constructor: copy constructor
+//1 T & constructor: copy constructor
+//
+//Optimization:
+//Since RVO is better than move-construction,
+//avoid copy constructor overloading.
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/utility_core.hpp>
+#include <iostream>
+
+bool moved = false;
+
+class obj
+{
+   BOOST_COPYABLE_AND_MOVABLE(obj)
+   public:
+
+   obj()
+   {
+      std::cout << "constructing obj" << "\n";
+   }
+
+   ~obj()
+   {}
+
+   obj(const obj &)
+   {
+      std::cout << "copy construct from const obj" << "\n";
+   }
+
+   // copy construct from movable object (non-const rvalue, explicitly moved lvalue)
+   obj(BOOST_RV_REF(obj))
+   {
+      std::cout << "move construct from movable rvalue" << "\n";
+   }
+
+   obj& operator =(BOOST_COPY_ASSIGN_REF(obj))
+   {
+      std::cout << "copy assign from const obj" << "\n";
+      return *this;
+   }
+
+   obj& operator =(BOOST_RV_REF(obj))
+   {
+      std::cout << "move assign from movable rvalue" << "\n";
+      return *this;
+   }
+};
+
+
+obj        rvalue_func()       { return obj(); }
+const obj  const_rvalue_func() { return obj();  }
+obj&       lvalue_func()       { static obj o;  return o; }
+const obj& const_lvalue_func() { static obj o; return o; }
+
+obj produce()     { return obj(); }
+
+void consume(obj){}
+
+int main()
+{
+   {  consume(produce());  }
+   {  obj o = produce();   }
+   {  obj o(produce());    }
+   {
+   obj o1(rvalue_func());
+   obj o2 = const_rvalue_func();
+   obj o3 = lvalue_func();
+   obj o4 = const_lvalue_func();
+   // can't explicitly move temporaries
+   //obj o5 = boost::move(rvalue_func());
+   obj o5;
+   //Maybe missed optimization: copied
+   o5 = rvalue_func();
+   //Explicit forward works OK and optimized
+   o5 = boost::forward<obj>(rvalue_func());
+
+   obj o7 = boost::move(lvalue_func());
+   obj o8 = boost::move(const_lvalue_func());
+
+   obj o;
+   o = rvalue_func();
+   o = const_rvalue_func();
+   o = lvalue_func();
+   o = const_lvalue_func();
+   // can't explicitly move temporaries
+   //o = boost::move(rvalue_func());
+   o = boost::forward<obj>(rvalue_func());
+   o = boost::move(const_rvalue_func());
+   o = boost::move(lvalue_func());
+   o = boost::move(const_lvalue_func());
+   }
+   return 0;
+}
+
+//We need to declare:
+//
+//2 conversions: rv<T> & and const rv<T> &
+//1 rv<T> & constructor: move constructor
+//1 const rv<T> & constructor: copy constructor
+//1 T & constructor: copy constructor
+
+#include <boost/move/detail/config_end.hpp>
diff --git a/test/inplace_merge_test.cpp b/test/inplace_merge_test.cpp
new file mode 100644
index 0000000..b69bce0
--- /dev/null
+++ b/test/inplace_merge_test.cpp
@@ -0,0 +1,283 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2016-2016.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//#define BOOST_MOVE_ADAPTIVE_SORT_INVARIANTS
+#define BOOST_MOVE_ADAPTIVE_SORT_STATS
+
+#include "order_type.hpp"
+
+#include <iostream>  //std::cout
+#include <boost/config.hpp>
+
+#include <boost/move/algo/detail/adaptive_sort_merge.hpp>
+#include <boost/move/core.hpp>
+#include <boost/move/unique_ptr.hpp>
+#include <boost/move/make_unique.hpp>
+
+#include <boost/move/detail/type_traits.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+#include <cstddef>
+
+const std::size_t BlockSize = 7u;
+
+#if defined(BOOST_MSVC)
+#pragma warning (disable : 4267)
+#endif
+
+
+const std::size_t left_merge = 0;
+const std::size_t buf_merge  = 1;
+const std::size_t unbuf_merge= 2;
+const std::size_t max_merge  = 3;
+
+template<class Op>
+void alternating_test(
+   const std::size_t NumBlocksA,
+   const std::size_t NumBlocksB,
+   const std::size_t ExtraA,
+   const std::size_t ExtraB,
+   Op op)
+{
+   using namespace boost::movelib::detail_adaptive;
+
+
+   const std::size_t DataSize   = ExtraA + NumBlocksA*BlockSize + NumBlocksB*BlockSize + ExtraB;
+   const std::size_t KeySize    = NumBlocksA + NumBlocksB + 1;
+   const std::size_t HdrSize    = BlockSize + KeySize;
+   const std::size_t ArraySize  = HdrSize + DataSize;
+
+   boost::movelib::unique_ptr<order_move_type[]> testarray(boost::movelib::make_unique<order_move_type[]>(ArraySize));
+
+
+   for(std::size_t szt_merge = 0; szt_merge != max_merge; ++szt_merge){
+      //Order keys
+      for (std::size_t szt_i = 0u; szt_i != KeySize; ++szt_i) {
+         testarray[szt_i].key = szt_i;
+         testarray[szt_i].val = std::size_t(-1);
+      }
+
+      //Order buffer
+      for (std::size_t szt_i = 0u; szt_i != BlockSize; ++szt_i) {
+         testarray[KeySize+szt_i].key = std::size_t(-1);
+         testarray[KeySize+szt_i].val = szt_i;
+      }
+
+      //Block A
+      std::size_t szt_k = 0;
+      for (std::size_t szt_i = 0u; szt_i != ExtraA;  ++szt_i) {
+         testarray[HdrSize+szt_k].key = (szt_k/2)*2;
+         testarray[HdrSize+szt_k].val = szt_k & 1;
+         ++szt_k;
+      }
+
+      for (std::size_t szt_b = 0u; szt_b != NumBlocksA; ++szt_b)
+      for (std::size_t szt_i = 0u; szt_i != BlockSize;  ++szt_i) {
+         testarray[HdrSize+szt_k].key = (szt_k/2)*2;
+         testarray[HdrSize+szt_k].val = szt_k & 1;
+         ++szt_k;
+      }
+
+      //Block B
+      std::size_t szt_l = 0;
+      for (std::size_t szt_b = 0u, szt_t = 0; szt_b != NumBlocksB; ++szt_b)
+      for (std::size_t szt_i = 0u; szt_i != BlockSize;  ++szt_i, ++szt_t) {
+         testarray[HdrSize+szt_k].key = (szt_l/2)*2+1;
+         testarray[HdrSize+szt_k].val = szt_l & 1;
+         ++szt_k;
+         ++szt_l;
+      }
+
+      for (std::size_t szt_i = 0u; szt_i != ExtraB;  ++szt_i) {
+         testarray[HdrSize+szt_k].key = (szt_l/2)*2+1;
+         testarray[HdrSize+szt_k].val = szt_l & 1;
+         ++szt_k;
+         ++szt_l;
+      }
+
+      if(szt_merge == left_merge){
+         //Merge Left
+         op_merge_blocks_left
+            ( testarray.get(), order_type_less()
+            , testarray.get()+HdrSize, BlockSize, ExtraA, NumBlocksA, NumBlocksB, ExtraB
+            , order_type_less(), op );
+         BOOST_TEST( is_order_type_ordered(testarray.get()+KeySize, DataSize) );
+         BOOST_TEST( is_key(testarray.get(), KeySize) );
+         BOOST_TEST(( !boost::move_detail::is_same<Op, boost::movelib::swap_op>::value
+                     || is_buffer(testarray.get()+ KeySize+DataSize, BlockSize) ));
+      }
+      else if(szt_merge == buf_merge){
+         //Merge with buf
+         op_merge_blocks_with_buf
+            ( testarray.get(), order_type_less()
+            , testarray.get()+HdrSize, BlockSize, ExtraA, NumBlocksA, NumBlocksB, ExtraB
+            , order_type_less(), op, testarray.get()+KeySize );
+         BOOST_TEST( is_order_type_ordered(testarray.get()+HdrSize, DataSize) );
+         BOOST_TEST( is_key(testarray.get(), KeySize) );
+         BOOST_TEST(( !boost::move_detail::is_same<Op, boost::movelib::swap_op>::value
+                     || is_buffer(testarray.get()+ KeySize, BlockSize) ));
+      }
+      else if(szt_merge == unbuf_merge){
+         //Merge Left
+         merge_blocks_bufferless
+            ( testarray.get(), order_type_less()
+            , testarray.get()+HdrSize, BlockSize, ExtraA, NumBlocksA, NumBlocksB, ExtraB
+            , order_type_less());
+         BOOST_TEST( is_order_type_ordered(testarray.get()+HdrSize, DataSize) );
+         BOOST_TEST( is_key(testarray.get(), KeySize) );
+         BOOST_TEST(( !boost::move_detail::is_same<Op, boost::movelib::swap_op>::value
+                     || is_buffer(testarray.get()+ KeySize, BlockSize) ));
+      }
+   }
+}
+
+int main()
+{
+   {
+      const std::size_t NumBlocksA = 3u;
+      const std::size_t NumBlocksB = 3u;
+      const std::size_t ExtraA     = BlockSize/2;
+      const std::size_t ExtraB     = ExtraA;
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+   }
+   {
+      const std::size_t NumBlocksA = 3u;
+      const std::size_t NumBlocksB = 3u;
+      const std::size_t ExtraA     = 0u;
+      const std::size_t ExtraB     = BlockSize/2;
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+   }
+   {
+      const std::size_t NumBlocksA = 3u;
+      const std::size_t NumBlocksB = 3u;
+      const std::size_t ExtraA     = BlockSize/2;
+      const std::size_t ExtraB     = 0;
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+   }
+   {
+      const std::size_t NumBlocksA = 3u;
+      const std::size_t NumBlocksB = 3u;
+      const std::size_t ExtraA     = 0;
+      const std::size_t ExtraB     = 0;
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+   }
+   {
+      const std::size_t NumBlocksA = 6u;
+      const std::size_t NumBlocksB = 3u;
+      const std::size_t ExtraA     = BlockSize/2;
+      const std::size_t ExtraB     = ExtraA;
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+   }
+   {
+      const std::size_t NumBlocksA = 6u;
+      const std::size_t NumBlocksB = 3u;
+      const std::size_t ExtraA     = BlockSize/2;
+      const std::size_t ExtraB     = 0;
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+   }
+   {
+      const std::size_t NumBlocksA = 3u;
+      const std::size_t NumBlocksB = 5u;
+      const std::size_t ExtraA     = BlockSize/2;
+      const std::size_t ExtraB     = ExtraA;
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+   }
+   {
+      const std::size_t NumBlocksA = 3u;
+      const std::size_t NumBlocksB = 5u;
+      const std::size_t ExtraA     = BlockSize/2;
+      const std::size_t ExtraB     = 0;
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+   }
+   {
+      const std::size_t NumBlocksA = 0u;
+      const std::size_t NumBlocksB = 0u;
+      const std::size_t ExtraA     = 0;
+      const std::size_t ExtraB     = 0;
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+   }
+   {
+      const std::size_t NumBlocksA = 0u;
+      const std::size_t NumBlocksB = 0u;
+      const std::size_t ExtraA     = BlockSize/2;
+      const std::size_t ExtraB     = 0;
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+   }
+   {
+      const std::size_t NumBlocksA = 0u;
+      const std::size_t NumBlocksB = 0u;
+      const std::size_t ExtraA     = 0;
+      const std::size_t ExtraB     = BlockSize/2;
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+   }
+   //
+   {
+      const std::size_t NumBlocksA = 0u;
+      const std::size_t NumBlocksB = 1u;
+      const std::size_t ExtraA     = 0;
+      const std::size_t ExtraB     = 0;
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+   }
+   {
+      const std::size_t NumBlocksA = 1u;
+      const std::size_t NumBlocksB = 0u;
+      const std::size_t ExtraA     = 0;
+      const std::size_t ExtraB     = 0;
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+   }
+   {
+      const std::size_t NumBlocksA = 1u;
+      const std::size_t NumBlocksB = 0u;
+      const std::size_t ExtraA     = BlockSize/2;
+      const std::size_t ExtraB     = 0;
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+   }
+   {
+      const std::size_t NumBlocksA = 0u;
+      const std::size_t NumBlocksB = 1u;
+      const std::size_t ExtraA     = BlockSize/2;
+      const std::size_t ExtraB     = 0;
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+   }
+   {
+      const std::size_t NumBlocksA = 1u;
+      const std::size_t NumBlocksB = 0u;
+      const std::size_t ExtraA     = 0;
+      const std::size_t ExtraB     = BlockSize/2;
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+   }
+   {
+      const std::size_t NumBlocksA = 0u;
+      const std::size_t NumBlocksB = 1u;
+      const std::size_t ExtraA     = 0;
+      const std::size_t ExtraB     = BlockSize/2;
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::move_op());
+      alternating_test(NumBlocksA, NumBlocksB, ExtraA, ExtraB, boost::movelib::swap_op());
+   }
+
+   return ::boost::report_errors();
+}
diff --git a/test/move.cpp b/test/move.cpp
new file mode 100644
index 0000000..2d40ec8
--- /dev/null
+++ b/test/move.cpp
@@ -0,0 +1,183 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2009.
+// (C) Copyright Ion Gaztanaga 2009-2014.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/utility_core.hpp>
+#include "../example/movable.hpp"
+#include "../example/copymovable.hpp"
+#include <boost/static_assert.hpp>
+
+movable function(movable m)
+{
+   return movable(boost::move(m));
+}
+
+movable functionr(BOOST_RV_REF(movable) m)
+{
+   return movable(boost::move(m));
+}
+
+movable function2(movable m)
+{
+   return boost::move(m);
+}
+
+BOOST_RV_REF(movable) function2r(BOOST_RV_REF(movable) m)
+{
+   return boost::move(m);
+}
+
+movable move_return_function2 ()
+{
+    return movable();
+}
+
+movable move_return_function ()
+{
+    movable m;
+    return (boost::move(m));
+}
+
+
+//Catch by value
+void function_value(movable)
+{}
+
+//Catch by reference
+void function_ref(const movable &)
+{}
+
+//Catch by reference
+void function_ref(BOOST_RV_REF(movable))
+{}
+
+movable create_movable()
+{  return movable(); }
+
+template<class Type>
+struct factory
+{
+   Type operator()() const
+   {
+      Type t;
+      return BOOST_MOVE_RET(Type, t);
+   }
+};
+
+template<class Type>
+struct factory<Type &>
+{
+   static Type t;
+   Type &operator()() const
+   {
+      return BOOST_MOVE_RET(Type&, t);
+   }
+};
+
+template<class Type>
+Type factory<Type&>::t;
+
+template <class R, class F>
+R factory_wrapper(F f)
+{
+  // lock();
+  R r = f();
+  // unlock();
+  return BOOST_MOVE_RET(R, r);
+}
+
+int main()
+{
+   #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+   BOOST_STATIC_ASSERT((boost::has_nothrow_move<movable>::value == true));
+   BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<copyable>::value == false));
+   BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<copyable*>::value == false));
+   BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<int>::value == false));
+   BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<int&>::value == false));
+   BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<int*>::value == false));
+   #endif
+
+   {
+      movable m;
+      movable m2(boost::move(m));
+      movable m3(function(movable(boost::move(m2))));
+      movable m4(function(boost::move(m3)));
+      (void)m;(void)m2;(void)m3;(void)m4;
+   }
+   {
+      movable m;
+      movable m2(boost::move(m));
+      movable m3(functionr(movable(boost::move(m2))));
+      movable m4(functionr(boost::move(m3))); 
+      (void)m;(void)m2;(void)m3;(void)m4;
+   }
+   {
+      movable m;
+      movable m2(boost::move(m));
+      movable m3(function2(movable(boost::move(m2))));
+      movable m4(function2(boost::move(m3)));
+      (void)m;(void)m2;(void)m3;(void)m4;
+   }
+   {
+      movable m;
+      movable m2(boost::move(m));
+      movable m3(function2r(movable(boost::move(m2))));
+      movable m4(function2r(boost::move(m3)));
+      (void)m;(void)m2;(void)m3;(void)m4;
+   }
+   {
+      movable m;
+      movable m2(boost::move(m));
+      movable m3(move_return_function());
+      (void)m;(void)m2;(void)m3;
+   }
+   {
+      movable m;
+      movable m2(boost::move(m));
+      movable m3(move_return_function2());
+      (void)m;(void)m2;(void)m3;
+   }
+   {
+      //movable
+      movable m (factory_wrapper<movable>(factory<movable>()));
+      m = factory_wrapper<movable>(factory<movable>());
+      movable&mr(factory_wrapper<movable&>(factory<movable&>()));
+      movable&mr2 = factory_wrapper<movable&>(factory<movable&>());
+      (void)mr;
+      (void)mr2;
+      (void)m;
+   }
+   {
+      //copyable
+      copyable c (factory_wrapper<copyable>(factory<copyable>()));
+      c = factory_wrapper<copyable>(factory<copyable>());
+      copyable&cr(factory_wrapper<copyable&>(factory<copyable&>()));
+      copyable&cr2 = factory_wrapper<copyable&>(factory<copyable&>());
+      (void)cr;
+      (void)cr2;
+      (void)c;
+   }
+
+   {
+      //copy_movable
+      copy_movable c (factory_wrapper<copy_movable>(factory<copy_movable>()));
+      c = factory_wrapper<copy_movable>(factory<copy_movable>());
+      copy_movable&cr(factory_wrapper<copy_movable&>(factory<copy_movable&>()));
+      copy_movable&cr2 = factory_wrapper<copy_movable&>(factory<copy_movable&>());
+      (void)cr;
+      (void)cr2;
+      (void)c;
+   }
+
+   return 0;
+}
+
+#include <boost/move/detail/config_end.hpp>
diff --git a/test/move_algorithm.cpp b/test/move_algorithm.cpp
new file mode 100644
index 0000000..2178328
--- /dev/null
+++ b/test/move_algorithm.cpp
@@ -0,0 +1,58 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2009.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/algorithm.hpp>
+#include <boost/container/vector.hpp>
+#include "../example/movable.hpp"
+
+int main()
+{
+   namespace bc = ::boost::container;
+   //Default construct 10 movable objects
+   bc::vector<movable> v(10);
+   bc::vector<movable> v2(10);
+
+   //Move to v2
+   boost::move(v.begin(), v.end(), v2.begin());
+
+   //Test values have been moved
+   if(!v[0].moved()){
+      return 1;
+   }
+
+   if(v2.size() != 10){
+      return 1;
+   }
+
+   if(v2[0].moved()){
+      return 1;
+   }
+
+   //Move to v again
+   boost::move_backward(v2.begin(), v2.end(), v.end());
+
+   //Test values have been moved
+   if(!v2[1].moved()){
+      return 1;
+   }
+
+   if(v.size() != 10){
+      return 1;
+   }
+
+   if(v[1].moved()){
+      return 1;
+   }
+
+   return 0;
+}
+
+#include <boost/move/detail/config_end.hpp>
diff --git a/test/move_if_noexcept.cpp b/test/move_if_noexcept.cpp
new file mode 100644
index 0000000..a03a821
--- /dev/null
+++ b/test/move_if_noexcept.cpp
@@ -0,0 +1,230 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Antony Polukhin 2014.
+// (C) Copyright Ion Gaztanaga 2014.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include "../example/movable.hpp"
+#include "../example/copymovable.hpp"
+#include <boost/static_assert.hpp>
+
+//////////////////////////////////////////////////////////////////////////////
+//A copy_movable_noexcept class
+class copy_movable_noexcept
+{
+   BOOST_COPYABLE_AND_MOVABLE(copy_movable_noexcept)
+   int value_;
+
+   public:
+   copy_movable_noexcept() : value_(1){}
+
+   //Move constructor and assignment
+   copy_movable_noexcept(BOOST_RV_REF(copy_movable_noexcept) m)
+   {  value_ = m.value_;   m.value_ = 0;  }
+
+   copy_movable_noexcept(const copy_movable_noexcept &m)
+   {  value_ = m.value_;   }
+
+   copy_movable_noexcept & operator=(BOOST_RV_REF(copy_movable_noexcept) m)
+   {  value_ = m.value_;   m.value_ = 0;  return *this;  }
+
+   copy_movable_noexcept & operator=(BOOST_COPY_ASSIGN_REF(copy_movable_noexcept) m)
+   {  value_ = m.value_;   return *this;  }
+
+   bool moved() const //Observer
+   {  return value_ == 0; }
+};
+
+namespace boost{
+
+template<>
+struct has_nothrow_move<copy_movable_noexcept>
+{
+   static const bool value = true;
+};
+
+}  //namespace boost{
+
+//////////////////////////////////////////////////////////////////////////////
+//A movable_throwable class
+class movable_throwable
+{
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(movable_throwable)
+   int value_;
+
+   public:
+   movable_throwable() : value_(1){}
+
+   //Move constructor and assignment
+   movable_throwable(BOOST_RV_REF(movable_throwable) m)
+   {  value_ = m.value_;   m.value_ = 0;  }
+
+   movable_throwable & operator=(BOOST_RV_REF(movable_throwable) m)
+   {  value_ = m.value_;   m.value_ = 0;  return *this;  }
+
+   bool moved() const //Observer
+   {  return !value_; }
+
+   int value() const //Observer
+   {  return value_; }
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Helper functions
+movable function(movable m)
+{
+   return movable(boost::move_if_noexcept(m));
+}
+
+copy_movable function(copy_movable m)
+{
+   return copy_movable(boost::move_if_noexcept(m));
+}
+
+copy_movable_noexcept function(copy_movable_noexcept m)
+{
+   return copy_movable_noexcept(boost::move_if_noexcept(m));
+}
+
+movable_throwable function(movable_throwable m)
+{
+   return movable_throwable(boost::move_if_noexcept(m));
+}
+
+movable functionr(BOOST_RV_REF(movable) m)
+{
+   return movable(boost::move_if_noexcept(m));
+}
+
+movable function2(movable m)
+{
+   return boost::move_if_noexcept(m);
+}
+
+BOOST_RV_REF(movable) function2r(BOOST_RV_REF(movable) m)
+{
+   return boost::move_if_noexcept(m);
+}
+
+movable move_return_function2 ()
+{
+    return movable();
+}
+
+movable move_return_function ()
+{
+    movable m;
+    return (boost::move_if_noexcept(m));
+}
+
+#define BOOST_CHECK(x) if (!(x)) { return __LINE__; }
+
+int main()
+{
+   {
+      movable m;
+      movable m2(boost::move_if_noexcept(m));
+      BOOST_CHECK(m.moved());
+      movable m3(function(movable(boost::move_if_noexcept(m2))));
+      BOOST_CHECK(m2.moved());
+      movable m4(function(boost::move_if_noexcept(m3)));
+      BOOST_CHECK(m3.moved());
+      BOOST_CHECK(!m4.moved());
+   }
+   {
+      movable m;
+      movable m2(boost::move_if_noexcept(m));
+      BOOST_CHECK(m.moved());
+      movable m3(functionr(movable(boost::move_if_noexcept(m2))));
+      BOOST_CHECK(m2.moved());
+      movable m4(functionr(boost::move_if_noexcept(m3)));
+      BOOST_CHECK(m3.moved());
+      BOOST_CHECK(!m4.moved());
+   }
+   {
+      movable m;
+      movable m2(boost::move_if_noexcept(m));
+      BOOST_CHECK(m.moved());
+      movable m3(function2(movable(boost::move_if_noexcept(m2))));
+      BOOST_CHECK(m2.moved());
+      movable m4(function2(boost::move_if_noexcept(m3)));
+      BOOST_CHECK(m3.moved());
+      BOOST_CHECK(!m4.moved());
+   }
+   {
+      movable m;
+      movable m2(boost::move_if_noexcept(m));
+      BOOST_CHECK(m.moved());
+      movable m3(function2r(movable(boost::move_if_noexcept(m2))));
+      BOOST_CHECK(m2.moved());
+      movable m4(function2r(boost::move_if_noexcept(m3)));
+      BOOST_CHECK(m3.moved());
+      BOOST_CHECK(!m4.moved());
+   }
+   {
+      movable m;
+      movable m2(boost::move_if_noexcept(m));
+      BOOST_CHECK(m.moved());
+      BOOST_CHECK(!m2.moved());
+      movable m3(move_return_function());
+      BOOST_CHECK(!m3.moved());
+   }
+   {
+      movable m;
+      movable m2(boost::move_if_noexcept(m));
+      BOOST_CHECK(m.moved());
+      BOOST_CHECK(!m2.moved());
+      movable m3(move_return_function2());
+      BOOST_CHECK(!m3.moved());
+   }
+
+   // copy_movable may throw during move, so it must be copied
+   {
+      copy_movable m;
+      copy_movable m2(boost::move_if_noexcept(m));
+      BOOST_CHECK(!m.moved());
+      copy_movable m3(function(copy_movable(boost::move_if_noexcept(m2))));
+      BOOST_CHECK(!m2.moved());
+      copy_movable m4(function(boost::move_if_noexcept(m3)));
+      BOOST_CHECK(!m3.moved());
+      BOOST_CHECK(!m4.moved());
+   }
+
+
+   // copy_movable_noexcept can not throw during move
+   {
+      copy_movable_noexcept m;
+      copy_movable_noexcept m2(boost::move_if_noexcept(m));
+      BOOST_CHECK(m.moved());
+      copy_movable_noexcept m3(function(copy_movable_noexcept(boost::move_if_noexcept(m2))));
+      BOOST_CHECK(m2.moved());
+      copy_movable_noexcept m4(function(boost::move_if_noexcept(m3)));
+      BOOST_CHECK(m3.moved());
+      BOOST_CHECK(!m4.moved());
+   }
+
+   // movable_throwable can not throw during move but it has no copy constructor
+   {
+      movable_throwable m;
+      movable_throwable m2(boost::move_if_noexcept(m));
+      BOOST_CHECK(m.moved());
+      movable_throwable m3(function(movable_throwable(boost::move_if_noexcept(m2))));
+      BOOST_CHECK(m2.moved());
+      movable_throwable m4(function(boost::move_if_noexcept(m3)));
+      BOOST_CHECK(m3.moved());
+      BOOST_CHECK(!m4.moved());
+   }
+
+   return boost::report_errors();
+}
+
+#include <boost/move/detail/config_end.hpp>
diff --git a/test/move_iterator.cpp b/test/move_iterator.cpp
new file mode 100644
index 0000000..fded99a
--- /dev/null
+++ b/test/move_iterator.cpp
@@ -0,0 +1,44 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright David Abrahams, Vicente Botet, Ion Gaztanaga 2009.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/iterator.hpp>
+#include <boost/container/vector.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include "../example/movable.hpp"
+
+int main()
+{
+   namespace bc = ::boost::container;
+   //Default construct 10 movable objects
+   bc::vector<movable> v(10);
+
+   //Test default constructed value
+   BOOST_TEST(!v[0].moved());
+
+   //Move values
+   bc::vector<movable> v2
+      (boost::make_move_iterator(v.begin()), boost::make_move_iterator(v.end()));
+
+   //Test values have been moved
+   BOOST_TEST(v[0].moved());
+   BOOST_TEST(v2.size() == 10);
+
+   //Move again
+   v.assign(boost::make_move_iterator(v2.begin()), boost::make_move_iterator(v2.end()));
+
+   //Test values have been moved
+   BOOST_TEST(v2[0].moved());
+   BOOST_TEST(!v[0].moved());
+
+   return ::boost::report_errors();
+}
+
+#include <boost/move/detail/config_end.hpp>
diff --git a/test/order_type.hpp b/test/order_type.hpp
new file mode 100644
index 0000000..da4a90a
--- /dev/null
+++ b/test/order_type.hpp
@@ -0,0 +1,172 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2016.
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_MOVE_TEST_ORDER_TYPE_HPP
+#define BOOST_MOVE_TEST_ORDER_TYPE_HPP
+
+#include <boost/config.hpp>
+#include <boost/move/core.hpp>
+#include <cstddef>
+#include <cstdio>
+
+struct order_perf_type
+{
+   public:
+   std::size_t key;
+   std::size_t val;
+
+   order_perf_type()
+   {
+      ++num_elements;
+   }
+
+   order_perf_type(const order_perf_type& other)
+      : key(other.key), val(other.val)
+   {
+      ++num_elements;
+      ++num_copy;
+   }
+
+   order_perf_type & operator=(const order_perf_type& other)
+   {
+      ++num_copy;
+      key = other.key;
+      val = other.val;
+      return *this;
+   }
+
+   ~order_perf_type ()
+   {
+      --num_elements;
+   }
+
+   static void reset_stats()
+   {
+      num_compare=0;
+      num_copy=0;
+   }
+
+   friend bool operator< (const order_perf_type& left, const order_perf_type& right)
+   {  ++num_compare; return left.key < right.key;  }
+
+   static boost::ulong_long_type num_compare;
+   static boost::ulong_long_type num_copy;
+   static boost::ulong_long_type num_elements;
+};
+
+boost::ulong_long_type order_perf_type::num_compare = 0;
+boost::ulong_long_type order_perf_type::num_copy = 0;
+boost::ulong_long_type order_perf_type::num_elements = 0;
+
+
+struct order_move_type
+{
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(order_move_type)
+
+   public:
+   std::size_t key;
+   std::size_t val;
+
+   static const std::size_t moved_constr_mark = std::size_t(-1);
+   static const std::size_t moved_assign_mark = std::size_t(-2);
+
+   order_move_type()
+      : key(0u), val(0u)
+   {}
+
+   order_move_type(BOOST_RV_REF(order_move_type) other)
+      : key(other.key), val(other.val)
+   {
+      other.key = other.val = std::size_t(-1);
+   }
+
+   order_move_type & operator=(BOOST_RV_REF(order_move_type) other)
+   {
+      key = other.key;
+      val = other.val;
+      other.key = other.val = std::size_t(-2);
+      return *this;
+   }
+
+   friend bool operator< (const order_move_type& left, const order_move_type& right)
+   {  return left.key < right.key;  }
+
+   ~order_move_type ()
+   {
+      key = val = std::size_t(-3);
+   }
+};
+
+struct order_type_less
+{
+   template<class T, class U>
+   bool operator()(const T &a, U const &b) const
+   {  return a < b;   }
+};
+
+template<class T>
+inline bool is_order_type_ordered(T *elements, std::size_t element_count, bool stable = true)
+{
+   for(std::size_t i = 1; i < element_count; ++i){
+      if(order_type_less()(elements[i], elements[i-1])){
+         std::printf("\n Ord KO !!!!");
+         return false;
+      }
+      if( stable && !(order_type_less()(elements[i-1], elements[i])) && (elements[i-1].val > elements[i].val) ){
+         std::printf("\n Stb KO !!!! ");
+         return false;
+      }
+   }
+   return true;
+}
+
+namespace boost {
+namespace movelib {
+namespace detail_adaptive {
+
+
+
+}}}
+
+template<class T>
+inline bool is_key(T *elements, std::size_t element_count)
+{
+   for(std::size_t i = 1; i < element_count; ++i){
+      if(elements[i].key >= element_count){
+         std::printf("\n Key.key KO !!!!");
+         return false;
+      }
+      if(elements[i].val != std::size_t(-1)){
+         std::printf("\n Key.val KO !!!!");
+         return false;
+      }
+   }
+   return true;
+}
+
+template<class T>
+inline bool is_buffer(T *elements, std::size_t element_count)
+{
+   for(std::size_t i = 1; i < element_count; ++i){
+      if(elements[i].key != std::size_t(-1)){
+         std::printf("\n Buf.key KO !!!!");
+         return false;
+      }
+      if(elements[i].val >= element_count){
+         std::printf("\n Buf.val KO !!!!");
+         return false;
+      }
+   }
+   return true;
+}
+
+
+#endif   //BOOST_MOVE_TEST_ORDER_TYPE_HPP
diff --git a/test/random_shuffle.hpp b/test/random_shuffle.hpp
new file mode 100644
index 0000000..5041d96
--- /dev/null
+++ b/test/random_shuffle.hpp
@@ -0,0 +1,23 @@
+#ifndef BOOST_MOVE_TEST_RANDOM_SHUFFLE_HPP
+#define BOOST_MOVE_TEST_RANDOM_SHUFFLE_HPP
+
+
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/move/detail/iterator_traits.hpp>
+#include <stdlib.h>
+
+template< class RandomIt >
+void random_shuffle( RandomIt first, RandomIt last )
+{
+   typedef typename boost::movelib::iterator_traits<RandomIt>::difference_type difference_type;
+   difference_type n = last - first;
+   for (difference_type i = n-1; i > 0; --i) {
+      difference_type j = std::rand() % (i+1);
+      if(j != i) {
+         boost::adl_move_swap(first[i], first[j]);
+      }
+   }
+}
+
+
+#endif// BOOST_MOVE_TEST_RANDOM_SHUFFLE_HPP
diff --git a/test/type_traits.cpp b/test/type_traits.cpp
new file mode 100644
index 0000000..3625777
--- /dev/null
+++ b/test/type_traits.cpp
@@ -0,0 +1,98 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2015.
+//
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/move/detail/type_traits.hpp>
+#include <boost/move/core.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+//
+//       pod_struct
+//
+#if defined(BOOST_MOVE_IS_POD)
+struct pod_struct
+{
+   int i;
+   float f;
+};
+#endif
+
+//
+//       deleted_copy_and_assign_type
+//
+#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
+
+struct deleted_copy_and_assign_type
+{
+   deleted_copy_and_assign_type(const deleted_copy_and_assign_type&) = delete;
+   deleted_copy_and_assign_type & operator=(const deleted_copy_and_assign_type&) = delete;
+};
+
+#endif   //defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
+
+//
+//       boost_move_type
+//
+class boost_move_type
+{
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(boost_move_type)
+   public:
+   boost_move_type(BOOST_RV_REF(boost_move_type)){}
+   boost_move_type & operator=(BOOST_RV_REF(boost_move_type)){ return *this; }
+};
+
+namespace is_pod_test
+{
+
+void test()
+{
+   BOOST_STATIC_ASSERT((boost::move_detail::is_pod<int>::value));
+   #if defined(BOOST_MOVE_IS_POD)
+   BOOST_STATIC_ASSERT((boost::move_detail::is_pod<pod_struct>::value));
+   #endif
+}
+
+}  //namespace is_pod_test
+
+namespace trivially_memcopyable_test {
+
+void test()
+{
+   #if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
+   BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_constructible<deleted_copy_and_assign_type>::value));
+   BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_assignable<deleted_copy_and_assign_type>::value));
+   #endif   //#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
+   //boost_move_type
+   BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_constructible<boost_move_type>::value));
+   BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_assignable<boost_move_type>::value));
+   BOOST_STATIC_ASSERT(!(boost::move_detail::is_copy_constructible<boost_move_type>::value));
+   BOOST_STATIC_ASSERT(!(boost::move_detail::is_copy_assignable<boost_move_type>::value));
+   //POD
+   BOOST_STATIC_ASSERT((boost::move_detail::is_trivially_copy_constructible<int>::value));
+   BOOST_STATIC_ASSERT((boost::move_detail::is_trivially_copy_assignable<int>::value));
+   BOOST_STATIC_ASSERT((boost::move_detail::is_copy_constructible<int>::value));
+   BOOST_STATIC_ASSERT((boost::move_detail::is_copy_assignable<int>::value));
+   #if defined(BOOST_MOVE_IS_POD)
+   BOOST_STATIC_ASSERT((boost::move_detail::is_trivially_copy_constructible<pod_struct>::value));
+   BOOST_STATIC_ASSERT((boost::move_detail::is_trivially_copy_assignable<pod_struct>::value));
+   BOOST_STATIC_ASSERT((boost::move_detail::is_copy_constructible<pod_struct>::value));
+   BOOST_STATIC_ASSERT((boost::move_detail::is_copy_assignable<pod_struct>::value));
+   #endif
+}
+
+}  //namespace trivially_memcopyable_test {
+
+int main()
+{
+   trivially_memcopyable_test::test();
+   is_pod_test::test();
+   boost::report_errors();
+}
diff --git a/test/unique_ptr_assign.cpp b/test/unique_ptr_assign.cpp
new file mode 100644
index 0000000..088b7f4
--- /dev/null
+++ b/test/unique_ptr_assign.cpp
@@ -0,0 +1,444 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Howard Hinnant 2009
+// (C) Copyright Ion Gaztanaga 2014-2014.
+//
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/move/utility_core.hpp>
+#include <boost/move/unique_ptr.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+//////////////////////////////////////////////
+//
+// The initial implementation of these tests
+// was written by Howard Hinnant. 
+//
+// These test were later refactored grouping
+// and porting them to Boost.Move.
+//
+// Many thanks to Howard for releasing his C++03
+// unique_ptr implementation with such detailed
+// test cases.
+//
+//////////////////////////////////////////////
+
+#include "unique_ptr_test_utils_beg.hpp"
+
+namespace bml = ::boost::movelib;
+
+////////////////////////////////
+//   unique_ptr_asgn_move_convert_defdel
+////////////////////////////////
+namespace unique_ptr_asgn_move_convert_defdel {
+
+void test()
+{
+   //Single unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<B> s(new B);
+   A* p = s.get();
+   bml::unique_ptr<A> s2(new A);
+   BOOST_TEST(A::count == 2);
+   s2 = boost::move(s);
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 1);
+   BOOST_TEST(B::count == 1);
+   }
+   BOOST_TEST(A::count == 0);
+   BOOST_TEST(B::count == 0);
+
+   //Unbounded array unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<A[]> s(new A[2]);
+   A* p = s.get();
+   bml::unique_ptr<const A[]> s2(new const A[2]);
+   BOOST_TEST(A::count == 4);
+   s2 = boost::move(s);
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 2);
+   }
+   BOOST_TEST(A::count == 0);
+   //Bounded array unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<A[2]> s(new A[2]);
+   A* p = s.get();
+   bml::unique_ptr<const A[2]> s2(new const A[2]);
+   BOOST_TEST(A::count == 4);
+   s2 = boost::move(s);
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 2);
+   }
+   {
+   BOOST_TEST(A::count == 0);
+   bml::unique_ptr<A[2]> s(new A[2]);
+   A* p = s.get();
+   bml::unique_ptr<const A[]> s2(new const A[2]);
+   BOOST_TEST(A::count == 4);
+   s2 = boost::move(s);
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 2);
+   }
+   BOOST_TEST(A::count == 0);
+}
+
+}  //namespace unique_ptr_asgn_move_convert_defdel{
+
+////////////////////////////////
+//   unique_ptr_asgn_move_convert_movdel
+////////////////////////////////
+
+namespace unique_ptr_asgn_move_convert_movedel{
+
+void test()
+{
+   //Single unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<B, move_constr_deleter<B> > s(new B);
+   A* p = s.get();
+   bml::unique_ptr<A, move_constr_deleter<A> > s2(new A);
+   BOOST_TEST(A::count == 2);
+   s2 = (boost::move(s));
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 1);
+   BOOST_TEST(B::count == 1);
+   BOOST_TEST(s2.get_deleter().state() == 5);
+   BOOST_TEST(s.get_deleter().state() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+   BOOST_TEST(B::count == 0);
+
+   //Unbounded array unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<A[], move_constr_deleter<A[]> > s(new A[2]);
+   A* p = s.get();
+   bml::unique_ptr<const A[], move_constr_deleter<const A[]> > s2(new const A[2]);
+   BOOST_TEST(A::count == 4);
+   s2 = (boost::move(s));
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 2);
+   BOOST_TEST(s2.get_deleter().state() == 5);
+   BOOST_TEST(s.get_deleter().state() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+
+   //Bounded array unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<A[2], move_constr_deleter<A[2]> > s(new A[3]);
+   A* p = s.get();
+   bml::unique_ptr<const A[2], move_constr_deleter<const A[2]> > s2(new const A[2]);
+   BOOST_TEST(A::count == 5);
+   s2 = (boost::move(s));
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 3);
+   BOOST_TEST(s2.get_deleter().state() == 5);
+   BOOST_TEST(s.get_deleter().state() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+   reset_counters();
+   {
+   bml::unique_ptr<A[2], move_constr_deleter<A[3]> > s(new A[2]);
+   A* p = s.get();
+   bml::unique_ptr<const A[], move_constr_deleter<const A[]> > s2(new const A[2]);
+   BOOST_TEST(A::count == 4);
+   s2 = (boost::move(s));
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 2);
+   BOOST_TEST(s2.get_deleter().state() == 5);
+   BOOST_TEST(s.get_deleter().state() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+}
+
+}  //namespace unique_ptr_asgn_move_convert_movedel{
+
+////////////////////////////////
+//   unique_ptr_asgn_move_convert_copydelref
+////////////////////////////////
+
+namespace unique_ptr_asgn_move_convert_copydelref{
+
+// test converting move assignment with reference deleters
+
+void test()
+{
+   //Single unique_ptr
+   reset_counters();
+   {
+   copy_constr_deleter<B> db(5);
+   bml::unique_ptr<B, copy_constr_deleter<B>&> s(new B, db);
+   A* p = s.get();
+   copy_constr_deleter<A> da(6);
+   bml::unique_ptr<A, copy_constr_deleter<A>&> s2(new A, da);
+   s2 = boost::move(s);
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 1);
+   BOOST_TEST(B::count == 1);
+   BOOST_TEST(s2.get_deleter().state() == 5);
+   }
+   BOOST_TEST(A::count == 0);
+   BOOST_TEST(B::count == 0);
+
+   //Unbounded array unique_ptr
+   reset_counters();
+   {
+   copy_constr_deleter<A[]> db(5);
+   bml::unique_ptr<A[], copy_constr_deleter<A[]>&> s(new A[2], db);
+   A* p = s.get();
+   copy_constr_deleter<const A[]> da(6);
+   bml::unique_ptr<const A[], copy_constr_deleter<const A[]>&> s2(new const A[2], da);
+   BOOST_TEST(A::count == 4);
+   s2 = boost::move(s);
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 2);
+   BOOST_TEST(s2.get_deleter().state() == 5);
+   }
+   BOOST_TEST(A::count == 0);
+
+   //Bounded array unique_ptr
+   reset_counters();
+   {
+   copy_constr_deleter<A[2]> db(5);
+   bml::unique_ptr<A[2], copy_constr_deleter<A[2]>&> s(new A[2], db);
+   A* p = s.get();
+   copy_constr_deleter<const A[2]> da(6);
+   bml::unique_ptr<const A[2], copy_constr_deleter<const A[2]>&> s2(new const A[2], da);
+   BOOST_TEST(A::count == 4);
+   s2 = boost::move(s);
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 2);
+   BOOST_TEST(s2.get_deleter().state() == 5);
+   }
+   BOOST_TEST(A::count == 0);
+   reset_counters();
+   {
+   copy_constr_deleter<A[2]> db(5);
+   bml::unique_ptr<A[2], copy_constr_deleter<A[2]>&> s(new A[2], db);
+   A* p = s.get();
+   copy_constr_deleter<const A[]> da(6);
+   bml::unique_ptr<const A[], copy_constr_deleter<const A[]>&> s2(new const A[2], da);
+   BOOST_TEST(A::count == 4);
+   s2 = boost::move(s);
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 2);
+   BOOST_TEST(s2.get_deleter().state() == 5);
+   }
+   BOOST_TEST(A::count == 0);
+}
+
+}  //namespace unique_ptr_asgn_move_convert_copydelref{
+
+////////////////////////////////
+//   unique_ptr_asgn_move_defdel
+////////////////////////////////
+namespace unique_ptr_asgn_move_defdel {
+
+void test()
+{
+   //Single unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<A> s1(new A);
+   A* p = s1.get();
+   bml::unique_ptr<A> s2(new A);
+   BOOST_TEST(A::count == 2);
+   s2 = boost::move(s1);
+   BOOST_TEST(A::count == 1);
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s1.get() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+
+   //Unbounded array unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<A[]> s1(new A[2]);
+   A* p = s1.get();
+   bml::unique_ptr<A[]> s2(new A[2]);
+   BOOST_TEST(A::count == 4);
+   s2 = boost::move(s1);
+   BOOST_TEST(A::count == 2);
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s1.get() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+   //Bounded array unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<A[2]> s1(new A[2]);
+   A* p = s1.get();
+   bml::unique_ptr<A[2]> s2(new A[2]);
+   BOOST_TEST(A::count == 4);
+   s2 = boost::move(s1);
+   BOOST_TEST(A::count == 2);
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s1.get() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+}
+
+}  //unique_ptr_asgn_move_defdel
+
+////////////////////////////////
+//   unique_ptr_asgn_move_movedel
+////////////////////////////////
+namespace unique_ptr_asgn_move_movedel {
+
+void test()
+{
+   //Single unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<A, move_constr_deleter<A> > s1(new A);
+   A* p = s1.get();
+   bml::unique_ptr<A, move_constr_deleter<A> > s2(new A);
+   BOOST_TEST(A::count == 2);
+   s2 = boost::move(s1);
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s1.get() == 0);
+   BOOST_TEST(A::count == 1);
+   BOOST_TEST(s2.get_deleter().state() == 5);
+   BOOST_TEST(s1.get_deleter().state() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+
+   //Unbounded array unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<A[], move_constr_deleter<A[]> > s1(new A[2]);
+   A* p = s1.get();
+   bml::unique_ptr<A[], move_constr_deleter<A[]> > s2(new A[2]);
+   BOOST_TEST(A::count == 4);
+   s2 = boost::move(s1);
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s1.get() == 0);
+   BOOST_TEST(A::count == 2);
+   BOOST_TEST(s2.get_deleter().state() == 5);
+   BOOST_TEST(s1.get_deleter().state() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+
+   BOOST_TEST(A::count == 0);
+   //Bounded array unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<A[2], move_constr_deleter<A[2]> > s1(new A[2]);
+   A* p = s1.get();
+   bml::unique_ptr<A[2], move_constr_deleter<A[2]> > s2(new A[2]);
+   BOOST_TEST(A::count == 4);
+   s2 = boost::move(s1);
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s1.get() == 0);
+   BOOST_TEST(A::count == 2);
+   BOOST_TEST(s2.get_deleter().state() == 5);
+   BOOST_TEST(s1.get_deleter().state() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+}
+
+}  //unique_ptr_asgn_move_movedel
+
+////////////////////////////////
+//   unique_ptr_asgn_move_copydelref
+////////////////////////////////
+namespace unique_ptr_asgn_move_copydelref {
+
+void test()
+{
+   //Single unique_ptr
+   reset_counters();
+   {
+   copy_constr_deleter<A> d1(5);
+   bml::unique_ptr<A, copy_constr_deleter<A>&> s1(new A, d1);
+   A* p = s1.get();
+   copy_constr_deleter<A> d2(6);
+   bml::unique_ptr<A, copy_constr_deleter<A>&> s2(new A, d2);
+   s2 = boost::move(s1);
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s1.get() == 0);
+   BOOST_TEST(A::count == 1);
+   BOOST_TEST(d1.state() == 5);
+   BOOST_TEST(d2.state() == 5);
+   }
+   BOOST_TEST(A::count == 0);
+
+   //Unbounded array unique_ptr
+   reset_counters();
+   {
+   copy_constr_deleter<A[]> d1(5);
+   bml::unique_ptr<A[], copy_constr_deleter<A[]>&> s1(new A[2], d1);
+   A* p = s1.get();
+   copy_constr_deleter<A[]> d2(6);
+   bml::unique_ptr<A[], copy_constr_deleter<A[]>&> s2(new A[2], d2);
+   BOOST_TEST(A::count == 4);
+   s2 = boost::move(s1);
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s1.get() == 0);
+   BOOST_TEST(A::count == 2);
+   BOOST_TEST(d1.state() == 5);
+   BOOST_TEST(d2.state() == 5);
+   }
+   BOOST_TEST(A::count == 0);
+   //Bounded array unique_ptr
+   reset_counters();
+   {
+   copy_constr_deleter<A[2]> d1(5);
+   bml::unique_ptr<A[2], copy_constr_deleter<A[2]>&> s1(new A[2], d1);
+   A* p = s1.get();
+   copy_constr_deleter<A[2]> d2(6);
+   bml::unique_ptr<A[2], copy_constr_deleter<A[2]>&> s2(new A[2], d2);
+   BOOST_TEST(A::count == 4);
+   s2 = boost::move(s1);
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s1.get() == 0);
+   BOOST_TEST(A::count == 2);
+   BOOST_TEST(d1.state() == 5);
+   BOOST_TEST(d2.state() == 5);
+   }
+   BOOST_TEST(A::count == 0);
+}
+
+}  //unique_ptr_asgn_move_copydelref
+
+////////////////////////////////
+//             main
+////////////////////////////////
+int main()
+{
+   //Assignment
+   unique_ptr_asgn_move_convert_defdel::test();
+   unique_ptr_asgn_move_convert_movedel::test();
+   unique_ptr_asgn_move_convert_copydelref::test();
+   unique_ptr_asgn_move_defdel::test();
+   unique_ptr_asgn_move_movedel::test();
+   unique_ptr_asgn_move_copydelref::test();
+
+   //Test results
+   return boost::report_errors();
+}
+
+#include "unique_ptr_test_utils_end.hpp"
diff --git a/test/unique_ptr_ctordtor.cpp b/test/unique_ptr_ctordtor.cpp
new file mode 100644
index 0000000..a583b92
--- /dev/null
+++ b/test/unique_ptr_ctordtor.cpp
@@ -0,0 +1,811 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Howard Hinnant 2009
+// (C) Copyright Ion Gaztanaga 2014-2014.
+//
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/move/utility_core.hpp>
+#include <boost/move/unique_ptr.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+//////////////////////////////////////////////
+//
+// The initial implementation of these tests
+// was written by Howard Hinnant. 
+//
+// These test were later refactored grouping
+// and porting them to Boost.Move.
+//
+// Many thanks to Howard for releasing his C++03
+// unique_ptr implementation with such detailed
+// test cases.
+//
+//////////////////////////////////////////////
+
+#include "unique_ptr_test_utils_beg.hpp"
+
+namespace bml = ::boost::movelib;
+
+////////////////////////////////
+//   unique_ptr_dtor_null
+////////////////////////////////
+
+namespace unique_ptr_dtor_null{
+
+// The deleter is not called if get() == 0
+
+void test()
+{
+   //Single unique_ptr
+   {
+   def_constr_deleter<int> d;
+   BOOST_TEST(d.state() == 5);
+   {
+   bml::unique_ptr<int, def_constr_deleter<int>&> p(0, d);
+   BOOST_TEST(p.get() == 0);
+   BOOST_TEST(&p.get_deleter() == &d);
+   }
+   BOOST_TEST(d.state() == 5);
+   }
+   {
+   //Unbounded array unique_ptr
+   def_constr_deleter<int[]> d;
+   BOOST_TEST(d.state() == 5);
+   {
+   bml::unique_ptr<int[], def_constr_deleter<int[]>&> p(0, d);
+   BOOST_TEST(p.get() == 0);
+   BOOST_TEST(&p.get_deleter() == &d);
+   }
+   BOOST_TEST(d.state() == 5);
+   }
+   {
+   //Bounded array unique_ptr
+   def_constr_deleter<int[2]> d;
+   BOOST_TEST(d.state() == 5);
+   {
+   bml::unique_ptr<int[2], def_constr_deleter<int[2]>&> p(0, d);
+   BOOST_TEST(p.get() == 0);
+   BOOST_TEST(&p.get_deleter() == &d);
+   }
+   BOOST_TEST(d.state() == 5);
+   }
+}
+
+}  //namespace unique_ptr_dtor_null{
+
+////////////////////////////////
+//   unique_ptr_ctor_default_delreq
+////////////////////////////////
+
+namespace unique_ptr_ctor_default_delreq{
+
+// default unique_ptr ctor should only require default deleter ctor
+
+void test()
+{
+   //Single unique_ptr
+   {
+   bml::unique_ptr<int> p;
+   BOOST_TEST(p.get() == 0);
+   }
+   {
+   bml::unique_ptr<int, def_constr_deleter<int> > p;
+   BOOST_TEST(p.get() == 0);
+   BOOST_TEST(p.get_deleter().state() == 5);
+   }
+   //Unbounded array unique_ptr
+   {
+   bml::unique_ptr<int[]> p;
+   BOOST_TEST(p.get() == 0);
+   }
+   {
+   bml::unique_ptr<int[], def_constr_deleter<int[]> > p;
+   BOOST_TEST(p.get() == 0);
+   BOOST_TEST(p.get_deleter().state() == 5);
+   }
+
+   //Unbounded array unique_ptr
+   {
+   bml::unique_ptr<int[]> p;
+   BOOST_TEST(p.get() == 0);
+   }
+   {
+   bml::unique_ptr<int[], def_constr_deleter<int[]> > p;
+   BOOST_TEST(p.get() == 0);
+   BOOST_TEST(p.get_deleter().state() == 5);
+   }
+
+   //Unbounded array unique_ptr
+   {
+   bml::unique_ptr<int[2]> p;
+   BOOST_TEST(p.get() == 0);
+   }
+   {
+   bml::unique_ptr<int[2], def_constr_deleter<int[2]> > p;
+   BOOST_TEST(p.get() == 0);
+   BOOST_TEST(p.get_deleter().state() == 5);
+   }
+}
+
+}  //namespace unique_ptr_ctor_default_delreq{
+
+////////////////////////////////
+//   unique_ptr_ctor_default_nocomplete
+////////////////////////////////
+
+namespace unique_ptr_ctor_default_nocomplete{
+
+// default unique_ptr ctor shouldn't require complete type
+
+void test()
+{
+   //Single unique_ptr
+   reset_counters();
+   {
+   J<I> s;
+   BOOST_TEST(s.get() == 0);
+   }
+   check(0);
+   {
+   J<I, def_constr_deleter<I> > s;
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   }
+   check(0);
+   //Unbounded array unique_ptr
+   reset_counters();
+   {
+   J<I[]> s;
+   BOOST_TEST(s.get() == 0);
+   }
+   check(0);
+   {
+   J<I[], def_constr_deleter<I[]> > s;
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   }
+   check(0);
+
+   //Bounded array unique_ptr
+   reset_counters();
+   {
+   J<I[2]> s;
+   BOOST_TEST(s.get() == 0);
+   }
+   check(0);
+   {
+   J<I[2], def_constr_deleter<I[2]> > s;
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   }
+   check(0);
+}
+
+}  //namespace unique_ptr_ctor_default_nocomplete{
+
+////////////////////////////////
+//   unique_ptr_ctor_pointer_delreq
+////////////////////////////////
+
+namespace unique_ptr_ctor_pointer_delreq{
+
+// unique_ptr(pointer) ctor should only require default deleter ctor
+
+void test()
+{
+   //Single unique_ptr
+   reset_counters();
+   {
+   A* p = new A;
+   BOOST_TEST(A::count == 1);
+   bml::unique_ptr<A> s(p);
+   BOOST_TEST(s.get() == p);
+   }
+   BOOST_TEST(A::count == 0);
+   {
+   A* p = new A;
+   BOOST_TEST(A::count == 1);
+   bml::unique_ptr<A, def_constr_deleter<A> > s(p);
+   BOOST_TEST(s.get() == p);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   }
+   BOOST_TEST(A::count == 0);
+   //Unbounded array unique_ptr
+   reset_counters();
+   {
+   A* p = new A[2];
+   BOOST_TEST(A::count == 2);
+   bml::unique_ptr<A[]> s(p);
+   BOOST_TEST(s.get() == p);
+   }
+   BOOST_TEST(A::count == 0);
+   {
+   A* p = new A[2];
+   BOOST_TEST(A::count == 2);
+   bml::unique_ptr<A[], def_constr_deleter<A[]> > s(p);
+   BOOST_TEST(s.get() == p);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   }
+   BOOST_TEST(A::count == 0);
+   //Bounded array unique_ptr
+   reset_counters();
+   {
+   A* p = new A[2];
+   BOOST_TEST(A::count == 2);
+   bml::unique_ptr<A[2]> s(p);
+   BOOST_TEST(s.get() == p);
+   }
+   BOOST_TEST(A::count == 0);
+   {
+   A* p = new A[2];
+   BOOST_TEST(A::count == 2);
+   bml::unique_ptr<A[2], def_constr_deleter<A[2]> > s(p);
+   BOOST_TEST(s.get() == p);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   }
+   BOOST_TEST(A::count == 0);
+}
+
+}  //namespace unique_ptr_ctor_pointer_delreq{
+
+////////////////////////////////
+//   unique_ptr_ctor_pointer_nocomplete
+////////////////////////////////
+
+namespace unique_ptr_ctor_pointer_nocomplete{
+
+// unique_ptr(pointer) ctor shouldn't require complete type
+
+void test()
+{
+   //Single unique_ptr
+   reset_counters();
+   {
+   I* p = get();
+   check(1);
+   J<I> s(p);
+   BOOST_TEST(s.get() == p);
+   }
+   check(0);
+   {
+   I* p = get();
+   check(1);
+   J<I, def_constr_deleter<I> > s(p);
+   BOOST_TEST(s.get() == p);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   }
+   check(0);
+   //Unbounded array unique_ptr
+   reset_counters();
+   {
+   I* p = get_array(2);
+   check(2);
+   J<I[]> s(p);
+   BOOST_TEST(s.get() == p);
+   }
+   check(0);
+   {
+   I* p = get_array(2);
+   check(2);
+   J<I[], def_constr_deleter<I[]> > s(p);
+   BOOST_TEST(s.get() == p);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   }
+   check(0);
+   //Bounded array unique_ptr
+   reset_counters();
+   {
+   I* p = get_array(2);
+   check(2);
+   J<I[]> s(p);
+   BOOST_TEST(s.get() == p);
+   }
+   check(0);
+   {
+   I* p = get_array(2);
+   check(2);
+   J<I[2], def_constr_deleter<I[2]> > s(p);
+   BOOST_TEST(s.get() == p);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   }
+   check(0);
+}
+
+}  //namespace unique_ptr_ctor_pointer_nocomplete{
+
+////////////////////////////////
+//   unique_ptr_ctor_pointer_convert
+////////////////////////////////
+
+namespace unique_ptr_ctor_pointer_convert{
+
+// unique_ptr(pointer) ctor should work with derived pointers
+// or same types (cv aside) for unique_ptr<arrays>
+
+void test()
+{
+   //Single unique_ptr
+   reset_counters();
+   {
+   B* p = new B;
+   BOOST_TEST(A::count == 1);
+   BOOST_TEST(B::count == 1);
+   bml::unique_ptr<A> s(p);
+   BOOST_TEST(s.get() == p);
+   }
+   BOOST_TEST(A::count == 0);
+   BOOST_TEST(B::count == 0);
+   {
+   B* p = new B;
+   BOOST_TEST(A::count == 1);
+   BOOST_TEST(B::count == 1);
+   bml::unique_ptr<A, def_constr_deleter<A> > s(p);
+   BOOST_TEST(s.get() == p);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   }
+   BOOST_TEST(A::count == 0);
+   BOOST_TEST(B::count == 0);
+   //Unbounded array unique_ptr
+   reset_counters();
+   {
+   A* p = new A[2];
+   BOOST_TEST(A::count == 2);
+   bml::unique_ptr<const A[]> s(p);
+   BOOST_TEST(s.get() == p);
+   }
+   BOOST_TEST(A::count == 0);
+   {
+   const A* p = new const A[2];
+   BOOST_TEST(A::count == 2);
+   bml::unique_ptr<const volatile A[], def_constr_deleter<const volatile A[]> > s(p);
+   BOOST_TEST(s.get() == p);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   }
+   BOOST_TEST(A::count == 0);
+   //Bounded array unique_ptr
+   reset_counters();
+   {
+   A* p = new A[2];
+   BOOST_TEST(A::count == 2);
+   bml::unique_ptr<const A[2]> s(p);
+   BOOST_TEST(s.get() == p);
+   }
+   BOOST_TEST(A::count == 0);
+   {
+   const A* p = new const A[2];
+   BOOST_TEST(A::count == 2);
+   bml::unique_ptr<const volatile A[2], def_constr_deleter<const volatile A[2]> > s(p);
+   BOOST_TEST(s.get() == p);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   }
+   BOOST_TEST(A::count == 0);
+}
+
+}  //namespace unique_ptr_ctor_pointer_convert{
+
+////////////////////////////////
+//   unique_ptr_ctor_pointer_deleter_movedel
+////////////////////////////////
+
+namespace unique_ptr_ctor_pointer_deleter_movedel{
+
+// test move ctor.  Should only require a MoveConstructible deleter, or if
+//    deleter is a reference, not even that.
+
+// unique_ptr(pointer, deleter()) only requires MoveConstructible deleter
+
+void test()
+{
+   //Single unique_ptr
+   reset_counters();
+   {
+   A* p = new A;
+   BOOST_TEST(A::count == 1);
+   move_constr_deleter<A> d;
+   bml::unique_ptr<A, move_constr_deleter<A> > s(p, ::boost::move(d));
+   BOOST_TEST(s.get() == p);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   bml::unique_ptr<A, move_constr_deleter<A> > s2(s.release(), move_constr_deleter<A>(6));
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s2.get_deleter().state() == 6);
+   }
+   BOOST_TEST(A::count == 0);
+   //Unbounded array unique_ptr
+   reset_counters();
+   {
+   A* p = new A[2];
+   BOOST_TEST(A::count == 2);
+   move_constr_deleter<A[]> d;
+   bml::unique_ptr<A[], move_constr_deleter<A[]> > s(p, ::boost::move(d));
+   BOOST_TEST(s.get() == p);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   bml::unique_ptr<A[], move_constr_deleter<A[]> > s2(s.release(), move_constr_deleter<A[]>(6));
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s2.get_deleter().state() == 6);
+   }
+   BOOST_TEST(A::count == 0);
+   //Bounded array unique_ptr
+   reset_counters();
+   {
+   A* p = new A[2];
+   BOOST_TEST(A::count == 2);
+   move_constr_deleter<A[2]> d;
+   bml::unique_ptr<A[2], move_constr_deleter<A[2]> > s(p, ::boost::move(d));
+   BOOST_TEST(s.get() == p);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   bml::unique_ptr<A[2], move_constr_deleter<A[2]> > s2(s.release(), move_constr_deleter<A[2]>(6));
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s2.get_deleter().state() == 6);
+   }
+   BOOST_TEST(A::count == 0);
+}
+
+}  //namespace unique_ptr_ctor_pointer_deleter_movedel{
+
+////////////////////////////////
+//   unique_ptr_ctor_pointer_deleter_copydel
+////////////////////////////////
+
+namespace unique_ptr_ctor_pointer_deleter_copydel{
+
+// unique_ptr(pointer, d) requires CopyConstructible deleter
+
+void test()
+{
+   //Single unique_ptr
+   reset_counters();
+   {
+   A* p = new A;
+   BOOST_TEST(A::count == 1);
+   copy_constr_deleter<A> d;
+   bml::unique_ptr<A, copy_constr_deleter<A> > s(p, d);
+   BOOST_TEST(s.get() == p);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   d.set_state(6);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   }
+   BOOST_TEST(A::count == 0);
+   //Unbounded array unique_ptr
+   reset_counters();
+   {
+   A* p = new A[2];
+   BOOST_TEST(A::count == 2);
+   copy_constr_deleter<A[]> d;
+   bml::unique_ptr<A[], copy_constr_deleter<A[]> > s(p, d);
+   BOOST_TEST(s.get() == p);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   d.set_state(6);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   }
+   BOOST_TEST(A::count == 0);
+   //Bounded array unique_ptr
+   reset_counters();
+   {
+   A* p = new A[2];
+   BOOST_TEST(A::count == 2);
+   copy_constr_deleter<A[2]> d;
+   bml::unique_ptr<A[2], copy_constr_deleter<A[2]> > s(p, d);
+   BOOST_TEST(s.get() == p);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   d.set_state(6);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   }
+   BOOST_TEST(A::count == 0);
+}
+
+}  //namespace unique_ptr_ctor_pointer_deleter_copydel{
+
+////////////////////////////////
+//   unique_ptr_ctor_pointer_deleter_dfctrdelref
+////////////////////////////////
+
+namespace unique_ptr_ctor_pointer_deleter_dfctrdelref{
+
+// unique_ptr<T, D&>(pointer, d) does not requires CopyConstructible deleter
+
+void test()
+{
+   //Single unique_ptr
+   reset_counters();
+   {
+   A* p = new A;
+   BOOST_TEST(A::count == 1);
+   def_constr_deleter<A> d;
+   bml::unique_ptr<A, def_constr_deleter<A>&> s(p, d);
+   BOOST_TEST(s.get() == p);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   d.set_state(6);
+   BOOST_TEST(s.get_deleter().state() == 6);
+   }
+   BOOST_TEST(A::count == 0);
+   //Unbounded array unique_ptr
+   reset_counters();
+   {
+   A* p = new A[2];
+   BOOST_TEST(A::count == 2);
+   def_constr_deleter<A[]> d;
+   bml::unique_ptr<A[], def_constr_deleter<A[]>&> s(p, d);
+   BOOST_TEST(s.get() == p);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   d.set_state(6);
+   BOOST_TEST(s.get_deleter().state() == 6);
+   }
+   BOOST_TEST(A::count == 0);
+   //Bounded array unique_ptr
+   reset_counters();
+   {
+   A* p = new A[2];
+   BOOST_TEST(A::count == 2);
+   def_constr_deleter<A[2]> d;
+   bml::unique_ptr<A[2], def_constr_deleter<A[2]>&> s(p, d);
+   BOOST_TEST(s.get() == p);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   d.set_state(6);
+   BOOST_TEST(s.get_deleter().state() == 6);
+   }
+   BOOST_TEST(A::count == 0);
+}
+
+}  //namespace unique_ptr_ctor_pointer_deleter_dfctrdelref{
+
+////////////////////////////////
+//   unique_ptr_ctor_pointer_deleter_dfctrdelconstref
+////////////////////////////////
+
+namespace unique_ptr_ctor_pointer_deleter_dfctrdelconstref{
+
+// unique_ptr<T, const D&>(pointer, d) does not requires CopyConstructible deleter
+
+void test()
+{
+   //Single unique_ptr
+   reset_counters();
+   {
+   A* p = new A;
+   BOOST_TEST(A::count == 1);
+   def_constr_deleter<A> d;
+   bml::unique_ptr<A, const def_constr_deleter<A>&> s(p, d);
+   BOOST_TEST(s.get() == p);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   }
+   BOOST_TEST(A::count == 0);
+   //Unbounded array unique_ptr
+   reset_counters();
+   {
+   A* p = new A[2];
+   BOOST_TEST(A::count == 2);
+   def_constr_deleter<A[]> d;
+   bml::unique_ptr<A[], const def_constr_deleter<A[]>&> s(p, d);
+   BOOST_TEST(s.get() == p);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   }
+   BOOST_TEST(A::count == 0);
+   //Bounded array unique_ptr
+   reset_counters();
+   {
+   A* p = new A[2];
+   BOOST_TEST(A::count == 2);
+   def_constr_deleter<A[2]> d;
+   bml::unique_ptr<A[2], const def_constr_deleter<A[2]>&> s(p, d);
+   BOOST_TEST(s.get() == p);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   }
+   BOOST_TEST(A::count == 0);
+}
+
+}  //namespace unique_ptr_ctor_pointer_deleter_dfctrdelconstref{
+
+////////////////////////////////
+//   unique_ptr_ctor_pointer_deleter_convert
+////////////////////////////////
+
+namespace unique_ptr_ctor_pointer_deleter_convert{
+
+// unique_ptr(pointer, deleter) should work with derived pointers
+// or same (cv aside) types for array unique_ptrs
+
+void test()
+{
+   //Single unique_ptr
+   reset_counters();
+   {
+   B* p = new B;
+   BOOST_TEST(A::count == 1);
+   BOOST_TEST(B::count == 1);
+   bml::unique_ptr<A, copy_constr_deleter<A> > s(p, copy_constr_deleter<A>());
+   BOOST_TEST(s.get() == p);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   }
+   BOOST_TEST(A::count == 0);
+   BOOST_TEST(B::count == 0);
+   //Unbounded array unique_ptr
+   reset_counters();
+   {
+   A* p = new A[2];
+   BOOST_TEST(A::count == 2);
+   bml::unique_ptr<const A[], copy_constr_deleter<const A[]> > s(p, copy_constr_deleter<const A[]>());
+   BOOST_TEST(s.get() == p);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   }
+   BOOST_TEST(A::count == 0);
+   BOOST_TEST(B::count == 0);
+   //Bounded array unique_ptr
+   reset_counters();
+   {
+   A* p = new A[2];
+   BOOST_TEST(A::count == 2);
+   bml::unique_ptr<const A[2], copy_constr_deleter<const A[2]> > s(p, copy_constr_deleter<const A[2]>());
+   BOOST_TEST(s.get() == p);
+   BOOST_TEST(s.get_deleter().state() == 5);
+   }
+   BOOST_TEST(A::count == 0);
+   BOOST_TEST(B::count == 0);
+}
+
+}  //namespace unique_ptr_ctor_pointer_deleter_convert{
+
+////////////////////////////////
+//   unique_ptr_ctor_pointer_deleter_void
+////////////////////////////////
+
+namespace unique_ptr_ctor_pointer_deleter_void{
+
+// unique_ptr(pointer, deleter) should work with function pointers
+// unique_ptr<void> should work
+
+bool my_free_called = false;
+
+void my_free(void*)
+{
+    my_free_called = true;
+}
+
+void test()
+{
+   {
+   int i = 0;
+   bml::unique_ptr<void, void (*)(void*)> s(&i, my_free);
+   BOOST_TEST(s.get() == &i);
+   BOOST_TEST(s.get_deleter() == my_free);
+   BOOST_TEST(!my_free_called);
+   }
+   BOOST_TEST(my_free_called);
+}
+
+}  //namespace unique_ptr_ctor_pointer_deleter_void{
+
+////////////////////////////////
+//   return_unique_single_conversion
+////////////////////////////////
+
+namespace return_unique_single_conversion{
+
+template<class T>
+bml::unique_ptr<T> make_unique_ptr_of_t()
+{
+   return bml::unique_ptr<T>(new T);
+}
+
+template<class T>
+bml::unique_ptr<T const> return_const_unique_of_t()
+{
+   return bml::unique_ptr<T const> (make_unique_ptr_of_t<T>());
+} 
+
+void test()
+{
+   reset_counters();
+   BOOST_TEST(A::count == 0);
+   {
+   bml::unique_ptr<const A> p(return_const_unique_of_t<A>());
+   BOOST_TEST(A::count == 1);
+   BOOST_TEST(B::count == 0);
+   }
+   BOOST_TEST(A::count == 0);
+   {
+   bml::unique_ptr<const A> p(return_const_unique_of_t<B>());
+   BOOST_TEST(A::count == 1);
+   BOOST_TEST(B::count == 1);
+   }
+   BOOST_TEST(A::count == 0);
+}
+
+}  //namespace return_unique_single_conversion{
+
+
+////////////////////////////////
+//   return_unique_array_conversion
+////////////////////////////////
+
+namespace return_unique_array_conversion{
+
+template<class T>
+bml::unique_ptr<T[]> return_unique_array_of_t(std::size_t n)
+{
+   return bml::unique_ptr<T[]>(new T[n]);
+}
+
+template<class T>
+bml::unique_ptr<const T[]> return_const_array_of_t(std::size_t n)
+{
+   return bml::unique_ptr<const T[]>(return_unique_array_of_t<T>(n));
+} 
+
+template<class T>
+bml::unique_ptr<T[2]> return_unique_array_of_t_2()
+{
+   return bml::unique_ptr<T[2]>(new T[2]);
+}
+
+template<class T>
+bml::unique_ptr<const T[2]> return_const_array_of_t_2()
+{
+   return bml::unique_ptr<const T[2]>(return_unique_array_of_t_2<T>());
+} 
+
+void test()
+{
+   reset_counters();
+   BOOST_TEST(A::count == 0);
+   {
+   bml::unique_ptr<const A[]> p(return_unique_array_of_t<A>(2));
+   BOOST_TEST(A::count == 2);
+   BOOST_TEST(B::count == 0);
+   }
+   BOOST_TEST(A::count == 0);
+   {
+   bml::unique_ptr<const volatile A[]> p(return_unique_array_of_t<volatile A>(2));
+   BOOST_TEST(A::count == 2);
+   BOOST_TEST(B::count == 0);
+   }
+   BOOST_TEST(A::count == 0);
+   {
+   bml::unique_ptr<const volatile A[2]> p(return_const_array_of_t_2<A>());
+   BOOST_TEST(A::count == 2);
+   BOOST_TEST(B::count == 0);
+   }
+   BOOST_TEST(A::count == 0);
+   {
+   bml::unique_ptr<const volatile A[]> p(return_const_array_of_t_2<A>());
+   BOOST_TEST(A::count == 2);
+   BOOST_TEST(B::count == 0);
+   }
+   BOOST_TEST(A::count == 0);
+}
+
+}  //namespace return_unique_array_conversion{
+
+////////////////////////////////
+//             main
+////////////////////////////////
+int main()
+{
+   //Constructors/Destructor
+   unique_ptr_dtor_null::test();
+   unique_ptr_ctor_default_delreq::test();
+   unique_ptr_ctor_default_nocomplete::test();
+   unique_ptr_ctor_pointer_delreq::test();
+   unique_ptr_ctor_pointer_nocomplete::test();
+   unique_ptr_ctor_pointer_convert::test();
+   unique_ptr_ctor_pointer_deleter_movedel::test();
+   unique_ptr_ctor_pointer_deleter_copydel::test();
+   unique_ptr_ctor_pointer_deleter_dfctrdelref::test();
+   unique_ptr_ctor_pointer_deleter_dfctrdelconstref::test();
+   unique_ptr_ctor_pointer_deleter_convert::test();
+   unique_ptr_ctor_pointer_deleter_void::test();
+   return_unique_single_conversion::test();
+   return_unique_array_conversion::test();
+
+   //Test results
+   return boost::report_errors();
+
+}
+
+#include "unique_ptr_test_utils_end.hpp"
diff --git a/test/unique_ptr_default_deleter.cpp b/test/unique_ptr_default_deleter.cpp
new file mode 100644
index 0000000..1bf16ea
--- /dev/null
+++ b/test/unique_ptr_default_deleter.cpp
@@ -0,0 +1,204 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Howard Hinnant 2009
+// (C) Copyright Ion Gaztanaga 2014-2014.
+//
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/move/default_delete.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+//////////////////////////////////////////////
+//
+// The initial implementation of these tests
+// was written by Howard Hinnant. 
+//
+// These test were later refactored grouping
+// and porting them to Boost.Move.
+//
+// Many thanks to Howard for releasing his C++03
+// unique_ptr implementation with such detailed
+// test cases.
+//
+//////////////////////////////////////////////
+
+////////////////////////////////
+//   unique_ptr_dltr_dflt_convert_ctor
+////////////////////////////////
+
+namespace bml = ::boost::movelib;
+
+struct A
+{
+   static int count;
+   A() {++count;}
+   A(const A&) {++count;}
+   virtual ~A() {--count;}
+};
+
+int A::count = 0;
+
+struct B
+   : public A
+{
+   static int count;
+   B() : A() {++count;}
+   B(const B&) : A() {++count;}
+   virtual ~B() {--count;}
+};
+
+int B::count = 0;
+
+void reset_counters()
+{  A::count = B::count = 0;  }
+
+namespace unique_ptr_dltr_dflt_convert_ctor{
+
+void test()
+{
+   //Single element deleter
+   {
+   reset_counters();
+   bml::default_delete<B> d2;
+   bml::default_delete<A> d1 = d2;
+   A* p = new B;
+   BOOST_TEST(A::count == 1);
+   BOOST_TEST(B::count == 1);
+   d1(p);
+   BOOST_TEST(A::count == 0);
+   BOOST_TEST(B::count == 0);
+   }
+   //Array element deleter
+   {
+   reset_counters();
+   bml::default_delete<A[]> d2;
+   bml::default_delete<const A[]> d1 = d2;
+   const A* p = new const A[2];
+   BOOST_TEST(A::count == 2);
+   d1(p);
+   BOOST_TEST(A::count == 0);
+   }
+   //Bounded array element deleter
+   {
+   reset_counters();
+   bml::default_delete<A[2]> d2;
+   bml::default_delete<const A[2]> d1 = d2;
+   const A* p = new const A[2];
+   BOOST_TEST(A::count == 2);
+   d1(p);
+   bml::default_delete<const A[]> d0 = d1;
+   d0(0);
+   BOOST_TEST(A::count == 0);
+   }
+}
+
+}  //namespace unique_ptr_dltr_dflt_convert_ctor{
+
+////////////////////////////////
+//   unique_ptr_dltr_dflt_convert_assign
+////////////////////////////////
+
+namespace unique_ptr_dltr_dflt_convert_assign{
+
+void test()
+{
+   //Single element deleter
+   {
+   reset_counters();
+   bml::default_delete<B> d2;
+   bml::default_delete<A> d1;
+   d1 = d2;
+   A* p = new B;
+   BOOST_TEST(A::count == 1);
+   BOOST_TEST(B::count == 1);
+   d1(p);
+   BOOST_TEST(A::count == 0);
+   BOOST_TEST(B::count == 0);
+   }
+   //Array element deleter
+   {
+   reset_counters();
+   bml::default_delete<A[]> d2;
+   bml::default_delete<const A[]> d1;
+   d1 = d2;
+   const A* p = new const A[2];
+   BOOST_TEST(A::count == 2);
+   d1(p);
+   BOOST_TEST(A::count == 0);
+   }
+   //Bounded array element deleter
+   {
+   reset_counters();
+   bml::default_delete<A[2]> d2;
+   bml::default_delete<const A[2]> d1;
+   d1 = d2;
+   const A* p = new const A[2];
+   BOOST_TEST(A::count == 2);
+   d1(p);
+   bml::default_delete<const A[]> d0;
+   d0 = d1;
+   d0(0);
+   BOOST_TEST(A::count == 0);
+   }
+}
+
+}  //namespace unique_ptr_dltr_dflt_convert_assign{
+
+
+////////////////////////////////
+//   unique_ptr_dltr_dflt_default
+////////////////////////////////
+
+namespace unique_ptr_dltr_dflt_default{
+
+void test()
+{
+   {
+   //Single element deleter
+   reset_counters();
+   bml::default_delete<A> d;
+   A* p = new A;
+   BOOST_TEST(A::count == 1);
+   d(p);
+   BOOST_TEST(A::count == 0);
+   }
+   {
+   //Array element deleter
+   reset_counters();
+   bml::default_delete<A[]> d;
+   A* p = new A[2];
+   BOOST_TEST(A::count == 2);
+   d(p);
+   BOOST_TEST(A::count == 0);
+   }
+
+   {
+   //Bounded Array element deleter
+   reset_counters();
+   bml::default_delete<A[10]> d;
+   A* p = new A[10];
+   BOOST_TEST(A::count == 10);
+   d(p);
+   BOOST_TEST(A::count == 0);
+   }
+}
+
+}  //namespace unique_ptr_dltr_dflt_default{
+
+////////////////////////////////
+//             main
+////////////////////////////////
+int main()
+{
+   unique_ptr_dltr_dflt_convert_ctor::test();
+   unique_ptr_dltr_dflt_convert_assign::test();
+   unique_ptr_dltr_dflt_default::test();
+
+   //Test results
+   return boost::report_errors();
+}
diff --git a/test/unique_ptr_functions.cpp b/test/unique_ptr_functions.cpp
new file mode 100644
index 0000000..d3b4d6d
--- /dev/null
+++ b/test/unique_ptr_functions.cpp
@@ -0,0 +1,395 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2014.
+//
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/move/make_unique.hpp>
+#include <boost/core/lightweight_test.hpp>
+#include <cstring>
+
+struct A
+{
+   int a, b, c;
+   static int count;
+   A() : a (999), b(1000), c(1001) {++count;}
+   A(int a) : a (a), b(1000), c(1001) {++count;}
+   A(int a, int b) : a (a), b(b), c(1001) {++count;}
+   A(int a, int b, int c) : a (a), b(b), c(c) {++count;}
+   A(const A&) {++count;}
+   virtual ~A() {--count;}
+};
+
+int A::count = 0;
+
+struct B
+   : public A
+{
+   static int count;
+   B() : A() {++count;}
+   B(const B&) : A() {++count;}
+   virtual ~B() {--count;}
+};
+
+int B::count = 0;
+
+void reset_counters()
+{  A::count = B::count = 0;  }
+
+static const unsigned PatternSize = 8;
+static const unsigned char ff_patternbuf[PatternSize] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+static const unsigned char ee_patternbuf[PatternSize] = { 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE };
+static const unsigned char dd_patternbuf[PatternSize] = { 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD };
+static const unsigned char cc_patternbuf[PatternSize] = { 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC };
+
+void volatile_memset(volatile void *p, int ch, std::size_t len)
+{
+   volatile unsigned char *puch = static_cast<volatile unsigned char *>(p);
+   for(std::size_t i = 0; i != len; ++i){
+      *puch = (unsigned char)ch;
+      ++puch;
+   }
+}
+
+int volatile_memcmp(const volatile void *p1, const volatile void *p2, std::size_t len)
+{
+   const volatile unsigned char *s1 = static_cast<const volatile unsigned char *>(p1);
+   const volatile unsigned char *s2 = static_cast<const volatile unsigned char *>(p2);
+   unsigned char u1, u2;
+
+   for ( ; len-- ; s1++, s2++) {
+      u1 = *s1;
+      u2 = *s2;
+      if (u1 != u2) {
+         return (u1-u2);
+      }
+   }
+   return 0;
+}
+
+void volatile_memcmp(volatile void *p, int ch, std::size_t len)
+{
+   volatile unsigned char *puch = static_cast<volatile unsigned char *>(p);
+   for(std::size_t i = 0; i != len; ++i){
+      *puch = (unsigned char)ch;
+      ++puch;
+   }
+}
+
+#include <iostream>
+
+struct default_init
+{
+   static void* operator new(std::size_t sz)
+   {
+      void *const p = ::operator new(sz);
+      //Make sure they are not optimized out
+      volatile_memset(p, 0xFF, sz);
+      std::cout << "0xFF" << '\n';
+      return p;
+   }
+   static void* operator new[](std::size_t sz)
+   {
+      void *const p = ::operator new[](sz);
+      //Make sure they are not optimized out
+      volatile_memset(p, 0xEE, sz);
+      std::cout << "0xEE" << '\n';
+      return p;
+   }
+   static void* operator new(std::size_t sz, const std::nothrow_t &)
+   {
+      void *const p = ::operator new(sz);
+      //Make sure they are not optimized out
+      volatile_memset(p, 0xDD, sz);
+      std::cout << "0xDD" << '\n';
+      return p;
+   }
+   static void* operator new[](std::size_t sz, const std::nothrow_t &)
+   {
+      void *const p = ::operator new[](sz);
+      //Make sure they are not optimized out
+      volatile_memset(p, 0xCC, sz);
+      std::cout << "0xCC" << '\n';
+      return p;
+   }
+   unsigned char buf[PatternSize];
+};
+
+namespace bml = ::boost::movelib;
+
+////////////////////////////////
+//   make_unique_single
+////////////////////////////////
+
+namespace make_unique_single{
+
+void test()
+{
+   //Single element deleter
+   reset_counters();
+   {
+   bml::unique_ptr<default_init> p(bml::make_unique_definit<default_init>());
+   BOOST_TEST(0 == volatile_memcmp(p.get(), ff_patternbuf, sizeof(ff_patternbuf)));
+   }
+   {
+   bml::unique_ptr<default_init> p(bml::make_unique_nothrow_definit<default_init>());
+   
+   BOOST_TEST(0 == volatile_memcmp(p.get(), dd_patternbuf, sizeof(dd_patternbuf)));
+   }
+
+   BOOST_TEST(A::count == 0);
+   {
+   bml::unique_ptr<A> p(bml::make_unique<A>());
+   BOOST_TEST(A::count == 1);
+   BOOST_TEST(p->a == 999);
+   BOOST_TEST(p->b == 1000);
+   BOOST_TEST(p->c == 1001);
+   }
+   BOOST_TEST(A::count == 0);
+   {
+   bml::unique_ptr<A> p(bml::make_unique_nothrow<A>(0));
+   BOOST_TEST(A::count == 1);
+   BOOST_TEST(p->a == 0);
+   BOOST_TEST(p->b == 1000);
+   BOOST_TEST(p->c == 1001);
+   }
+   BOOST_TEST(A::count == 0);
+   {
+   bml::unique_ptr<A> p(bml::make_unique<A>(0, 1));
+   BOOST_TEST(A::count == 1);
+   BOOST_TEST(p->a == 0);
+   BOOST_TEST(p->b == 1);
+   BOOST_TEST(p->c == 1001);
+   }
+   BOOST_TEST(A::count == 0);
+   {
+   bml::unique_ptr<A> p(bml::make_unique_nothrow<A>(0, 1, 2));
+   BOOST_TEST(A::count == 1);
+   BOOST_TEST(p->a == 0);
+   BOOST_TEST(p->b == 1);
+   BOOST_TEST(p->c == 2);
+   }
+   BOOST_TEST(A::count == 0);
+}
+
+}  //namespace make_unique_single{
+
+
+////////////////////////////////
+//    make_unique_array
+////////////////////////////////
+
+namespace make_unique_array{
+
+void test()
+{
+   //Array element
+   reset_counters();
+   {
+      bml::unique_ptr<A[]> p(bml::make_unique<A[]>(10));
+      BOOST_TEST(A::count == 10);
+      for(int i = 0; i != 10; ++i){
+         BOOST_TEST(p[i].a == 999);
+         BOOST_TEST(p[i].b == 1000);
+         BOOST_TEST(p[i].c == 1001);
+      }
+   }
+   BOOST_TEST(A::count == 0);
+   {
+      bml::unique_ptr<A[]> p(bml::make_unique_nothrow<A[]>(10));
+      BOOST_TEST(A::count == 10);
+      for(int i = 0; i != 10; ++i){
+         BOOST_TEST(p[i].a == 999);
+         BOOST_TEST(p[i].b == 1000);
+         BOOST_TEST(p[i].c == 1001);
+      }
+   }
+   BOOST_TEST(A::count == 0);
+   reset_counters();
+   {
+      bml::unique_ptr<default_init[]> p(bml::make_unique_definit<default_init[]>(10));
+      for(unsigned i = 0; i != 10; ++i){
+         BOOST_TEST(0 == volatile_memcmp(&p[i], ee_patternbuf, sizeof(ee_patternbuf)));
+      }
+   }
+   reset_counters();
+   {
+      bml::unique_ptr<default_init[]> p(bml::make_unique_nothrow_definit<default_init[]>(10));
+      for(unsigned i = 0; i != 10; ++i){
+         BOOST_TEST(0 == volatile_memcmp(&p[i], cc_patternbuf, sizeof(cc_patternbuf)));
+      }
+   }
+}
+
+}  //namespace make_unique_array{
+
+////////////////////////////////
+//       unique_compare
+////////////////////////////////
+
+namespace unique_compare{
+
+void test()
+{
+   //Single element deleter
+   reset_counters();
+   {
+      bml::unique_ptr<A> pa(bml::make_unique<A>());
+      bml::unique_ptr<A> pb(bml::make_unique<A>());
+      BOOST_TEST(A::count == 2);
+
+      //Take references to less and greater
+      bml::unique_ptr<A> &rpl = pa < pb ? pa : pb;
+      bml::unique_ptr<A> &rpg = pa < pb ? pb : pa;
+
+      //Now test operations with .get()
+
+      //Equal
+      BOOST_TEST(rpl == rpl && rpl.get() == rpl.get());
+      BOOST_TEST(!(rpl == rpg) && !(rpl.get() == rpg.get()));
+      //Unequal
+      BOOST_TEST(rpl != rpg && rpl.get() != rpg.get());
+      BOOST_TEST(!(rpl != rpl) && !(rpl.get() != rpl.get()));
+      //Less
+      BOOST_TEST(rpl < rpg && rpl.get() < rpg.get());
+      BOOST_TEST(!(rpg < rpl) && !(rpg.get() < rpl.get()));
+      //Greater
+      BOOST_TEST(rpg > rpl && rpg.get() > rpl.get());
+      BOOST_TEST(!(rpg > rpg) && !(rpg.get() > rpg.get()));
+      //Less or equal
+      BOOST_TEST(rpl <= rpg && rpl.get() <= rpg.get());
+      BOOST_TEST(rpl <= rpl && rpl.get() <= rpl.get());
+      BOOST_TEST(!(rpg <= rpl) && !(rpg.get() <= rpl.get()));
+      //Greater or equal
+      BOOST_TEST(rpg >= rpl && rpg.get() >= rpl.get());
+      BOOST_TEST(rpg >= rpg && rpg.get() >= rpg.get());
+      BOOST_TEST(!(rpl >= rpg) && !(rpl.get() >= rpg.get()));
+   }
+   BOOST_TEST(A::count == 0);
+}
+
+}  //namespace unique_compare{
+
+////////////////////////////////
+//       unique_compare_zero
+////////////////////////////////
+namespace unique_compare_zero{
+
+void test()
+{
+   //Single element deleter
+   reset_counters();
+   {
+      bml::unique_ptr<A> pa(bml::make_unique<A>());
+      bml::unique_ptr<A> pb;
+      BOOST_TEST(A::count == 1);
+
+      //Equal
+      BOOST_TEST(!(pa == 0));
+      BOOST_TEST(!(0  == pa));
+      BOOST_TEST((pb == 0));
+      BOOST_TEST((0  == pb));
+      //Unequal
+      BOOST_TEST((pa != 0));
+      BOOST_TEST((0  != pa));
+      BOOST_TEST(!(pb != 0));
+      BOOST_TEST(!(0  != pb));
+      //Less
+      BOOST_TEST((pa < 0) == (pa.get() < (A*)0));
+      BOOST_TEST((0 < pa) == ((A*)0 < pa.get()));
+      BOOST_TEST((pb < 0) == (pb.get() < (A*)0));
+      BOOST_TEST((0 < pb) == ((A*)0 < pb.get()));
+      //Greater
+      BOOST_TEST((pa > 0) == (pa.get() > (A*)0));
+      BOOST_TEST((0 > pa) == ((A*)0 > pa.get()));
+      BOOST_TEST((pb > 0) == (pb.get() > (A*)0));
+      BOOST_TEST((0 > pb) == ((A*)0 > pb.get()));
+      //Less or equal
+      BOOST_TEST((pa <= 0) == (pa.get() <= (A*)0));
+      BOOST_TEST((0 <= pa) == ((A*)0 <= pa.get()));
+      BOOST_TEST((pb <= 0) == (pb.get() <= (A*)0));
+      BOOST_TEST((0 <= pb) == ((A*)0 <= pb.get()));
+      //Greater or equal
+      BOOST_TEST((pa >= 0) == (pa.get() >= (A*)0));
+      BOOST_TEST((0 >= pa) == ((A*)0 >= pa.get()));
+      BOOST_TEST((pb >= 0) == (pb.get() >= (A*)0));
+      BOOST_TEST((0 >= pb) == ((A*)0 >= pb.get()));
+   }
+   BOOST_TEST(A::count == 0);
+}
+
+}  //namespace unique_compare_zero{
+
+////////////////////////////////
+//       unique_compare_nullptr
+////////////////////////////////
+
+namespace unique_compare_nullptr{
+
+void test()
+{
+   #if !defined(BOOST_NO_CXX11_NULLPTR)
+   //Single element deleter
+   reset_counters();
+   {
+      bml::unique_ptr<A> pa(bml::make_unique<A>());
+      bml::unique_ptr<A> pb;
+      BOOST_TEST(A::count == 1);
+
+      //Equal
+      BOOST_TEST(!(pa == nullptr));
+      BOOST_TEST(!(nullptr  == pa));
+      BOOST_TEST((pb == nullptr));
+      BOOST_TEST((nullptr  == pb));
+      //Unequal
+      BOOST_TEST((pa != nullptr));
+      BOOST_TEST((nullptr  != pa));
+      BOOST_TEST(!(pb != nullptr));
+      BOOST_TEST(!(nullptr  != pb));
+      //Less
+      BOOST_TEST((pa < nullptr) == (pa.get() < (A*)nullptr));
+      BOOST_TEST((nullptr < pa) == ((A*)nullptr < pa.get()));
+      BOOST_TEST((pb < nullptr) == (pb.get() < (A*)nullptr));
+      BOOST_TEST((nullptr < pb) == ((A*)nullptr < pb.get()));
+      //Greater
+      BOOST_TEST((pa > nullptr) == (pa.get() > (A*)nullptr));
+      BOOST_TEST((nullptr > pa) == ((A*)nullptr > pa.get()));
+      BOOST_TEST((pb > nullptr) == (pb.get() > (A*)nullptr));
+      BOOST_TEST((nullptr > pb) == ((A*)nullptr > pb.get()));
+      //Less or equal
+      BOOST_TEST((pa <= nullptr) == (pa.get() <= (A*)nullptr));
+      BOOST_TEST((nullptr <= pa) == ((A*)nullptr <= pa.get()));
+      BOOST_TEST((pb <= nullptr) == (pb.get() <= (A*)nullptr));
+      BOOST_TEST((nullptr <= pb) == ((A*)nullptr <= pb.get()));
+      //Greater or equal
+      BOOST_TEST((pa >= nullptr) == (pa.get() >= (A*)nullptr));
+      BOOST_TEST((nullptr >= pa) == ((A*)nullptr >= pa.get()));
+      BOOST_TEST((pb >= nullptr) == (pb.get() >= (A*)nullptr));
+      BOOST_TEST((nullptr >= pb) == ((A*)nullptr >= pb.get()));
+   }
+   BOOST_TEST(A::count == 0);
+   #endif   //#if !defined(BOOST_NO_CXX11_NULLPTR)
+}
+
+}  //namespace unique_compare_nullptr{
+
+
+////////////////////////////////
+//             main
+////////////////////////////////
+int main()
+{
+   make_unique_single::test();
+   make_unique_array::test();
+   unique_compare::test();
+   unique_compare_zero::test();
+   unique_compare_nullptr::test();
+
+   //Test results
+   return boost::report_errors();
+}
diff --git a/test/unique_ptr_modifiers.cpp b/test/unique_ptr_modifiers.cpp
new file mode 100644
index 0000000..376c104
--- /dev/null
+++ b/test/unique_ptr_modifiers.cpp
@@ -0,0 +1,381 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Howard Hinnant 2009
+// (C) Copyright Ion Gaztanaga 2014-2014.
+//
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/move/utility_core.hpp>
+#include <boost/move/unique_ptr.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/move/adl_move_swap.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+//////////////////////////////////////////////
+//
+// The initial implementation of these tests
+// was written by Howard Hinnant. 
+//
+// These test were later refactored grouping
+// and porting them to Boost.Move.
+//
+// Many thanks to Howard for releasing his C++03
+// unique_ptr implementation with such detailed
+// test cases.
+//
+//////////////////////////////////////////////
+
+#include "unique_ptr_test_utils_beg.hpp"
+
+namespace bml = ::boost::movelib;
+
+////////////////////////////////
+//   unique_ptr_modifiers_release
+////////////////////////////////
+
+namespace unique_ptr_modifiers_release{
+
+void test()
+{
+   //Single unique_ptr
+   {
+   bml::unique_ptr<int> p(new int(3));
+   int* i = p.get();
+   int* j = p.release();
+   BOOST_TEST(p.get() == 0);
+   BOOST_TEST(i == j);
+   p.reset(j);
+   }
+   //Unbounded array unique_ptr
+   {
+   bml::unique_ptr<int[]> p(new int[2]);
+   int* i = p.get();
+   int* j = p.release();
+   BOOST_TEST(p.get() == 0);
+   BOOST_TEST(i == j);
+   p.reset(j);
+   }
+   //Bounded array unique_ptr
+   {
+   bml::unique_ptr<int[2]> p(new int[2]);
+   int* i = p.get();
+   int* j = p.release();
+   BOOST_TEST(p.get() == 0);
+   BOOST_TEST(i == j);
+   p.reset(j);
+   }
+}
+
+}  //namespace unique_ptr_modifiers_release{
+
+////////////////////////////////
+//   unique_ptr_modifiers_reset
+////////////////////////////////
+
+namespace unique_ptr_modifiers_reset{
+
+void test()
+{
+   //Single unique_ptr
+   {
+      reset_counters();
+      {  //reset()
+      bml::unique_ptr<A> p(new A);
+      BOOST_TEST(A::count == 1);
+      A* i = p.get();
+      (void)i;
+      p.reset();
+      BOOST_TEST(A::count == 0);
+      BOOST_TEST(p.get() == 0);
+      }
+      BOOST_TEST(A::count == 0);
+      {  //reset(p)
+      bml::unique_ptr<A> p(new A);
+      BOOST_TEST(A::count == 1);
+      A* i = p.get();
+      (void)i;
+      p.reset(new A);
+      BOOST_TEST(A::count == 1);
+      }
+      BOOST_TEST(A::count == 0);
+      {  //reset(0)
+      bml::unique_ptr<A> p(new A);
+      BOOST_TEST(A::count == 1);
+      A* i = p.get();
+      (void)i;
+      p.reset(0);
+      BOOST_TEST(A::count == 0);
+      BOOST_TEST(p.get() == 0);
+      }
+      BOOST_TEST(A::count == 0);
+   }
+   //Unbounded array unique_ptr
+   {
+      reset_counters();
+      {  //reset()
+      bml::unique_ptr<A[]> p(new A[2]);
+      BOOST_TEST(A::count == 2);
+      A* i = p.get();
+      (void)i;
+      p.reset();
+      BOOST_TEST(A::count == 0);
+      BOOST_TEST(p.get() == 0);
+      }
+      BOOST_TEST(A::count == 0);
+      {  //reset(p)
+      bml::unique_ptr<A[]> p(new A[2]);
+      BOOST_TEST(A::count == 2);
+      A* i = p.get();
+      (void)i;
+      p.reset(new A[3]);
+      BOOST_TEST(A::count == 3);
+      }
+      BOOST_TEST(A::count == 0);
+      {  //reset(0)
+      bml::unique_ptr<A[]> p(new A[2]);
+      BOOST_TEST(A::count == 2);
+      A* i = p.get();
+      (void)i;
+      p.reset(0);
+      BOOST_TEST(A::count == 0);
+      BOOST_TEST(p.get() == 0);
+      }
+      BOOST_TEST(A::count == 0);
+   }
+   {
+      //Bounded array unique_ptr
+      reset_counters();
+      {  //reset()
+      bml::unique_ptr<A[2]> p(new A[2]);
+      BOOST_TEST(A::count == 2);
+      A* i = p.get();
+      (void)i;
+      p.reset();
+      BOOST_TEST(A::count == 0);
+      BOOST_TEST(p.get() == 0);
+      }
+      BOOST_TEST(A::count == 0);
+      {  //reset(p)
+      bml::unique_ptr<A[2]> p(new A[2]);
+      BOOST_TEST(A::count == 2);
+      A* i = p.get();
+      (void)i;
+      p.reset(new A[3]);
+      BOOST_TEST(A::count == 3);
+      }
+      BOOST_TEST(A::count == 0);
+      {  //reset(0)
+      bml::unique_ptr<A[2]> p(new A[2]);
+      BOOST_TEST(A::count == 2);
+      A* i = p.get();
+      (void)i;
+      p.reset(0);
+      BOOST_TEST(A::count == 0);
+      BOOST_TEST(p.get() == 0);
+      }
+      BOOST_TEST(A::count == 0);
+   }
+}
+
+}  //namespace unique_ptr_modifiers_reset{
+
+////////////////////////////////
+//   unique_ptr_modifiers_reset_convert
+////////////////////////////////
+
+namespace unique_ptr_modifiers_reset_convert{
+
+void test()
+{
+   //Single unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<A> p(new A);
+   BOOST_TEST(A::count == 1);
+   BOOST_TEST(B::count == 0);
+   A* i = p.get();
+   (void)i;
+   p.reset(new B);
+   BOOST_TEST(A::count == 1);
+   BOOST_TEST(B::count == 1);
+   }
+   BOOST_TEST(A::count == 0);
+   BOOST_TEST(B::count == 0);
+   {
+   bml::unique_ptr<A> p(new B);
+   BOOST_TEST(A::count == 1);
+   BOOST_TEST(B::count == 1);
+   A* i = p.get();
+   (void)i;
+   p.reset(new B);
+   BOOST_TEST(A::count == 1);
+   BOOST_TEST(B::count == 1);
+   }
+   BOOST_TEST(A::count == 0);
+   BOOST_TEST(B::count == 0);
+   //Unbounded array unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<const volatile A[2]> p(new const A[2]);
+   BOOST_TEST(A::count == 2);
+   const volatile A* i = p.get();
+   (void)i;
+   p.reset(new volatile A[3]);
+   BOOST_TEST(A::count == 3);
+   }
+   BOOST_TEST(A::count == 0);
+   {
+   bml::unique_ptr<const A[2]> p(new A[2]);
+   BOOST_TEST(A::count == 2);
+   const A* i = p.get();
+   (void)i;
+   p.reset(new const A[3]);
+   BOOST_TEST(A::count == 3);
+   }
+   BOOST_TEST(A::count == 0);
+   //Bounded array unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<const volatile A[2]> p(new const A[2]);
+   BOOST_TEST(A::count == 2);
+   const volatile A* i = p.get();
+   (void)i;
+   p.reset(new volatile A[3]);
+   BOOST_TEST(A::count == 3);
+   }
+   BOOST_TEST(A::count == 0);
+   {
+   bml::unique_ptr<const A[2]> p(new A[2]);
+   BOOST_TEST(A::count == 2);
+   const A* i = p.get();
+   (void)i;
+   p.reset(new const A[3]);
+   BOOST_TEST(A::count == 3);
+   }
+   BOOST_TEST(A::count == 0);
+}
+
+}  //unique_ptr_modifiers_reset_convert
+
+
+////////////////////////////////
+//   unique_ptr_modifiers
+////////////////////////////////
+
+namespace unique_ptr_modifiers_swap{
+
+// test swap
+
+void test()
+{
+   //Single unique_ptr
+   reset_counters();
+   {
+   A* p1 = new A(1);
+   move_constr_deleter<A> d1(1);
+   bml::unique_ptr<A, move_constr_deleter<A> > s1(p1, ::boost::move(d1));
+   A* p2 = new A(2);
+   move_constr_deleter<A> d2(2);
+   bml::unique_ptr<A, move_constr_deleter<A> > s2(p2, ::boost::move(d2));
+   BOOST_TEST(s1.get() == p1);
+   BOOST_TEST(*s1 == A(1));
+   BOOST_TEST(s1.get_deleter().state() == 1);
+   BOOST_TEST(s2.get() == p2);
+   BOOST_TEST(*s2 == A(2));
+   BOOST_TEST(s2.get_deleter().state() == 2);
+   boost::adl_move_swap(s1, s2);
+   BOOST_TEST(s1.get() == p2);
+   BOOST_TEST(*s1 == A(2));
+   BOOST_TEST(s1.get_deleter().state() == 2);
+   BOOST_TEST(s2.get() == p1);
+   BOOST_TEST(*s2 == A(1));
+   BOOST_TEST(s2.get_deleter().state() == 1);
+   }
+   //Unbounded array unique_ptr
+   reset_counters();
+   {
+   A* p1 = new A[2];
+   p1[0].set(1);
+   p1[1].set(2);
+   move_constr_deleter<A[]> d1(1);
+   bml::unique_ptr<A[], move_constr_deleter<A[]> > s1(p1, ::boost::move(d1));
+   A* p2 = new A[2];
+   p2[0].set(3);
+   p2[1].set(4);
+   move_constr_deleter<A[]> d2(2);
+   bml::unique_ptr<A[], move_constr_deleter<A[]> > s2(p2, ::boost::move(d2));
+   BOOST_TEST(s1.get() == p1);
+   BOOST_TEST(s1[0] == A(1));
+   BOOST_TEST(s1[1] == A(2));
+   BOOST_TEST(s1.get_deleter().state() == 1);
+   BOOST_TEST(s2.get() == p2);
+   BOOST_TEST(s2[0] == A(3));
+   BOOST_TEST(s2[1] == A(4));
+   BOOST_TEST(s2.get_deleter().state() == 2);
+   swap(s1, s2);
+   BOOST_TEST(s1.get() == p2);
+   BOOST_TEST(s1[0] == A(3));
+   BOOST_TEST(s1[1] == A(4));
+   BOOST_TEST(s1.get_deleter().state() == 2);
+   BOOST_TEST(s2.get() == p1);
+   BOOST_TEST(s2[0] == A(1));
+   BOOST_TEST(s2[1] == A(2));
+   BOOST_TEST(s2.get_deleter().state() == 1);
+   }
+   //Bounded array unique_ptr
+   reset_counters();
+   {
+   A* p1 = new A[2];
+   p1[0].set(1);
+   p1[1].set(2);
+   move_constr_deleter<A[2]> d1(1);
+   bml::unique_ptr<A[2], move_constr_deleter<A[2]> > s1(p1, ::boost::move(d1));
+   A* p2 = new A[2];
+   p2[0].set(3);
+   p2[1].set(4);
+   move_constr_deleter<A[2]> d2(2);
+   bml::unique_ptr<A[2], move_constr_deleter<A[2]> > s2(p2, ::boost::move(d2));
+   BOOST_TEST(s1.get() == p1);
+   BOOST_TEST(s1[0] == A(1));
+   BOOST_TEST(s1[1] == A(2));
+   BOOST_TEST(s1.get_deleter().state() == 1);
+   BOOST_TEST(s2.get() == p2);
+   BOOST_TEST(s2[0] == A(3));
+   BOOST_TEST(s2[1] == A(4));
+   BOOST_TEST(s2.get_deleter().state() == 2);
+   swap(s1, s2);
+   BOOST_TEST(s1.get() == p2);
+   BOOST_TEST(s1[0] == A(3));
+   BOOST_TEST(s1[1] == A(4));
+   BOOST_TEST(s1.get_deleter().state() == 2);
+   BOOST_TEST(s2.get() == p1);
+   BOOST_TEST(s2[0] == A(1));
+   BOOST_TEST(s2[1] == A(2));
+   BOOST_TEST(s2.get_deleter().state() == 1);
+   }
+}
+
+}  //namespace unique_ptr_modifiers_swap{
+
+////////////////////////////////
+//             main
+////////////////////////////////
+int main()
+{
+   //Modifiers
+   unique_ptr_modifiers_release::test();
+   unique_ptr_modifiers_reset::test();
+   unique_ptr_modifiers_reset_convert::test();
+   unique_ptr_modifiers_swap::test();
+
+   //Test results
+   return boost::report_errors();
+
+}
+
+#include "unique_ptr_test_utils_end.hpp"
diff --git a/test/unique_ptr_movector.cpp b/test/unique_ptr_movector.cpp
new file mode 100644
index 0000000..ece216b
--- /dev/null
+++ b/test/unique_ptr_movector.cpp
@@ -0,0 +1,517 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Howard Hinnant 2009
+// (C) Copyright Ion Gaztanaga 2014-2014.
+//
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/move/utility_core.hpp>
+#include <boost/move/unique_ptr.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+//////////////////////////////////////////////
+//
+// The initial implementation of these tests
+// was written by Howard Hinnant. 
+//
+// These test were later refactored grouping
+// and porting them to Boost.Move.
+//
+// Many thanks to Howard for releasing his C++03
+// unique_ptr implementation with such detailed
+// test cases.
+//
+//////////////////////////////////////////////
+
+#include "unique_ptr_test_utils_beg.hpp"
+
+namespace bml = ::boost::movelib;
+namespace bmupmu = ::boost::move_upmu;
+
+////////////////////////////////
+//   unique_ptr_ctor_move_defdel
+////////////////////////////////
+
+namespace unique_ptr_ctor_move_defdel{
+
+// test converting move ctor.  Should only require a MoveConstructible deleter, or if
+//    deleter is a reference, not even that.
+
+void test()
+{
+   //Single unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<A> s(new A);
+   A* p = s.get();
+   bml::unique_ptr<A> s2(boost::move(s));
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 1);
+   }
+   BOOST_TEST(A::count == 0);
+   //Unbounded array unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<A[]> s(new A[2]);
+   A* p = s.get();
+   bml::unique_ptr<A[]> s2(boost::move(s));
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 2);
+   }
+   BOOST_TEST(A::count == 0);
+   //Bounded array unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<A[2]> s(new A[2]);
+   A* p = s.get();
+   bml::unique_ptr<A[2]> s2(boost::move(s));
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 2);
+   }
+   BOOST_TEST(A::count == 0);
+}
+
+}  //namespace unique_ptr_ctor_move_defdel{
+
+////////////////////////////////
+//   unique_ptr_ctor_move_movedel
+////////////////////////////////
+
+namespace unique_ptr_ctor_move_movedel{
+
+// test converting move ctor.  Should only require a MoveConstructible deleter, or if
+//    deleter is a reference, not even that.
+
+void test()
+{
+   //Single unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<A, move_constr_deleter<A> > s(new A);
+   A* p = s.get();
+   bml::unique_ptr<A, move_constr_deleter<A> > s2 = boost::move(s);
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 1);
+   BOOST_TEST(s2.get_deleter().state() == 5);
+   BOOST_TEST(s.get_deleter().state() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+   //Unbounded array unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<A[], move_constr_deleter<A[]> > s(new A[2]);
+   A* p = s.get();
+   bml::unique_ptr<A[], move_constr_deleter<A[]> > s2 = boost::move(s);
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 2);
+   BOOST_TEST(s2.get_deleter().state() == 5);
+   BOOST_TEST(s.get_deleter().state() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+   //Bounded array unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<A[2]> s(new A[2]);
+   A* p = s.get();
+   bml::unique_ptr<A[2]> s2 = boost::move(s);
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 2);
+   }
+   BOOST_TEST(A::count == 0);
+}
+
+}  //namespace unique_ptr_ctor_move_movedel{
+
+////////////////////////////////
+//   unique_ptr_ctor_move_dfctrdelref
+////////////////////////////////
+
+namespace unique_ptr_ctor_move_dfctrdelref{
+
+// test converting move ctor.  Should only require a MoveConstructible deleter, or if
+//    deleter is a reference, not even that.
+
+void test()
+{
+   //Single unique_ptr
+   reset_counters();
+   {
+   def_constr_deleter<A> d;
+   bml::unique_ptr<A, def_constr_deleter<A>&> s(new A, d);
+   A* p = s.get();
+   bml::unique_ptr<A, def_constr_deleter<A>&> s2 = boost::move(s);
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 1);
+   d.set_state(6);
+   BOOST_TEST(s2.get_deleter().state() == d.state());
+   BOOST_TEST(s.get_deleter().state() ==  d.state());
+   }
+   BOOST_TEST(A::count == 0);
+   //Unbounded array unique_ptr
+   reset_counters();
+   {
+   def_constr_deleter<A[]> d;
+   bml::unique_ptr<A[], def_constr_deleter<A[]>&> s(new A[2], d);
+   A* p = s.get();
+   bml::unique_ptr<A[], def_constr_deleter<A[]>&> s2 = boost::move(s);
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 2);
+   d.set_state(6);
+   BOOST_TEST(s2.get_deleter().state() == d.state());
+   BOOST_TEST(s.get_deleter().state() ==  d.state());
+   }
+   BOOST_TEST(A::count == 0);
+   //Bounded array unique_ptr
+   reset_counters();
+   {
+   def_constr_deleter<A[2]> d;
+   bml::unique_ptr<A[2], def_constr_deleter<A[2]>&> s(new A[2], d);
+   A* p = s.get();
+   bml::unique_ptr<A[2], def_constr_deleter<A[2]>&> s2(boost::move(s));
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 2);
+   d.set_state(6);
+   BOOST_TEST(s2.get_deleter().state() == d.state());
+   BOOST_TEST(s.get_deleter().state() ==  d.state());
+   }
+   BOOST_TEST(A::count == 0);
+}
+
+}  //namespace unique_ptr_ctor_move_dfctrdelref{
+
+////////////////////////////////
+//   unique_ptr_ctor_move_convert_defdel
+////////////////////////////////
+
+namespace unique_ptr_ctor_move_convert_defdel{
+
+// test converting move ctor.  Should only require a MoveConstructible deleter, or if
+//    deleter is a reference, not even that.
+
+void test()
+{
+   //Single unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<B> s(new B);
+   A* p = s.get();
+   bml::unique_ptr<A> s2(boost::move(s));
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 1);
+   BOOST_TEST(B::count == 1);
+   }
+   BOOST_TEST(A::count == 0);
+   BOOST_TEST(B::count == 0);
+   //Unbounded array unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<A[]> s(new A[2]);
+   A* p = s.get();
+   bml::unique_ptr<const volatile A[]> s2(boost::move(s));
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 2);
+   }
+   BOOST_TEST(A::count == 0);
+
+   //Bounded array unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<A[2]> s(new A[2]);
+   A* p = s.get();
+   bml::unique_ptr<const volatile A[2]> s2(boost::move(s));
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 2);
+   }
+   BOOST_TEST(A::count == 0);
+   {
+   bml::unique_ptr<A[2]> s(new A[2]);
+   A* p = s.get();
+   bml::unique_ptr<const volatile A[]> s2(boost::move(s));
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 2);
+   }
+   BOOST_TEST(A::count == 0);
+}
+
+}  //namespace unique_ptr_ctor_move_convert_defdel{
+
+////////////////////////////////
+//   unique_ptr_ctor_move_convert_movedel
+////////////////////////////////
+
+namespace unique_ptr_ctor_move_convert_movedel{
+
+// test converting move ctor.  Should only require a MoveConstructible deleter, or if
+//    deleter is a reference, not even that.
+
+void test()
+{
+   //Single unique_ptr
+   reset_counters();
+   BOOST_STATIC_ASSERT((bmupmu::is_convertible<B, A>::value));
+   {
+   bml::unique_ptr<B, move_constr_deleter<B> > s(new B);
+   A* p = s.get();
+   bml::unique_ptr<A, move_constr_deleter<A> > s2(boost::move(s));
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 1);
+   BOOST_TEST(B::count == 1);
+   BOOST_TEST(s2.get_deleter().state() == 5);
+   BOOST_TEST(s.get_deleter().state() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+   BOOST_TEST(B::count == 0);
+   //Unbounded array unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<const A[], move_constr_deleter<const A[]> > s(new const A[2]);
+   const A* p = s.get();
+   bml::unique_ptr<const volatile A[], move_constr_deleter<const volatile A[]> > s2(boost::move(s));
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 2);
+   BOOST_TEST(s2.get_deleter().state() == 5);
+   BOOST_TEST(s.get_deleter().state() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+   BOOST_TEST(B::count == 0);
+   //Bounded array unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<const A[2], move_constr_deleter<const A[2]> > s(new const A[2]);
+   const A* p = s.get();
+   bml::unique_ptr<const volatile A[2], move_constr_deleter<const volatile A[2]> > s2(boost::move(s));
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 2);
+   BOOST_TEST(s2.get_deleter().state() == 5);
+   BOOST_TEST(s.get_deleter().state() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+   BOOST_TEST(B::count == 0);
+   {
+   bml::unique_ptr<const A[2], move_constr_deleter<const A[2]> > s(new const A[2]);
+   const A* p = s.get();
+   bml::unique_ptr<const volatile A[], move_constr_deleter<const volatile A[]> > s2(boost::move(s));
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 2);
+   BOOST_TEST(s2.get_deleter().state() == 5);
+   BOOST_TEST(s.get_deleter().state() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+   BOOST_TEST(B::count == 0);
+}
+
+}  //namespace unique_ptr_ctor_move_convert_movedel{
+
+////////////////////////////////
+//   unique_ptr_ctor_move_convert_dfctrdelref
+////////////////////////////////
+
+namespace unique_ptr_ctor_move_convert_dfctrdelref{
+
+// test converting move ctor.  Should only require a MoveConstructible deleter, or if
+//    deleter is a reference, not even that.
+
+void test()
+{
+   //Single unique_ptr
+   reset_counters();
+   {
+   def_constr_deleter<A> d;
+   bml::unique_ptr<B, def_constr_deleter<A>&> s(new B, d);
+   A* p = s.get();
+   bml::unique_ptr<A, def_constr_deleter<A>&> s2(boost::move(s));
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 1);
+   BOOST_TEST(B::count == 1);
+   d.set_state(6);
+   BOOST_TEST(s2.get_deleter().state() == d.state());
+   BOOST_TEST(s.get_deleter().state() ==  d.state());
+   }
+   BOOST_TEST(A::count == 0);
+   BOOST_TEST(B::count == 0);
+   //Unbounded array unique_ptr
+   reset_counters();
+   {
+   def_constr_deleter<volatile A[]> d;
+   bml::unique_ptr<A[], def_constr_deleter<volatile A[]>&> s(new A[2], d);
+   A* p = s.get();
+   bml::unique_ptr<volatile A[], def_constr_deleter<volatile A[]>&> s2(boost::move(s));
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 2);
+   d.set_state(6);
+   BOOST_TEST(s2.get_deleter().state() == d.state());
+   BOOST_TEST(s.get_deleter().state() ==  d.state());
+   }
+   BOOST_TEST(A::count == 0);
+   //Bounded array unique_ptr
+   reset_counters();
+   {
+   def_constr_deleter<volatile A[2]> d;
+   bml::unique_ptr<A[2], def_constr_deleter<volatile A[2]>&> s(new A[2], d);
+   A* p = s.get();
+   bml::unique_ptr<volatile A[2], def_constr_deleter<volatile A[2]>&> s2(boost::move(s));
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 2);
+   d.set_state(6);
+   BOOST_TEST(s2.get_deleter().state() == d.state());
+   BOOST_TEST(s.get_deleter().state() ==  d.state());
+   }
+   BOOST_TEST(A::count == 0);
+   {
+   def_constr_deleter<volatile A[]> d;
+   bml::unique_ptr<A[2], def_constr_deleter<volatile A[]>&> s(new A[2], d);
+   A* p = s.get();
+   bml::unique_ptr<volatile A[], def_constr_deleter<volatile A[]>&> s2(boost::move(s));
+   BOOST_TEST(s2.get() == p);
+   BOOST_TEST(s.get() == 0);
+   BOOST_TEST(A::count == 2);
+   d.set_state(6);
+   BOOST_TEST(s2.get_deleter().state() == d.state());
+   BOOST_TEST(s.get_deleter().state() ==  d.state());
+   }
+   BOOST_TEST(A::count == 0);
+}
+
+}  //namespace unique_ptr_ctor_move_convert_dfctrdelref{
+
+////////////////////////////////
+//   unique_ptr_ctor_move_sourcesink
+////////////////////////////////
+
+namespace unique_ptr_ctor_move_sourcesink{
+
+// test move ctor.  Should only require a MoveConstructible deleter, or if
+//    deleter is a reference, not even that.
+
+bml::unique_ptr<A> source1()
+{  return bml::unique_ptr<A>(new A);  }
+
+bml::unique_ptr<A[]> source1_unbounded_array()
+{  return bml::unique_ptr<A[]> (new A[2]);  }
+
+bml::unique_ptr<A[2]> source1_bounded_array()
+{  return bml::unique_ptr<A[2]> (new A[2]);  }
+
+void sink1(bml::unique_ptr<A>)
+{}
+
+void sink1_unbounded_array(bml::unique_ptr<A[]>)
+{}
+
+void sink1_bounded_array(bml::unique_ptr<A[2]>)
+{}
+
+bml::unique_ptr<A, move_constr_deleter<A> > source2()
+{  return bml::unique_ptr<A, move_constr_deleter<A> > (new A);  }
+
+bml::unique_ptr<A[], move_constr_deleter<A[]> > source2_unbounded_array()
+{  return bml::unique_ptr<A[], move_constr_deleter<A[]> >(new A[2]);  }
+
+bml::unique_ptr<A[2], move_constr_deleter<A[2]> > source2_bounded_array()
+{  return bml::unique_ptr<A[2], move_constr_deleter<A[2]> >(new A[2]);  }
+
+void sink2(bml::unique_ptr<A, move_constr_deleter<A> >)
+{}
+
+void sink2_unbounded_array(bml::unique_ptr<A[], move_constr_deleter<A[]> >)
+{}
+
+void sink2_bounded_array(bml::unique_ptr<A[2], move_constr_deleter<A[2]> >)
+{}
+
+bml::unique_ptr<A, def_constr_deleter<A>&> source3()
+{
+   static def_constr_deleter<A> d;
+   return bml::unique_ptr<A, def_constr_deleter<A>&>(new A, d);
+}
+
+bml::unique_ptr<A[], def_constr_deleter<A[]>&> source3_unbounded_array()
+{
+   static def_constr_deleter<A[]> d;
+   return bml::unique_ptr<A[], def_constr_deleter<A[]>&>(new A[2], d);
+}
+
+bml::unique_ptr<A[2], def_constr_deleter<A[2]>&> source3_bounded_array()
+{
+   static def_constr_deleter<A[2]> d;
+   return bml::unique_ptr<A[2], def_constr_deleter<A[2]>&>(new A[2], d);
+}
+
+void sink3(bml::unique_ptr<A, def_constr_deleter<A>&> )
+{}
+
+void sink3_unbounded_array(bml::unique_ptr<A[], def_constr_deleter<A[]>&> )
+{}
+
+void sink3_bounded_array(bml::unique_ptr<A[2], def_constr_deleter<A[2]>&> )
+{}
+
+void test()
+{
+   //Single unique_ptr
+   reset_counters(); 
+   sink1(source1());
+   sink2(source2());
+   sink3(source3());
+   BOOST_TEST(A::count == 0);
+   //Unbounded array unique_ptr
+   reset_counters();
+   sink1_unbounded_array(source1_unbounded_array());
+   sink2_unbounded_array(source2_unbounded_array());
+   sink3_unbounded_array(source3_unbounded_array());
+   BOOST_TEST(A::count == 0);
+   //Bbounded array unique_ptr
+   reset_counters();
+   sink1_bounded_array(source1_bounded_array());
+   sink2_bounded_array(source2_bounded_array());
+   sink3_bounded_array(source3_bounded_array());
+   BOOST_TEST(A::count == 0);
+}
+
+}  //namespace unique_ptr_ctor_move_sourcesink{
+
+////////////////////////////////
+//             main
+////////////////////////////////
+int main()
+{
+   //Move Constructor
+   unique_ptr_ctor_move_defdel::test();
+   unique_ptr_ctor_move_movedel::test();
+   unique_ptr_ctor_move_dfctrdelref::test();
+   unique_ptr_ctor_move_convert_defdel::test();
+   unique_ptr_ctor_move_convert_movedel::test();
+   unique_ptr_ctor_move_convert_dfctrdelref::test();
+   unique_ptr_ctor_move_sourcesink::test();
+
+   //Test results
+   return boost::report_errors();
+}
+
+#include "unique_ptr_test_utils_end.hpp"
diff --git a/test/unique_ptr_nullptr.cpp b/test/unique_ptr_nullptr.cpp
new file mode 100644
index 0000000..555fcc2
--- /dev/null
+++ b/test/unique_ptr_nullptr.cpp
@@ -0,0 +1,228 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Howard Hinnant 2009
+// (C) Copyright Ion Gaztanaga 2014-2014.
+//
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/move/utility_core.hpp>
+#include <boost/move/unique_ptr.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+//////////////////////////////////////////////
+//
+// The initial implementation of these tests
+// was written by Howard Hinnant. 
+//
+// These test were later refactored grouping
+// and porting them to Boost.Move.
+//
+// Many thanks to Howard for releasing his C++03
+// unique_ptr implementation with such detailed
+// test cases.
+//
+//////////////////////////////////////////////
+
+#include "unique_ptr_test_utils_beg.hpp"
+
+namespace bml = ::boost::movelib;
+
+////////////////////////////////
+//   unique_ptr_zero
+////////////////////////////////
+namespace unique_ptr_zero {
+
+// test initialization/assignment from zero
+
+void test()
+{
+   //Single unique_ptr
+   reset_counters();
+   {
+   bml::unique_ptr<A> s2(0);
+   BOOST_TEST(A::count == 0);
+   }
+   BOOST_TEST(A::count == 0);
+   {
+   bml::unique_ptr<A> s2(new A);
+   BOOST_TEST(A::count == 1);
+   s2 = 0;
+   BOOST_TEST(A::count == 0);
+   BOOST_TEST(s2.get() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+
+   //Unbounded array unique_ptr
+   {
+   bml::unique_ptr<A[]> s2(0);
+   BOOST_TEST(A::count == 0);
+   }
+   BOOST_TEST(A::count == 0);
+   {
+   bml::unique_ptr<A[]> s2(new A[2]);
+   BOOST_TEST(A::count == 2);
+   s2 = 0;
+   BOOST_TEST(A::count == 0);
+   BOOST_TEST(s2.get() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+
+   //Bounded array unique_ptr
+   {
+   bml::unique_ptr<A[2]> s2(0);
+   BOOST_TEST(A::count == 0);
+   }
+   BOOST_TEST(A::count == 0);
+   {
+   bml::unique_ptr<A[2]> s2(new A[2]);
+   BOOST_TEST(A::count == 2);
+   s2 = 0;
+   BOOST_TEST(A::count == 0);
+   BOOST_TEST(s2.get() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+}
+
+}  //namespace unique_ptr_zero {
+
+
+////////////////////////////////
+//       unique_ptr_nullptr
+////////////////////////////////
+
+namespace unique_ptr_nullptr{
+
+void test()
+{
+   #if !defined(BOOST_NO_CXX11_NULLPTR)
+   //Single unique_ptr
+   reset_counters();
+   {
+      bml::unique_ptr<A> p(new A);
+      BOOST_TEST(A::count == 1);
+      A* i = p.get();
+      (void)i;
+      p.reset(nullptr);
+      BOOST_TEST(A::count == 0);
+      BOOST_TEST(p.get() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+   {
+      bml::unique_ptr<A> p(new A);
+      BOOST_TEST(A::count == 1);
+      A* i = p.get();
+      (void)i;
+      p = nullptr;
+      BOOST_TEST(A::count == 0);
+      BOOST_TEST(p.get() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+
+   {
+      bml::unique_ptr<A> pi(nullptr);
+      BOOST_TEST(pi.get() == nullptr);
+      BOOST_TEST(pi.get() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+   {
+      bml::unique_ptr<A> pi(nullptr, bml::unique_ptr<A>::deleter_type());
+      BOOST_TEST(pi.get() == nullptr);
+      BOOST_TEST(pi.get() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+
+   //Unbounded array unique_ptr
+   reset_counters();
+   {
+      bml::unique_ptr<A[]> p(new A[2]);
+      BOOST_TEST(A::count == 2);
+      A* i = p.get();
+      (void)i;
+      p.reset(nullptr);
+      BOOST_TEST(A::count == 0);
+      BOOST_TEST(p.get() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+   {
+      bml::unique_ptr<A[]> p(new A[2]);
+      BOOST_TEST(A::count == 2);
+      A* i = p.get();
+      (void)i;
+      p = nullptr;
+      BOOST_TEST(A::count == 0);
+      BOOST_TEST(p.get() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+   {
+      bml::unique_ptr<A[]> pi(nullptr);
+      BOOST_TEST(pi.get() == nullptr);
+      BOOST_TEST(pi.get() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+   {
+      bml::unique_ptr<A[]> pi(nullptr, bml::unique_ptr<A[]>::deleter_type());
+      BOOST_TEST(pi.get() == nullptr);
+      BOOST_TEST(pi.get() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+
+   //Bounded array unique_ptr
+   reset_counters();
+   {
+      bml::unique_ptr<A[2]> p(new A[2]);
+      BOOST_TEST(A::count == 2);
+      A* i = p.get();
+      (void)i;
+      p.reset(nullptr);
+      BOOST_TEST(A::count == 0);
+      BOOST_TEST(p.get() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+   {
+      bml::unique_ptr<A[2]> p(new A[2]);
+      BOOST_TEST(A::count == 2);
+      A* i = p.get();
+      (void)i;
+      p = nullptr;
+      BOOST_TEST(A::count == 0);
+      BOOST_TEST(p.get() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+   {
+      bml::unique_ptr<A[2]> pi(nullptr);
+      BOOST_TEST(pi.get() == nullptr);
+      BOOST_TEST(pi.get() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+   {
+      bml::unique_ptr<A[2]> pi(nullptr, bml::unique_ptr<A[2]>::deleter_type());
+      BOOST_TEST(pi.get() == nullptr);
+      BOOST_TEST(pi.get() == 0);
+   }
+   BOOST_TEST(A::count == 0);
+   #endif
+}
+
+}  //namespace unique_ptr_nullptr{
+
+////////////////////////////////
+//             main
+////////////////////////////////
+int main()
+{
+   //nullptr
+   unique_ptr_zero::test();
+   unique_ptr_nullptr::test();
+
+   //Test results
+   return boost::report_errors();
+
+}
+
+#include "unique_ptr_test_utils_end.hpp"
diff --git a/test/unique_ptr_observers.cpp b/test/unique_ptr_observers.cpp
new file mode 100644
index 0000000..14376a0
--- /dev/null
+++ b/test/unique_ptr_observers.cpp
@@ -0,0 +1,287 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Howard Hinnant 2009
+// (C) Copyright Ion Gaztanaga 2014-2014.
+//
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/move/utility_core.hpp>
+#include <boost/move/unique_ptr.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+//////////////////////////////////////////////
+//
+// The initial implementation of these tests
+// was written by Howard Hinnant. 
+//
+// These test were later refactored grouping
+// and porting them to Boost.Move.
+//
+// Many thanks to Howard for releasing his C++03
+// unique_ptr implementation with such detailed
+// test cases.
+//
+//////////////////////////////////////////////
+
+#include "unique_ptr_test_utils_beg.hpp"
+
+namespace bml = ::boost::movelib;
+
+////////////////////////////////
+//   unique_ptr_observers_dereference
+////////////////////////////////
+
+namespace unique_ptr_observers_dereference{
+
+void test()
+{
+   //Single unique_ptr
+   {
+   bml::unique_ptr<int> p(new int(3));
+   BOOST_TEST(*p == 3);
+   }
+   //Unbounded array unique_ptr
+   {
+   int *pi = new int[2];
+   pi[0] = 3;
+   pi[1] = 4;
+   bml::unique_ptr<int[]> p(pi);
+   BOOST_TEST(p[0] == 3);
+   BOOST_TEST(p[1] == 4);
+   }
+   //Bounded array unique_ptr
+   {
+   int *pi = new int[2];
+   pi[0] = 3;
+   pi[1] = 4;
+   bml::unique_ptr<int[2]> p(pi);
+   BOOST_TEST(p[0] == 3);
+   BOOST_TEST(p[1] == 4);
+   }
+}
+
+}  //namespace unique_ptr_observers_dereference{
+
+////////////////////////////////
+//   unique_ptr_observers_dereference
+////////////////////////////////
+
+namespace unique_ptr_observers_explicit_bool{
+
+void test()
+{
+   //Single unique_ptr
+   {
+   bml::unique_ptr<int> p(new int(3));
+   if (p)
+      ;
+   else
+      BOOST_TEST(false);
+   if (!p)
+      BOOST_TEST(false);
+   }
+   {
+   bml::unique_ptr<int> p;
+   if (!p)
+      ;
+   else
+      BOOST_TEST(false);
+   if (p)
+      BOOST_TEST(false);
+   }
+   //Unbounded array unique_ptr
+   {
+   bml::unique_ptr<int[]> p(new int[2]);
+   if (p)
+      ;
+   else
+      BOOST_TEST(false);
+   if (!p)
+      BOOST_TEST(false);
+   }
+   {
+   bml::unique_ptr<int[]> p;
+   if (!p)
+      ;
+   else
+      BOOST_TEST(false);
+   if (p)
+      BOOST_TEST(false);
+   }
+   //Bounded array unique_ptr
+   {
+   bml::unique_ptr<int[2]> p(new int[2]);
+   if (p)
+      ;
+   else
+      BOOST_TEST(false);
+   if (!p)
+      BOOST_TEST(false);
+   }
+   {
+   bml::unique_ptr<int[2]> p;
+   if (!p)
+      ;
+   else
+      BOOST_TEST(false);
+   if (p)
+      BOOST_TEST(false);
+   }
+}
+
+}  //namespace unique_ptr_observers_explicit_bool{
+
+////////////////////////////////
+//   unique_ptr_observers_get
+////////////////////////////////
+
+namespace unique_ptr_observers_get{
+
+void test()
+{
+   //Single unique_ptr
+   {
+   int* p = new int;
+   bml::unique_ptr<int> s(p);
+   BOOST_TEST(s.get() == p);
+   }
+   //Unbounded array unique_ptr
+   {
+   int* p = new int[2];
+   bml::unique_ptr<int[]> s(p);
+   BOOST_TEST(s.get() == p);
+   }
+   {
+   int* p = new int[2];
+   bml::unique_ptr<int[2]> s(p);
+   BOOST_TEST(s.get() == p);
+   }
+   //Bounded array unique_ptr
+   {
+   int *pi = new int[2];
+   pi[0] = 3;
+   pi[1] = 4;
+   bml::unique_ptr<int[2]> p(pi);
+   BOOST_TEST(p[0] == 3);
+   BOOST_TEST(p[1] == 4);
+   }
+}
+
+}  //namespace unique_ptr_observers_get{
+
+////////////////////////////////
+//   unique_ptr_observers_get_deleter
+////////////////////////////////
+
+namespace unique_ptr_observers_get_deleter{
+
+struct Deleter
+{
+   void operator()(void*) {}
+
+   int test() {return 5;}
+   int test() const {return 6;}
+};
+
+void test()
+{
+   //Single unique_ptr
+   {
+   bml::unique_ptr<int, Deleter> p;
+   BOOST_TEST(p.get_deleter().test() == 5);
+   }
+   {
+   const bml::unique_ptr<int, Deleter> p;
+   BOOST_TEST(p.get_deleter().test() == 6);
+   }
+   //Unbounded array unique_ptr
+   {
+   bml::unique_ptr<int[], Deleter> p;
+   BOOST_TEST(p.get_deleter().test() == 5);
+   }
+   {
+   const bml::unique_ptr<int[], Deleter> p;
+   BOOST_TEST(p.get_deleter().test() == 6);
+   }
+   //Bounded array unique_ptr
+   {
+   bml::unique_ptr<int[2], Deleter> p;
+   BOOST_TEST(p.get_deleter().test() == 5);
+   }
+   {
+   const bml::unique_ptr<int[2], Deleter> p;
+   BOOST_TEST(p.get_deleter().test() == 6);
+   }
+}
+
+}  //namespace unique_ptr_observers_get_deleter{
+
+////////////////////////////////
+//   unique_ptr_observers_op_arrow
+////////////////////////////////
+
+namespace unique_ptr_observers_op_arrow{
+
+void test()
+{
+   //Single unique_ptr
+   {
+   bml::unique_ptr<A> p(new A);
+   BOOST_TEST(p->state_ == 999);
+   }
+}
+
+}  //namespace unique_ptr_observers_op_arrow{
+
+
+namespace unique_ptr_observers_op_index{
+
+void test()
+{
+   //Unbounded array unique_ptr
+   {
+   A *pa = new A[2];
+   //pa[0] is left default constructed
+   pa[1].set(888);
+   bml::unique_ptr<A[]> p(pa);
+   BOOST_TEST(p[0].state_ == 999);
+   BOOST_TEST(p[1].state_ == 888);
+   }
+   //Bounded array unique_ptr
+   {
+   A *pa = new A[2];
+   //pa[0] is left default constructed
+   pa[1].set(888);
+   bml::unique_ptr<A[2]> p(pa);
+   BOOST_TEST(p[0].state_ == 999);
+   BOOST_TEST(p[1].state_ == 888);
+   }
+}
+
+}  //namespace unique_ptr_observers_op_index{
+
+////////////////////////////////
+//             main
+////////////////////////////////
+int main()
+{
+   //Observers
+   unique_ptr_observers_dereference::test();
+   unique_ptr_observers_explicit_bool::test();
+   unique_ptr_observers_get::test();
+   unique_ptr_observers_get_deleter::test();
+   unique_ptr_observers_op_arrow::test();
+   unique_ptr_observers_op_index::test();
+
+   //Test results
+   return boost::report_errors();
+
+}
+
+#include "unique_ptr_test_utils_end.hpp"
diff --git a/test/unique_ptr_test_utils_beg.hpp b/test/unique_ptr_test_utils_beg.hpp
new file mode 100644
index 0000000..965732c
--- /dev/null
+++ b/test/unique_ptr_test_utils_beg.hpp
@@ -0,0 +1,209 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Howard Hinnant 2009
+// (C) Copyright Ion Gaztanaga 2014-2014.
+//
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_MOVE_UNIQUE_PTR_TEST_UTILS_BEG_HPP
+#define BOOST_MOVE_UNIQUE_PTR_TEST_UTILS_BEG_HPP
+#include <boost/move/core.hpp>
+#include <boost/move/detail/unique_ptr_meta_utils.hpp>
+#include <boost/static_assert.hpp>
+
+//////////////////////////////////////////////
+//
+// The initial implementation of these tests
+// was written by Howard Hinnant. 
+//
+// These test were later refactored grouping
+// and porting them to Boost.Move.
+//
+// Many thanks to Howard for releasing his C++03
+// unique_ptr implementation with such detailed
+// test cases.
+//
+//////////////////////////////////////////////
+
+//A deleter that can only default constructed
+template <class T>
+class def_constr_deleter
+{
+   int state_;
+   def_constr_deleter(const def_constr_deleter&);
+   def_constr_deleter& operator=(const def_constr_deleter&);
+
+   public:
+   typedef typename ::boost::move_upmu::remove_extent<T>::type element_type;
+   static const bool is_array = ::boost::move_upmu::is_array<T>::value;
+
+   def_constr_deleter() : state_(5) {}
+
+   explicit def_constr_deleter(int s) : state_(s) {}
+
+   int state() const {return state_;}
+
+   void set_state(int s) {state_ = s;}
+
+   void operator()(element_type* p) const
+   {  is_array ? delete []p : delete p;   }
+
+   void operator()(element_type* p)
+   {  ++state_;   is_array ? delete []p : delete p;  }
+};
+
+//A deleter that can be copy constructed
+template <class T>
+class copy_constr_deleter
+{
+   int state_;
+
+   public:
+   typedef typename ::boost::move_upmu::remove_extent<T>::type element_type;
+   static const bool is_array = ::boost::move_upmu::is_array<T>::value;
+
+   copy_constr_deleter() : state_(5) {}
+
+   template<class U>
+   copy_constr_deleter(const copy_constr_deleter<U>&
+      , typename boost::move_upd::enable_def_del<U, T>::type* =0)
+   {  state_ = 5; }
+
+   explicit copy_constr_deleter(int s) : state_(s) {}
+
+   template <class U>
+   typename boost::move_upd::enable_def_del<U, T, copy_constr_deleter&>::type
+      operator=(const copy_constr_deleter<U> &d)
+   {
+      state_ = d.state();
+      return *this;
+   }
+
+   int state() const          {return state_;}
+
+   void set_state(int s)      {state_ = s;}
+
+   void operator()(element_type* p) const
+   {  is_array ? delete []p : delete p;   }
+
+   void operator()(element_type* p)
+   {  ++state_;   is_array ? delete []p : delete p;  }
+};
+
+//A deleter that can be only move constructed
+template <class T>
+class move_constr_deleter
+{
+   int state_;
+
+   BOOST_MOVABLE_BUT_NOT_COPYABLE(move_constr_deleter)
+
+   public:
+   typedef typename ::boost::move_upmu::remove_extent<T>::type element_type;
+   static const bool is_array = ::boost::move_upmu::is_array<T>::value;
+
+   move_constr_deleter() : state_(5) {}
+
+   move_constr_deleter(BOOST_RV_REF(move_constr_deleter) r)
+      : state_(r.state_)
+   {  r.state_ = 0;  }
+
+   explicit move_constr_deleter(int s) : state_(s) {}
+
+   template <class U>
+   move_constr_deleter(BOOST_RV_REF(move_constr_deleter<U>) d
+      , typename boost::move_upd::enable_def_del<U, T>::type* =0)
+      : state_(d.state())
+   { d.set_state(0);  }
+
+   move_constr_deleter& operator=(BOOST_RV_REF(move_constr_deleter) r)
+   {
+      state_ = r.state_;
+      r.state_ = 0;
+      return *this;
+   }
+
+   template <class U>
+   typename boost::move_upd::enable_def_del<U, T, move_constr_deleter&>::type
+      operator=(BOOST_RV_REF(move_constr_deleter<U>) d)
+   {
+      state_ = d.state();
+      d.set_state(0);
+      return *this;
+   }
+
+   int state() const          {return state_;}
+
+   void set_state(int s)      {state_ = s;}
+
+   void operator()(element_type* p) const
+   {  is_array ? delete []p : delete p;   }
+
+   void operator()(element_type* p)
+   {  ++state_;   is_array ? delete []p : delete p;  }
+
+   friend bool operator==(const move_constr_deleter& x, const move_constr_deleter& y)
+      {return x.state_ == y.state_;}
+};
+
+//A base class containing state with a static instance counter
+struct A
+{
+   int state_;
+   static int count;
+
+   A()               : state_(999)      {++count;}
+   explicit A(int i) : state_(i)        {++count;}
+   A(const A& a)     : state_(a.state_) {++count;}
+   A& operator=(const A& a) { state_ = a.state_; return *this; }
+   void set(int i)   {state_ = i;}
+   virtual ~A()      {--count;}
+   friend bool operator==(const A& x, const A& y) { return x.state_ == y.state_; }
+};
+
+int A::count = 0;
+
+//A class derived from A with a static instance counter
+struct B
+   : public A
+{
+   static int count;
+   B() : A() {++count;}
+   B(const B &b) : A(b) {++count;}
+   virtual ~B() {--count;}
+};
+
+int B::count = 0;
+
+void reset_counters();
+
+BOOST_STATIC_ASSERT((::boost::move_upmu::is_convertible<B, A>::value));
+
+//Incomplete Type function declarations
+struct I;
+void check(int i);
+I* get();
+I* get_array(int i);
+
+#include <boost/move/unique_ptr.hpp>
+
+template <class T, class D = ::boost::movelib::default_delete<T> >
+struct J
+{
+   typedef boost::movelib::unique_ptr<T, D> unique_ptr_type;
+   typedef typename unique_ptr_type::element_type element_type;
+   boost::movelib::unique_ptr<T, D> a_;
+   J() {}
+   explicit J(element_type*a) : a_(a) {}
+   ~J();
+
+   element_type* get() const {return a_.get();}
+   D& get_deleter() {return a_.get_deleter();}
+};
+
+#endif   //BOOST_MOVE_UNIQUE_PTR_TEST_UTILS_BEG_HPP
diff --git a/test/unique_ptr_test_utils_end.hpp b/test/unique_ptr_test_utils_end.hpp
new file mode 100644
index 0000000..ca0fb92
--- /dev/null
+++ b/test/unique_ptr_test_utils_end.hpp
@@ -0,0 +1,46 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Howard Hinnant 2009
+// (C) Copyright Ion Gaztanaga 2014-2014.
+//
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_MOVE_UNIQUE_PTR_TEST_UTILS_END_HPP
+#define BOOST_MOVE_UNIQUE_PTR_TEST_UTILS_END_HPP
+
+#ifndef BOOST_MOVE_UNIQUE_PTR_TEST_UTILS_BEG_HPP
+#error "unique_ptr_test_utils_beg.hpp MUST be included before this header"
+#endif
+
+//Define the incomplete I type and out of line functions
+
+struct I
+{
+   static int count;
+   I() {++count;}
+   I(const A&) {++count;}
+   ~I() {--count;}
+};
+
+int I::count = 0;
+
+I* get() {return new I;}
+I* get_array(int i) {return new I[i];}
+
+void check(int i)
+{
+   BOOST_TEST(I::count == i);
+}
+
+template <class T, class D>
+J<T, D>::~J() {}
+
+void reset_counters()
+{  A::count = 0; B::count = 0; I::count = 0; }
+
+#endif   //BOOST_MOVE_UNIQUE_PTR_TEST_UTILS_END_HPP
diff --git a/test/unique_ptr_types.cpp b/test/unique_ptr_types.cpp
new file mode 100644
index 0000000..7dbc0c3
--- /dev/null
+++ b/test/unique_ptr_types.cpp
@@ -0,0 +1,200 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Howard Hinnant 2009
+// (C) Copyright Ion Gaztanaga 2014-2014.
+//
+// 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)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#include <boost/move/utility_core.hpp>
+#include <boost/move/unique_ptr.hpp>
+#include <boost/move/detail/type_traits.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+//////////////////////////////////////////////
+//
+// The initial implementation of these tests
+// was written by Howard Hinnant. 
+//
+// These test were later refactored grouping
+// and porting them to Boost.Move.
+//
+// Many thanks to Howard for releasing his C++03
+// unique_ptr implementation with such detailed
+// test cases.
+//
+//////////////////////////////////////////////
+
+#include "unique_ptr_test_utils_beg.hpp"
+
+namespace bml = ::boost::movelib;
+namespace bmupmu = ::boost::move_upmu;
+
+////////////////////////////////
+//   unique_ptr_pointer_type
+////////////////////////////////
+namespace unique_ptr_pointer_type {
+
+struct Deleter
+{
+   struct pointer {};
+};
+
+// Test unique_ptr::pointer type
+void test()
+{
+   //Single unique_ptr
+   {
+   typedef bml::unique_ptr<int> P;
+   BOOST_STATIC_ASSERT((bmupmu::is_same<P::pointer, int*>::value));
+   }
+   {
+   typedef bml::unique_ptr<int, Deleter> P;
+   BOOST_STATIC_ASSERT((bmupmu::is_same<P::pointer, Deleter::pointer>::value));
+   }
+   //Unbounded array unique_ptr
+   {
+   typedef bml::unique_ptr<int[]> P;
+   BOOST_STATIC_ASSERT((bmupmu::is_same<P::pointer, int*>::value));
+   }
+   {
+   typedef bml::unique_ptr<int[], Deleter> P;
+   BOOST_STATIC_ASSERT((bmupmu::is_same<P::pointer, Deleter::pointer>::value));
+   }
+   //Bounded array unique_ptr
+   {
+   typedef bml::unique_ptr<int[5]> P;
+   BOOST_STATIC_ASSERT((bmupmu::is_same<P::pointer, int*>::value));
+   }
+   {
+   typedef bml::unique_ptr<int[5], Deleter> P;
+   BOOST_STATIC_ASSERT((bmupmu::is_same<P::pointer, Deleter::pointer>::value));
+   }
+   //Unbounded array of bounded array unique_ptr
+   {
+   typedef int int_5_t [5];
+   typedef bml::unique_ptr<int_5_t[]> P;
+   BOOST_STATIC_ASSERT((bmupmu::is_same<P::pointer, int_5_t*>::value));
+   }
+   {
+   typedef int int_5_t [5];
+   typedef bml::unique_ptr<int_5_t[], Deleter> P;
+   BOOST_STATIC_ASSERT((bmupmu::is_same<P::pointer, Deleter::pointer>::value));
+   }
+}
+
+}  //namespace unique_ptr_pointer_type {
+
+////////////////////////////////
+//    unique_ptr_deleter_type
+////////////////////////////////
+namespace unique_ptr_deleter_type {
+
+struct Deleter
+{};
+
+// Test unique_ptr::deleter type
+void test()
+{
+   //Single unique_ptr
+   {
+   typedef bml::unique_ptr<int> P;
+   BOOST_STATIC_ASSERT((bmupmu::is_same<P::deleter_type, bml::default_delete<int> >::value));
+   }
+   {
+   typedef bml::unique_ptr<int, Deleter> P;
+   BOOST_STATIC_ASSERT((bmupmu::is_same<P::deleter_type, Deleter >::value));
+   }
+   //Unbounded array unique_ptr
+   {
+   typedef bml::unique_ptr<int[]> P;
+   BOOST_STATIC_ASSERT((bmupmu::is_same<P::deleter_type, bml::default_delete<int[]> >::value));
+   }
+   {
+   typedef bml::unique_ptr<int[], Deleter> P;
+   BOOST_STATIC_ASSERT((bmupmu::is_same<P::deleter_type, Deleter >::value));
+   }
+   //Bounded array unique_ptr
+   {
+   typedef bml::unique_ptr<int[2]> P;
+   BOOST_STATIC_ASSERT((bmupmu::is_same<P::deleter_type, bml::default_delete<int[2]> >::value));
+   }
+   {
+   typedef bml::unique_ptr<int[2], Deleter> P;
+   BOOST_STATIC_ASSERT((bmupmu::is_same<P::deleter_type, Deleter >::value));
+   }
+}
+
+}  //namespace unique_ptr_deleter_type {
+
+////////////////////////////////
+//    unique_ptr_element_type
+////////////////////////////////
+namespace unique_ptr_element_type {
+
+// Test unique_ptr::deleter type
+void test()
+{
+   //Single unique_ptr
+   {
+   typedef bml::unique_ptr<const int> P;
+   BOOST_STATIC_ASSERT((bmupmu::is_same<P::element_type, const int>::value));
+   }
+   //Unbounded array unique_ptr
+   {
+   typedef bml::unique_ptr<const int[]> P;
+   BOOST_STATIC_ASSERT((bmupmu::is_same<P::element_type, const int>::value));
+   }
+   //Bounded array unique_ptr
+   {
+   typedef bml::unique_ptr<const int[2]> P;
+   BOOST_STATIC_ASSERT((bmupmu::is_same<P::element_type, const int>::value));
+   }
+}
+
+}  //namespace unique_ptr_element_type {
+
+////////////////////////////////
+//    unique_ptr_construct_assign_traits
+////////////////////////////////
+
+namespace unique_ptr_construct_assign_traits {
+
+   void test()
+   {
+      typedef bml::unique_ptr<int> unique_ptr_t;
+      //Even if BOOST_MOVE_TT_CXX11_IS_COPY_CONSTRUCTIBLE is not defined
+      //boost::unique_ptr shall work with boost::movelib traits
+      BOOST_STATIC_ASSERT(!(boost::move_detail::is_copy_constructible<unique_ptr_t>::value));
+      //Even if BOOST_MOVE_TT_CXX11_IS_COPY_ASSIGNABLE is not defined
+      //boost::unique_ptr shall work with boost::movelib traits
+      BOOST_STATIC_ASSERT(!(boost::move_detail::is_copy_assignable<unique_ptr_t>::value));
+      //Important traits for containers like boost::vector
+      BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_constructible<unique_ptr_t>::value));
+      BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_assignable<unique_ptr_t>::value));
+   }
+
+}  //namespace unique_ptr_construct_assign_traits {
+
+////////////////////////////////
+//             main
+////////////////////////////////
+
+int main()
+{
+   //General
+   unique_ptr_pointer_type::test();
+   unique_ptr_deleter_type::test();
+   unique_ptr_element_type::test();
+   unique_ptr_construct_assign_traits::test();
+
+   //Test results
+   return boost::report_errors();
+}
+
+#include "unique_ptr_test_utils_end.hpp"