// Flip an edge, work only in 2D and 3D
Dart_handle
flip_edge (LCC & m, Dart_handle d)
{
  CGAL_assertion ( !m.is_free(d,2) );
  CGAL_assertion ( !m.is_free(d,1) && !m.is_free(d,0) );
  CGAL_assertion ( !m.is_free(m.beta(d,2), 0) && !m.is_free(m.beta(d, 2), 1) );
  
  if (!m.is_removable<1>(d)) return LCC::null_handle;

  Dart_handle d1 = m.beta(d,1);
  Dart_handle d2 = m.beta(d,2,0);

  CGAL_assertion ( !m.is_free(d1,1) && !m.is_free(d2,0) );

  Dart_handle d3 = m.beta(d1,1);
  Dart_handle d4 = m.beta(d2, 0);

  // We isolated the edge
  m.basic_link_beta_1(m.beta(d,0), m.beta(d,2,1));
  m.basic_link_beta_0(m.beta(d,1), m.beta(d,2,0));
  if ( !m.is_free(d,3) )
  {
    m.basic_link_beta_0(m.beta(d,0,3), m.beta(d,2,1,3));
    m.basic_link_beta_1(m.beta(d,1,3), m.beta(d,2,0,3));
  }

  // Then we push the two extremities.
  m.basic_link_beta_0(d3, d);
  m.basic_link_beta_0(d2, m.beta(d,2));
  m.link_beta_1(d4, d);
  m.link_beta_1(d1, m.beta(d,2));

  if ( !m.is_free(d,3) )
  {
    m.basic_link_beta_0(m.beta(d4,3), m.beta(d,3));
    m.basic_link_beta_0(m.beta(d1,3), m.beta(d,2,3));
    m.link_beta_1(m.beta(d3,3), m.beta(d,3));
    m.link_beta_1(m.beta(d2,3), m.beta(d,2,3));
  }
  
  // CGAL::remove_cell<LCC,1>(m, d);
  // insert_cell_1_in_cell_2(m, d1, d1->beta(1)->beta(1));

  return d;
}