void HexahedronSetTopologyModifier::removeHexahedraProcess( const sofa::helper::vector<unsigned int> &indices,
        const bool removeIsolatedItems)
{
    if(!m_container->hasHexahedra())
        return;

    bool removeIsolatedVertices = removeIsolatedItems && removeIsolated.getValue();
    bool removeIsolatedEdges = removeIsolatedItems && m_container->hasEdges();
    bool removeIsolatedQuads = removeIsolatedItems && m_container->hasQuads();

    if(removeIsolatedVertices)
    {
        if(!m_container->hasHexahedraAroundVertex())
            m_container->createHexahedraAroundVertexArray();
    }

    if(removeIsolatedEdges)
    {
        if(!m_container->hasHexahedraAroundEdge())
            m_container->createHexahedraAroundEdgeArray();
    }

    if(removeIsolatedQuads)
    {
        if(!m_container->hasHexahedraAroundQuad())
            m_container->createHexahedraAroundQuadArray();
    }

    sofa::helper::vector<unsigned int> quadToBeRemoved;
    sofa::helper::vector<unsigned int> edgeToBeRemoved;
    sofa::helper::vector<unsigned int> vertexToBeRemoved;

    unsigned int lastHexahedron = m_container->getNumberOfHexahedra() - 1;

    helper::WriteAccessor< Data< sofa::helper::vector<Hexahedron> > > m_hexahedron = m_container->d_hexahedron;

    for(unsigned int i=0; i<indices.size(); ++i, --lastHexahedron)
    {
        const Hexahedron &t = m_hexahedron[ indices[i] ];
        const Hexahedron &h = m_hexahedron[ lastHexahedron ];

        if(m_container->hasHexahedraAroundVertex())
        {
            for(unsigned int v=0; v<8; ++v)
            {
                sofa::helper::vector< unsigned int > &shell = m_container->m_hexahedraAroundVertex[ t[v] ];
                shell.erase(remove(shell.begin(), shell.end(), indices[i]), shell.end());
                if(removeIsolatedVertices && shell.empty())
                    vertexToBeRemoved.push_back(t[v]);
            }
        }

        if(m_container->hasHexahedraAroundEdge())
        {
            for(unsigned int e=0; e<12; ++e)
            {
                sofa::helper::vector< unsigned int > &shell = m_container->m_hexahedraAroundEdge[ m_container->m_edgesInHexahedron[indices[i]][e]];
                shell.erase(remove(shell.begin(), shell.end(), indices[i]), shell.end());
                if(removeIsolatedEdges && shell.empty())
                    edgeToBeRemoved.push_back(m_container->m_edgesInHexahedron[indices[i]][e]);
            }
        }

        if(m_container->hasHexahedraAroundQuad())
        {
            for(unsigned int q=0; q<6; ++q)
            {
                sofa::helper::vector< unsigned int > &shell = m_container->m_hexahedraAroundQuad[ m_container->m_quadsInHexahedron[indices[i]][q]];
                shell.erase(remove(shell.begin(), shell.end(), indices[i]), shell.end());
                if(removeIsolatedQuads && shell.empty())
                    quadToBeRemoved.push_back(m_container->m_quadsInHexahedron[indices[i]][q]);
            }
        }

        // now updates the shell information of the edge formely at the end of the array
        if( indices[i] < lastHexahedron )
        {
            if(m_container->hasHexahedraAroundVertex())
            {
                for(unsigned int v=0; v<8; ++v)
                {
                    sofa::helper::vector< unsigned int > &shell = m_container->m_hexahedraAroundVertex[ h[v] ];
                    replace(shell.begin(), shell.end(), lastHexahedron, indices[i]);
                }
            }

            if(m_container->hasHexahedraAroundEdge())
            {
                for(unsigned int e=0; e<12; ++e)
                {
                    sofa::helper::vector< unsigned int > &shell =  m_container->m_hexahedraAroundEdge[ m_container->m_edgesInHexahedron[lastHexahedron][e]];
                    replace(shell.begin(), shell.end(), lastHexahedron, indices[i]);
                }
            }

            if(m_container->hasHexahedraAroundQuad())
            {
                for(unsigned int q=0; q<6; ++q)
                {
                    sofa::helper::vector< unsigned int > &shell =  m_container->m_hexahedraAroundQuad[ m_container->m_quadsInHexahedron[lastHexahedron][q]];
                    replace(shell.begin(), shell.end(), lastHexahedron, indices[i]);
                }
            }
        }

        if(m_container->hasQuadsInHexahedron())
        {
            // removes the quadsInHexahedrons from the quadsInHexahedronArray
            m_container->m_quadsInHexahedron[ indices[i] ] = m_container->m_quadsInHexahedron[ lastHexahedron ]; // overwriting with last valid value.
            m_container->m_quadsInHexahedron.resize( lastHexahedron ); // resizing to erase multiple occurence of the hexa.
        }

        if(m_container->hasEdgesInHexahedron())
        {
            // removes the edgesInHexahedrons from the edgesInHexahedronArray
            m_container->m_edgesInHexahedron[ indices[i] ] = m_container->m_edgesInHexahedron[ lastHexahedron ]; // overwriting with last valid value.
            m_container->m_edgesInHexahedron.resize( lastHexahedron ); // resizing to erase multiple occurence of the hexa.
        }

        // removes the hexahedron from the hexahedronArray
        m_hexahedron[ indices[i] ] = m_hexahedron[ lastHexahedron ]; // overwriting with last valid value.
        m_hexahedron.resize( lastHexahedron ); // resizing to erase multiple occurence of the hexa.
    }

    if( (!quadToBeRemoved.empty()) || (!edgeToBeRemoved.empty()))
    {
        if(!quadToBeRemoved.empty())
        {
            /// warn that quads will be deleted
            removeQuadsWarning(quadToBeRemoved);
        }

        if(!edgeToBeRemoved.empty())
        {
            /// warn that edges will be deleted
            removeEdgesWarning(edgeToBeRemoved);
        }

        propagateTopologicalChanges();

        if(!quadToBeRemoved.empty())
        {
            /// actually remove quads without looking for isolated vertices
            removeQuadsProcess(quadToBeRemoved, false, false);
        }

        if(!edgeToBeRemoved.empty())
        {
            /// actually remove edges without looking for isolated vertices
            removeEdgesProcess(edgeToBeRemoved, false);
        }
    }

    if(!vertexToBeRemoved.empty())
    {
        removePointsWarning(vertexToBeRemoved);
        propagateTopologicalChanges();
        removePointsProcess(vertexToBeRemoved);
    }
}
      void TriangleSetTopologyModifier::removeTrianglesProcess(const sofa::helper::vector<unsigned int> &indices,
							       const bool removeIsolatedEdges,
							       const bool removeIsolatedPoints)
      {

	if(!m_container->hasTriangles()) // this method should only be called when triangles exist
	{
#ifndef NDEBUG
	  sout << "Error. [TriangleSetTopologyModifier::removeTrianglesProcess] triangle array is empty." << endl;
#endif
	  return;
	}


	if(m_container->hasEdges() && removeIsolatedEdges)
	{

	  if(!m_container->hasEdgesInTriangle())
	    m_container->createEdgesInTriangleArray();

	  if(!m_container->hasTrianglesAroundEdge())
	    m_container->createTrianglesAroundEdgeArray();
	}

	if(removeIsolatedPoints)
	{

	  if(!m_container->hasTrianglesAroundVertex())
	    m_container->createTrianglesAroundVertexArray();
	}

	sofa::helper::vector<unsigned int> edgeToBeRemoved;
	sofa::helper::vector<unsigned int> vertexToBeRemoved;
	helper::WriteAccessor< Data< sofa::helper::vector<Triangle> > > m_triangle = m_container->d_triangle;

	unsigned int lastTriangle = m_container->getNumberOfTriangles() - 1;
	for(unsigned int i = 0; i<indices.size(); ++i, --lastTriangle)
	{
	  Triangle &t = m_triangle[ indices[i] ];
	  Triangle &q = m_triangle[ lastTriangle ];

	  if(m_container->hasTrianglesAroundVertex())
	  {
	    for(unsigned int j=0; j<3; ++j)
	    {
	      sofa::helper::vector< unsigned int > &shell = m_container->m_trianglesAroundVertex[ t[j] ];
	      shell.erase(remove(shell.begin(), shell.end(), indices[i]), shell.end());
	      if(removeIsolatedPoints && shell.empty())
		vertexToBeRemoved.push_back(t[j]);
	    }
	  }

	  if(m_container->hasTrianglesAroundEdge())
	  {
	    for(unsigned int j=0; j<3; ++j)
	    {
	      sofa::helper::vector< unsigned int > &shell = m_container->m_trianglesAroundEdge[ m_container->m_edgesInTriangle[indices[i]][j]];
	      shell.erase(remove(shell.begin(), shell.end(), indices[i]), shell.end());
	      if(removeIsolatedEdges && shell.empty())
		edgeToBeRemoved.push_back(m_container->m_edgesInTriangle[indices[i]][j]);
	    }
	  }

	  if(indices[i] < lastTriangle)
	  {

	    if(m_container->hasTrianglesAroundVertex())
	    {

	      for(unsigned int j=0; j<3; ++j)
	      {
		sofa::helper::vector< unsigned int > &shell = m_container->m_trianglesAroundVertex[ q[j] ];
		replace(shell.begin(), shell.end(), lastTriangle, indices[i]);
	      }
	    }

	    if(m_container->hasTrianglesAroundEdge())
	    {

	      for(unsigned int j=0; j<3; ++j)
	      {
		sofa::helper::vector< unsigned int > &shell = m_container->m_trianglesAroundEdge[ m_container->m_edgesInTriangle[lastTriangle][j]];
		replace(shell.begin(), shell.end(), lastTriangle, indices[i]);
	      }
	    }
	  }

	  // removes the edgesInTriangles from the edgesInTrianglesArray
	  if(m_container->hasEdgesInTriangle())
	  {

	    m_container->m_edgesInTriangle[ indices[i] ] = m_container->m_edgesInTriangle[ lastTriangle ]; // overwriting with last valid value.
	    m_container->m_edgesInTriangle.resize( lastTriangle ); // resizing to erase multiple occurence of the triangle.
	  }

	  // removes the triangle from the triangleArray
	  m_triangle[ indices[i] ] = m_triangle[ lastTriangle ]; // overwriting with last valid value.
	  m_triangle.resize( lastTriangle ); // resizing to erase multiple occurence of the triangle.
	}

	removeTrianglesPostProcessing(edgeToBeRemoved, vertexToBeRemoved); // Arrange the current topology.

	if(!edgeToBeRemoved.empty())
	{
	  /// warn that edges will be deleted
	  removeEdgesWarning(edgeToBeRemoved);
	  propagateTopologicalChanges();
	  /// actually remove edges without looking for isolated vertices
	  removeEdgesProcess(edgeToBeRemoved, false);
	}

	if(!vertexToBeRemoved.empty())
	{
	  removePointsWarning(vertexToBeRemoved);
	  /// propagate to all components
	  propagateTopologicalChanges();
	  removePointsProcess(vertexToBeRemoved);
	}

/*
#ifndef NDEBUG // TO BE REMOVED WHEN SURE.
	Debug();
#endif
*/
      }
void QuadSetTopologyModifier::removeQuadsProcess(const sofa::helper::vector<unsigned int> &indices,
        const bool removeIsolatedEdges,
        const bool removeIsolatedPoints)
{
    if(!m_container->hasQuads()) // this method should only be called when quads exist
    {
#ifndef NDEBUG
        sout << "Error. [QuadSetTopologyModifier::removeQuadsProcess] quad array is empty." << sendl;
#endif
        return;
    }

    if(m_container->hasEdges() && removeIsolatedEdges)
    {
        if(!m_container->hasEdgesInQuad())
            m_container->createEdgesInQuadArray();

        if(!m_container->hasQuadsAroundEdge())
            m_container->createQuadsAroundEdgeArray();
    }

    if(removeIsolatedPoints)
    {
        if(!m_container->hasQuadsAroundVertex())
            m_container->createQuadsAroundVertexArray();
    }

    sofa::helper::vector<unsigned int> edgeToBeRemoved;
    sofa::helper::vector<unsigned int> vertexToBeRemoved;
    helper::WriteAccessor< Data< sofa::helper::vector<Quad> > > m_quad = m_container->d_quad;

    unsigned int lastQuad = m_container->getNumberOfQuads() - 1;
    for(unsigned int i=0; i<indices.size(); ++i, --lastQuad)
    {
        const Quad &t = m_quad[ indices[i] ];
        const Quad &q = m_quad[ lastQuad ];

        // first check that the quad vertex shell array has been initialized
        if(m_container->hasQuadsAroundVertex())
        {
            for(unsigned int v=0; v<4; ++v)
            {
                sofa::helper::vector< unsigned int > &shell = m_container->m_quadsAroundVertex[ t[v] ];
                shell.erase(remove(shell.begin(), shell.end(), indices[i]), shell.end());
                if(removeIsolatedPoints && shell.empty())
                    vertexToBeRemoved.push_back(t[v]);
            }
        }

        if(m_container->hasQuadsAroundEdge())
        {
            for(unsigned int e=0; e<4; ++e)
            {
                sofa::helper::vector< unsigned int > &shell = m_container->m_quadsAroundEdge[ m_container->m_edgesInQuad[indices[i]][e]];
                shell.erase(remove(shell.begin(), shell.end(), indices[i]), shell.end());
                if(removeIsolatedEdges && shell.empty())
                    edgeToBeRemoved.push_back(m_container->m_edgesInQuad[indices[i]][e]);
            }
        }

        if(indices[i] < lastQuad)
        {
            // now updates the shell information of the quad at the end of the array
            if(m_container->hasQuadsAroundVertex())
            {
                for(unsigned int v=0; v<4; ++v)
                {
                    sofa::helper::vector< unsigned int > &shell = m_container->m_quadsAroundVertex[ q[v] ];
                    replace(shell.begin(), shell.end(), lastQuad, indices[i]);
                }
            }

            if(m_container->hasQuadsAroundEdge())
            {
                for(unsigned int e=0; e<4; ++e)
                {
                    sofa::helper::vector< unsigned int > &shell =  m_container->m_quadsAroundEdge[ m_container->m_edgesInQuad[lastQuad][e]];
                    replace(shell.begin(), shell.end(), lastQuad, indices[i]);
                }
            }
        }

        // removes the edgesInQuads from the edgesInQuadsArray
        if(m_container->hasEdgesInQuad())
        {
            m_container->m_edgesInQuad[ indices[i] ] = m_container->m_edgesInQuad[ lastQuad ]; // overwriting with last valid value.
            m_container->m_edgesInQuad.resize( lastQuad ); // resizing to erase multiple occurence of the quad.
        }

        // removes the quad from the quadArray
        m_quad[ indices[i] ] = m_quad[ lastQuad ]; // overwriting with last valid value.
        m_quad.resize( lastQuad ); // resizing to erase multiple occurence of the quad.
    }

    if(!edgeToBeRemoved.empty())
    {
        /// warn that edges will be deleted
        removeEdgesWarning(edgeToBeRemoved);
        propagateTopologicalChanges();
        /// actually remove edges without looking for isolated vertices
        removeEdgesProcess(edgeToBeRemoved,false);
    }

    if(!vertexToBeRemoved.empty())
    {
        removePointsWarning(vertexToBeRemoved);
        /// propagate to all components
        propagateTopologicalChanges();
        removePointsProcess(vertexToBeRemoved);
    }
}