viennagrid_numeric compare(viennagrid::mesh const & mesh1, NTreeNode * ntree1, viennagrid::quantity_field const & solution1,
                           viennagrid::mesh const & mesh2, NTreeNode * ntree2, viennagrid::quantity_field const & solution2,
                           viennagrid_numeric inside_epsilon, viennagrid_numeric epsilon)
{

  typedef viennagrid::result_of::const_element_range<MeshType>::type          ConstElementRangeType;
  typedef viennagrid::result_of::iterator<ConstElementRangeType>::type        ConstElementRangeIterator;


  ConstElementRangeType vertices1(mesh1, 0);
  ConstElementRangeType vertices2(mesh2, 0);

  ConstElementRangeType lines1(mesh1, 1);
  ConstElementRangeType lines2(mesh2, 1);

  ConstElementRangeType triangles1(mesh1, 2);
  ConstElementRangeType triangles2(mesh2, 2);


  viennagrid_numeric distance_vertices1 = compare_on_vertices(mesh1, ntree1, solution1, mesh2, ntree2, solution2, inside_epsilon);
  viennagrid_numeric distance_vertices2 = compare_on_vertices(mesh2, ntree2, solution2, mesh1, ntree1, solution1, inside_epsilon);


  viennagrid_numeric worst_distance = -1;

  for (ConstElementRangeIterator lit1 = lines1.begin(); lit1 != lines1.end(); ++lit1)
  {
    PointType l1p1 = viennagrid::get_point( viennagrid::vertices(*lit1)[0] );
    PointType l1p2 = viennagrid::get_point( viennagrid::vertices(*lit1)[1] );

    for (ConstElementRangeIterator lit2 = lines2.begin(); lit2 != lines2.end(); ++lit2)
    {
      PointType l2p1 = viennagrid::get_point( viennagrid::vertices(*lit2)[0] );
      PointType l2p2 = viennagrid::get_point( viennagrid::vertices(*lit2)[1] );

      bool intersect = viennagrid::element_line_intersect(*lit2, l1p1, l1p2, epsilon);
      if (intersect)
      {
        std::pair<PointType, PointType> cp = viennagrid::closest_points(*lit1, *lit2);
        if (!(viennagrid::detail::is_equal(epsilon, cp.first, l1p1) ||
              viennagrid::detail::is_equal(epsilon, cp.first, l1p2) ||
              viennagrid::detail::is_equal(epsilon, cp.first, l2p1) ||
              viennagrid::detail::is_equal(epsilon, cp.first, l2p2)))
        {
          viennagrid_numeric value1 = get_value(mesh1, ntree1, solution1, cp.first, inside_epsilon);
          viennagrid_numeric value2 = get_value(mesh2, ntree2, solution2, cp.first, inside_epsilon);

          if ((value1 < 0) || (value2 < 0))
            continue;

          viennagrid_numeric distance = std::abs(value1 - value2);
          if (worst_distance < distance)
            worst_distance = distance;
        }
      }
    }
  }

  return std::max( std::max(distance_vertices1, distance_vertices2), worst_distance );
}
static int main_(int /* argc */, char ** /*argv*/)
{
    platformstl::file_path_buffer       path1;
    platformstl::file_path_buffer       path2;

    stlsoft::scoped_handle<char const*>     scoper1(::tmpnam(&path1[0]), ::remove);
    stlsoft::scoped_handle<char const*>     scoper2(::tmpnam(&path2[0]), ::remove);

    // Define the data:
    //
    // "FastFormat can write to vectored file APIs"
    static char fragment0[] =   " ";
    static char fragment1[] =   "FastFormat";
    static char fragment2[] =   "can";
    static char fragment3[] =   "write";
    static char fragment4[] =   "to";
    static char fragment5[] =   "vectored";
    static char fragment6[] =   "file";
    static char fragment7[] =   "APIs";

    fprintf(stdout, "writing to '%s' via raw API (writev())\n", path1.c_str());
    {
        iovec   vecs[] = 
        {
                {   &fragment1[0],  STLSOFT_NUM_ELEMENTS(fragment1) - 1 }   // "FastFormat"
            ,   {   &fragment0[0],  STLSOFT_NUM_ELEMENTS(fragment0) - 1 }   // " "
            ,   {   &fragment2[0],  STLSOFT_NUM_ELEMENTS(fragment2) - 1 }   // "can"
            ,   {   &fragment0[0],  STLSOFT_NUM_ELEMENTS(fragment0) - 1 }   // " "
            ,   {   &fragment3[0],  STLSOFT_NUM_ELEMENTS(fragment3) - 1 }   // "write"
            ,   {   &fragment0[0],  STLSOFT_NUM_ELEMENTS(fragment0) - 1 }   // " "
            ,   {   &fragment4[0],  STLSOFT_NUM_ELEMENTS(fragment4) - 1 }   // "to"
            ,   {   &fragment0[0],  STLSOFT_NUM_ELEMENTS(fragment0) - 1 }   // " "
            ,   {   &fragment5[0],  STLSOFT_NUM_ELEMENTS(fragment5) - 1 }   // "vectored"
            ,   {   &fragment0[0],  STLSOFT_NUM_ELEMENTS(fragment0) - 1 }   // " "
            ,   {   &fragment6[0],  STLSOFT_NUM_ELEMENTS(fragment6) - 1 }   // "file"
            ,   {   &fragment0[0],  STLSOFT_NUM_ELEMENTS(fragment0) - 1 }   // " "
            ,   {   &fragment7[0],  STLSOFT_NUM_ELEMENTS(fragment7) - 1 }   // "APIs"
        };

        int     fh  =   ::open(path1.c_str(), O_RDWR | O_CREAT, S_IWRITE | S_IREAD);
        ssize_t cb  =   ::writev(fh, &vecs[0], STLSOFT_NUM_ELEMENTS(vecs));

        ::close(fh);

        STLSOFT_SUPPRESS_UNUSED(cb);
    }

    fprintf(stdout, "writing to '%s' via FastFormat's vectored_file sink\n", path2.c_str());
    {
        int                             fh  =   ::open(path2.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IWRITE | S_IREAD);
        stlsoft::scoped_handle<int>     fh_(fh, ::close, -1);
        fastformat::sinks::vectored_file_sink  s(fh);

        fastformat::fmt(s, "{1}{0}{2}{0}{3}{0}{4}{0}{5}{0}{6}{0}{7}", fragment0, fragment1, fragment2, fragment3, fragment4, fragment5, fragment6, fragment7);
    }

    fprintf(stdout, "memory mapping '%s'\n", path1.c_str());
    platformstl::file_lines lines1(path1.c_str());

    fprintf(stdout, "memory mapping '%s'\n", path2.c_str());
    platformstl::file_lines lines2(path2.c_str());

    if(lines1 != lines2)
    {
        fprintf(stderr, "file contents differ!\n");
    }
    else
    {
        fprintf(stdout, "file contents identical\n");
    }

    return EXIT_SUCCESS;
}