/*
 * $Revision: 3547 $
 *
 * last checkin:
 *   $Author: beyer $
 *   $Date: 2013-06-06 14:47:08 +0200 (Thu, 06 Jun 2013) $
 ***************************************************************/

/** \file
 * \brief Pure declaration header, find template implementation in
 *        Graph.h
 *
 * Declaration of NodeElement, EdgeElement, and Graph classes.
 *
 * \author Carsten Gutwenger
 *
 * \par License:
 * This file is part of the Open Graph Drawing Framework (OGDF).
 *
 * \par
 * Copyright (C)<br>
 * See README.txt in the root directory of the OGDF installation for details.
 *
 * \par
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * Version 2 or 3 as published by the Free Software Foundation;
 * see the file LICENSE.txt included in the packaging of this file
 * for details.
 *
 * \par
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * \par
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 * \see  http://www.gnu.org/copyleft/gpl.html
 ***************************************************************/


#ifdef _MSC_VER
#pragma once
#endif

#ifndef OGDF_GRAPH_D_H
#define OGDF_GRAPH_D_H


#include <ogdf/basic/GraphList.h>


namespace ogdf {

//
// in embedded graphs, adjacency lists are given in clockwise order.
//


class OGDF_EXPORT Graph;
class OGDF_EXPORT NodeElement;
class OGDF_EXPORT EdgeElement;
class OGDF_EXPORT AdjElement;
class OGDF_EXPORT FaceElement;
class OGDF_EXPORT ClusterElement;

typedef NodeElement *node; //!< The type of nodes.
typedef EdgeElement *edge; //!< The type of edges.
typedef AdjElement *adjEntry; //!< The type of adjacency entries.

//! Class for adjacency list elements.
/**
 * Adjacency list elements represent the occurrence of an edges in
 * the adjacency list of a node.
 */
class OGDF_EXPORT AdjElement : private GraphElement {
	friend class Graph;
	friend class GraphListBase;
	friend class GraphList<AdjElement>;

	AdjElement *m_twin; //!< The corresponding adjacency entry (same edge)
	edge m_edge; //!< The associated edge.
	node m_node; //!< The node whose adjacency list contains this entry.
	int m_id;    //!< The (unique) index of the adjacency entry.

	//! Constructs an adjacency element for a given node.
	AdjElement(node v) : m_node(v) { }
	//! Constructs an adjacency entry for a given edge and index.
	AdjElement(edge e, int id) : m_edge(e), m_id(id) { }

public:
	//! Returns the edge associated with this adjacency entry.
	edge theEdge() const { return m_edge; }
	//! Conversion to edge.
	operator edge() const { return m_edge; }
	//! Returns the node whose adjacency list contains this element.
	node theNode() const { return m_node; }

	//! Returns the corresponding adjacency element associated with the same edge.
	adjEntry twin() const { return m_twin; }

	//! Returns the associated node of the corresponding adjacency entry (shorthand for twin()->theNode()).
	node twinNode() const { return m_twin->m_node; }

	//! Returns the index of this adjacency element.
	int index() const { return m_id; }

	// traversing faces in clockwise (resp. counter-clockwise) order
	// (if face is an interior face)

	//! Returns the clockwise successor in face. Use faceCycleSucc instead!
	adjEntry clockwiseFaceSucc() const { return m_twin->cyclicPred(); }
	//! Returns the clockwise predecessor in face.  Use faceCycleSucc instead!
	adjEntry clockwiseFacePred() const { return cyclicSucc()->m_twin; }
	//! Returns the counter-clockwise successor in face.
	adjEntry counterClockwiseFaceSucc() const { return m_twin->cyclicSucc(); }
	//! Returns the counter-clockwise predecessor in face.
	adjEntry counterClockwiseFacePred() const { return cyclicPred()->m_twin; }

	// default is traversing faces in clockwise order
	//! Returns the cyclic successor in face.
	adjEntry faceCycleSucc() const { return clockwiseFaceSucc(); }
	//! Returns the cyclic predecessor in face.
	adjEntry faceCyclePred() const { return clockwiseFacePred(); }


	//! Returns the successor in the adjacency list.
	adjEntry succ() const { return (adjEntry)m_next; }
	//! Returns the predecessor in the adjacency list.
	adjEntry pred() const { return (adjEntry)m_prev; }

	//! Returns the cyclic successor in the adjacency list.
	adjEntry cyclicSucc() const;
	//! Returns the cyclic predecessor in the adjacency list.
	adjEntry cyclicPred() const;

#ifdef OGDF_DEBUG
	const Graph *graphOf() const;
#endif

	//! Standard Comparer
	static int compare(const AdjElement& x,const AdjElement& y) { return x.m_id-y.m_id; }
	OGDF_AUGMENT_STATICCOMPARER(AdjElement)

	OGDF_NEW_DELETE
}; // class AdjElement


//! Class for the representation of nodes.
class OGDF_EXPORT NodeElement : private GraphElement {
	friend class Graph;
	friend class GraphList<NodeElement>;

	GraphList<AdjElement> m_adjEdges; //!< The adjacency list of the node.
	int m_indeg;  //!< The indegree of the node.
	int m_outdeg; //!< The outdegree of the node.
	int m_id;     //!< The (unique) index of the node.

#ifdef OGDF_DEBUG
	// we store the graph containing this node for debugging purposes
	const Graph *m_pGraph; //!< The graph containg this node (debug only).
#endif


	// construction
#ifdef OGDF_DEBUG
	//! Constructs a node element with index \a id.
	/**
	 * \remarks The parameter \a pGraph is only passed in a debug build.
	 * It is used, e.g., by NodeArray for checking if a node belongs to
	 * the correct graph.
	 */
	NodeElement(const Graph *pGraph, int id) :
		m_indeg(0), m_outdeg(0), m_id(id), m_pGraph(pGraph) { }
#else
	NodeElement(int id) : m_indeg(0), m_outdeg(0), m_id(id) { }
#endif


public:
	//! Returns the (unique) node index.
	int index() const { return m_id; }

	//! Returns the indegree of the node.
	int indeg() const { return m_indeg; }
	//! Returns the outdegree of the node.
	int outdeg() const { return m_outdeg; }
	//! Returns the degree of the node (indegree + outdegree).
	int degree() const { return m_indeg + m_outdeg; }

	//! Returns the first entry in the adjaceny list.
	adjEntry firstAdj() const { return m_adjEdges.begin();  }
	//! Returns the last entry in the adjacency list.
	adjEntry lastAdj () const { return m_adjEdges.rbegin(); }

	//! Returns the successor in the list of all nodes.
	node succ() const { return (node)m_next; }
	//! Returns the predecessor in the list of all nodes.
	node pred() const { return (node)m_prev; }

#ifdef OGDF_DEBUG
	//! Returns the graph containing this node (debug only).
	const Graph *graphOf() const { return m_pGraph; }
#endif

	//! Standard Comparer
	static int compare(const NodeElement& x,const NodeElement& y) { return x.m_id-y.m_id; }
	OGDF_AUGMENT_STATICCOMPARER(NodeElement)

	OGDF_NEW_DELETE
}; // class NodeElement


inline adjEntry AdjElement::cyclicSucc() const
{
	return (m_next) ? (adjEntry)m_next : m_node->firstAdj();
}

inline adjEntry AdjElement::cyclicPred() const
{
	return (m_prev) ? (adjEntry)m_prev : m_node->lastAdj();
}

inline bool test_forall_adj_edges(adjEntry &adj, edge &e)
{
	if (adj) { e = adj->theEdge(); return true; }
	else return false;
}



//! Class for the representation of edges.
class OGDF_EXPORT EdgeElement : private GraphElement {
	friend class Graph;
	friend class GraphList<EdgeElement>;

	node m_src; //!< The source node of the edge.
	node m_tgt; //!< The target node of the edge.
	AdjElement *m_adjSrc; //!< Corresponding adjacancy entry at source node.
	AdjElement *m_adjTgt; //!< Corresponding adjacancy entry at target node.
	int m_id; // The (unique) index of the node.

	//! Constructs an edge element (\a src,\a tgt).
	/**
	 * @param src is the source node of the edge.
	 * @param tgt is the target node of the edge.
	 * @param adjSrc is the corresponding adjacency entry at source node.
	 * @param adjTgt is the corresponding adjacency entry at target node.
	 * @param id is the index of the edge.
	 */
	EdgeElement(node src, node tgt, AdjElement *adjSrc, AdjElement *adjTgt, int id) :
		m_src(src), m_tgt(tgt), m_adjSrc(adjSrc), m_adjTgt(adjTgt), m_id(id) { }

	//! Constructs an edge element (\a src,\a tgt).
	/**
	 * @param src is the source node of the edge.
	 * @param tgt is the target node of the edge.
	 * @param id is the index of the edge.
	 */
	EdgeElement(node src, node tgt, int id) :
		m_src(src), m_tgt(tgt), m_id(id) { }

public:
	//! Returns the index of the edge.
	int index() const { return m_id; }
	//! Returns the source node of the edge.
	node source() const { return m_src; }
	//! Returns the target node of the edge.
	node target() const { return m_tgt; }

	//! Returns the corresponding adjacancy entry at source node.
	adjEntry adjSource() const { return m_adjSrc; }
	//! Returns the corresponding adjacancy entry at target node.
	adjEntry adjTarget() const { return m_adjTgt; }

	//! Returns the adjacent node different from \a v.
	node opposite(node v) const { return (v == m_src) ? m_tgt : m_src; }
	// Returns true iff the edge is a self-loop (source node = target node).
	bool isSelfLoop() const { return m_src == m_tgt; }

	//! Returns the successor in the list of all edges.
	edge succ() const { return (edge)m_next; }
	//! Returns the predecessor in the list of all edges.
	edge pred() const { return (edge)m_prev; }

#ifdef OGDF_DEBUG
	//! Returns the graph containing this node (debug only).
	const Graph *graphOf() const { return m_src->graphOf(); }
#endif

	//! Returns true iff \a v is incident to the edge.
	bool isIncident(node v) const { return v == m_src || v == m_tgt; }

	//! Returns the common node of the edge and \a e. Returns NULL if the two edges are not adjacent.
	node commonNode(edge e) const { return (m_src==e->m_src || m_src==e->m_tgt) ? m_src : ((m_tgt==e->m_src || m_tgt==e->m_tgt) ? m_tgt: 0); }

	//! Standard Comparer
	static int compare(const EdgeElement& x,const EdgeElement& y) { return x.m_id-y.m_id; }
	OGDF_AUGMENT_STATICCOMPARER(EdgeElement)

	OGDF_NEW_DELETE
}; // class EdgeElement


#ifdef OGDF_DEBUG
inline const Graph *AdjElement::graphOf() const {
	return m_node->graphOf();
}
#endif


template<>inline bool doDestruction<node>(const node *) { return false; }
template<>inline bool doDestruction<edge>(const edge *) { return false; }
template<>inline bool doDestruction<adjEntry>(const adjEntry *) { return false; }

class NodeArrayBase;
class EdgeArrayBase;
class AdjEntryArrayBase;
template<class T> class NodeArray;
template<class T> class EdgeArray;
template<class T> class AdjEntryArray;
class OGDF_EXPORT GraphObserver;


//---------------------------------------------------------
// iteration macros
//---------------------------------------------------------

//! Iteration over all nodes \a v of graph \a G.
#define forall_nodes(v,G) for((v)=(G).firstNode(); (v); (v)=(v)->succ())
//! Iteration over all nodes \a v of graph \a G in reverse order.
#define forall_rev_nodes(v,G) for((v)=(G).lastNode(); (v); (v)=(v)->pred())

//! Iteration over all edges \a e of graph \a G.
#define forall_edges(e,G) for((e)=(G).firstEdge(); (e); (e)=(e)->succ())
//! Iteration over all edges \a e of graph \a G in reverse order.
#define forall_rev_edges(e,G) for((e)=(G).lastEdge(); (e); (e)=(e)->pred())

//! Iteration over all adjacency list entries \a adj of node \a v.
#define forall_adj(adj,v) for((adj)=(v)->firstAdj(); (adj); (adj)=(adj)->succ())
//! Iteration over all adjacency list entries \a adj of node \a v in reverse order.
#define forall_rev_adj(adj,v) for((adj)=(v)->lastAdj(); (adj); (adj)=(adj)->pred())

//! Iteration over all adjacent edges \a e of node \a v.
#define forall_adj_edges(e,v)\
for(ogdf::adjEntry ogdf_loop_var=(v)->firstAdj();\
	ogdf::test_forall_adj_edges(ogdf_loop_var,(e));\
	ogdf_loop_var=ogdf_loop_var->succ())


//! Data type for general directed graphs (adjacency list representation).
/**
 * <H3>Thread Safety</H3>
 * The class Graph allows shared access of threads to const methods only.
 * If one thread executes a non-const method, shared access is no longer thread-safe.
 *
 * <H3>Iteration</H3>
 * Besides the usage of iteration macros defined in Graph_d.h, the following
 * code is recommended for further iteration tasks.
 * <ul>
 *   <li> Iteration over all outgoing edges \a e of node \a v:
 *     \code
 *  forall_adj_edges(e,v)
 *    if(e->source() != v) continue;
 *     \endcode
 *
 *   <li> Iteration over all ingoing edges \a e of node \a v:
 *     \code
 *  forall_adj_edges(e,v)
 *	  if(e->target() != v) continue;
 *     \endcode
 *
 *   <li> Iteration over all nodes \a x reachable by an outgoing edge \a e
 *        of node \a v (without self-loops):
 *     \code
 *  forall_adj_edges(e,v)
 *    if ((x = e->target()) == v) continue;
 *     \endcode
 *
 *   <li> Iteration over all nodes \a x reachable by an outgoing edge \a e
 *        of node \a v (with self-loops):
 *     \code
 *  forall_adj_edges(e,v) {
 *    if (e->source() != v) continue;
 *    x = e->target();
 *  }
 *     \endcode
 *
 *  <li> Iteration over all nodes \a x reachable by an ingoing edge \a e
 *       of node \a v (without self-loops):
 *     \code
 *  forall_adj_edges(e,v)
 *    if ((x = e->source()) == v) continue;
 *     \endcode
 *
 * <li> Iteration over all nodes \a x reachable by an ingoing edge \a e
 *      of node \a v (with self-loops):
 *     \code
 *  forall_adj_edges(e,v) {
 *    if (e->target() != v) continue;
 *    x = e->source();
 *  }
 *     \endcode
 * </ul>
 */

class OGDF_EXPORT Graph
{
	GraphList<NodeElement> m_nodes; //!< The list of all nodes.
	GraphList<EdgeElement> m_edges; //!< The list of all edges.
	int m_nNodes; //!< The number of nodes in the graph.
	int m_nEdges; //!< The number of edges in the graph.

	int m_nodeIdCount; //!< The Index that will be assigned to the next created node.
	int m_edgeIdCount; //!< The Index that will be assigned to the next created edge.

	int m_nodeArrayTableSize; //!< The current table size of node arrays associated with this graph.
	int m_edgeArrayTableSize; //!< The current table size of edge arrays associated with this graph.

	mutable ListPure<NodeArrayBase*> m_regNodeArrays; //!< The registered node arrays.
	mutable ListPure<EdgeArrayBase*> m_regEdgeArrays; //!< The registered edge arrays.
	mutable ListPure<AdjEntryArrayBase*> m_regAdjArrays;  //!< The registered adjEntry arrays.
	mutable ListPure<GraphObserver*> m_regStructures; //!< The registered graph structures.

#ifndef OGDF_MEMORY_POOL_NTS
	mutable CriticalSection m_csRegArrays; //!< The critical section for protecting shared acces to register/unregister methods.
#endif

	GraphList<EdgeElement> m_hiddenEdges; //!< The list of hidden edges.

public:
	//
	// enumerations
	//

	//! The type of edges (only used in derived classes).
	enum EdgeType {
		association = 0,
		generalization = 1,
		dependency = 2
	}; // should be more flexible, standard, dissect, expand

	//! The type of nodes.
	enum NodeType {
		vertex,
		dummy,
		generalizationMerger,
		generalizationExpander,
		highDegreeExpander,
		lowDegreeExpander,
		associationClass
	};


	//! Constructs an empty graph.
	Graph();

	//! Constructs a graph that is a copy of \a G.
	/**
	 * The constructor assures that the adjacency lists of nodes in the
	 * constructed graph are in the same order as the adjacency lists in \a G.
	 * This is in particular important when dealing with embedded graphs.
	 *
	 * @param G is the graph that will be copied.
	 */
	Graph(const Graph &G);

	//! Destructor.
	virtual ~Graph();


	/**
	 * @name Access methods
	 */
	//@{

	//! Returns true iff the graph is empty, i.e., contains no nodes.
	bool empty() const { return m_nNodes == 0; }

	//! Returns the number of nodes in the graph.
	int numberOfNodes() const { return m_nNodes; }

	//! Returns the number of edges in the graph.
	int numberOfEdges() const { return m_nEdges; }

	//! Returns the largest used node index.
	int maxNodeIndex() const { return m_nodeIdCount-1; }
	//! Returns the largest used edge index.
	int maxEdgeIndex() const { return m_edgeIdCount-1; }
	//! Returns the largest used adjEntry index.
	int maxAdjEntryIndex() const { return (m_edgeIdCount<<1)-1; }

	//! Returns the table size of node arrays associated with this graph.
	int nodeArrayTableSize() const { return m_nodeArrayTableSize; }
	//! Returns the table size of edge arrays associated with this graph.
	int edgeArrayTableSize() const { return m_edgeArrayTableSize; }
	//! Returns the table size of adjEntry arrays associated with this graph.
	int adjEntryArrayTableSize() const { return m_edgeArrayTableSize << 1; }

	//! Returns the first node in the list of all nodes.
	node firstNode() const { return m_nodes.begin (); }
	//! Returns the last node in the list of all nodes.
	node lastNode () const { return m_nodes.rbegin(); }

	//! Returns the first edge in the list of all edges.
	edge firstEdge() const { return m_edges.begin (); }
	//! Returns the last edge in the list of all edges.
	edge lastEdge () const { return m_edges.rbegin(); }

	//! Returns a randomly chosen node.
	node chooseNode() const;
	//! Returns a randomly chosen edge.
	edge chooseEdge() const;

	//! Returns a list with all nodes of the graph.
	/**
	 * @tparam NODELIST is the type of node list, which is returned.
	 * @param  nodes    is assigned the list of all nodes.
	 */
	template<class NODELIST>
	void allNodes(NODELIST &nodes) const {
		nodes.clear();
		for (node v = m_nodes.begin(); v; v = v->succ())
			nodes.pushBack(v);
	}

	//! Returns a list with all edges of the graph.
	/**
	 * @tparam EDGELIST is the type of edge list, which is returned.
	 * @param  edges    is assigned the list of all edges.
	 */
	template<class EDGELIST>
	void allEdges(EDGELIST &edges) const {
		edges.clear();
		for (edge e = m_edges.begin(); e; e = e->succ())
			edges.pushBack(e);
	}

	//! Returns a list with all edges adjacent to node \a v.
	/**
	 * @tparam EDGELIST is the type of edge list, which is returned.
	 * @param  v        is the node whose incident edges are queried.
	 * @param  edges    is assigned the list of all edges incident to \a v
	 *                  (including incoming and outcoming edges).
	 */
	template<class EDGELIST>
	void adjEdges(node v, EDGELIST &edges) const {
		edges.clear();
		edge e;
		forall_adj_edges(e,v)
			edges.pushBack(e);
	}

	//! Returns a list with all entries in the adjacency list of node \a v.
	/**
	 * @tparam ADJLIST is the type of adjacency entry list, which is returned.
	 * @param  v       is the node whose adjacency entries are queried.
	 * @param  entries is assigned the list of all adjacency entries in the adjacency list of \a v.
	 */
	template<class ADJLIST>
	void adjEntries(node v, ADJLIST &entries) const {
		entries.clear();
		adjEntry adj;
		forall_adj(adj,v)
			entries.pushBack(adj);
	}

	//! Returns a list with all incoming edges of node \a v.
	/**
	 * @tparam EDGELIST is the type of edge list, which is returned.
	 * @param  v        is the node whose incident edges are queried.
	 * @param  edges    is assigned the list of all incoming edges incident to \a v.
	 */
	template<class EDGELIST>
	void inEdges(node v, EDGELIST &edges) const {
		edges.clear();
		edge e;
		forall_adj_edges(e,v)
			if (e->target() == v) edges.pushBack(e);
	}

	//! Returns a list with all outgoing edges of node \a v.
	/**
	 * @tparam EDGELIST is the type of edge list, which is returned.
	 * @param  v        is the node whose incident edges are queried.
	 * @param  edges    is assigned the list of all outgoing edges incident to \a v.
	 */
	template<class EDGELIST>
	void outEdges(node v, EDGELIST &edges) const {
		edges.clear();
		edge e;
		forall_adj_edges(e,v)
			if (e->source() == v) edges.pushBack(e);
	}


	//@}
	/**
	 * @name Creation of new nodes and edges
	 */
	//@{

	//! Creates a new node and returns it.
	node newNode();

	//! Creates a new node with predefined index and returns it.
	/**
	 * \pre \a index is currently not the index of any other node in the graph.
	 *
	 * \attention Passing a node index that is already in use results in an inconsistent
	 *            data structure. Only use this method if you know what you're doing!
	 *
	 * @param index is the index that will be assigned to the newly created node.
	 * @return the newly created node.
	 */
	node newNode(int index);

	//! Creates a new edge (\a v,\a w) and returns it.
	/**
	 * @param v is the source node of the newly created edge.
	 * @param w is the target node of the newly created edge.
	 * @return the newly created edge.
	 */
	edge newEdge(node v, node w);

	//! Creates a new edge (\a v,\a w) with predefined index and returns it.
	/**
	 * \pre \a index is currently not the index of any other edge in the graph.
	 *
	 * \attention  Passing an edge index that is already in use results in an inconsistent
	 *             data structure. Only use this method if you know what you're doing!
	 *
	 * @param v     is the source node of the newly created edge.
	 * @param w     is the target node of the newly created edge.
	 * @param index is the index that will be assigned to the newly created edge.
	 * @return the newly created edge.
	 */
	edge newEdge(node v, node w, int index);

	//! Creates a new edge at predefined positions in the adjacency lists.
	/**
	 * Let \a v be the node whose adjacency list contains \a adjSrc,
	 * and \a w the node whose adjacency list contains \a adjTgt. Then,
	 * the created edge is (\a v,\a w).
	 *
	 * @param adjSrc is the adjacency entry after which the new edge is inserted
	 *               in the adjacency list of \a v.
	 * @param adjTgt is the adjacency entry after which the new edge is inserted
	 *               in the adjacency list of \a w.
	 * @param dir    specifies if the edge is inserted before or after the given
	 *               adjacency entries.
	 * @return the newly created edge.
	 */
	edge newEdge(adjEntry adjSrc, adjEntry adjTgt, Direction dir = ogdf::after);

	//! Creates a new edge at predefined positions in the adjacency lists.
	/**
	 * Let \a w be the node whose adjacency list contains \a adjTgt. Then,
	 * the created edge is (\a v,\a w).
	 *
	 * @param v      is the source node of the new edge; the edge is added at the end
	 *               of the adjacency list of \a v.
	 * @param adjTgt is the adjacency entry after which the new edge is inserted
	 *               in the adjacency list of \a w.
	 * @return the newly created edge.
	 */
	edge newEdge(node v, adjEntry adjTgt);

	//! Creates a new edge at predefined positions in the adjacency lists.
	/**
	 * Let \a v be the node whose adjacency list contains \a adjSrc. Then,
	 * the created edge is (\a v,\a w).
	 *
	 * @param adjSrc is the adjacency entry after which the new edge is inserted
	 *               in the adjacency list of \a v.
	 * @param w      is the source node of the new edge; the edge is added at the end
	 *               of the adjacency list of \a w.
	 * @return the newly created edge.
	 */
	edge newEdge(adjEntry adjSrc, node w);


	//@}
	/**
	 * @name Removing nodes and edges
	 */
	//@{

	//! Removes node \a v and all incident edges from the graph.
	/**
	 * @param v is the node that will be deleted.
	 */
	virtual void delNode(node v);

	//! Removes edge \a e from the graph.
	/**
	 * @param e is the egde that will be deleted.
	 */
	virtual void delEdge(edge e);

	//! Removes all nodes and all edges from the graph.
	void clear();


	//@}
	/**
	 * @name Hiding edges
	 * These methods are used for temporarily hiding edges. Edges are removed from the
	 * list of all edges and their corresponding adfjacency entries from the repsective
	 * adjacency lists, but the edge objects themselves are not destroyed; hiddenedges
	 * can later be reactivated with restoreEdge().
	 */
	//@{

	//! Hides the edge \a e.
	/**
	 * The edge \a e is removed from the list of all edges and adjacency lists of nodes, but
	 * not deleted; \a e can be restored by calling restoreEdge(e).
	 *
	 * \attention If an edge is hidden, its source and target node may not be deleted!
	 *
	 * @param e is the edge that will be hidden.
	 */
	void hideEdge(edge e);

	//! Restores a hidden edge \a e.
	/**
	 * \pre \a e is currently hidden and its source and target have not been removed!
	 *
	 * @param e is the hidden edge that will be restored.
	 */
	void restoreEdge(edge e);

	//! Restores all hidden edges.
	void restoreAllEdges();


	/**
	 * @name Advanced modification methods
	 */
	//@{

	//! Splits edge \a e into two edges introducing a new node.
	/**
	 * Let \a e=(\a v,\a w). Then, the resulting two edges are \a e=(\a v,\a u)
	 * and \a e'=(\a u,\a w), where \a u is a new node.
	 *
	 * \note The edge \a e is modified by this operation.
	 *
	 * @param e is the edge to be split.
	 * @return The edge \a e'.
	 */
	virtual edge split(edge e);

	//! Undoes a split operation.
	/**
	 * Removes node \a u by joining the two edges adjacent to \a u. The
	 * outgoing edge of \a u is removed and the incoming edge \a e is reused
	 *
	 * \pre \a u has exactly one incoming and one outgoing edge, and
	 *    none of them is a self-loop.
	 *
	 * @param u is the node to be unsplit.
	 * @return The edge \a e.
	 */
	void unsplit(node u);

	//! Undoes a split operation.
	/**
	 * For two edges \a eIn = (\a x,\a u) and \a eOut = (\a u,\a y), removes
	 * node \a u by joining \a eIn and \a eOut. Edge \a eOut is removed and
	 * \a eIn is reused.
	 *
	 * \pre \a eIn and \a eOut are the only edges incident with \a u and
	 *      none of them is a self-loop.
	 *
	 * @param eIn  is the (only) incoming edge of \a u.
	 * @param eOut is the (only) outgoing edge of \a u.
	 */
	virtual void unsplit(edge eIn, edge eOut);

	//! Splits a node while preserving the order of adjacency entries.
	/**
	 * This method splits a node \a v into two nodes \a vl and \a vr. Node
	 * \a vl receives all adjacent edges of \a v from \a adjStartLeft until
	 * the edge preceding \a adjStartRight, and \a vr the remaining nodes
	 * (thus \a adjStartRight is the first edge that goes to \a vr). The
	 * order of adjacency entries is preserved. Additionally, a new edge
	 * (\a vl,\a vr) is created, such that this edge is inserted before
	 * \a adjStartLeft and \a adjStartRight in the the adjacency lists of
	 * \a vl and \a vr.
	 *
	 * Node \a v is modified to become node \a vl, and node \a vr is returned.
	 * This method is useful when modifying combinatorial embeddings.
	 *
	 * @param adjStartLeft  is the first entry that goes to the left node.
	 * @param adjStartRight is the first entry that goes to the right node.
	 * @return the newly created node.
	 */
	node splitNode(adjEntry adjStartLeft, adjEntry adjStartRight);

	//! Contracts edge \a e while preserving the order of adjacency entries.
	/**
	 * @param e is the edge to be contracted.
	 * @return the endpoint of \a e to which all edges have been moved.
	 */
	node contract(edge e);

	//! Moves edge \a e to a different adjacency list.
	/**
	 * The source adjacency entry of \a e is moved to the adjacency list containing
	 * \a adjSrc and is inserted before or after \a adjSrc, and its target adjacency entry
	 * to the adjacency list containing \a adjTgt and is inserted before or after
	 * \a adjTgt; e is afterwards an edge from owner(\a adjSrc) to owner(\a adjTgt).
	 *
	 * @param e      is the edge to be moved.
	 * @param adjSrc is the adjaceny entry before or after which the source adjacency entry
	 *               of \a e will be inserted.
	 * @param dirSrc specifies if the source adjacency entry of \a e will be inserted before or after \a adjSrc.
	 * @param adjTgt is the adjaceny entry before or after which the target adjacency entry
	 *               of \a e will be inserted.
	 * @param dirTgt specifies if the target adjacency entry of \a e will be inserted before or after \a adjTgt.
	 */
	void move(edge e, adjEntry adjSrc, Direction dirSrc,
		adjEntry adjTgt, Direction dirTgt);

	//! Moves the target node of edge \a e to node \a w.
	/**
	 * If \a e=(\a v,\a u) before, then \a e=(\a v,\a w) afterwards.
	 *
	 * @param e is the edge whose target node is moved.
	 * @param w is the new target node of \a e.
	 */
	void moveTarget(edge e, node w);

	//! Moves the target node of edge \a e to a specific position in an adjacency list.
	/**
	 * Let \a w be the node containing \a adjTgt. If \a e=(\a v,\a u) before, then \a e=(\a v,\a w) afterwards.
	 * Inserts the adjacency entry before or after \a adjTgt according to \a dir.
	 *
	 * @param e is the edge whose target node is moved.
	 * @param adjTgt is the adjacency entry before or after which the target adjacency entry of \a e is inserted.
	 * @param dir specifies if the target adjacency entry of \a e is inserted before or after \a adjTgt.
	 */
	void moveTarget(edge e, adjEntry adjTgt, Direction dir);

	//! Moves the source node of edge \a e to node \a w.
	/**
	 * If \a e=(\a v,\a u) before, then \a e=(\a w,\a u) afterwards.
	 *
	 * @param e is the edge whose source node is moved.
	 * @param w is the new source node of \a e.
	 */
	void moveSource(edge e, node w);

	//! Moves the source node of edge \a e to a specific position in an adjacency list.
	/**
	 * Let \a w be the node containing \a adjSrc. If \a e=(\a v,\a u) before, then \a e=(\a w,\a u) afterwards.
	 * Inserts the adjacency entry before or after \a adjSrc according to \a dir.
	 *
	 * @param e is the edge whose source node is moved.
	 * @param adjSrc is the adjacency entry before or after which the source adjacency entry of \a e is inserted.
	 * @param dir specifies if the source adjacency entry of \a e is inserted before or after \a adjSrc.
	 */
	void moveSource(edge e, adjEntry adjSrc, Direction dir);

	//! Searches and returns an edge connecting nodes \a v and \a w in time O(min(deg(v), deg(w))).
	/**
	 * @param v is the source node of the edge to be searched.
	 * @param w is the target node of the edge to be searched.
	 * @return an edge (\ v,\a w) if such an edge exists, 0 otherwise.
	 */
	edge searchEdge (node v, node w) const;

	//! Reverses the edge \a e, i.e., exchanges source and target node.
	/**
	 * @param e is the edge to be reveresed.
	 */
	void reverseEdge(edge e);

	//! Reverses all edges in the graph.
	void reverseAllEdges();

	//! Collapses all nodes in the list \a nodes to the first node in the list.
	/**
	 * Parallel edges are removed.
	 *
	 * @tparam NODELIST is the type of input node list.
	 * @param  nodes    is the list of nodes that will be collapsed. This list will be empty after the call.
	 */
	template<class NODELIST>
	void collaps(NODELIST &nodes){
		node v = nodes.popFrontRet();
		while (!nodes.empty())
		{
			node w = nodes.popFrontRet();
			adjEntry adj = w->firstAdj();
			while (adj !=0)
			{
				adjEntry succ = adj->succ();
				edge e = adj->theEdge();
				if (e->source() == v || e->target() == v)
					delEdge(e);
				else if (e->source() == w)
					moveSource(e,v);
				else
					moveTarget(e,v);
				adj = succ;
			}
			delNode(w);
		}
	}

	//! Sorts the adjacency list of node \a v according to \a newOrder.
	/**
	 * \pre \a newOrder contains exactly the adjacency entries of \a v!
	 *
	 * @tparam ADJ_ENTRY_LIST is the type of the input adjacency entry list.
	 * @param  v              is the node whose adjacency list will be sorted.
	 * @param  newOrder       is the list of adjacency entries of \a v in the new order.
	 */
	template<class ADJ_ENTRY_LIST>
	void sort(node v, const ADJ_ENTRY_LIST &newOrder) {
#ifdef OGDF_DEBUG
		typename ADJ_ENTRY_LIST::const_iterator it;
		for(it = newOrder.begin(); it.valid() ; ++it) {
			OGDF_ASSERT((*it)->theNode() == v);
		}
#endif
		v->m_adjEdges.sort(newOrder);
	}

	//! Reverses the adjacency list of \a v.
	/**
	 * @param v is the node whose adjacency list will be reveresed.
	 */
	void reverseAdjEdges(node v) {
		v->m_adjEdges.reverse();
	}

	//! Moves adjacency entry \a adjMove before or after \a adjPos.
	/**
	 * \pre \a adjMove and adjAfter are distinct entries in the same adjacency list.
	 *
	 * @param adjMove is an entry in the adjacency list of a node in this graph.
	 * @param adjPos  is an entry in the same adjacency list as \a adjMove.
	 * @param dir     specifies if \a adjMove is moved before or after \a adjPos.
	 */
	void moveAdj(adjEntry adjMove, Direction dir, adjEntry adjPos) {
		OGDF_ASSERT(adjMove->graphOf() == this && adjPos->graphOf() == this);
		OGDF_ASSERT(adjMove != 0 && adjPos != 0);
		GraphList<AdjElement> &adjList = adjMove->m_node->m_adjEdges;
		adjList.move(adjMove, adjList, adjPos, dir);
	}

	//! Moves adjacency entry \a adjMove after \a adjAfter.
	/**
	 * \pre \a adjMove and \a adjAfter are distinct entries in the same adjacency list.
	 *
	 * @param adjMove  is an entry in the adjacency list of a node in this graph.
	 * @param adjAfter is an entry in the same adjacency list as \a adjMove.
	 */
	void moveAdjAfter(adjEntry adjMove, adjEntry adjAfter) {
		OGDF_ASSERT(adjMove->graphOf() == this && adjAfter->graphOf() == this);
		OGDF_ASSERT(adjMove != 0 && adjAfter != 0);
		adjMove->m_node->m_adjEdges.moveAfter(adjMove,adjAfter);
	}

	//! Moves adjacency entry \a adjMove before \a adjBefore.
	/**
	 * \pre \a adjMove and \a adjBefore are distinct entries in the same adjacency list.
	 *
	 * @param adjMove   is an entry in the adjacency list of a node in this graph.
	 * @param adjBefore is an entry in the same adjacency list as \a adjMove.
	 */
	void moveAdjBefore(adjEntry adjMove, adjEntry adjBefore) {
		OGDF_ASSERT(adjMove->graphOf() == this && adjBefore->graphOf() == this);
		OGDF_ASSERT(adjMove != 0 && adjBefore != 0);
		adjMove->m_node->m_adjEdges.moveBefore(adjMove,adjBefore);
	}

	//! Reverses all adjacency lists.
	void reverseAdjEdges();

	//! Exchanges two entries in an adjacency list.
	/**
	 * \pre \a adj1 and \a adj2 must be belong to the same adjacency list.
	 *
	 * @param adj1 the first adjacency entry to be swapped.
	 * @param adj2 the secomd adjacency entry to be swapped.
	 */
	void swapAdjEdges(adjEntry adj1, adjEntry adj2) {
		OGDF_ASSERT(adj1->theNode() == adj2->theNode());
		OGDF_ASSERT(adj1->graphOf() == this);

		adj1->theNode()->m_adjEdges.swap(adj1,adj2);
	}


	//@}
	/**
	 * @name Miscellaneous
	 */
	//@{

	//! Returns the genus of the graph's embedding.
	/**
	 * The genus of a graph is defined as follows. Let \f$G\f$ be a graph
	 * with \f$m\f$ edges, \f$n\f$ nodes, \f$c\f$ connected components, \f$nz\f$
	 * isolated vertices, and \f$fc\f$ face cycles. Then,
	 * \f[
	 *   genus(G) = (m/2 + 2c - n -nz -fc)/2
	 * \f]
	 *
	 * @return the genus of the graph's current embedding; if this is 0, then the graph is planarly embedded.
	 */
	int genus() const;

	//! Returns true iff the graph represents a combinatorial embedding.
	/**
	 * @return true if the current embedding (given by the adjacency lists) represents a combinatorial embedding, false otherwise.
	 */
	bool representsCombEmbedding() const {
		return (genus() == 0);
	}

	//! Checks the consistency of the data structure.
	/**
	 * \remark This method is meant for debugging purposes only.
	 *
	 * @return true if everything is ok, false if the data structure is inconsistent.
	 */
	bool consistencyCheck() const;


	//@}
	/**
	 * @name Registering arrays and observers
	 * These methods are used by various graph array types like NodeArray or EdgeArray.
	 * There should be no need to use them directly in user code.
	 */
	//@{

	//! Registers a node array.
	/**
	 * \remark This method is automatically called by node arrays; it should not be called manually.
	 *
	 * @param pNodeArray is a pointer to the node array's base; this node array must be associated with this graph.
	 * @return an iterator pointing to the entry for the registered node array in the list of registered node arrays.
	 *         This iterator is required for unregistering the node array again.
	 */
	ListIterator<NodeArrayBase*> registerArray(NodeArrayBase *pNodeArray) const;

	//! Registers an edge array.
	/**
	 * \remark This method is automatically called by edge arrays; it should not be called manually.
	 *
	 * @param pEdgeArray is a pointer to the edge array's base; this edge array must be associated with this graph.
	 * @return an iterator pointing to the entry for the registered edge array in the list of registered edge arrays.
	 *         This iterator is required for unregistering the edge array again.
	 */
	ListIterator<EdgeArrayBase*> registerArray(EdgeArrayBase *pEdgeArray) const;

	//! Registers an adjEntry array.
	/**
	 * \remark This method is automatically called by adjacency entry arrays; it should not be called manually.
	 *
	 * @param pAdjArray is a pointer to the adjacency entry array's base; this adjacency entry array must be
	 *                  associated with this graph.
	 * @return an iterator pointing to the entry for the registered adjacency entry array in the list of registered
	 *         adjacency entry arrays. This iterator is required for unregistering the adjacency entry array again.
	 */
	ListIterator<AdjEntryArrayBase*> registerArray(AdjEntryArrayBase *pAdjArray) const;

	//! Registers a graph observer (e.g. a ClusterGraph).
	/**
	 * @param pStructure is a pointer to the graph observer that shall be registered; this graph observer must be
	 *                   associated with this graph.
	 * @return an iterator pointing to the entry for the registered graph observer in the list of registered
	 *         graph observers. This iterator is required for unregistering the graph observer again.
	 */
	ListIterator<GraphObserver*> registerStructure(GraphObserver *pStructure) const;

	//! Unregisters a node array.
	/**
	 * @param it is an iterator pointing to the entry in the list of registered node arrays for the node array to
	 *        be unregistered.
	 */
	void unregisterArray(ListIterator<NodeArrayBase*> it) const;

	//! Unregisters an edge array.
	/**
	 * @param it is an iterator pointing to the entry in the list of registered edge arrays for the edge array to
	 *        be unregistered.
	 */
	void unregisterArray(ListIterator<EdgeArrayBase*> it) const;

	//! unregisters an adjEntry array.
	/**
	 * @param it is an iterator pointing to the entry in the list of registered adjacency entry arrays for the
	 *           adjacency entry array to be unregistered.
	 */
	void unregisterArray(ListIterator<AdjEntryArrayBase*> it) const;

	//! Unregisters a graph observer.
	/**
	 * @param it is an iterator pointing to the entry in the list of registered graph observers for the graph
	 *           observer to be unregistered.
	 */
	void unregisterStructure(ListIterator<GraphObserver*> it) const;


	//! Resets the edge id count to \a maxId.
	/**
	 * The next edge will get edge id \a maxId+1. Use this function with caution!
	 * It is provided as an efficient way to reduce the edge id count. The Graph class
	 * increments the edge id count whenever an edge is created; free edge ids resulting
	 * from removing edges are not reused (there is not something like a freelist).
	 *
	 * This function is , e.g., useful, when a lot of edges has been added and
	 * <em>all</em> these edges are removed again (without creating other new edges
	 * meanwile). Then, it is safe to reduce the edge id count to the value it had
	 * before, cf. the following code snippet:
	 * \code
	 *   int oldIdCount = G.maxEdgeIndex();
	 *   Create some edges
	 *   ...
	 *   Remove all these edges again
	 *   G.resetEdgeIdCount(oldIdCount);
	 * \endcode
	 *
	 * Reducing the edge id count will reduce the memory consumption of edge arrays
	 * associated with the graph.
	 *
	 * \pre -1 \f$\leq\f$ \a maxId \f$\leq\f$ maximal edge id in the graph.
	 *
	 * @param maxId is an upper bound of the edge ids in the graph.
	 */
	void resetEdgeIdCount(int maxId);


	//@}
	/**
	 * @name Operators
	 */
	//@{
	//! Assignment operator.
	/**
	 * The assignment operature assures that the adjacency lists of nodes in the
	 * constructed graph are in the same order as the adjacency lists in \a G.
	 * This is in particular important when dealing with embedded graphs.
	 *
	 * @param G is the graph to be copied.
	 * @return this graph.
	 */
	Graph &operator=(const Graph &G);

	OGDF_MALLOC_NEW_DELETE

	//@}

public:

	//! Returns the smallest power of 2 which is >= 2^\a start and > \a idCount.
	static int nextPower2(int start, int idCount);


	//! Info structure for maintaining connected components.
	class CCsInfo {

		const Graph *m_graph;	//!< points to the associated graph.
		int m_numCC;			//!< the number of connected components.

		Array<node> m_nodes;	//!< array of all nodes.
		Array<edge> m_edges;	//!< array of all edges.
		Array<int>  m_startNode; //!< start node of each connected component in m_nodes.
		Array<int>  m_startEdge; //!< start edge of each connected component in m_edges.

	public:
		//! Creates a info structure associated with no graph.
		CCsInfo() : m_graph(0), m_numCC(0) { }

		//! Creates a info structure associated with graph \a G.
		CCsInfo(const Graph& G);

		//! Returns the associated graph.
		const Graph &constGraph() const { return *m_graph; }

		//! Returns the number of connected components.
		int numberOfCCs() const { return m_numCC; }

		//! Returns the number of nodes in connected component \ cc.
		int numberOfNodes(int cc) const { return stopNode(cc) - startNode(cc); }

		//! Returns the number of edges in connected component \ cc.
		int numberOfEdges(int cc) const { return stopEdge(cc) - startEdge(cc); }

		//! Returns the index of the first node in connected component \a cc.
		int startNode(int cc) const { return m_startNode[cc]; }

		//! Returns the index of (one past) the last node in connected component \a cc.
		int stopNode (int cc) const { return m_startNode[cc+1]; }

		//! Returns the index of the first edge in connected component \a cc.
		int startEdge(int cc) const { return m_startEdge[cc]; }

		//! Returns the index of (one past) the last edge in connected component \a cc.
		int stopEdge (int cc) const { return m_startEdge[cc+1]; }

		//! Returns the node with index \a i.
		node v(int i) const { return m_nodes[i]; }

		//! Returns the edge with index \a i.
		edge e(int i) const { return m_edges[i]; }
	};

protected:
	void construct(const Graph &G, NodeArray<node> &mapNode, EdgeArray<edge> &mapEdge);

	void assign(const Graph &G, NodeArray<node> &mapNode, EdgeArray<edge> &mapEdge);

	//! Constructs a copy of the subgraph of \a G induced by \a nodes.
	/**
	 * This method preserves the order in the adjacency lists, i.e., if
	 * \a G is embedded, its embedding induces the embedding of the copy.
	 */
	void constructInitByNodes(
		const Graph &G,
		const List<node> &nodes,
		NodeArray<node> &mapNode,
		EdgeArray<edge> &mapEdge);

	void constructInitByActiveNodes(
		const List<node> &nodes,
		const NodeArray<bool> &activeNodes,
		NodeArray<node> &mapNode,
		EdgeArray<edge> &mapEdge);

	//! Constructs a copy of connected component \a cc in \a info.
	void constructInitByCC(
		const CCsInfo &info,
		int cc,
		NodeArray<node> &mapNode,
		EdgeArray<edge> &mapEdge);

private:
	void copy(const Graph &G, NodeArray<node> &mapNode,
		EdgeArray<edge> &mapEdge);
	void copy(const Graph &G);

	edge createEdgeElement(node v, node w, adjEntry adjSrc, adjEntry adjTgt);
	node pureNewNode();

	// moves adjacency entry to node w
	void moveAdj(adjEntry adj, node w);

	void reinitArrays();
	void reinitStructures();
	void resetAdjEntryIndex(int newIndex, int oldIndex);

	//! Enter critical section for (un-)registering arrays.
	void enterCSRegArrays() const {
#ifndef OGDF_MEMORY_POOL_NTS
		m_csRegArrays.enter();
#endif
	}

	//! Leave critical section for (un-)registering arrays.
	void leaveCSRegArrays() const {
#ifndef OGDF_MEMORY_POOL_NTS
		m_csRegArrays.leave();
#endif
	}


}; // class Graph



//! Bucket function using the index of an edge's source node as bucket.
class OGDF_EXPORT BucketSourceIndex : public BucketFunc<edge> {
public:
	//! Returns source index of \a e.
	int getBucket(const edge &e) { return e->source()->index(); }
};

//! Bucket function using the index of an edge's target node as bucket.
class OGDF_EXPORT BucketTargetIndex : public BucketFunc<edge> {
public:
	//! Returns target index of \a e.
	int getBucket(const edge &e) { return e->target()->index(); }
};


} //namespace

#endif

