diff --git a/test/test_fcl_collision-bench.py b/test/test_fcl_collision-bench.py
new file mode 100644
index 0000000000000000000000000000000000000000..8bd9836e35dcd2993efff7517c29ff5edc3fa9ab
--- /dev/null
+++ b/test/test_fcl_collision-bench.py
@@ -0,0 +1,59 @@
+import matplotlib.pyplot as plt
+import csv, sys, numpy as np
+from math import sqrt
+
+filename = sys.argv[1] 
+
+with open(filename, 'r') as file:
+    reader = csv.reader (file, strict = True)
+    fieldnames = None
+    #fieldnames = reader.fieldnames
+    converters = (str, int, int, int, float, lambda x: float(x)*1e-3)
+
+    for row in reader:
+        if fieldnames is None:
+            fieldnames = [ n.strip() for n in row]
+            values = []
+            continue
+
+        values.append ( [ c(v) for v, c in zip(row, converters) ] )
+
+request1 = values[:int(len(values)/2)]
+request2 = values[int(len(values)/2):]
+
+Ntransforms = 1
+while values[0][0:3] == values[Ntransforms][0:3]:
+    Ntransforms += 1
+
+splitMethods = ['avg', 'med', 'cen']
+BVs = list (set ([ v[0] for v in request1[::Ntransforms] ]))
+xvals = [ BVs.index(v[0]) + len(BVs)*v[2] + 3*len(BVs)*v[1] for v in request1[::Ntransforms] ]
+cases = [ v[0] + ("*" if v[1] == 1 else "") + " " + splitMethods[v[2]] for v in request1[::Ntransforms] ]
+
+idx_reorder = sorted (list(range(len(xvals))), key=lambda i: xvals[i])
+def reorder (l): return [ l[i] for i in idx_reorder ]
+
+xvals_s = reorder (xvals)
+cases_s = reorder (cases)
+
+# Time
+plt.figure(0)
+for i in range(Ntransforms):
+    plt.plot(xvals_s, reorder([ v[5] for v in request1[i::Ntransforms] ]) , '-.o', label=str(i))
+    plt.plot(xvals_s, reorder([ v[5] for v in request2[i::Ntransforms] ]) , ':+',  label=str(i)+"+lb")
+
+plt.legend()
+plt.xticks(ticks=xvals_s, labels=cases_s, rotation=90)
+plt.ylabel('Time (us)')
+plt.yscale('log')
+
+# Distance
+plt.figure(1)
+for i in range(Ntransforms):
+    plt.plot(xvals_s, reorder([ v[4] for v in request2[i::Ntransforms] ]) , ':+',  label=str(i)+"+lb")
+
+plt.legend()
+plt.ylabel('Distance lower bound')
+plt.xticks(ticks=xvals_s, labels=cases_s, rotation=90)
+
+plt.show()
diff --git a/test/test_fcl_collision.cpp b/test/test_fcl_collision.cpp
index 41aa95f35c1cc5d6e270d511cbd2a3caeed8a3d5..eb09945343f49809851d221e95624bc8cc687c7a 100644
--- a/test/test_fcl_collision.cpp
+++ b/test/test_fcl_collision.cpp
@@ -33,7 +33,11 @@
  *  POSSIBILITY OF SUCH DAMAGE.
  */
 
-/** \author Jia Pan */
+/** \author Joseph Mirabel */
+
+#define BOOST_CHRONO_VERSION 2
+#include <boost/chrono/chrono.hpp>
+#include <boost/chrono/chrono_io.hpp>
 
 #define BOOST_TEST_MODULE FCL_COLLISION
 #define BOOST_TEST_DYN_LINK
@@ -47,38 +51,15 @@
 #include <hpp/fcl/BV/BV.h>
 #include <hpp/fcl/shape/geometric_shapes.h>
 #include <hpp/fcl/narrowphase/narrowphase.h>
+#include <hpp/fcl/mesh_loader/assimp.h>
 #include "test_fcl_utility.h"
 #include "fcl_resources/config.h"
 #include <boost/filesystem.hpp>
 
 using namespace hpp::fcl;
 
-template<typename BV>
-bool collide_Test(const Transform3f& tf,
-                  const std::vector<Vec3f>& vertices1, const std::vector<Triangle>& triangles1,
-                  const std::vector<Vec3f>& vertices2, const std::vector<Triangle>& triangles2, SplitMethodType split_method, bool verbose = true);
-
-template<typename BV>
-bool collide_Test2(const Transform3f& tf,
-                   const std::vector<Vec3f>& vertices1, const std::vector<Triangle>& triangles1,
-                   const std::vector<Vec3f>& vertices2, const std::vector<Triangle>& triangles2, SplitMethodType split_method, bool verbose = true);
-
-template<typename BV, typename TraversalNode>
-bool collide_Test_Oriented(const Transform3f& tf,
-                           const std::vector<Vec3f>& vertices1, const std::vector<Triangle>& triangles1,
-                           const std::vector<Vec3f>& vertices2, const std::vector<Triangle>& triangles2, SplitMethodType split_method, bool verbose = true);
-
-
-template<typename BV>
-bool test_collide_func(const Transform3f& tf,
-                       const std::vector<Vec3f>& vertices1, const std::vector<Triangle>& triangles1,
-                       const std::vector<Vec3f>& vertices2, const std::vector<Triangle>& triangles2, SplitMethodType split_method);
-
 int num_max_contacts = std::numeric_limits<int>::max();
 
-std::vector<Contact> global_pairs;
-std::vector<Contact> global_pairs_now;
-
 BOOST_AUTO_TEST_CASE(OBB_Box_test)
 {
   FCL_REAL r_extents[] = {-1000, -1000, -1000, 1000, 1000, 1000};
@@ -230,6 +211,262 @@ BOOST_AUTO_TEST_CASE(OBB_AABB_test)
   std::cout << std::endl;
 }
 
+std::ostream* bench_stream = NULL;
+bool bs_nl = true;
+bool bs_hp = false;
+#define BENCHMARK(stream) if (bench_stream!=NULL) { *bench_stream << (bs_nl ? "" : ", ") << stream; bs_nl = false; }
+#define BENCHMARK_HEADER(stream) if (!bs_hp) { BENCHMARK(stream) }
+#define BENCHMARK_NEXT() if (bench_stream!=NULL && !bs_nl) { *bench_stream << '\n';  bs_nl = true; bs_hp = true; }
+
+typedef std::vector<Contact> Contacts_t;
+typedef boost::mpl::vector<OBB, RSS, AABB, KDOP<24>, KDOP<18>, KDOP<16>, kIOS, OBBRSS> BVs_t;
+
+typedef boost::chrono::high_resolution_clock clock_type;
+typedef clock_type::duration duration_type;
+
+#define BV_STR_SPECIALIZATION(bv) \
+  template <> const char* str< bv > () { return #bv; }
+template <typename BV> const char* str();
+BV_STR_SPECIALIZATION(AABB)
+BV_STR_SPECIALIZATION(OBB)
+BV_STR_SPECIALIZATION(RSS)
+BV_STR_SPECIALIZATION(KDOP<24>)
+BV_STR_SPECIALIZATION(KDOP<18>)
+BV_STR_SPECIALIZATION(KDOP<16>)
+BV_STR_SPECIALIZATION(kIOS)
+BV_STR_SPECIALIZATION(OBBRSS)
+
+template <typename T> struct wrap {};
+
+struct base_traits
+{
+  enum { IS_IMPLEMENTED = true
+  };
+};
+
+template<typename BV, int _Options>
+struct traits : base_traits
+{};
+
+template<size_t N>
+struct traits<KDOP<N>, 0> : base_traits
+{
+  enum { IS_IMPLEMENTED = false
+  };
+};
+
+struct mesh_mesh_run_test
+{
+  mesh_mesh_run_test (const std::vector<Transform3f>& _transforms,
+      const CollisionRequest _request
+      ) :
+    transforms (_transforms),
+    request (_request),
+    enable_statistics (false),
+    benchmark (false),
+    isInit (false),
+    indent (0)
+  {}
+
+  const std::vector<Transform3f>& transforms;
+  const CollisionRequest request;
+  bool enable_statistics, benchmark;
+  std::vector<Contacts_t> contacts;
+  std::vector<Contacts_t> contacts_ref;
+  bool isInit;
+
+  int indent;
+
+  const char* getindent()
+  {
+    assert (indent < 9);
+    static const char* t[] = { "", "\t", "\t\t", "\t\t\t", "\t\t\t\t", "\t\t\t\t\t",
+      "\t\t\t\t\t\t", "\t\t\t\t\t\t\t", "\t\t\t\t\t\t\t\t" };
+    return t[indent];
+  }
+
+  template<typename BV>
+  void query (
+      const std::vector<Transform3f>& transforms,
+      SplitMethodType splitMethod,
+      const CollisionRequest request,
+      std::vector<Contacts_t>& contacts
+      )
+  {
+    BENCHMARK_HEADER("BV");
+    BENCHMARK_HEADER("oriented");
+    BENCHMARK_HEADER("Split method");
+    if (enable_statistics) {
+      BENCHMARK_HEADER("num_bv_tests");
+      BENCHMARK_HEADER("num_leaf_tests");
+    }
+    BENCHMARK_HEADER("numContacts");
+    BENCHMARK_HEADER("distance_lower_bound");
+    BENCHMARK_HEADER("time");
+    BENCHMARK_NEXT();
+
+    typedef BVHModel<BV> BVH_t;
+    typedef boost::shared_ptr<BVH_t> BVHPtr_t;
+
+    BVHPtr_t model1 (new BVH_t), model2 (new BVH_t);
+    model1->bv_splitter.reset(new BVSplitter<BV>(splitMethod));
+    model2->bv_splitter.reset(new BVSplitter<BV>(splitMethod));
+
+    loadPolyhedronFromResource (TEST_RESOURCES_DIR "/env.obj", Vec3f::Ones(), model1);
+    loadPolyhedronFromResource (TEST_RESOURCES_DIR "/rob.obj", Vec3f::Ones(), model2);
+
+    clock_type::time_point start, end;
+    const Transform3f tf2;
+    const std::size_t N = transforms.size();
+    std::size_t s = N, e;
+    std::vector<CollisionResult> results (2 * N);
+    if (traits<BV, 0>::IS_IMPLEMENTED)
+    {
+      BOOST_TEST_MESSAGE (getindent() << "BV: " << str<BV>() << " oriented");
+      ++indent;
+
+      s = 0;
+      e = N;
+      start = clock_type::now();
+      for(std::size_t i = 0; i < transforms.size(); ++i)
+      {
+        const Transform3f& tf1 = transforms[i];
+
+        CollisionResult& local_result (results[i]);
+        MeshCollisionTraversalNode<BV, 0> node (request);
+        node.enable_statistics = enable_statistics;
+
+        bool success = initialize (node,
+            *model1, tf1, *model2, tf2,
+            local_result);
+        BOOST_REQUIRE (success);
+
+        collide(&node, request, local_result);
+
+        end = clock_type::now();
+
+        BENCHMARK(str<BV>());
+        BENCHMARK(1);
+        BENCHMARK(splitMethod);
+        if (enable_statistics) {
+          BOOST_TEST_MESSAGE (getindent() << "statistics: " << node.num_bv_tests << " " << node.num_leaf_tests);
+          BOOST_TEST_MESSAGE (getindent() << "nb contacts: " << local_result.numContacts());
+          BENCHMARK(node.num_bv_tests);
+          BENCHMARK(node.num_leaf_tests);
+        }
+        BENCHMARK(local_result.numContacts());
+        BENCHMARK(local_result.distance_lower_bound);
+        BENCHMARK((end - start).count());
+        BENCHMARK_NEXT();
+      }
+      --indent;
+    }
+
+    if (traits<BV, RelativeTransformationIsIdentity>::IS_IMPLEMENTED)
+    {
+      BOOST_TEST_MESSAGE (getindent() << "BV: " << str<BV>());
+      ++indent;
+
+      e = 2*N;
+      for(std::size_t i = 0; i < transforms.size(); ++i)
+      {
+        start = clock_type::now();
+        const Transform3f tf1 = transforms[i];
+
+        CollisionResult& local_result (results[i + N]);
+        MeshCollisionTraversalNode<BV, RelativeTransformationIsIdentity> node (request);
+        node.enable_statistics = enable_statistics;
+
+        BVH_t* model1_tmp = new BVH_t(*model1);
+        Transform3f tf1_tmp = tf1;
+        BVH_t* model2_tmp = new BVH_t(*model2);
+        Transform3f tf2_tmp = tf2;
+
+        bool success = initialize (node,
+            *model1_tmp, tf1_tmp, *model2_tmp, tf2_tmp,
+            local_result, true, true);
+        BOOST_REQUIRE (success);
+
+        collide(&node, request, local_result);
+        delete model1_tmp;
+        delete model2_tmp;
+
+        end = clock_type::now();
+        BENCHMARK(str<BV>());
+        BENCHMARK("0");
+        BENCHMARK(splitMethod);
+        if (enable_statistics) {
+          BOOST_TEST_MESSAGE (getindent() << "statistics: " << node.num_bv_tests << " " << node.num_leaf_tests);
+          BOOST_TEST_MESSAGE (getindent() << "nb contacts: " << local_result.numContacts());
+          BENCHMARK(node.num_bv_tests);
+          BENCHMARK(node.num_leaf_tests);
+        }
+        BENCHMARK(local_result.numContacts());
+        BENCHMARK(local_result.distance_lower_bound);
+        BENCHMARK((end - start).count());
+        BENCHMARK_NEXT();
+      }
+      --indent;
+    }
+
+    contacts.resize (2*N);
+    for(std::size_t i = s; i < e; ++i)
+    {
+      const CollisionResult& local_result (results[i]);
+
+      if(local_result.numContacts() > 0)
+      {
+        local_result.getContacts(contacts[i]);
+        std::sort(contacts[i].begin(), contacts[i].end());
+      }
+    }
+  }
+
+  template<typename BV>
+  void check ()
+  {
+    if (benchmark) return;
+    const std::size_t N = transforms.size();
+
+    BOOST_REQUIRE_EQUAL(contacts.size(), 2*N);
+    BOOST_REQUIRE_EQUAL(contacts.size(), contacts_ref.size());
+
+    if (traits<BV, 0>::IS_IMPLEMENTED) {
+      for(std::size_t i = 0; i < N; ++i) {
+        BOOST_CHECK_EQUAL(contacts_ref[i].size(), contacts[i].size());
+        for(std::size_t j = 0; j < contacts[i].size(); ++j) {
+          BOOST_CHECK_EQUAL(contacts_ref[i][j].b1, contacts[i][j].b1);
+          BOOST_CHECK_EQUAL(contacts_ref[i][j].b2, contacts[i][j].b2);
+        }
+      }
+    }
+    if (traits<BV, RelativeTransformationIsIdentity>::IS_IMPLEMENTED) {
+      for(std::size_t i = N; i < 2*N; ++i) {
+        BOOST_CHECK_EQUAL(contacts_ref[i].size(), contacts[i].size());
+        for(std::size_t j = 0; j < contacts[i].size(); ++j) {
+          BOOST_CHECK_EQUAL(contacts_ref[i][j].b1, contacts[i][j].b1);
+          BOOST_CHECK_EQUAL(contacts_ref[i][j].b2, contacts[i][j].b2);
+        }
+      }
+    }
+  }
+
+  template<typename BV>
+  void operator() (wrap<BV>)
+  {
+    SplitMethodType splitMethods[] = {SPLIT_METHOD_MEAN, SPLIT_METHOD_MEDIAN, SPLIT_METHOD_BV_CENTER};
+    for (int i = 0; i < 3; ++i)
+    {
+      BOOST_TEST_MESSAGE (getindent() << "splitMethod: " << splitMethods[i]);
+      ++indent;
+      query <BV> (transforms, splitMethods[i], request, (isInit ? contacts : contacts_ref));
+      if (isInit) check<BV> ();
+      isInit = true;
+      --indent;
+    }
+  }
+};
+
 // This test
 //  1. load two objects "env.obj" and "rob.obj" from directory
 //     fcl_resources,
@@ -248,807 +485,60 @@ BOOST_AUTO_TEST_CASE(OBB_AABB_test)
 //
 BOOST_AUTO_TEST_CASE(mesh_mesh)
 {
-  std::vector<Vec3f> p1, p2;
-  std::vector<Triangle> t1, t2;
-  boost::filesystem::path path(TEST_RESOURCES_DIR);
-  
-  loadOBJFile((path / "env.obj").string().c_str(), p1, t1);
-  loadOBJFile((path / "rob.obj").string().c_str(), p2, t2);
-
   std::vector<Transform3f> transforms;
   FCL_REAL extents[] = {-3000, -3000, 0, 3000, 3000, 3000};
   std::size_t n = 10;
-  bool verbose = false;
 
   generateRandomTransforms(extents, transforms, n);
 
-  // collision
+  Eigen::IOFormat f (Eigen::FullPrecision, 0, ", ", ",", "", "", "(", ")");
   for(std::size_t i = 0; i < transforms.size(); ++i)
   {
-    Eigen::IOFormat f (Eigen::FullPrecision, 0, ", ", ",", "", "", "(", ")");
-
-    std::cerr
-      << "q1=" << transforms [i].getTranslation ().format (f) << "+" <<
-      transforms [i].getQuatRotation ().coeffs ().format (f) << std::endl;
-    global_pairs.clear();
-    global_pairs_now.clear();
-
-    // First test: constacts are stored in vector global_pairs
-    collide_Test<OBB>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose);
-
-    collide_Test<OBB>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test<OBB>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test<RSS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test<RSS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test<RSS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test<AABB>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test<AABB>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test<AABB>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test<KDOP<24> >(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test<KDOP<24> >(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test<KDOP<24> >(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test<KDOP<18> >(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test<KDOP<18> >(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test<KDOP<18> >(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test<KDOP<16> >(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test<KDOP<16> >(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test<KDOP<16> >(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test2<OBB>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test2<OBB>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test2<OBB>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test2<RSS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test2<RSS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test2<RSS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test2<AABB>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test2<AABB>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test2<AABB>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test2<KDOP<24> >(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test2<KDOP<24> >(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test2<KDOP<24> >(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test2<KDOP<18> >(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test2<KDOP<18> >(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test2<KDOP<18> >(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test2<KDOP<16> >(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test2<KDOP<16> >(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test2<KDOP<16> >(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test_Oriented<OBB, MeshCollisionTraversalNodeOBB>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose);
-
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test_Oriented<OBB, MeshCollisionTraversalNodeOBB>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose);
-
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test_Oriented<OBB, MeshCollisionTraversalNodeOBB>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test_Oriented<RSS, MeshCollisionTraversalNodeRSS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test_Oriented<RSS, MeshCollisionTraversalNodeRSS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test_Oriented<RSS, MeshCollisionTraversalNodeRSS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    test_collide_func<RSS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    test_collide_func<OBB>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    test_collide_func<AABB>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    
-    collide_Test<kIOS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test<kIOS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test<kIOS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test2<kIOS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test2<kIOS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test2<kIOS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-    
-    collide_Test_Oriented<kIOS, MeshCollisionTraversalNodekIOS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test_Oriented<kIOS, MeshCollisionTraversalNodekIOS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test_Oriented<kIOS, MeshCollisionTraversalNodekIOS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    test_collide_func<kIOS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    test_collide_func<kIOS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    test_collide_func<kIOS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test<OBBRSS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test<OBBRSS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test<OBBRSS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test2<OBBRSS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test2<OBBRSS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test2<OBBRSS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-    
-    collide_Test_Oriented<OBBRSS, MeshCollisionTraversalNodeOBBRSS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test_Oriented<OBBRSS, MeshCollisionTraversalNodeOBBRSS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    collide_Test_Oriented<OBBRSS, MeshCollisionTraversalNodeOBBRSS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER, verbose);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    test_collide_func<OBBRSS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEAN);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    test_collide_func<OBBRSS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_MEDIAN);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-
-    test_collide_func<OBBRSS>(transforms[i], p1, t1, p2, t2, SPLIT_METHOD_BV_CENTER);
-    assert (global_pairs.size() == global_pairs_now.size());
-    for(std::size_t j = 0; j < global_pairs.size(); ++j)
-    {
-      BOOST_CHECK(global_pairs[j].b1 == global_pairs_now[j].b1);
-      BOOST_CHECK(global_pairs[j].b2 == global_pairs_now[j].b2);
-    }
-  }
-}
-
-
-template<typename BV>
-bool collide_Test2(const Transform3f& tf,
-                   const std::vector<Vec3f>& vertices1, const std::vector<Triangle>& triangles1,
-                   const std::vector<Vec3f>& vertices2, const std::vector<Triangle>& triangles2, SplitMethodType split_method, bool verbose)
-{
-  BVHModel<BV> m1;
-  BVHModel<BV> m2;
-  m1.bv_splitter.reset(new BVSplitter<BV>(split_method));
-  m2.bv_splitter.reset(new BVSplitter<BV>(split_method));
-
-  std::vector<Vec3f> vertices1_new(vertices1.size());
-  for(unsigned int i = 0; i < vertices1_new.size(); ++i)
-  {
-    vertices1_new[i] = tf.transform(vertices1[i]);
+    BOOST_TEST_MESSAGE("q" << i << "="
+        << transforms [i].getTranslation  ()          .format (f) << "+"
+        << transforms [i].getQuatRotation ().coeffs ().format (f));
   }
 
-
-  m1.beginModel();
-  m1.addSubModel(vertices1_new, triangles1);
-  m1.endModel();
-
-  m2.beginModel();
-  m2.addSubModel(vertices2, triangles2);
-  m2.endModel();
-
-  Transform3f pose1, pose2;
-
-  CollisionResult local_result;
-  CollisionRequest request (CONTACT, num_max_contacts);
-  MeshCollisionTraversalNode<BV> node (request);
-
-  bool success = initialize <BV> (node, m1, pose1, m2, pose2, local_result);
-  BOOST_REQUIRE (success);
-
-  node.enable_statistics = verbose;
-
-  collide(&node, request, local_result);
-
-  if(local_result.numContacts() > 0)
-  {
-    if(global_pairs.size() == 0)
-    {
-      local_result.getContacts(global_pairs);
-      std::sort(global_pairs.begin(), global_pairs.end());
-    }
-    else
-    {
-      local_result.getContacts(global_pairs_now);
-      std::sort(global_pairs_now.begin(), global_pairs_now.end());
-    }
-
-
-    if(verbose)
-      std::cout << "in collision " << local_result.numContacts() << ": " << std::endl;
-    if(verbose) std::cout << node.num_bv_tests << " " << node.num_leaf_tests << std::endl;
-    return true;
-  }
-  else
-  {
-    if(verbose) std::cout << "collision free " << std::endl;
-    if(verbose) std::cout << node.num_bv_tests << " " << node.num_leaf_tests << std::endl;
-    return false;
-  }
-}
-
-// Test collision between two sets of triangles
-// first object is in pose tf, second object is in pose identity.
-template<typename BV>
-bool collide_Test(const Transform3f& tf,
-                  const std::vector<Vec3f>& vertices1, const std::vector<Triangle>& triangles1,
-                  const std::vector<Vec3f>& vertices2, const std::vector<Triangle>& triangles2, SplitMethodType split_method, bool verbose)
-{
-  BVHModel<BV> m1;
-  BVHModel<BV> m2;
-  m1.bv_splitter.reset(new BVSplitter<BV>(split_method));
-  m2.bv_splitter.reset(new BVSplitter<BV>(split_method));
-
-  m1.beginModel();
-  m1.addSubModel(vertices1, triangles1);
-  m1.endModel();
-
-  m2.beginModel();
-  m2.addSubModel(vertices2, triangles2);
-  m2.endModel();
-
-  Transform3f pose1(tf), pose2;
-
-  CollisionResult local_result;
-  CollisionRequest request (CONTACT, num_max_contacts);
-  MeshCollisionTraversalNode<BV> node (request);
-
-  bool success = initialize <BV> (node, m1, pose1, m2, pose2, local_result);
-  BOOST_REQUIRE (success);
-
-  node.enable_statistics = verbose;
-
-  collide(&node, request, local_result);
-
-  if(local_result.numContacts() > 0)
-  {
-    if(global_pairs.size() == 0)
-    {
-      local_result.getContacts(global_pairs);
-      std::sort(global_pairs.begin(), global_pairs.end());
-    }
-    else
-    {
-      local_result.getContacts(global_pairs_now);
-      std::sort(global_pairs_now.begin(), global_pairs_now.end());
-    }
-
-    if(verbose)
-      std::cout << "in collision " << local_result.numContacts() << ": " << std::endl;
-    if(verbose) std::cout << node.num_bv_tests << " " << node.num_leaf_tests << std::endl;
-    return true;
-  }
-  else
-  {
-    if(verbose) std::cout << "collision free " << std::endl;
-    if(verbose) std::cout << node.num_bv_tests << " " << node.num_leaf_tests << std::endl;
-    return false;
-  }
+  // Request all contacts and check that all methods give the same result.
+  mesh_mesh_run_test runner (transforms, CollisionRequest (CONTACT, num_max_contacts));
+  runner.enable_statistics = true;
+  boost::mpl::for_each<BVs_t, wrap<boost::mpl::placeholders::_1> > (runner);
 }
 
-// This function is the same as collide_Test, except that the type of traversal
-// node is chosen via template argument.
-template<typename BV, typename TraversalNode>
-bool collide_Test_Oriented(const Transform3f& tf,
-                           const std::vector<Vec3f>& vertices1, const std::vector<Triangle>& triangles1,
-                           const std::vector<Vec3f>& vertices2, const std::vector<Triangle>& triangles2, SplitMethodType split_method, bool verbose)
+BOOST_AUTO_TEST_CASE(mesh_mesh_benchmark)
 {
-  BVHModel<BV> m1;
-  BVHModel<BV> m2;
-  m1.bv_splitter.reset(new BVSplitter<BV>(split_method));
-  m2.bv_splitter.reset(new BVSplitter<BV>(split_method));
-
-  m1.beginModel();
-  m1.addSubModel(vertices1, triangles1);
-  m1.endModel();
-
-  m2.beginModel();
-  m2.addSubModel(vertices2, triangles2);
-  m2.endModel();
-
-  Transform3f pose1(tf), pose2;
-
-  CollisionResult local_result;
-  CollisionRequest request (CONTACT, num_max_contacts);
-  TraversalNode node (request);
-  bool success = initialize (node, (const BVHModel<BV>&)m1, pose1,
-                             (const BVHModel<BV>&)m2, pose2, local_result);
-  BOOST_REQUIRE (success);
-
-  node.enable_statistics = verbose;
-
-  collide(&node, request, local_result);
+  std::vector<Transform3f> transforms;
+  FCL_REAL extents[] = {-3000, -3000, 0, 3000, 3000, 3000};
+  std::size_t n = 10;
 
-  if(local_result.numContacts() > 0)
-  {
-    if(global_pairs.size() == 0)
-    {
-      local_result.getContacts(global_pairs);
-      std::sort(global_pairs.begin(), global_pairs.end());
-    }
-    else
-    {
-      local_result.getContacts(global_pairs_now);
-      std::sort(global_pairs_now.begin(), global_pairs_now.end());
-    }
+  generateRandomTransforms(extents, transforms, n);
 
-    if(verbose)
-      std::cout << "in collision " << local_result.numContacts() << ": " << std::endl;
-    if(verbose) std::cout << node.num_bv_tests << " " << node.num_leaf_tests << std::endl;
-    return true;
-  }
-  else
+  Eigen::IOFormat f (Eigen::FullPrecision, 0, ", ", ",", "", "", "(", ")");
+  for(std::size_t i = 0; i < transforms.size(); ++i)
   {
-    if(verbose) std::cout << "collision free " << std::endl;
-    if(verbose) std::cout << node.num_bv_tests << " " << node.num_leaf_tests << std::endl;
-    return false;
+    BOOST_TEST_MESSAGE("q" << i << "="
+        << transforms [i].getTranslation  ()          .format (f) << "+"
+        << transforms [i].getQuatRotation ().coeffs ().format (f));
   }
-}
 
+  // Request all contacts and check that all methods give the same result.
+  typedef boost::mpl::vector<OBB, RSS, AABB, KDOP<24>, KDOP<18>, KDOP<16>, kIOS, OBBRSS> BVs_t;
 
-template<typename BV>
-bool test_collide_func(const Transform3f& tf,
-                       const std::vector<Vec3f>& vertices1, const std::vector<Triangle>& triangles1,
-                       const std::vector<Vec3f>& vertices2, const std::vector<Triangle>& triangles2, SplitMethodType split_method)
-{
-  BVHModel<BV> m1;
-  BVHModel<BV> m2;
-  m1.bv_splitter.reset(new BVSplitter<BV>(split_method));
-  m2.bv_splitter.reset(new BVSplitter<BV>(split_method));
-
-  m1.beginModel();
-  m1.addSubModel(vertices1, triangles1);
-  m1.endModel();
-
-  m2.beginModel();
-  m2.addSubModel(vertices2, triangles2);
-  m2.endModel();
-
-  Transform3f pose1(tf), pose2;
-
-  std::vector<Contact> contacts;
+  std::ofstream ofs ("./test_fcl_collision.benchmark.csv", std::ofstream::out);
+  bench_stream = &ofs;
 
-  CollisionRequest request (CONTACT, num_max_contacts);
-  CollisionResult result;
-  int num_contacts = collide(&m1, pose1, &m2, pose2, 
-                             request, result);
-	
-  result.getContacts(contacts);
-
-  global_pairs_now.resize(num_contacts);
-
-  for(int i = 0; i < num_contacts; ++i)
-  {
-    global_pairs_now[i].b1 = contacts[i].b1;
-    global_pairs_now[i].b2 = contacts[i].b2;
-  }
+  // without lower bound.
+  mesh_mesh_run_test runner1 (transforms, CollisionRequest ());
+  runner1.enable_statistics = false;
+  runner1.benchmark = true;
+  boost::mpl::for_each<BVs_t, wrap<boost::mpl::placeholders::_1> > (runner1);
 
-  std::sort(global_pairs_now.begin(), global_pairs_now.end());
+  // with lower bound.
+  mesh_mesh_run_test runner2 (transforms, CollisionRequest (DISTANCE_LOWER_BOUND, 1));
+  runner2.enable_statistics = false;
+  runner2.benchmark = true;
+  boost::mpl::for_each<BVs_t, wrap<boost::mpl::placeholders::_1> > (runner2);
 
-  if(num_contacts > 0) return true;
-  else return false;
+  bench_stream = NULL;
+  ofs.close();
 }