001/*
002 * Copyright 2006 - 2013
003 *     Stefan Balev     <stefan.balev@graphstream-project.org>
004 *     Julien Baudry    <julien.baudry@graphstream-project.org>
005 *     Antoine Dutot    <antoine.dutot@graphstream-project.org>
006 *     Yoann Pigné      <yoann.pigne@graphstream-project.org>
007 *     Guilhelm Savin   <guilhelm.savin@graphstream-project.org>
008 * 
009 * This file is part of GraphStream <http://graphstream-project.org>.
010 * 
011 * GraphStream is a library whose purpose is to handle static or dynamic
012 * graph, create them from scratch, file or any source and display them.
013 * 
014 * This program is free software distributed under the terms of two licenses, the
015 * CeCILL-C license that fits European law, and the GNU Lesser General Public
016 * License. You can  use, modify and/ or redistribute the software under the terms
017 * of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following
018 * URL <http://www.cecill.info> or under the terms of the GNU LGPL as published by
019 * the Free Software Foundation, either version 3 of the License, or (at your
020 * option) any later version.
021 * 
022 * This program is distributed in the hope that it will be useful, but WITHOUT ANY
023 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
024 * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
025 * 
026 * You should have received a copy of the GNU Lesser General Public License
027 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
028 * 
029 * The fact that you are presently reading this means that you have had
030 * knowledge of the CeCILL-C and LGPL licenses and that you accept their terms.
031 */
032package org.graphstream.graph;
033
034import java.util.Collection;
035import java.util.Iterator;
036
037/**
038 * An Interface that advises general purpose methods for handling nodes as
039 * elements of a graph.
040 * 
041 * <h3>Important</h3>
042 * <p>
043 * Implementing classes should indicate the complexity of their implementation
044 * for each method.
045 * </p>
046 * 
047 * @since July 12 2007
048 */
049public interface Node extends Element, Iterable<Edge> {
050        /**
051         * Parent graph. Some elements are not able to give their parent graph.
052         * 
053         * @return The graph containing this node or null if unknown.
054         */
055        Graph getGraph();
056
057        /**
058         * Total number of relations with other nodes or this node.
059         * 
060         * @return The number of edges/relations/links.
061         */
062        int getDegree();
063
064        /**
065         * Number of leaving edges.
066         * 
067         * @return the count of edges that only enter this node plus all undirected
068         *         edges.
069         */
070        int getOutDegree();
071
072        /**
073         * Number of entering edges.
074         * 
075         * @return the count of edges that only leave this node plus all undirected
076         *         edges.
077         */
078        int getInDegree();
079
080        /**
081         * True if an edge leaves this node toward node 'id'.
082         * 
083         * @param id
084         *            Identifier of the target node.
085         * @return True if a directed edge goes from this node to 'id' or if an
086         *         undirected edge exists.
087         */
088        boolean hasEdgeToward(String id);
089
090        /**
091         * True if an edge enters this node from node 'id'.
092         * 
093         * @param id
094         *            Identifier of the source node.
095         * @return True if a directed edge goes from this node to 'id' or if an
096         *         undirected edge exists.
097         */
098        boolean hasEdgeFrom(String id);
099
100        /**
101         * True if an edge exists between this node and node 'id'.
102         * 
103         * @param id
104         *            Identifier of another node.
105         * @return True if a edge exists between this node and node 'id'.
106         */
107        boolean hasEdgeBetween(String id);
108
109        /**
110         * Retrieve an edge that leaves this node toward 'id'.
111         * <p>
112         * This method selects only edges leaving this node an pointing at node 'id'
113         * (this also selects undirected edges).
114         * </p>
115         * <p>
116         * This method is implicitly generic and return something which extends
117         * Edge. The return type is the one of the left part of the assignment. For
118         * example, in the following call :
119         * 
120         * <pre>
121         * ExtendedEdge e = node.getEdgeToward(&quot;...&quot;);
122         * </pre>
123         * 
124         * the method will return an ExtendedEdge. If no left part exists, method
125         * will just return an Edge.
126         * </p>
127         * 
128         * @param id
129         *            Identifier of the target node.
130         * @return Directed edge going from this node to 'id', or undirected edge if
131         *         it exists, else null.
132         */
133        <T extends Edge> T getEdgeToward(String id);
134
135        /**
136         * Retrieve an edge that leaves node 'id' toward this node.
137         * <p>
138         * This method selects only edges leaving node 'id' an pointing at this node
139         * (this also selects undirected edges).
140         * </p>
141         * <p>
142         * This method is implicitly generic and return something which extends
143         * Edge. The return type is the one of the left part of the assignment. For
144         * example, in the following call :
145         * 
146         * <pre>
147         * ExtendedEdge e = node.getEdgeFrom(&quot;...&quot;);
148         * </pre>
149         * 
150         * the method will return an ExtendedEdge. If no left part exists, method
151         * will just return an Edge.
152         * </p>
153         * 
154         * @param id
155         *            Identifier of the source node.
156         * @return Directed edge going from node 'id' to this node, or undirected
157         *         edge if it exists, else null.
158         */
159        <T extends Edge> T getEdgeFrom(String id);
160
161        /**
162         * Retrieve an edge between this node and the node 'id', if it exits.
163         * <p>
164         * This method selects directed or undirected edges. If the edge is
165         * directed, its direction is not important and leaving or entering edges
166         * will be selected.
167         * </p>
168         * <p>
169         * This method is implicitly generic and return something which extends
170         * Edge. The return type is the one of the left part of the assignment. For
171         * example, in the following call :
172         * 
173         * <pre>
174         * ExtendedEdge e = node.getEdgeBetween(&quot;...&quot;);
175         * </pre>
176         * 
177         * the method will return an ExtendedEdge. If no left part exists, method
178         * will just return an Edge.
179         * </p>
180         * 
181         * @param id
182         *            Identifier of the opposite node.
183         * @return Edge between node 'id' and this node if it exists, else null.
184         */
185        <T extends Edge> T getEdgeBetween(String id);
186
187        /**
188         * Iterator on the set of connected edges.
189         * <p>
190         * This iterator iterates on all edges leaving and entering (this includes
191         * any non-directed edge present, and a non-directed edge is only iterated
192         * once).
193         * </p>
194         * <p>
195         * This method is implicitly generic and return an Iterator over something
196         * which extends Edge. The return type is the one of the left part of the
197         * assignment. For example, in the following call :
198         * 
199         * <pre>
200         * Iterator&lt;ExtendedEdge&gt; ite = node.getEdgeIterator();
201         * </pre>
202         * 
203         * the method will return an Iterator&lt;ExtendedEdge&gt;. If no left part
204         * exists, method will just return an Iterator&lt;Edge&gt;.
205         * </p>
206         * 
207         * @return The iterator, edges are iterated in arbitrary order.
208         */
209        <T extends Edge> Iterator<T> getEdgeIterator();
210
211        /**
212         * Iterator only on leaving edges.
213         * <p>
214         * This iterator iterates only on directed edges going from this node to
215         * others (non-directed edges are included in the iteration).
216         * </p>
217         * <p>
218         * This method is implicitly generic and return an Iterator over something
219         * which extends Edge. The return type is the one of the left part of the
220         * assignment. For example, in the following call :
221         * 
222         * <pre>
223         * Iterator&lt;ExtendedEdge&gt; ite = node.getEnteringEdgeIterator();
224         * </pre>
225         * 
226         * the method will return an Iterator&lt;ExtendedEdge&gt;. If no left part
227         * exists, method will just return an Iterator&lt;Edge&gt;.
228         * </p>
229         * 
230         * @return The iterator, edges are iterated in arbitrary order.
231         */
232        <T extends Edge> Iterator<T> getEnteringEdgeIterator();
233
234        /**
235         * Iterator only on entering edges.
236         * <p>
237         * This iterator iterates only on directed edges going from other nodes
238         * toward this node (non-directed edges are included in the iteration).
239         * </p>
240         * <p>
241         * This method is implicitly generic and return an Iterator over something
242         * which extends Edge. The return type is the one of the left part of the
243         * assignment. For example, in the following call :
244         * 
245         * <pre>
246         * Iterator&lt;ExtendedEdge&gt; ite = node.getLeavingEdgeIterator();
247         * </pre>
248         * 
249         * the method will return an Iterator&lt;ExtendedEdge&gt;. If no left part
250         * exists, method will just return an Iterator&lt;Edge&gt;.
251         * </p>
252         * 
253         * @return The iterator, edges are iterated in arbitrary order.
254         */
255        <T extends Edge> Iterator<T> getLeavingEdgeIterator();
256
257        /**
258         * Iterator on the set of neighbor nodes connected to this node via one or
259         * more edges. This iterator iterates across any leaving, entering and non
260         * directed edges (nodes are neighbors even if they only have a directed
261         * edge from them toward this node). If there are multiple edges connecting
262         * the same node, it might be iterated several times.
263         * 
264         * @return The iterator, neighbors are iterated in arbitrary order.
265         */
266        <T extends Node> Iterator<T> getNeighborNodeIterator();
267
268        /**
269         * I-th edge. Edges are stored in no given order.
270         * <p>
271         * However this method allows to iterate very quickly on all edges, or to
272         * choose a given edge with direct access.
273         * </p>
274         * <p>
275         * This method is implicitly generic and return something which extends
276         * Edge. The return type is the one of the left part of the assignment. For
277         * example, in the following call :
278         * 
279         * <pre>
280         * ExtendedEdge e = node.getEdge(i);
281         * </pre>
282         * 
283         * the method will return an ExtendedEdge. If no left part exists, method
284         * will just return an Edge.
285         * </p>
286         * 
287         * @param i
288         *            Index of the edge.
289         * @return The i-th edge.
290         * @throws IndexOutOfBoundException
291         *             if <code>i</code> is negative or greater than or equal to the
292         *             degree
293         */
294        <T extends Edge> T getEdge(int i);
295
296        /**
297         * I-th entering edge. Edges are stored in no given order.
298         * <p>
299         * However this method allows to iterate very quickly on all entering edges,
300         * or to choose a given entering edge with direct access.
301         * </p>
302         * <p>
303         * This method is implicitly generic and return something which extends
304         * Edge. The return type is the one of the left part of the assignment. For
305         * example, in the following call :
306         * 
307         * <pre>
308         * ExtendedEdge e = node.getEnteringEdge(i);
309         * </pre>
310         * 
311         * the method will return an ExtendedEdge. If no left part exists, method
312         * will just return an Edge.
313         * </p>
314         * 
315         * @param i
316         *            Index of the edge.
317         * @return The i-th entering edge.
318         * @throws IndexOutOfBoundException
319         *             if <code>i</code> is negative or greater than or equal to the
320         *             in-degree
321         */
322        <T extends Edge> T getEnteringEdge(int i);
323
324        /**
325         * I-th leaving edge. Edges are stored in no given order.
326         * <p>
327         * However this method allows to iterate very quickly on all leaving edges,
328         * or to choose a given leaving edge with direct access.
329         * </p>
330         * <p>
331         * This method is implicitly generic and return something which extends
332         * Edge. The return type is the one of the left part of the assignment. For
333         * example, in the following call :
334         * 
335         * <pre>
336         * ExtendedEdge e = node.getLeavingEdge(i);
337         * </pre>
338         * 
339         * the method will return an ExtendedEdge. If no left part exists, method
340         * will just return an Edge.
341         * </p>
342         * 
343         * @param i
344         *            Index of the edge.
345         * @return The i-th leaving edge.
346         * @throws IndexOutOfBoundException
347         *             if <code>i</code> is negative or greater than or equal to the
348         *             out-degree
349         */
350        <T extends Edge> T getLeavingEdge(int i);
351
352        /**
353         * Iterator for breadth first exploration of the graph, starting at this
354         * node.
355         * <p>
356         * If the graph is not connected, only a part of it will be explored. By
357         * default, this iterator will respect edge orientation.
358         * </p>
359         * <p>
360         * This method is implicitly generic and return an Iterator over something
361         * which extends Node. The return type is the one of the left part of the
362         * assignment. For example, in the following call :
363         * 
364         * <pre>
365         * Iterator&lt;ExtendedNode&gt; ite = node.getBreadthFirstIterator();
366         * </pre>
367         * 
368         * the method will return an Iterator&lt;ExtendedNode&gt;. If no left part
369         * exists, method will just return an Iterator&lt;Node&gt;.
370         * </p>
371         * 
372         * @return An iterator able to explore the graph in a breadth first way
373         *         starting at this node.
374         */
375        <T extends Node> Iterator<T> getBreadthFirstIterator();
376
377        /**
378         * Iterator for breadth first exploration of the graph, starting at this
379         * node.
380         * <p>
381         * If the graph is not connected, only a part of it will be explored.
382         * </p>
383         * <p>
384         * This method is implicitly generic and return an Iterator over something
385         * which extends Node. The return type is the one of the left part of the
386         * assignment. For example, in the following call :
387         * 
388         * <pre>
389         * Iterator&lt;ExtendedNode&gt; ite = node.getBreadthFirstIterator(true);
390         * </pre>
391         * 
392         * the method will return an Iterator&lt;ExtendedNode&gt;. If no left part
393         * exists, method will just return an Iterator&lt;Node&gt;.
394         * </p>
395         * 
396         * @param directed
397         *            If false, the iterator will ignore edge orientation (the
398         *            default is "True").
399         * @return An iterator able to explore the graph in a breadth first way
400         *         starting at this node.
401         */
402        <T extends Node> Iterator<T> getBreadthFirstIterator(boolean directed);
403
404        /**
405         * Iterator for depth first exploration of the graph, starting at this node.
406         * <p>
407         * If the graph is not connected, only a part of it will be explored. By
408         * default, this iterator will respect edge orientation.
409         * </p>
410         * <p>
411         * This method is implicitly generic and return an Iterator over something
412         * which extends Node. The return type is the one of the left part of the
413         * assignment. For example, in the following call :
414         * 
415         * <pre>
416         * Iterator&lt;ExtendedNode&gt; ite = node.getDepthFirstIterator();
417         * </pre>
418         * 
419         * the method will return an Iterator&lt;ExtendedNode&gt;. If no left part
420         * exists, method will just return an Iterator&lt;Node&gt;.
421         * </p>
422         * 
423         * @return An iterator able to explore the graph in a depth first way
424         *         starting at this node.
425         * @complexity of the depth first iterator O(n+m) with n the number of nodes
426         *             and m the number of edges.
427         */
428        <T extends Node> Iterator<T> getDepthFirstIterator();
429
430        /**
431         * Iterator for depth first exploration of the graph, starting at this node.
432         * <p>
433         * If the graph is not connected, only a part of it will be explored.
434         * </p>
435         * <p>
436         * This method is implicitly generic and return an Iterator over something
437         * which extends Node. The return type is the one of the left part of the
438         * assignment. For example, in the following call :
439         * 
440         * <pre>
441         * Iterator&lt;ExtendedNode&gt; ite = node.getDepthFirstIterator(true);
442         * </pre>
443         * 
444         * the method will return an Iterator&lt;ExtendedNode&gt;. If no left part
445         * exists, method will just return an Iterator&lt;Node&gt;.
446         * </p>
447         * 
448         * @param directed
449         *            If false, the iterator will ignore edge orientation (the
450         *            default is "True").
451         * @return An iterator able to explore the graph in a depth first way
452         *         starting at this node.
453         */
454        <T extends Node> Iterator<T> getDepthFirstIterator(boolean directed);
455
456        /**
457         * Set of all entering and leaving edges.
458         * 
459         * <p>
460         * This method is implicitly generic and return an Iterable over something
461         * which extends Edge. The return type is the one of the left part of the
462         * assignment. For example, in the following call :
463         * 
464         * <pre>
465         * Iterable&lt;ExtendedEdge&gt; ite = node.getEdgeSet();
466         * </pre>
467         * 
468         * the method will return an Iterable&lt;ExtendedEdge&gt;. If no left part
469         * exists, method will just return an Iterable&lt;Edge&gt;.
470         * </p>
471         * 
472         * @return A collection containing all directed and undirected edges,
473         *         leaving or entering.
474         */
475        <T extends Edge> Iterable<T> getEachEdge();
476
477        /**
478         * Set of all leaving edges.
479         * <p>
480         * This method is implicitly generic and return an Iterable over something
481         * which extends Edge. The return type is the one of the left part of the
482         * assignment. For example, in the following call :
483         * 
484         * <pre>
485         * Iterable&lt;ExtendedEdge&gt; ite = node.getLeavingEdgeSet();
486         * </pre>
487         * 
488         * the method will return an Iterable&lt;ExtendedEdge&gt;. If no left part
489         * exists, method will just return an Iterable&lt;Edge&gt;.
490         * </p>
491         * 
492         * @return A collection of only edges that leave this node plus all
493         *         undirected edges.
494         */
495        <T extends Edge> Iterable<T> getEachLeavingEdge();
496
497        /**
498         * Set of all entering edges.
499         * <p>
500         * This method is implicitly generic and return an Iterable over something
501         * which extends Edge. The return type is the one of the left part of the
502         * assignment. For example, in the following call :
503         * 
504         * <pre>
505         * Iterable&lt;ExtendedEdge&gt; ite = node.getEnteringEdgeSet();
506         * </pre>
507         * 
508         * the method will return an Iterable&lt;ExtendedEdge&gt;. If no left part
509         * exists, method will just return an Iterable&lt;Edge&gt;.
510         * </p>
511         * 
512         * @return A collection of only edges that enter this node plus all
513         *         undirected edges.
514         */
515        <T extends Edge> Iterable<T> getEachEnteringEdge();
516
517        /**
518         * Set of all entering and leaving edges.
519         * 
520         * <p>
521         * This method is implicitly generic and return an Iterable over something
522         * which extends Edge. The return type is the one of the left part of the
523         * assignment. For example, in the following call :
524         * 
525         * <pre>
526         * Iterable&lt;ExtendedEdge&gt; ite = node.getEdgeSet();
527         * </pre>
528         * 
529         * the method will return an Iterable&lt;ExtendedEdge&gt;. If no left part
530         * exists, method will just return an Iterable&lt;Edge&gt;.
531         * </p>
532         * 
533         * @return A collection containing all directed and undirected edges,
534         *         leaving or entering.
535         */
536        <T extends Edge> Collection<T> getEdgeSet();
537
538        /**
539         * Set of all leaving edges.
540         * <p>
541         * This method is implicitly generic and return an Iterable over something
542         * which extends Edge. The return type is the one of the left part of the
543         * assignment. For example, in the following call :
544         * 
545         * <pre>
546         * Iterable&lt;ExtendedEdge&gt; ite = node.getLeavingEdgeSet();
547         * </pre>
548         * 
549         * the method will return an Iterable&lt;ExtendedEdge&gt;. If no left part
550         * exists, method will just return an Iterable&lt;Edge&gt;.
551         * </p>
552         * 
553         * @return A collection of only edges that leave this node plus all
554         *         undirected edges.
555         */
556        <T extends Edge> Collection<T> getLeavingEdgeSet();
557
558        /**
559         * Set of all entering edges.
560         * <p>
561         * This method is implicitly generic and return an Iterable over something
562         * which extends Edge. The return type is the one of the left part of the
563         * assignment. For example, in the following call :
564         * 
565         * <pre>
566         * Iterable&lt;ExtendedEdge&gt; ite = node.getEnteringEdgeSet();
567         * </pre>
568         * 
569         * the method will return an Iterable&lt;ExtendedEdge&gt;. If no left part
570         * exists, method will just return an Iterable&lt;Edge&gt;.
571         * </p>
572         * 
573         * @return A collection of only edges that enter this node plus all
574         *         undirected edges.
575         */
576        <T extends Edge> Collection<T> getEnteringEdgeSet();
577
578        /**
579         * Override the Object.toString() method.
580         */
581        String toString();
582
583        // New methods
584
585        /**
586         * True if an edge leaves this node toward a given node.
587         * 
588         * @param node
589         *            The target node.
590         * @return True if a directed edge goes from this node to the other node or
591         *         if an undirected edge exists.
592         */
593        boolean hasEdgeToward(Node node);
594
595        /**
596         * True if an edge leaves this node toward a node with given index.
597         * 
598         * @param index
599         *            Index of the target node.
600         * @return True if a directed edge goes from this node to the other node or
601         *         if an undirected edge exists.
602         * @throws IndexOutOfBoundsException
603         *             if the index is negative or greater than {@code
604         *             getNodeCount() - 1}.
605         */
606        boolean hasEdgeToward(int index) throws IndexOutOfBoundsException;
607
608        /**
609         * True if an edge enters this node from a given node.
610         * 
611         * @param node
612         *            The source node.
613         * @return True if a directed edge goes from the other node to this node or
614         *         if an undirected edge exists.
615         */
616        boolean hasEdgeFrom(Node node);
617
618        /**
619         * True if an edge enters this node from a node with given index.
620         * 
621         * @param index
622         *            Index of the source node.
623         * @return True if a directed edge goes from the other node to this node or
624         *         if an undirected edge exists.
625         * @throws IndexOutOfBoundsException
626         *             if the index is negative or greater than {@code
627         *             getNodeCount() - 1}.
628         */
629        boolean hasEdgeFrom(int index) throws IndexOutOfBoundsException;
630
631        /**
632         * True if an edge exists between this node and another node.
633         * 
634         * @param node
635         *            Another node.
636         * @return True if an edge exists between this node and the other node.
637         */
638        boolean hasEdgeBetween(Node node);
639
640        /**
641         * True if an edge exists between this node and a node with given index.
642         * 
643         * @param index
644         *            Index of another node.
645         * @return True if an edge exists between this node and the other node.
646         * @throws IndexOutOfBoundsException
647         *             if the index is negative or greater than {@code
648         *             getNodeCount() - 1}.
649         */
650        boolean hasEdgeBetween(int index) throws IndexOutOfBoundsException;
651
652        /**
653         * Retrieves an edge that leaves this node toward another node.
654         * <p>
655         * This method selects only edges leaving this node an pointing at the
656         * parameter node (this also selects undirected edges).
657         * </p>
658         * <p>
659         * This method is implicitly generic and returns something which extends
660         * Edge. The return type is the one of the left part of the assignment. For
661         * example, in the following call :
662         * 
663         * <pre>
664         * ExtendedEdge e = node.getEdgeToward(...);
665         * </pre>
666         * 
667         * the method will return an ExtendedEdge. If no left part exists, method
668         * will just return an Edge.
669         * </p>
670         * 
671         * @param node
672         *            The target node.
673         * @return Directed edge going from this node to the parameter node, or
674         *         undirected edge if it exists, else null.
675         */
676        <T extends Edge> T getEdgeToward(Node node);
677
678        /**
679         * Retrieves an edge that leaves this node toward the node with given index.
680         * <p>
681         * This method selects only edges leaving this node an pointing at the
682         * parameter node (this also selects undirected edges).
683         * </p>
684         * <p>
685         * This method is implicitly generic and returns something which extends
686         * Edge. The return type is the one of the left part of the assignment. For
687         * example, in the following call :
688         * 
689         * <pre>
690         * ExtendedEdge e = node.getEdgeToward(...);
691         * </pre>
692         * 
693         * the method will return an ExtendedEdge. If no left part exists, method
694         * will just return an Edge.
695         * </p>
696         * 
697         * @param index
698         *            Index of the target node.
699         * @return Directed edge going from this node to the parameter node, or
700         *         undirected edge if it exists, else null.
701         * @throws IndexOutOfBoundsException
702         *             if the index is negative or greater than {@code
703         *             getNodeCount() - 1}.
704         */
705        <T extends Edge> T getEdgeToward(int index)
706                        throws IndexOutOfBoundsException;
707
708        /**
709         * Retrieves an edge that leaves given node toward this node.
710         * <p>
711         * This method selects only edges leaving the other node an pointing at this
712         * node (this also selects undirected edges).
713         * </p>
714         * <p>
715         * This method is implicitly generic and returns something which extends
716         * Edge. The return type is the one of the left part of the assignment. For
717         * example, in the following call :
718         * 
719         * <pre>
720         * ExtendedEdge e = node.getEdgeFrom(...);
721         * </pre>
722         * 
723         * the method will return an ExtendedEdge. If no left part exists, method
724         * will just return an Edge.
725         * </p>
726         * 
727         * @param node
728         *            The source node.
729         * @return Directed edge going from the parameter node to this node, or
730         *         undirected edge if it exists, else null.
731         */
732        <T extends Edge> T getEdgeFrom(Node node);
733
734        /**
735         * Retrieves an edge that leaves node with given index toward this node.
736         * <p>
737         * This method selects only edges leaving the other node an pointing at this
738         * node (this also selects undirected edges).
739         * </p>
740         * <p>
741         * This method is implicitly generic and returns something which extends
742         * Edge. The return type is the one of the left part of the assignment. For
743         * example, in the following call :
744         * 
745         * <pre>
746         * ExtendedEdge e = node.getEdgeFrom(&quot;...&quot;);
747         * </pre>
748         * 
749         * the method will return an ExtendedEdge. If no left part exists, method
750         * will just return an Edge.
751         * </p>
752         * 
753         * @param index
754         *            Index of the source node.
755         * @return Directed edge going from the parameter node to this node, or
756         *         undirected edge if it exists, else null.
757         * @throws IndexOutOfBoundsException
758         *             if the index is negative or greater than {@code
759         *             getNodeCount() - 1}.
760         */
761        <T extends Edge> T getEdgeFrom(int index) throws IndexOutOfBoundsException;
762
763        /**
764         * Retrieves an edge between this node and and another node if one exists.
765         * <p>
766         * This method selects directed or undirected edges. If the edge is
767         * directed, its direction is not important and leaving or entering edges
768         * will be selected.
769         * </p>
770         * <p>
771         * This method is implicitly generic and return something which extends
772         * Edge. The return type is the one of the left part of the assignment. For
773         * example, in the following call :
774         * 
775         * <pre>
776         * ExtendedEdge e = node.getEdgeBetween(...);
777         * </pre>
778         * 
779         * the method will return an ExtendedEdge. If no left part exists, method
780         * will just return an Edge.
781         * </p>
782         * 
783         * @param node
784         *            The opposite node.
785         * @return Edge between this node and the parameter node if it exists, else
786         *         null.
787         */
788        <T extends Edge> T getEdgeBetween(Node node);
789
790        /**
791         * Retrieves an edge between this node and the node with index i if one
792         * exists.
793         * <p>
794         * This method selects directed or undirected edges. If the edge is
795         * directed, its direction is not important and leaving or entering edges
796         * will be selected.
797         * </p>
798         * <p>
799         * This method is implicitly generic and return something which extends
800         * Edge. The return type is the one of the left part of the assignment. For
801         * example, in the following call :
802         * 
803         * <pre>
804         * ExtendedEdge e = node.getEdgeBetween(...);
805         * </pre>
806         * 
807         * the method will return an ExtendedEdge. If no left part exists, method
808         * will just return an Edge.
809         * </p>
810         * 
811         * @param index
812         *            The index of the opposite node.
813         * @return Edge between node with index i and this node if it exists, else
814         *         null.
815         * @throws IndexOutOfBoundsException
816         *             if the index is negative or greater than {@code
817         *             getNodeCount() - 1}.
818         */
819        <T extends Edge> T getEdgeBetween(int index)
820                        throws IndexOutOfBoundsException;
821
822}