improving GSDI, under construction...
authorcmzmasek@gmail.com <cmzmasek@gmail.com@ca865154-3058-d1c3-3e42-d8f55a55bdbd>
Wed, 27 Jun 2012 04:59:21 +0000 (04:59 +0000)
committercmzmasek@gmail.com <cmzmasek@gmail.com@ca865154-3058-d1c3-3e42-d8f55a55bdbd>
Wed, 27 Jun 2012 04:59:21 +0000 (04:59 +0000)
forester/java/src/org/forester/analysis/AncestralTaxonomyInference.java
forester/java/src/org/forester/application/gsdi.java
forester/java/src/org/forester/phylogeny/iterators/PostOrderStackObject.java
forester/java/src/org/forester/phylogeny/iterators/PostorderTreeIterator.java
forester/java/src/org/forester/sdi/GSDI.java
forester/java/src/org/forester/sdi/GSDIold.java [new file with mode: 0644]
forester/java/src/org/forester/sdi/TestGSDI.java
forester/java/src/org/forester/ws/seqdb/SequenceDbWsTools.java

index 6b036ef..5a6a32a 100644 (file)
@@ -103,17 +103,6 @@ public final class AncestralTaxonomyInference {
                 else {
                     node = "[" + desc.getId() + "]";
                 }
-                //   final List<PhylogenyNode> e = desc.getAllExternalDescendants();
-                //TODO remove me!
-                //                System.out.println();
-                //                int x = 0;
-                //                for( final PhylogenyNode object : e ) {
-                //                    System.out.println( x + ":" );
-                //                    System.out.println( object.getName() + "  " );
-                //                    x++;
-                //                }
-                //                System.out.println();
-                //
                 throw new AncestralTaxonomyInferenceException( "node " + node
                         + " has no or inappropriate taxonomic information" );
             }
index 676d5da..4c5d0cd 100644 (file)
@@ -34,6 +34,7 @@ import java.util.List;
 
 import org.forester.io.parsers.PhylogenyParser;
 import org.forester.io.parsers.nhx.NHXParser;
+import org.forester.io.parsers.phyloxml.PhyloXmlDataFormatException;
 import org.forester.io.parsers.phyloxml.PhyloXmlParser;
 import org.forester.io.parsers.util.ParserUtils;
 import org.forester.io.writers.PhylogenyWriter;
@@ -203,20 +204,42 @@ public final class gsdi {
                 final TaxonomyComparisonBase comp_base = GSDI.determineTaxonomyComparisonBase( gene_tree );
                 switch ( comp_base ) {
                     case SCIENTIFIC_NAME:
-                        PhylogenyMethods
-                                .transferNodeNameToField( species_tree,
-                                                          PhylogenyMethods.PhylogenyNodeField.TAXONOMY_SCIENTIFIC_NAME,
-                                                          true );
+                        try {
+                            PhylogenyMethods
+                                    .transferNodeNameToField( species_tree,
+                                                              PhylogenyMethods.PhylogenyNodeField.TAXONOMY_SCIENTIFIC_NAME,
+                                                              true );
+                        }
+                        catch ( final PhyloXmlDataFormatException e ) {
+                            ForesterUtil.fatalError( gsdi.PRG_NAME,
+                                                     "Failed to transfer general node name to scientific name, in ["
+                                                             + species_tree_file + "]: " + e.getMessage() );
+                        }
                         break;
                     case CODE:
-                        PhylogenyMethods.transferNodeNameToField( species_tree,
-                                                                  PhylogenyMethods.PhylogenyNodeField.TAXONOMY_CODE,
-                                                                  true );
+                        try {
+                            PhylogenyMethods
+                                    .transferNodeNameToField( species_tree,
+                                                              PhylogenyMethods.PhylogenyNodeField.TAXONOMY_CODE,
+                                                              true );
+                        }
+                        catch ( final PhyloXmlDataFormatException e ) {
+                            ForesterUtil.fatalError( gsdi.PRG_NAME,
+                                                     "Failed to transfer general node name to taxonomy code, in ["
+                                                             + species_tree_file + "]: " + e.getMessage() );
+                        }
                         break;
                     case ID:
-                        PhylogenyMethods.transferNodeNameToField( species_tree,
-                                                                  PhylogenyMethods.PhylogenyNodeField.TAXONOMY_ID,
-                                                                  true );
+                        try {
+                            PhylogenyMethods.transferNodeNameToField( species_tree,
+                                                                      PhylogenyMethods.PhylogenyNodeField.TAXONOMY_ID,
+                                                                      true );
+                        }
+                        catch ( final PhyloXmlDataFormatException e ) {
+                            ForesterUtil.fatalError( gsdi.PRG_NAME,
+                                                     "Failed to transfer general node name to taxonomy id, in ["
+                                                             + species_tree_file + "]: " + e.getMessage() );
+                        }
                         break;
                     default:
                         ForesterUtil.fatalError( gsdi.PRG_NAME, "unable to determine comparison base" );
@@ -224,8 +247,8 @@ public final class gsdi {
             }
         }
         catch ( final IOException e ) {
-            ForesterUtil.fatalError( gsdi.PRG_NAME,
-                                     "Failed to read species tree from [" + gene_tree_file + "]: " + e.getMessage() );
+            ForesterUtil.fatalError( gsdi.PRG_NAME, "Failed to read species tree from [" + species_tree_file + "]: "
+                    + e.getMessage() );
         }
         gene_tree.setRooted( true );
         species_tree.setRooted( true );
index b18562a..ae291ee 100644 (file)
@@ -32,39 +32,21 @@ import org.forester.phylogeny.PhylogenyNode;
  * 
  * @version 1.00 -- last modified: 06/15/00
  */
-public class PostOrderStackObject {
+public final class PostOrderStackObject {
 
     final private PhylogenyNode _node;
     final private int           _phase;
 
-    /**
-     * Creates a new PostOrderStackObject object.
-     * 
-     * @param n
-     *            DOCUMENT ME!
-     * @param i
-     *            DOCUMENT ME!
-     */
     public PostOrderStackObject( final PhylogenyNode n, final int i ) {
         _node = n;
         _phase = i;
     }
 
-    /**
-     * DOCUMENT ME!
-     * 
-     * @return DOCUMENT ME!
-     */
-    public PhylogenyNode getNode() {
+    final public PhylogenyNode getNode() {
         return _node;
     }
 
-    /**
-     * DOCUMENT ME!
-     * 
-     * @return DOCUMENT ME!
-     */
-    public int getPhase() {
+    final public int getPhase() {
         return _phase;
     }
 }
index 0d06ff9..737a75d 100644 (file)
@@ -34,7 +34,7 @@ import org.forester.phylogeny.PhylogenyNode;
 /*
  * *
  */
-public class PostorderTreeIterator implements PhylogenyNodeIterator {
+public final class PostorderTreeIterator implements PhylogenyNodeIterator {
 
     final private Phylogeny                   _tree;
     final private PhylogenyNode               _root;
@@ -55,25 +55,20 @@ public class PostorderTreeIterator implements PhylogenyNodeIterator {
         reset();
     }
 
-    private PhylogenyNode getRoot() {
+    final private PhylogenyNode getRoot() {
         return _root;
     }
 
-    private Stack<PostOrderStackObject> getStack() {
+    final private Stack<PostOrderStackObject> getStack() {
         return _stack;
     }
 
-    private Phylogeny getTree() {
+    final private Phylogeny getTree() {
         return _tree;
     }
 
-    /**
-     * DOCUMENT ME!
-     * 
-     * @return DOCUMENT ME!
-     */
     @Override
-    public boolean hasNext() {
+    final public boolean hasNext() {
         return _has_next;
     }
 
@@ -81,7 +76,7 @@ public class PostorderTreeIterator implements PhylogenyNodeIterator {
      * Advances the Iterator by one.
      */
     @Override
-    public PhylogenyNode next() throws NoSuchElementException {
+    final public PhylogenyNode next() throws NoSuchElementException {
         if ( !hasNext() ) {
             throw new NoSuchElementException( "Attempt to call \"next()\" on iterator which has no more next elements." );
         }
@@ -89,7 +84,6 @@ public class PostorderTreeIterator implements PhylogenyNodeIterator {
             final PostOrderStackObject si = getStack().pop();
             final PhylogenyNode node = si.getNode();
             final int phase = si.getPhase();
-            // if ( node != null ) {
             if ( phase > node.getNumberOfDescendants() ) {
                 setHasNext( node != getRoot() );
                 return node;
@@ -99,34 +93,23 @@ public class PostorderTreeIterator implements PhylogenyNodeIterator {
                 if ( node.isInternal() ) {
                     getStack().push( new PostOrderStackObject( node.getChildNode( phase - 1 ), 1 ) );
                 }
-                // else {
-                // getStack().push( new PostOrderStackObject( null, 1 ) );
-                // }
             }
-            // }
         }
     }
 
-    /**
-     * Not supported.
-     * 
-     */
     @Override
-    public void remove() {
+    final public void remove() {
         throw new UnsupportedOperationException();
     }
 
-    /**
-     * DOCUMENT ME!
-     */
     @Override
-    public void reset() {
+    final public void reset() {
         setHasNext( true );
         getStack().clear();
         getStack().push( new PostOrderStackObject( getTree().getRoot(), 1 ) );
     }
 
-    private void setHasNext( final boolean has_next ) {
+    final private void setHasNext( final boolean has_next ) {
         _has_next = has_next;
     }
-} // End of class PostorderTreeIterator.
+}
index 780aba9..3fea313 100644 (file)
@@ -63,15 +63,14 @@ import org.forester.util.ForesterUtil;
  */
 public final class GSDI extends SDI {
 
-    private final HashMap<PhylogenyNode, Integer> _transversal_counts;
-    private final boolean                         _most_parsimonious_duplication_model;
-    private final boolean                         _strip_gene_tree;
-    private final boolean                         _strip_species_tree;
-    private int                                   _speciation_or_duplication_events_sum;
-    private int                                   _speciations_sum;
-    private final List<PhylogenyNode>             _stripped_gene_tree_nodes;
-    private final List<PhylogenyNode>             _stripped_species_tree_nodes;
-    private final Set<PhylogenyNode>              _mapped_species_tree_nodes;
+    private final boolean             _most_parsimonious_duplication_model;
+    private final boolean             _strip_gene_tree;
+    private final boolean             _strip_species_tree;
+    private int                       _speciation_or_duplication_events_sum;
+    private int                       _speciations_sum;
+    private final List<PhylogenyNode> _stripped_gene_tree_nodes;
+    private final List<PhylogenyNode> _stripped_species_tree_nodes;
+    private final Set<PhylogenyNode>  _mapped_species_tree_nodes;
 
     /**
      * Constructor which sets the gene tree and the species tree to be compared.
@@ -109,7 +108,6 @@ public final class GSDI extends SDI {
         _speciation_or_duplication_events_sum = 0;
         _speciations_sum = 0;
         _most_parsimonious_duplication_model = most_parsimonious_duplication_model;
-        _transversal_counts = new HashMap<PhylogenyNode, Integer>();
         _duplications_sum = 0;
         _strip_gene_tree = strip_gene_tree;
         _strip_species_tree = strip_species_tree;
@@ -118,7 +116,8 @@ public final class GSDI extends SDI {
         _mapped_species_tree_nodes = new HashSet<PhylogenyNode>();
         getSpeciesTree().preOrderReId();
         linkNodesOfG();
-        geneTreePostOrderTraversal( getGeneTree().getRoot() );
+        //geneTreePostOrderTraversal( getGeneTree().getRoot(), null );
+        geneTreePostOrderTraversal();
     }
 
     GSDI( final Phylogeny gene_tree, final Phylogeny species_tree, final boolean most_parsimonious_duplication_model )
@@ -126,24 +125,6 @@ public final class GSDI extends SDI {
         this( gene_tree, species_tree, most_parsimonious_duplication_model, false, false );
     }
 
-    private final Event createDuplicationEvent() {
-        final Event event = Event.createSingleDuplicationEvent();
-        ++_duplications_sum;
-        return event;
-    }
-
-    private final Event createSingleSpeciationOrDuplicationEvent() {
-        final Event event = Event.createSingleSpeciationOrDuplicationEvent();
-        ++_speciation_or_duplication_events_sum;
-        return event;
-    }
-
-    private final Event createSpeciationEvent() {
-        final Event event = Event.createSingleSpeciationEvent();
-        ++_speciations_sum;
-        return event;
-    }
-
     // s is the node on the species tree g maps to.
     private final void determineEvent( final PhylogenyNode s, final PhylogenyNode g ) {
         Event event = null;
@@ -155,74 +136,93 @@ public final class GSDI extends SDI {
                 ++sum_g_childs_mapping_to_s;
             }
         }
-        // Determine the sum of traversals.
-        int traversals_sum = 0;
-        int max_traversals = 0;
-        PhylogenyNode max_traversals_node = null;
-        if ( !s.isExternal() ) {
-            for( int i = 0; i < s.getNumberOfDescendants(); ++i ) {
-                final PhylogenyNode current_node = s.getChildNode( i );
-                final int traversals = getTraversalCount( current_node );
-                traversals_sum += traversals;
-                if ( traversals > max_traversals ) {
-                    max_traversals = traversals;
-                    max_traversals_node = current_node;
-                }
-            }
-        }
-        // System.out.println( " sum=" + traversals_sum );
-        // System.out.println( " max=" + max_traversals );
-        // System.out.println( " m=" + sum_g_childs_mapping_to_s );
-        if ( sum_g_childs_mapping_to_s > 0 ) {
-            if ( traversals_sum == 2 ) {
+        if ( g.getLink().getNumberOfDescendants() == 2 ) {
+            if ( sum_g_childs_mapping_to_s > 0 ) {
                 event = createDuplicationEvent();
-                System.out.print( g.toString() );
-                System.out.println( " : ==2" );
-                //  _transversal_counts.clear();
             }
-            else if ( traversals_sum > 2 ) {
-                if ( max_traversals <= 1 ) {
-                    if ( _most_parsimonious_duplication_model ) {
-                        event = createSpeciationEvent();
-                    }
-                    else {
-                        event = createSingleSpeciationOrDuplicationEvent();
+            else {
+                event = createSpeciationEvent();
+            }
+        }
+        else {
+            if ( sum_g_childs_mapping_to_s > 0 ) {
+                boolean multiple = false;
+                Set<PhylogenyNode> set = new HashSet<PhylogenyNode>();
+                for( PhylogenyNode n : g.getChildNode1().getLink().getAllExternalDescendants() ) {
+                    set.add( n );
+                }
+                for( PhylogenyNode n : g.getChildNode2().getLink().getAllExternalDescendants() ) {
+                    if ( set.contains( n ) ) {
+                        multiple = true;
+                        break;
                     }
+                    // else {
+                    //     set.add( n );
+                    // }
                 }
-                else {
+                if ( multiple ) {
                     event = createDuplicationEvent();
-                    //System.out.println( g.toString() );
-                    _transversal_counts.put( max_traversals_node, 1 );
-                    //  _transversal_counts.clear();
+                }
+                else {
+                    event = createSingleSpeciationOrDuplicationEvent();
                 }
             }
             else {
-                event = createDuplicationEvent();
-                //   _transversal_counts.clear();
+                event = createSpeciationEvent();
             }
-            normalizeTcounts( s );
-        }
-        else {
-            event = createSpeciationEvent();
         }
         g.getNodeData().setEvent( event );
     }
 
-    private void normalizeTcounts( final PhylogenyNode s ) {
-        int min_traversals = Integer.MAX_VALUE;
-        for( int i = 0; i < s.getNumberOfDescendants(); ++i ) {
-            final PhylogenyNode current_node = s.getChildNode( i );
-            final int traversals = getTraversalCount( current_node );
-            if ( traversals < min_traversals ) {
-                min_traversals = traversals;
-            }
-        }
-        for( int i = 0; i < s.getNumberOfDescendants(); ++i ) {
-            final PhylogenyNode current_node = s.getChildNode( i );
-            _transversal_counts.put( current_node, getTraversalCount( current_node ) - min_traversals );
-        }
-    }
-
+    //    private final void determineEvent2( final PhylogenyNode s, final PhylogenyNode g ) {
+    //        Event event = null;
+    //        // Determine how many children map to same node as parent.
+    //        int sum_g_childs_mapping_to_s = 0;
+    //        for( int i = 0; i < g.getNumberOfDescendants(); ++i ) {
+    //            final PhylogenyNode c = g.getChildNode( i );
+    //            if ( c.getLink() == s ) {
+    //                ++sum_g_childs_mapping_to_s;
+    //            }
+    //        }
+    //        // Determine the sum of traversals.
+    //        int traversals_sum = 0;
+    //        int max_traversals = 0;
+    //        PhylogenyNode max_traversals_node = null;
+    //        if ( !s.isExternal() ) {
+    //            for( int i = 0; i < s.getNumberOfDescendants(); ++i ) {
+    //                final PhylogenyNode current_node = s.getChildNode( i );
+    //                final int traversals = getTraversalCount( current_node );
+    //                traversals_sum += traversals;
+    //                if ( traversals > max_traversals ) {
+    //                    max_traversals = traversals;
+    //                    max_traversals_node = current_node;
+    //                }
+    //            }
+    //        }
+    //        // System.out.println( " sum=" + traversals_sum );
+    //        // System.out.println( " max=" + max_traversals );
+    //        // System.out.println( " m=" + sum_g_childs_mapping_to_s );
+    //        if ( s.getNumberOfDescendants() == 2 ) {
+    //            if ( sum_g_childs_mapping_to_s == 0 ) {
+    //                event = createSpeciationEvent();
+    //            }
+    //            else {
+    //                event = createDuplicationEvent();
+    //            }
+    //        }
+    //        else {
+    //            if ( sum_g_childs_mapping_to_s == 2 ) {
+    //                event = createDuplicationEvent();
+    //            }
+    //            else if ( sum_g_childs_mapping_to_s == 1 ) {
+    //                event = createSingleSpeciationOrDuplicationEvent();
+    //            }
+    //            else {
+    //                event = createSpeciationEvent();
+    //            }
+    //        }
+    //        g.getNodeData().setEvent( event );
+    //    }
     /**
      * Traverses the subtree of PhylogenyNode g in postorder, calculating the
      * mapping function M, and determines which nodes represent speciation
@@ -235,71 +235,59 @@ public final class GSDI extends SDI {
      * @param g
      *            starting node of a gene tree - normally the root
      */
-    final void geneTreePostOrderTraversal( final PhylogenyNode g ) {
-        if ( !g.isExternal() ) {
-            boolean all_ext = true;
-            for( int i = 0; i < g.getNumberOfDescendants(); ++i ) {
-                if ( g.getChildNode( i ).isInternal() ) {
-                    all_ext = false;
-                    break;
+    final void geneTreePostOrderTraversal() {
+        for( PhylogenyNodeIterator it = getGeneTree().iteratorPostorder(); it.hasNext(); ) {
+            PhylogenyNode g = it.next();
+            if ( !g.isExternal() ) {
+                final PhylogenyNode[] linked_nodes = new PhylogenyNode[ g.getNumberOfDescendants() ];
+                for( int i = 0; i < linked_nodes.length; ++i ) {
+                    if ( g.getChildNode( i ).getLink() == null ) {
+                        System.out.println( "link is null for " + g.getChildNode( i ) );
+                        System.exit( -1 );
+                    }
+                    linked_nodes[ i ] = g.getChildNode( i ).getLink();
                 }
-            }
-            if ( all_ext ) {
-                //_transversal_counts.clear();
-            }
-            for( int i = 0; i < g.getNumberOfDescendants(); ++i ) {
-                geneTreePostOrderTraversal( g.getChildNode( i ) );
-            }
-            final PhylogenyNode[] linked_nodes = new PhylogenyNode[ g.getNumberOfDescendants() ];
-            for( int i = 0; i < linked_nodes.length; ++i ) {
-                if ( g.getChildNode( i ).getLink() == null ) {
-                    System.out.println( "link is null for " + g.getChildNode( i ) );
-                    System.exit( -1 );
+                final int[] min_max = obtainMinMaxIdIndices( linked_nodes );
+                int min_i = min_max[ 0 ];
+                int max_i = min_max[ 1 ];
+                while ( linked_nodes[ min_i ] != linked_nodes[ max_i ] ) {
+                    linked_nodes[ max_i ] = linked_nodes[ max_i ].getParent();
+                    final int[] min_max_ = obtainMinMaxIdIndices( linked_nodes );
+                    min_i = min_max_[ 0 ];
+                    max_i = min_max_[ 1 ];
                 }
-                linked_nodes[ i ] = g.getChildNode( i ).getLink();
-            }
-            final int[] min_max = obtainMinMaxIdIndices( linked_nodes );
-            int min_i = min_max[ 0 ];
-            int max_i = min_max[ 1 ];
-            // initTransversalCounts();
-            while ( linked_nodes[ min_i ] != linked_nodes[ max_i ] ) {
-                increaseTraversalCount( linked_nodes[ max_i ] );
-                linked_nodes[ max_i ] = linked_nodes[ max_i ].getParent();
-                final int[] min_max_ = obtainMinMaxIdIndices( linked_nodes );
-                min_i = min_max_[ 0 ];
-                max_i = min_max_[ 1 ];
+                final PhylogenyNode s = linked_nodes[ max_i ];
+                g.setLink( s );
+                // Determines whether dup. or spec.
+                determineEvent( s, g );
             }
-            final PhylogenyNode s = linked_nodes[ max_i ];
-            g.setLink( s );
-            // Determines whether dup. or spec.
-            determineEvent( s, g );
         }
     }
 
-    public final int getSpeciationOrDuplicationEventsSum() {
-        return _speciation_or_duplication_events_sum;
+    private final Event createDuplicationEvent() {
+        final Event event = Event.createSingleDuplicationEvent();
+        ++_duplications_sum;
+        return event;
     }
 
-    public final int getSpeciationsSum() {
-        return _speciations_sum;
+    private final Event createSingleSpeciationOrDuplicationEvent() {
+        final Event event = Event.createSingleSpeciationOrDuplicationEvent();
+        ++_speciation_or_duplication_events_sum;
+        return event;
     }
 
-    private final int getTraversalCount( final PhylogenyNode node ) {
-        if ( _transversal_counts.containsKey( node ) ) {
-            return _transversal_counts.get( node );
-        }
-        return 0;
+    private final Event createSpeciationEvent() {
+        final Event event = Event.createSingleSpeciationEvent();
+        ++_speciations_sum;
+        return event;
     }
 
-    private final void increaseTraversalCount( final PhylogenyNode node ) {
-        if ( _transversal_counts.containsKey( node ) ) {
-            _transversal_counts.put( node, _transversal_counts.get( node ) + 1 );
-        }
-        else {
-            _transversal_counts.put( node, 1 );
-        }
-        // System.out.println( "count for node " + node.getID() + " is now "
-        // + getTraversalCount( node ) );
+    public final int getSpeciationOrDuplicationEventsSum() {
+        return _speciation_or_duplication_events_sum;
+    }
+
+    public final int getSpeciationsSum() {
+        return _speciations_sum;
     }
 
     /**
diff --git a/forester/java/src/org/forester/sdi/GSDIold.java b/forester/java/src/org/forester/sdi/GSDIold.java
new file mode 100644 (file)
index 0000000..1fa6684
--- /dev/null
@@ -0,0 +1,761 @@
+// $Id:
+// FORESTER -- software libraries and applications
+// for evolutionary biology research and applications.
+//
+// Copyright (C) 2008-2009 Christian M. Zmasek
+// Copyright (C) 2008-2009 Burnham Institute for Medical Research
+// All rights reserved
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// Contact: phylosoft @ gmail . com
+// WWW: www.phylosoft.org/forester
+
+package org.forester.sdi;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.forester.phylogeny.Phylogeny;
+import org.forester.phylogeny.PhylogenyNode;
+import org.forester.phylogeny.data.Event;
+import org.forester.phylogeny.data.Taxonomy;
+import org.forester.phylogeny.iterators.PhylogenyNodeIterator;
+import org.forester.util.ForesterUtil;
+
+/*
+ * Implements our algorithm for speciation - duplication inference (SDI). <p>
+ * The initialization is accomplished by: </p> <ul> <li>method
+ * "linkExtNodesOfG()" of class SDI: setting the links for the external nodes of
+ * the gene tree <li>"preorderReID(int)" from class Phylogeny: numbering of
+ * nodes of the species tree in preorder <li>the optional stripping of the
+ * species tree is accomplished by method "stripTree(Phylogeny,Phylogeny)" of
+ * class Phylogeny </ul> <p> The recursion part is accomplished by this class'
+ * method "geneTreePostOrderTraversal(PhylogenyNode)". <p> Requires JDK 1.5 or
+ * greater.
+ * 
+ * @see SDI#linkNodesOfG()
+ * 
+ * @see Phylogeny#preorderReID(int)
+ * 
+ * @see
+ * PhylogenyMethods#taxonomyBasedDeletionOfExternalNodes(Phylogeny,Phylogeny)
+ * 
+ * @see #geneTreePostOrderTraversal(PhylogenyNode)
+ * 
+ * @author Christian M. Zmasek
+ */
+public final class GSDIold extends SDI {
+
+    private final HashMap<PhylogenyNode, Integer> _transversal_counts;
+    private final boolean                         _most_parsimonious_duplication_model;
+    private final boolean                         _strip_gene_tree;
+    private final boolean                         _strip_species_tree;
+    private int                                   _speciation_or_duplication_events_sum;
+    private int                                   _speciations_sum;
+    private final List<PhylogenyNode>             _stripped_gene_tree_nodes;
+    private final List<PhylogenyNode>             _stripped_species_tree_nodes;
+    private final Set<PhylogenyNode>              _mapped_species_tree_nodes;
+
+    /**
+     * Constructor which sets the gene tree and the species tree to be compared.
+     * species_tree is the species tree to which the gene tree gene_tree will be
+     * compared to - with method "infer(boolean)". Both Trees must be completely
+     * binary and rooted. The actual inference is accomplished with method
+     * "infer(boolean)". The mapping cost L can then be calculated with method
+     * "computeMappingCost()".
+     * <p>
+     * 
+     * @see #infer(boolean)
+     * @see SDI#computeMappingCostL()
+     * @param gene_tree
+     *            reference to a rooted gene tree to which assign duplication vs
+     *            speciation, must have species names in the species name fields
+     *            for all external nodes
+     * @param species_tree
+     *            reference to a rooted binary species tree which might get
+     *            stripped in the process, must have species names in the
+     *            species name fields for all external nodes
+     * 
+     * @param most_parsimonious_duplication_model
+     *            set to true to assign nodes as speciations which would
+     *            otherwise be assiged as unknown because of polytomies in the
+     *            species tree.
+     * @throws SdiException 
+     * 
+     */
+    public GSDIold( final Phylogeny gene_tree,
+                 final Phylogeny species_tree,
+                 final boolean most_parsimonious_duplication_model,
+                 final boolean strip_gene_tree,
+                 final boolean strip_species_tree ) throws SdiException {
+        super( gene_tree, species_tree );
+        _speciation_or_duplication_events_sum = 0;
+        _speciations_sum = 0;
+        _most_parsimonious_duplication_model = most_parsimonious_duplication_model;
+        _transversal_counts = new HashMap<PhylogenyNode, Integer>();
+        _duplications_sum = 0;
+        _strip_gene_tree = strip_gene_tree;
+        _strip_species_tree = strip_species_tree;
+        _stripped_gene_tree_nodes = new ArrayList<PhylogenyNode>();
+        _stripped_species_tree_nodes = new ArrayList<PhylogenyNode>();
+        _mapped_species_tree_nodes = new HashSet<PhylogenyNode>();
+        getSpeciesTree().preOrderReId();
+        linkNodesOfG();
+        //geneTreePostOrderTraversal( getGeneTree().getRoot(), null );
+        geneTreePostOrderTraversal2();
+    }
+
+    GSDIold( final Phylogeny gene_tree, final Phylogeny species_tree, final boolean most_parsimonious_duplication_model )
+            throws SdiException {
+        this( gene_tree, species_tree, most_parsimonious_duplication_model, false, false );
+    }
+
+    // s is the node on the species tree g maps to.
+    private final void determineEvent( final PhylogenyNode s, final PhylogenyNode g ) {
+        Event event = null;
+        // Determine how many children map to same node as parent.
+        int sum_g_childs_mapping_to_s = 0;
+        for( int i = 0; i < g.getNumberOfDescendants(); ++i ) {
+            final PhylogenyNode c = g.getChildNode( i );
+            if ( c.getLink() == s ) {
+                ++sum_g_childs_mapping_to_s;
+            }
+        }
+        // Determine the sum of traversals.
+        int traversals_sum = 0;
+        int max_traversals = 0;
+        PhylogenyNode max_traversals_node = null;
+        if ( !s.isExternal() ) {
+            for( int i = 0; i < s.getNumberOfDescendants(); ++i ) {
+                final PhylogenyNode current_node = s.getChildNode( i );
+                final int traversals = getTraversalCount( current_node );
+                traversals_sum += traversals;
+                if ( traversals > max_traversals ) {
+                    max_traversals = traversals;
+                    max_traversals_node = current_node;
+                }
+            }
+        }
+        // System.out.println( " sum=" + traversals_sum );
+        // System.out.println( " max=" + max_traversals );
+        // System.out.println( " m=" + sum_g_childs_mapping_to_s );
+        if ( sum_g_childs_mapping_to_s > 0 ) {
+            if ( traversals_sum == 2 ) {
+                event = createDuplicationEvent();
+                System.out.print( g.toString() );
+                System.out.println( " : ==2" );
+                //  _transversal_counts.clear();
+            }
+            else if ( traversals_sum > 2 ) {
+                if ( max_traversals <= 1 ) {
+                    if ( _most_parsimonious_duplication_model ) {
+                        event = createSpeciationEvent();
+                    }
+                    else {
+                        event = createSingleSpeciationOrDuplicationEvent();
+                    }
+                }
+                else {
+                    event = createDuplicationEvent();
+                    //     normalizeTcounts( s );
+                    //System.out.println( g.toString() );
+                    _transversal_counts.put( max_traversals_node, 1 );
+                    //  _transversal_counts.clear();
+                }
+            }
+            else {
+                event = createDuplicationEvent();
+                //   _transversal_counts.clear();
+            }
+            //normalizeTcounts( s );
+        }
+        else {
+            event = createSpeciationEvent();
+        }
+        g.getNodeData().setEvent( event );
+    }
+
+    //    private final void determineEvent2( final PhylogenyNode s, final PhylogenyNode g ) {
+    //        Event event = null;
+    //        // Determine how many children map to same node as parent.
+    //        int sum_g_childs_mapping_to_s = 0;
+    //        for( int i = 0; i < g.getNumberOfDescendants(); ++i ) {
+    //            final PhylogenyNode c = g.getChildNode( i );
+    //            if ( c.getLink() == s ) {
+    //                ++sum_g_childs_mapping_to_s;
+    //            }
+    //        }
+    //        // Determine the sum of traversals.
+    //        int traversals_sum = 0;
+    //        int max_traversals = 0;
+    //        PhylogenyNode max_traversals_node = null;
+    //        if ( !s.isExternal() ) {
+    //            for( int i = 0; i < s.getNumberOfDescendants(); ++i ) {
+    //                final PhylogenyNode current_node = s.getChildNode( i );
+    //                final int traversals = getTraversalCount( current_node );
+    //                traversals_sum += traversals;
+    //                if ( traversals > max_traversals ) {
+    //                    max_traversals = traversals;
+    //                    max_traversals_node = current_node;
+    //                }
+    //            }
+    //        }
+    //        // System.out.println( " sum=" + traversals_sum );
+    //        // System.out.println( " max=" + max_traversals );
+    //        // System.out.println( " m=" + sum_g_childs_mapping_to_s );
+    //        if ( s.getNumberOfDescendants() == 2 ) {
+    //            if ( sum_g_childs_mapping_to_s == 0 ) {
+    //                event = createSpeciationEvent();
+    //            }
+    //            else {
+    //                event = createDuplicationEvent();
+    //            }
+    //        }
+    //        else {
+    //            if ( sum_g_childs_mapping_to_s == 2 ) {
+    //                event = createDuplicationEvent();
+    //            }
+    //            else if ( sum_g_childs_mapping_to_s == 1 ) {
+    //                event = createSingleSpeciationOrDuplicationEvent();
+    //            }
+    //            else {
+    //                event = createSpeciationEvent();
+    //            }
+    //        }
+    //        g.getNodeData().setEvent( event );
+    //    }
+    final void geneTreePostOrderTraversal2() {
+        PhylogenyNode g = null;
+        for( PhylogenyNodeIterator it = getGeneTree().iteratorPostorder(); it.hasNext(); ) {
+            g = it.next();
+            if ( !g.isExternal() ) {
+                for( PhylogenyNodeIterator itw = getGeneTree().iteratorPostorder(); it.hasNext(); ) {
+                    PhylogenyNode gg = it.next();
+                    gg.setLink( null );
+                }
+                try {
+                    linkNodesOfG();
+                }
+                catch ( SdiException e ) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+                _transversal_counts.clear();
+                final PhylogenyNode[] linked_nodes = new PhylogenyNode[ g.getNumberOfDescendants() ];
+                for( int i = 0; i < linked_nodes.length; ++i ) {
+                    if ( g.getChildNode( i ).getLink() == null ) {
+                        System.out.println( "link is null for " + g.getChildNode( i ) );
+                        System.exit( -1 );
+                    }
+                    linked_nodes[ i ] = g.getChildNode( i ).getLink();
+                }
+                final int[] min_max = obtainMinMaxIdIndices( linked_nodes );
+                int min_i = min_max[ 0 ];
+                int max_i = min_max[ 1 ];
+                // initTransversalCounts();
+                while ( linked_nodes[ min_i ] != linked_nodes[ max_i ] ) {
+                    increaseTraversalCount( linked_nodes[ max_i ] );
+                    //                if ( linked_nodes[ max_i ].isExternal() ) {
+                    //                    System.out.println( "i am ext!" );
+                    //                    PhylogenyNode n = linked_nodes[ max_i ];
+                    //                    while ( !n.isRoot() ) {
+                    //                        _transversal_counts.put( n, 0 );
+                    //                        n = n.getParent();
+                    //                    }
+                    //                }
+                    linked_nodes[ max_i ] = linked_nodes[ max_i ].getParent();
+                    final int[] min_max_ = obtainMinMaxIdIndices( linked_nodes );
+                    min_i = min_max_[ 0 ];
+                    max_i = min_max_[ 1 ];
+                }
+                final PhylogenyNode s = linked_nodes[ max_i ];
+                g.setLink( s );
+                // Determines whether dup. or spec.
+                determineEvent( s, g );
+            }
+        }
+    }
+
+    final void geneTreePostOrderTraversal() {
+        PhylogenyNode prev;
+        PhylogenyNode g = null;
+        for( PhylogenyNodeIterator it = getGeneTree().iteratorPostorder(); it.hasNext(); ) {
+            prev = g;
+            g = it.next();
+            if ( !g.isExternal() ) {
+                final PhylogenyNode[] linked_nodes = new PhylogenyNode[ g.getNumberOfDescendants() ];
+                for( int i = 0; i < linked_nodes.length; ++i ) {
+                    if ( g.getChildNode( i ).getLink() == null ) {
+                        System.out.println( "link is null for " + g.getChildNode( i ) );
+                        System.exit( -1 );
+                    }
+                    linked_nodes[ i ] = g.getChildNode( i ).getLink();
+                }
+                final int[] min_max = obtainMinMaxIdIndices( linked_nodes );
+                int min_i = min_max[ 0 ];
+                int max_i = min_max[ 1 ];
+                // initTransversalCounts();
+                while ( linked_nodes[ min_i ] != linked_nodes[ max_i ] ) {
+                    increaseTraversalCount( linked_nodes[ max_i ] );
+                    //                if ( linked_nodes[ max_i ].isExternal() ) {
+                    //                    System.out.println( "i am ext!" );
+                    //                    PhylogenyNode n = linked_nodes[ max_i ];
+                    //                    while ( !n.isRoot() ) {
+                    //                        _transversal_counts.put( n, 0 );
+                    //                        n = n.getParent();
+                    //                    }
+                    //                }
+                    linked_nodes[ max_i ] = linked_nodes[ max_i ].getParent();
+                    final int[] min_max_ = obtainMinMaxIdIndices( linked_nodes );
+                    min_i = min_max_[ 0 ];
+                    max_i = min_max_[ 1 ];
+                }
+                final PhylogenyNode s = linked_nodes[ max_i ];
+                g.setLink( s );
+                // Determines whether dup. or spec.
+                determineEvent( s, g );
+                if ( false ) {
+                    System.out.println( "******" );
+                    _transversal_counts.clear();
+                }
+            }
+        }
+    }
+
+    /**
+     * Traverses the subtree of PhylogenyNode g in postorder, calculating the
+     * mapping function M, and determines which nodes represent speciation
+     * events and which ones duplication events.
+     * <p>
+     * Preconditions: Mapping M for external nodes must have been calculated and
+     * the species tree must be labeled in preorder.
+     * <p>
+     * 
+     * @param g
+     *            starting node of a gene tree - normally the root
+     */
+    final void geneTreePostOrderTraversal( final PhylogenyNode g ) {
+        if ( !g.isExternal() ) {
+            for( int i = 0; i < g.getNumberOfDescendants(); ++i ) {
+                geneTreePostOrderTraversal( g.getChildNode( i ) );
+            }
+            final PhylogenyNode[] linked_nodes = new PhylogenyNode[ g.getNumberOfDescendants() ];
+            for( int i = 0; i < linked_nodes.length; ++i ) {
+                if ( g.getChildNode( i ).getLink() == null ) {
+                    System.out.println( "link is null for " + g.getChildNode( i ) );
+                    System.exit( -1 );
+                }
+                linked_nodes[ i ] = g.getChildNode( i ).getLink();
+            }
+            final int[] min_max = obtainMinMaxIdIndices( linked_nodes );
+            int min_i = min_max[ 0 ];
+            int max_i = min_max[ 1 ];
+            // initTransversalCounts();
+            while ( linked_nodes[ min_i ] != linked_nodes[ max_i ] ) {
+                increaseTraversalCount( linked_nodes[ max_i ] );
+                //                if ( linked_nodes[ max_i ].isExternal() ) {
+                //                    System.out.println( "i am ext!" );
+                //                    PhylogenyNode n = linked_nodes[ max_i ];
+                //                    while ( !n.isRoot() ) {
+                //                        _transversal_counts.put( n, 0 );
+                //                        n = n.getParent();
+                //                    }
+                //                }
+                linked_nodes[ max_i ] = linked_nodes[ max_i ].getParent();
+                final int[] min_max_ = obtainMinMaxIdIndices( linked_nodes );
+                min_i = min_max_[ 0 ];
+                max_i = min_max_[ 1 ];
+            }
+            final PhylogenyNode s = linked_nodes[ max_i ];
+            g.setLink( s );
+            // Determines whether dup. or spec.
+            determineEvent( s, g );
+        }
+    }
+
+    private final Event createDuplicationEvent() {
+        final Event event = Event.createSingleDuplicationEvent();
+        ++_duplications_sum;
+        return event;
+    }
+
+    private final Event createSingleSpeciationOrDuplicationEvent() {
+        final Event event = Event.createSingleSpeciationOrDuplicationEvent();
+        ++_speciation_or_duplication_events_sum;
+        return event;
+    }
+
+    private final Event createSpeciationEvent() {
+        final Event event = Event.createSingleSpeciationEvent();
+        ++_speciations_sum;
+        return event;
+    }
+
+    public final int getSpeciationOrDuplicationEventsSum() {
+        return _speciation_or_duplication_events_sum;
+    }
+
+    public final int getSpeciationsSum() {
+        return _speciations_sum;
+    }
+
+    private final int getTraversalCount( final PhylogenyNode node ) {
+        if ( _transversal_counts.containsKey( node ) ) {
+            return _transversal_counts.get( node );
+        }
+        return 0;
+    }
+
+    private final void increaseTraversalCount( final PhylogenyNode node ) {
+        if ( _transversal_counts.containsKey( node ) ) {
+            _transversal_counts.put( node, _transversal_counts.get( node ) + 1 );
+        }
+        else {
+            _transversal_counts.put( node, 1 );
+        }
+        // System.out.println( "count for node " + node.getID() + " is now "
+        // + getTraversalCount( node ) );
+    }
+
+    private void normalizeTcounts( final PhylogenyNode s ) {
+        //        int min_traversals = Integer.MAX_VALUE;
+        //        for( int i = 0; i < s.getNumberOfDescendants(); ++i ) {
+        //            final PhylogenyNode current_node = s.getChildNode( i );
+        //            final int traversals = getTraversalCount( current_node );
+        //            if ( traversals < min_traversals ) {
+        //                min_traversals = traversals;
+        //            }
+        //        }
+        for( int i = 0; i < s.getNumberOfDescendants(); ++i ) {
+            final PhylogenyNode current_node = s.getChildNode( i );
+            // _transversal_counts.put( current_node, getTraversalCount( current_node ) - min_traversals );
+            if ( getTraversalCount( current_node ) > 1 ) {
+                _transversal_counts.put( current_node, 1 );
+            }
+        }
+    }
+
+    /**
+     * This allows for linking of internal nodes of the species tree (as opposed
+     * to just external nodes, as in the method it overrides.
+     * @throws SdiException 
+     * 
+     */
+    @Override
+    //    final void linkNodesOfG() {
+    //        final HashMap<Taxonomy, PhylogenyNode> speciestree_ext_nodes = createTaxonomyToNodeMap();
+    //        if ( _strip_gene_tree ) {
+    //            stripGeneTree( speciestree_ext_nodes );
+    //            if ( ( _gene_tree == null ) || ( _gene_tree.getNumberOfExternalNodes() < 2 ) ) {
+    //                throw new IllegalArgumentException( "species tree does not contain any"
+    //                        + " nodes matching species in the gene tree" );
+    //            }
+    //        }
+    //        // Retrieve the reference to the PhylogenyNode with a matching species.
+    //        for( final PhylogenyNodeIterator iter = _gene_tree.iteratorExternalForward(); iter.hasNext(); ) {
+    //            final PhylogenyNode g = iter.next();
+    //            if ( !g.getNodeData().isHasTaxonomy() ) {
+    //                throw new IllegalArgumentException( "gene tree node " + g + " has no taxonomic data" );
+    //            }
+    //            final PhylogenyNode s = speciestree_ext_nodes.get( g.getNodeData().getTaxonomy() );
+    //            if ( s == null ) {
+    //                throw new IllegalArgumentException( "species " + g.getNodeData().getTaxonomy()
+    //                        + " not present in species tree" );
+    //            }
+    //            g.setLink( s );
+    //        }
+    //    }
+    final void linkNodesOfG() throws SdiException {
+        final Map<String, PhylogenyNode> species_to_node_map = new HashMap<String, PhylogenyNode>();
+        final List<PhylogenyNode> species_tree_ext_nodes = new ArrayList<PhylogenyNode>();
+        final TaxonomyComparisonBase tax_comp_base = determineTaxonomyComparisonBase( _gene_tree );
+        // System.out.println( "comp base is: " + tax_comp_base );
+        // Stringyfied taxonomy is the key, node is the value.
+        for( final PhylogenyNodeIterator iter = _species_tree.iteratorExternalForward(); iter.hasNext(); ) {
+            final PhylogenyNode s = iter.next();
+            species_tree_ext_nodes.add( s );
+            final String tax_str = taxonomyToString( s, tax_comp_base );
+            if ( !ForesterUtil.isEmpty( tax_str ) ) {
+                if ( species_to_node_map.containsKey( tax_str ) ) {
+                    throw new SdiException( "taxonomy \"" + s + "\" is not unique in species tree" );
+                }
+                species_to_node_map.put( tax_str, s );
+            }
+        }
+        // Retrieve the reference to the node with a matching stringyfied taxonomy.
+        for( final PhylogenyNodeIterator iter = _gene_tree.iteratorExternalForward(); iter.hasNext(); ) {
+            final PhylogenyNode g = iter.next();
+            if ( !g.getNodeData().isHasTaxonomy() ) {
+                if ( _strip_gene_tree ) {
+                    _stripped_gene_tree_nodes.add( g );
+                }
+                else {
+                    throw new SdiException( "gene tree node \"" + g + "\" has no taxonomic data" );
+                }
+            }
+            else {
+                final String tax_str = taxonomyToString( g, tax_comp_base );
+                if ( ForesterUtil.isEmpty( tax_str ) ) {
+                    if ( _strip_gene_tree ) {
+                        _stripped_gene_tree_nodes.add( g );
+                    }
+                    else {
+                        throw new SdiException( "gene tree node \"" + g + "\" has no appropriate taxonomic data" );
+                    }
+                }
+                else {
+                    final PhylogenyNode s = species_to_node_map.get( tax_str );
+                    if ( s == null ) {
+                        if ( _strip_gene_tree ) {
+                            _stripped_gene_tree_nodes.add( g );
+                        }
+                        else {
+                            throw new SdiException( "taxonomy \"" + g.getNodeData().getTaxonomy()
+                                    + "\" not present in species tree" );
+                        }
+                    }
+                    else {
+                        g.setLink( s );
+                        _mapped_species_tree_nodes.add( s );
+                        //  System.out.println( "setting link of " + g + " to " + s );
+                    }
+                }
+            }
+        } // for loop
+        if ( _strip_gene_tree ) {
+            for( final PhylogenyNode g : _stripped_gene_tree_nodes ) {
+                _gene_tree.deleteSubtree( g, true );
+            }
+        }
+        if ( _strip_species_tree ) {
+            for( final PhylogenyNode s : species_tree_ext_nodes ) {
+                if ( !_mapped_species_tree_nodes.contains( s ) ) {
+                    _species_tree.deleteSubtree( s, true );
+                }
+            }
+        }
+    }
+
+    public Set<PhylogenyNode> getMappedExternalSpeciesTreeNodes() {
+        return _mapped_species_tree_nodes;
+    }
+
+    //    final private HashMap<Taxonomy, PhylogenyNode> createTaxonomyToNodeMap() {
+    //        final HashMap<Taxonomy, PhylogenyNode> speciestree_ext_nodes = new HashMap<Taxonomy, PhylogenyNode>();
+    //        for( final PhylogenyNodeIterator iter = _species_tree.iteratorLevelOrder(); iter.hasNext(); ) {
+    //            final PhylogenyNode n = iter.next();
+    //            if ( n.getNodeData().isHasTaxonomy() ) {
+    //                if ( speciestree_ext_nodes.containsKey( n.getNodeData().getTaxonomy() ) ) {
+    //                    throw new IllegalArgumentException( "taxonomy [" + n.getNodeData().getTaxonomy()
+    //                            + "] is not unique in species phylogeny" );
+    //                }
+    //                speciestree_ext_nodes.put( n.getNodeData().getTaxonomy(), n );
+    //            }
+    //        }
+    //        return speciestree_ext_nodes;
+    //    }
+    //    private final void stripGeneTree( final HashMap<Taxonomy, PhylogenyNode> speciestree_ext_nodes ) {
+    //        //  final Set<PhylogenyNode> to_delete = new HashSet<PhylogenyNode>();
+    //        for( final PhylogenyNodeIterator iter = _gene_tree.iteratorExternalForward(); iter.hasNext(); ) {
+    //            final PhylogenyNode g = iter.next();
+    //            if ( !g.getNodeData().isHasTaxonomy() ) {
+    //                throw new IllegalArgumentException( "gene tree node " + g + " has no taxonomic data" );
+    //            }
+    //            if ( !speciestree_ext_nodes.containsKey( g.getNodeData().getTaxonomy() ) ) {
+    //                _stripped_gene_tree_nodes.add( g );
+    //            }
+    //        }
+    //        for( final PhylogenyNode n : _stripped_gene_tree_nodes ) {
+    //            _gene_tree.deleteSubtree( n, true );
+    //        }
+    //    }
+    //    private final void stripGeneTree2( final HashMap<Taxonomy, PhylogenyNode> speciestree_ext_nodes ) {
+    //        //  final Set<PhylogenyNode> to_delete = new HashSet<PhylogenyNode>();
+    //        for( final PhylogenyNodeIterator iter = _gene_tree.iteratorExternalForward(); iter.hasNext(); ) {
+    //            final PhylogenyNode g = iter.next();
+    //            if ( !g.getNodeData().isHasTaxonomy() ) {
+    //                _stripped_gene_tree_nodes.add( g );
+    //            }
+    //            else {
+    //                if ( !speciestree_ext_nodes.containsKey( g.getNodeData().getTaxonomy() ) ) {
+    //                    _stripped_gene_tree_nodes.add( g );
+    //                }
+    //            }
+    //        }
+    //        for( final PhylogenyNode n : _stripped_gene_tree_nodes ) {
+    //            _gene_tree.deleteSubtree( n, true );
+    //        }
+    //    }
+    public static TaxonomyComparisonBase determineTaxonomyComparisonBase( final Phylogeny gene_tree ) {
+        int with_id_count = 0;
+        int with_code_count = 0;
+        int with_sn_count = 0;
+        int max = 0;
+        for( final PhylogenyNodeIterator iter = gene_tree.iteratorExternalForward(); iter.hasNext(); ) {
+            final PhylogenyNode g = iter.next();
+            if ( g.getNodeData().isHasTaxonomy() ) {
+                final Taxonomy tax = g.getNodeData().getTaxonomy();
+                if ( ( tax.getIdentifier() != null ) && !ForesterUtil.isEmpty( tax.getIdentifier().getValue() ) ) {
+                    if ( ++with_id_count > max ) {
+                        max = with_id_count;
+                    }
+                }
+                if ( !ForesterUtil.isEmpty( tax.getTaxonomyCode() ) ) {
+                    if ( ++with_code_count > max ) {
+                        max = with_code_count;
+                    }
+                }
+                if ( !ForesterUtil.isEmpty( tax.getScientificName() ) ) {
+                    if ( ++with_sn_count > max ) {
+                        max = with_sn_count;
+                    }
+                }
+            }
+        }
+        if ( max == 0 ) {
+            throw new IllegalArgumentException( "gene tree has no taxonomic data" );
+        }
+        else if ( max == 1 ) {
+            throw new IllegalArgumentException( "gene tree has only one node with taxonomic data" );
+        }
+        else if ( max == with_sn_count ) {
+            return SDI.TaxonomyComparisonBase.SCIENTIFIC_NAME;
+        }
+        else if ( max == with_id_count ) {
+            return SDI.TaxonomyComparisonBase.ID;
+        }
+        else {
+            return SDI.TaxonomyComparisonBase.CODE;
+        }
+    }
+
+    public List<PhylogenyNode> getStrippedExternalGeneTreeNodes() {
+        return _stripped_gene_tree_nodes;
+    }
+
+    @Override
+    public final String toString() {
+        final StringBuffer sb = new StringBuffer();
+        sb.append( "Most parsimonious duplication model: " + _most_parsimonious_duplication_model );
+        sb.append( ForesterUtil.getLineSeparator() );
+        sb.append( "Speciations sum                    : " + getSpeciationsSum() );
+        sb.append( ForesterUtil.getLineSeparator() );
+        sb.append( "Duplications sum                   : " + getDuplicationsSum() );
+        sb.append( ForesterUtil.getLineSeparator() );
+        if ( !_most_parsimonious_duplication_model ) {
+            sb.append( "Speciation or duplications sum     : " + getSpeciationOrDuplicationEventsSum() );
+            sb.append( ForesterUtil.getLineSeparator() );
+        }
+        sb.append( "mapping cost L                     : " + computeMappingCostL() );
+        return sb.toString();
+    }
+
+    static final int[] obtainMinMaxIdIndices( final PhylogenyNode[] linked_nodes ) {
+        int max_i = 0;
+        int min_i = 0;
+        int max_i_id = -Integer.MAX_VALUE;
+        int min_i_id = Integer.MAX_VALUE;
+        for( int i = 0; i < linked_nodes.length; ++i ) {
+            final int id_i = linked_nodes[ i ].getId();
+            if ( id_i > max_i_id ) {
+                max_i = i;
+                max_i_id = linked_nodes[ max_i ].getId();
+            }
+            if ( id_i < min_i_id ) {
+                min_i = i;
+                min_i_id = linked_nodes[ min_i ].getId();
+            }
+        }
+        return new int[] { min_i, max_i };
+    }
+    /**
+     * Updates the mapping function M after the root of the gene tree has been
+     * moved by one branch. It calculates M for the root of the gene tree and
+     * one of its two children.
+     * <p>
+     * To be used ONLY by method "SDIunrooted.fastInfer(Phylogeny,Phylogeny)".
+     * <p>
+     * (Last modfied: )
+     * 
+     * @param prev_root_was_dup
+     *            true if the previous root was a duplication, false otherwise
+     * @param prev_root_c1
+     *            child 1 of the previous root
+     * @param prev_root_c2
+     *            child 2 of the previous root
+     * @return number of duplications which have been assigned in gene tree
+     */
+    // int updateM( final boolean prev_root_was_dup,
+    // final PhylogenyNode prev_root_c1, final PhylogenyNode prev_root_c2 ) {
+    // final PhylogenyNode root = getGeneTree().getRoot();
+    // if ( ( root.getChildNode1() == prev_root_c1 )
+    // || ( root.getChildNode2() == prev_root_c1 ) ) {
+    // calculateMforNode( prev_root_c1 );
+    // }
+    // else {
+    // calculateMforNode( prev_root_c2 );
+    // }
+    // Event event = null;
+    // if ( prev_root_was_dup ) {
+    // event = Event.createSingleDuplicationEvent();
+    // }
+    // else {
+    // event = Event.createSingleSpeciationEvent();
+    // }
+    // root.getPhylogenyNodeData().setEvent( event );
+    // calculateMforNode( root );
+    // return getDuplications();
+    // } // updateM( boolean, PhylogenyNode, PhylogenyNode )
+    // Helper method for updateM( boolean, PhylogenyNode, PhylogenyNode )
+    // Calculates M for PhylogenyNode n, given that M for the two children
+    // of n has been calculated.
+    // (Last modified: 10/02/01)
+    // private void calculateMforNode( final PhylogenyNode n ) {
+    // if ( !n.isExternal() ) {
+    // boolean was_duplication = n.isDuplication();
+    // PhylogenyNode a = n.getChildNode1().getLink(), b = n
+    // .getChildNode2().getLink();
+    // while ( a != b ) {
+    // if ( a.getID() > b.getID() ) {
+    // a = a.getParent();
+    // }
+    // else {
+    // b = b.getParent();
+    // }
+    // }
+    // n.setLink( a );
+    // Event event = null;
+    // if ( ( a == n.getChildNode1().getLink() )
+    // || ( a == n.getChildNode2().getLink() ) ) {
+    // event = Event.createSingleDuplicationEvent();
+    // if ( !was_duplication ) {
+    // increaseDuplications();
+    // }
+    // }
+    // else {
+    // event = Event.createSingleSpeciationEvent();
+    // if ( was_duplication ) {
+    // decreaseDuplications();
+    // }
+    // }
+    // n.getPhylogenyNodeData().setEvent( event );
+    // }
+    // } // calculateMforNode( PhylogenyNode )
+}
index 70655c6..7aae382 100644 (file)
@@ -28,7 +28,6 @@ package org.forester.sdi;
 import java.io.IOException;
 
 import org.forester.archaeopteryx.Archaeopteryx;
-import org.forester.development.DevelopmentTools;
 import org.forester.io.parsers.nhx.NHXParser;
 import org.forester.phylogeny.Phylogeny;
 import org.forester.phylogeny.PhylogenyMethods;
@@ -118,6 +117,8 @@ public final class TestGSDI {
             final Phylogeny g1 = TestGSDI
                     .createPhylogeny( "((((B[&&NHX:S=B],A1[&&NHX:S=A1]),C[&&NHX:S=C]),A2[&&NHX:S=A2]),D[&&NHX:S=D])" );
             final GSDI sdi1 = new GSDI( g1, s1, false );
+            Archaeopteryx.createApplication( g1 );
+            Archaeopteryx.createApplication( s1 );
             if ( sdi1.getDuplicationsSum() != 1 ) {
                 return false;
             }
@@ -134,1072 +135,1072 @@ public final class TestGSDI {
             if ( !pm.obtainLCA( g1.getNode( "D" ), g1.getNode( "A1" ) ).getNodeData().getEvent().isSpeciation() ) {
                 return false;
             }
-            final Phylogeny g2 = TestGSDI
-                    .createPhylogeny( "((((A2[&&NHX:S=A2],A1[&&NHX:S=A1]),B[&&NHX:S=B]),C[&&NHX:S=C]),D[&&NHX:S=D])" );
-            final GSDI sdi2 = new GSDI( g2, s1, false );
-            if ( sdi2.getDuplicationsSum() != 0 ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g2.getNode( "A1" ), g2.getNode( "A2" ) ).getNodeData().getEvent().isSpeciation() ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g2.getNode( "A1" ), g2.getNode( "B" ) ).getNodeData().getEvent().isSpeciation() ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g2.getNode( "A1" ), g2.getNode( "C" ) ).getNodeData().getEvent()
-                    .isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g2.getNode( "A1" ), g2.getNode( "D" ) ).getNodeData().getEvent().isSpeciation() ) {
-                return false;
-            }
-            final Phylogeny g3 = TestGSDI
-                    .createPhylogeny( "((((A2[&&NHX:S=A2],A1[&&NHX:S=A1]),C[&&NHX:S=C]),B[&&NHX:S=B]),D[&&NHX:S=D])" );
-            final GSDI sdi3 = new GSDI( g3, s1, false );
-            if ( sdi3.getDuplicationsSum() != 0 ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g3.getNode( "A1" ), g3.getNode( "A2" ) ).getNodeData().getEvent().isSpeciation() ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g3.getNode( "A1" ), g3.getNode( "C" ) ).getNodeData().getEvent().isSpeciation() ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g3.getNode( "A1" ), g3.getNode( "B" ) ).getNodeData().getEvent()
-                    .isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g3.getNode( "A1" ), g3.getNode( "D" ) ).getNodeData().getEvent().isSpeciation() ) {
-                return false;
-            }
-            final Phylogeny g4 = TestGSDI
-                    .createPhylogeny( "(((B[&&NHX:S=B],C1[&&NHX:S=C]),C2[&&NHX:S=C]),D[&&NHX:S=D])" );
-            final GSDI sdi4 = new GSDI( g4, s1, false );
-            if ( sdi4.getDuplicationsSum() != 1 ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g4.getNode( "B" ), g4.getNode( "C1" ) ).getNodeData().getEvent().isSpeciation() ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g4.getNode( "B" ), g4.getNode( "C2" ) ).getNodeData().getEvent().isDuplication() ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g4.getNode( "B" ), g4.getNode( "D" ) ).getNodeData().getEvent().isSpeciation() ) {
-                return false;
-            }
-            final Phylogeny g5 = TestGSDI
-                    .createPhylogeny( "(((D1[&&NHX:S=D],A1[&&NHX:S=A1]),B[&&NHX:S=B]),((D2[&&NHX:S=D],D3[&&NHX:S=D]),C[&&NHX:S=C]))" );
-            final GSDI sdi5 = new GSDI( g5, s1, false );
-            if ( sdi5.getDuplicationsSum() != 3 ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g5.getNode( "D1" ), g5.getNode( "A1" ) ).getNodeData().getEvent().isSpeciation() ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g5.getNode( "D1" ), g5.getNode( "B" ) ).getNodeData().getEvent().isDuplication() ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g5.getNode( "D1" ), g5.getNode( "D2" ) ).getNodeData().getEvent().isDuplication() ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g5.getNode( "D2" ), g5.getNode( "D3" ) ).getNodeData().getEvent().isDuplication() ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g5.getNode( "C" ), g5.getNode( "D3" ) ).getNodeData().getEvent().isSpeciation() ) {
-                return false;
-            }
-            final Phylogeny species7 = TestGSDI.createPhylogeny( "(((((((([&&NHX:S=a1],[&&NHX:S=a2]),"
-                    + "([&&NHX:S=b1],[&&NHX:S=b2])),[&&NHX:S=x]),(([&&NHX:S=m1],[&&NHX:S=m2]),"
-                    + "([&&NHX:S=n1],[&&NHX:S=n2]))),(([&&NHX:S=i1],[&&NHX:S=i2]),"
-                    + "([&&NHX:S=j1],[&&NHX:S=j2]))),(([&&NHX:S=e1],[&&NHX:S=e2]),"
-                    + "([&&NHX:S=f1],[&&NHX:S=f2]))),[&&NHX:S=y]),[&&NHX:S=z])" );
-            final Phylogeny gene7_2 = TestGSDI
-                    .createPhylogeny( "(((((((((a1[&&NHX:S=a1],a2[&&NHX:S=a2]),b1[&&NHX:S=b1]),x[&&NHX:S=x]),m1[&&NHX:S=m1]),i1[&&NHX:S=i1]),j2[&&NHX:S=j2]),e1[&&NHX:S=e1]),y[&&NHX:S=y]),z[&&NHX:S=z])" );
-            gene7_2.setRooted( true );
-            final GSDI sdi7_2 = new GSDI( gene7_2, species7, false );
-            if ( sdi7_2.getDuplicationsSum() != 1 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( gene7_2, "a1", "a2" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( gene7_2, "a1", "b1" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( gene7_2, "a1", "x" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( gene7_2, "a1", "m1" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( gene7_2, "a1", "i1" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( gene7_2, "a1", "j2" ).isDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( gene7_2, "a1", "e1" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( gene7_2, "a1", "y" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( gene7_2, "a1", "z" ).isSpeciation() ) {
-                return false;
-            }
-            final Phylogeny g2_0 = TestGSDI.createPhylogeny( "(m1[&&NHX:S=m1],m3[&&NHX:S=m3])" );
-            final GSDI sdi2_0 = new GSDI( g2_0, s2, false );
-            if ( sdi2_0.getDuplicationsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_0.getSpeciationOrDuplicationEventsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_0.getSpeciationsSum() != 1 ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g2_0.getNode( "m1" ), g2_0.getNode( "m3" ) ).getNodeData().getEvent().isSpeciation() ) {
-                return false;
-            }
-            final Phylogeny g2_1 = TestGSDI.createPhylogeny( "(e2[&&NHX:S=e2],h2[&&NHX:S=h2])" );
-            final GSDI sdi2_1 = new GSDI( g2_1, s2, false );
-            if ( sdi2_1.getDuplicationsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_1.getSpeciationOrDuplicationEventsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_1.getSpeciationsSum() != 1 ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g2_1.getNode( "e2" ), g2_1.getNode( "h2" ) ).getNodeData().getEvent().isSpeciation() ) {
-                return false;
-            }
-            final Phylogeny g2_2 = TestGSDI.createPhylogeny( "(e2[&&NHX:S=e2],p4[&&NHX:S=p4])" );
-            final GSDI sdi2_2 = new GSDI( g2_2, s2, false );
-            if ( sdi2_2.getDuplicationsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_2.getSpeciationOrDuplicationEventsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_2.getSpeciationsSum() != 1 ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g2_2.getNode( "e2" ), g2_2.getNode( "p4" ) ).getNodeData().getEvent().isSpeciation() ) {
-                return false;
-            }
-            final Phylogeny g2_3 = TestGSDI.createPhylogeny( "(e2a[&&NHX:S=e2],e2b[&&NHX:S=e2])" );
-            final GSDI sdi2_3 = new GSDI( g2_3, s2, false );
-            if ( sdi2_3.getDuplicationsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_3.getSpeciationOrDuplicationEventsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_3.getSpeciationsSum() != 0 ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g2_3.getNode( "e2a" ), g2_3.getNode( "e2b" ) ).getNodeData().getEvent().isDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_4 = TestGSDI.createPhylogeny( "((j1[&&NHX:S=j1],j4[&&NHX:S=j4]),i3[&&NHX:S=i3])" );
-            final GSDI sdi2_4 = new GSDI( g2_4, s2, false );
-            if ( sdi2_4.getDuplicationsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_4.getSpeciationOrDuplicationEventsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_4.getSpeciationsSum() != 2 ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g2_4.getNode( "j1" ), g2_4.getNode( "j4" ) ).getNodeData().getEvent().isSpeciation() ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g2_4.getNode( "j1" ), g2_4.getNode( "i3" ) ).getNodeData().getEvent().isSpeciation() ) {
-                return false;
-            }
-            final Phylogeny g2_5 = TestGSDI.createPhylogeny( "((j1[&&NHX:S=j1],j4[&&NHX:S=j4]),f3[&&NHX:S=f3])" );
-            final GSDI sdi2_5 = new GSDI( g2_5, s2, false );
-            if ( sdi2_5.getDuplicationsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_5.getSpeciationOrDuplicationEventsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_5.getSpeciationsSum() != 2 ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g2_5.getNode( "j1" ), g2_5.getNode( "j4" ) ).getNodeData().getEvent().isSpeciation() ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g2_5.getNode( "j1" ), g2_5.getNode( "f3" ) ).getNodeData().getEvent().isSpeciation() ) {
-                return false;
-            }
-            final Phylogeny g2_6 = TestGSDI.createPhylogeny( "((j3[&&NHX:S=j3],i4[&&NHX:S=i4]),f3[&&NHX:S=f3])" );
-            final GSDI sdi2_6 = new GSDI( g2_6, s2, false );
-            if ( sdi2_6.getDuplicationsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_6.getSpeciationOrDuplicationEventsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_6.getSpeciationsSum() != 2 ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g2_6.getNode( "j3" ), g2_6.getNode( "i4" ) ).getNodeData().getEvent().isSpeciation() ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g2_6.getNode( "j3" ), g2_6.getNode( "f3" ) ).getNodeData().getEvent().isSpeciation() ) {
-                return false;
-            }
-            final Phylogeny g2_7 = TestGSDI.createPhylogeny( "((j1[&&NHX:S=j1],k1[&&NHX:S=k1]),i1[&&NHX:S=i1])" );
-            final GSDI sdi2_7 = new GSDI( g2_7, s2, false );
-            if ( sdi2_7.getDuplicationsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_7.getSpeciationOrDuplicationEventsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_7.getSpeciationsSum() != 1 ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g2_7.getNode( "j1" ), g2_7.getNode( "k1" ) ).getNodeData().getEvent().isSpeciation() ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g2_7.getNode( "j1" ), g2_7.getNode( "i1" ) ).getNodeData().getEvent()
-                    .isSpeciationOrDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_8 = TestGSDI.createPhylogeny( "(j1[&&NHX:S=j1],(k1[&&NHX:S=k1],i1[&&NHX:S=i1]))" );
-            final GSDI sdi2_8 = new GSDI( g2_8, s2, false );
-            if ( sdi2_8.getDuplicationsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_8.getSpeciationOrDuplicationEventsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_8.getSpeciationsSum() != 1 ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g2_8.getNode( "j1" ), g2_8.getNode( "k1" ) ).getNodeData().getEvent()
-                    .isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !pm.obtainLCA( g2_8.getNode( "k1" ), g2_8.getNode( "i1" ) ).getNodeData().getEvent().isSpeciation() ) {
-                return false;
-            }
-            final Phylogeny g2_9 = TestGSDI.createPhylogeny( "((j1[&&NHX:S=j1],k4[&&NHX:S=k4]),f2[&&NHX:S=f2])" );
-            final GSDI sdi2_9 = new GSDI( g2_9, s2, false );
-            if ( sdi2_9.getDuplicationsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_9.getSpeciationOrDuplicationEventsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_9.getSpeciationsSum() != 2 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_9, "j1", "k4" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_9, "j1", "f2" ).isSpeciation() ) {
-                return false;
-            }
-            final Phylogeny g2_10 = TestGSDI.createPhylogeny( "((m1[&&NHX:S=m1],k4[&&NHX:S=k4]),f2[&&NHX:S=f2])" );
-            final GSDI sdi2_10 = new GSDI( g2_10, s2, false );
-            if ( sdi2_10.getDuplicationsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_10.getSpeciationOrDuplicationEventsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_10.getSpeciationsSum() != 1 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_10, "m1", "k4" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_10, "m1", "f2" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_11 = TestGSDI.createPhylogeny( "((m1[&&NHX:S=m1],k4[&&NHX:S=k4]),x[&&NHX:S=x])" );
-            final GSDI sdi2_11 = new GSDI( g2_11, s2, false );
-            if ( sdi2_11.getDuplicationsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_11.getSpeciationOrDuplicationEventsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_11.getSpeciationsSum() != 1 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_11, "m1", "k4" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_11, "m1", "x" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_12 = TestGSDI.createPhylogeny( "(m1[&&NHX:S=m1],(k4[&&NHX:S=k4],x[&&NHX:S=x]))" );
-            final GSDI sdi2_12 = new GSDI( g2_12, s2, false );
-            if ( sdi2_12.getDuplicationsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_12.getSpeciationOrDuplicationEventsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_12.getSpeciationsSum() != 1 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_12, "x", "k4" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_12, "m1", "x" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_13 = TestGSDI.createPhylogeny( "(x[&&NHX:S=x],(y[&&NHX:S=y],z[&&NHX:S=z]))" );
-            final GSDI sdi2_13 = new GSDI( g2_13, s2, false );
-            if ( sdi2_13.getDuplicationsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_13.getSpeciationOrDuplicationEventsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_13.getSpeciationsSum() != 1 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_13, "y", "z" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_13, "x", "z" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_14 = TestGSDI.createPhylogeny( "(a1_1[&&NHX:S=a1],(b1[&&NHX:S=b1],a1[&&NHX:S=a1]))" );
-            final GSDI sdi2_14 = new GSDI( g2_14, s2, false );
-            if ( sdi2_14.getDuplicationsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_14.getSpeciationOrDuplicationEventsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_14.getSpeciationsSum() != 1 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_14, "b1", "a1" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_14, "b1", "a1_1" ).isDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_15 = TestGSDI.createPhylogeny( "(a2[&&NHX:S=a2],(b1[&&NHX:S=b1],a1[&&NHX:S=a1]))" );
-            final GSDI sdi2_15 = new GSDI( g2_15, s2, false );
-            if ( sdi2_15.getDuplicationsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_15.getSpeciationOrDuplicationEventsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_15.getSpeciationsSum() != 1 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_15, "b1", "a1" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_15, "b1", "a2" ).isDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_16 = TestGSDI.createPhylogeny( "(n2[&&NHX:S=n2],(j3[&&NHX:S=j3],n1[&&NHX:S=n1]))" );
-            final GSDI sdi2_16 = new GSDI( g2_16, s2, false );
-            if ( sdi2_16.getDuplicationsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_16.getSpeciationOrDuplicationEventsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_16.getSpeciationsSum() != 1 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_16, "j3", "n1" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_16, "j3", "n2" ).isDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_17 = TestGSDI.createPhylogeny( "(p4[&&NHX:S=p4],(j3[&&NHX:S=j3],n1[&&NHX:S=n1]))" );
-            final GSDI sdi2_17 = new GSDI( g2_17, s2, false );
-            if ( sdi2_17.getDuplicationsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_17.getSpeciationOrDuplicationEventsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_17.getSpeciationsSum() != 1 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_17, "j3", "n1" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_17, "j3", "p4" ).isDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_18 = TestGSDI
-                    .createPhylogeny( "((n11[&&NHX:S=n1],n12[&&NHX:S=n1]),(n13[&&NHX:S=n1],n14[&&NHX:S=n1]))" );
-            final GSDI sdi2_18 = new GSDI( g2_18, s2, false );
-            if ( sdi2_18.getDuplicationsSum() != 3 ) {
-                return false;
-            }
-            if ( sdi2_18.getSpeciationOrDuplicationEventsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_18.getSpeciationsSum() != 0 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_18, "n11", "n12" ).isDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_18, "n13", "n14" ).isDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_18, "n11", "n13" ).isDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_19 = TestGSDI
-                    .createPhylogeny( "((n11[&&NHX:S=n1],n21[&&NHX:S=n2]),(n12[&&NHX:S=n1],n22[&&NHX:S=n2]))" );
-            final GSDI sdi2_19 = new GSDI( g2_19, s2, false );
-            if ( sdi2_19.getDuplicationsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_19.getSpeciationOrDuplicationEventsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_19.getSpeciationsSum() != 2 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_19, "n11", "n21" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_19, "n12", "n22" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_19, "n11", "n12" ).isDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_20 = TestGSDI
-                    .createPhylogeny( "((n11[&&NHX:S=n1],n2[&&NHX:S=n2]),(n12[&&NHX:S=n1],n3[&&NHX:S=n3]))" );
-            final GSDI sdi2_20 = new GSDI( g2_20, s2, false );
-            if ( sdi2_20.getDuplicationsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_20.getSpeciationOrDuplicationEventsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_20.getSpeciationsSum() != 2 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_20, "n11", "n2" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_20, "n12", "n3" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_20, "n11", "n12" ).isDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_21 = TestGSDI
-                    .createPhylogeny( "((n1[&&NHX:S=n1],n2[&&NHX:S=n2]),(n3[&&NHX:S=n3],a1[&&NHX:S=a1]))" );
-            final GSDI sdi2_21 = new GSDI( g2_21, s2, false );
-            if ( sdi2_21.getDuplicationsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_21.getSpeciationOrDuplicationEventsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_21.getSpeciationsSum() != 2 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_21, "n1", "n2" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_21, "n3", "a1" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_21, "n2", "a1" ).isDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_22 = TestGSDI
-                    .createPhylogeny( "((n1[&&NHX:S=n1],n2[&&NHX:S=n2]),(n3[&&NHX:S=n3],n4[&&NHX:S=n4]))" );
-            final GSDI sdi2_22 = new GSDI( g2_22, s2, false );
-            Archaeopteryx.createApplication( g2_22 );
-            Archaeopteryx.createApplication( s2 );
-            if ( sdi2_22.getDuplicationsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_22.getSpeciationOrDuplicationEventsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_22.getSpeciationsSum() != 2 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_22, "n1", "n2" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_22, "n3", "n4" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_22, "n1", "n3" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_23 = TestGSDI
-                    .createPhylogeny( "((a1[&&NHX:S=a1],b1[&&NHX:S=b1]),(c1[&&NHX:S=c1],d1[&&NHX:S=d1]))" );
-            final GSDI sdi2_23 = new GSDI( g2_23, s2, false );
-            if ( sdi2_23.getDuplicationsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_23.getSpeciationOrDuplicationEventsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_23.getSpeciationsSum() != 2 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_23, "a1", "b1" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_23, "c1", "d1" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_23, "a1", "c1" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_24 = TestGSDI
-                    .createPhylogeny( "((a1[&&NHX:S=a1],e1[&&NHX:S=e1]),(i1[&&NHX:S=i1],m1[&&NHX:S=m1]))" );
-            final GSDI sdi2_24 = new GSDI( g2_24, s2, false );
-            if ( sdi2_24.getDuplicationsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_24.getSpeciationOrDuplicationEventsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_24.getSpeciationsSum() != 2 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_24, "a1", "e1" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_24, "i1", "m1" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_24, "a1", "i1" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_25 = TestGSDI
-                    .createPhylogeny( "((a1[&&NHX:S=a1],a4[&&NHX:S=a4]),(b1[&&NHX:S=b1],c1[&&NHX:S=c1]))" );
-            final GSDI sdi2_25 = new GSDI( g2_25, s2, false );
-            if ( sdi2_25.getDuplicationsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_25.getSpeciationOrDuplicationEventsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_25.getSpeciationsSum() != 2 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_25, "a1", "a4" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_25, "b1", "c1" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_25, "a1", "b1" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_26 = TestGSDI
-                    .createPhylogeny( "(((a1[&&NHX:S=a1],a4[&&NHX:S=a4]),b1[&&NHX:S=b1]),e1[&&NHX:S=e1])" );
-            final GSDI sdi2_26 = new GSDI( g2_26, s2, false );
-            if ( sdi2_26.getDuplicationsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_26.getSpeciationOrDuplicationEventsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_26.getSpeciationsSum() != 3 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_26, "a1", "a4" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_26, "a1", "b1" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_26, "a1", "e1" ).isSpeciation() ) {
-                return false;
-            }
-            final Phylogeny g2_27 = TestGSDI
-                    .createPhylogeny( "(((a1[&&NHX:S=a1],a4[&&NHX:S=a4]),b1[&&NHX:S=b1]),c1[&&NHX:S=c1])" );
-            final GSDI sdi2_27 = new GSDI( g2_27, s2, false );
-            if ( sdi2_27.getDuplicationsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_27.getSpeciationOrDuplicationEventsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_27.getSpeciationsSum() != 2 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_27, "a1", "a4" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_27, "a1", "b1" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_27, "a1", "c1" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_28 = TestGSDI
-                    .createPhylogeny( "(((a1[&&NHX:S=a1],b1[&&NHX:S=b1]),c1[&&NHX:S=c1]),e1[&&NHX:S=e1])" );
-            final GSDI sdi2_28 = new GSDI( g2_28, s2, false );
-            if ( sdi2_28.getDuplicationsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_28.getSpeciationOrDuplicationEventsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_28.getSpeciationsSum() != 2 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_28, "a1", "b1" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_28, "a1", "c1" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_28, "a1", "e1" ).isSpeciation() ) {
-                return false;
-            }
-            final Phylogeny g2_29 = TestGSDI
-                    .createPhylogeny( "(((a1[&&NHX:S=a1],b1[&&NHX:S=b1]),c1[&&NHX:S=c1]),d1[&&NHX:S=d1])" );
-            final GSDI sdi2_29 = new GSDI( g2_29, s2, false );
-            if ( sdi2_29.getDuplicationsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_29.getSpeciationOrDuplicationEventsSum() != 2 ) {
-                return false;
-            }
-            if ( sdi2_29.getSpeciationsSum() != 1 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_29, "a1", "b1" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_29, "a1", "c1" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_29, "a1", "d1" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_30 = TestGSDI
-                    .createPhylogeny( "(((a1[&&NHX:S=a1],b1[&&NHX:S=b1]),c1[&&NHX:S=c1]),a2[&&NHX:S=a2])" );
-            final GSDI sdi2_30 = new GSDI( g2_30, s2, false );
-            if ( sdi2_30.getDuplicationsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_30.getSpeciationOrDuplicationEventsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_30.getSpeciationsSum() != 1 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_30, "a1", "b1" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_30, "a1", "c1" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_30, "a1", "a2" ).isDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_31 = TestGSDI
-                    .createPhylogeny( "(((a1[&&NHX:S=a1],b1[&&NHX:S=b1]),c1[&&NHX:S=c1]),c2[&&NHX:S=c2])" );
-            final GSDI sdi2_31 = new GSDI( g2_31, s2, false );
-            if ( sdi2_31.getDuplicationsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_31.getSpeciationOrDuplicationEventsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_31.getSpeciationsSum() != 1 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_31, "a1", "b1" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_31, "a1", "c1" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_31, "a1", "c2" ).isDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_32 = TestGSDI
-                    .createPhylogeny( "((((((((((a1[&&NHX:S=a1],a2[&&NHX:S=a2]),b1[&&NHX:S=b1]),c1[&&NHX:S=c1]),d1[&&NHX:S=d1]),x[&&NHX:S=x]),p1[&&NHX:S=p1]),i1[&&NHX:S=i1]),e1[&&NHX:S=e1]),y[&&NHX:S=y]),z[&&NHX:S=z])" );
-            final GSDI sdi2_32 = new GSDI( g2_32, s2, false );
-            if ( sdi2_32.getDuplicationsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_32.getSpeciationOrDuplicationEventsSum() != 7 ) {
-                return false;
-            }
-            if ( sdi2_32.getSpeciationsSum() != 3 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_32, "a1", "a2" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_32, "a1", "b1" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_32, "a1", "c1" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_32, "a1", "d1" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_32, "a1", "x" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_32, "a1", "p1" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_32, "a1", "i1" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_32, "a1", "e1" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_32, "a1", "y" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_32, "a1", "z" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
+            //            final Phylogeny g2 = TestGSDI
+            //                    .createPhylogeny( "((((A2[&&NHX:S=A2],A1[&&NHX:S=A1]),B[&&NHX:S=B]),C[&&NHX:S=C]),D[&&NHX:S=D])" );
+            //            final GSDI sdi2 = new GSDI( g2, s1, false );
+            //            if ( sdi2.getDuplicationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g2.getNode( "A1" ), g2.getNode( "A2" ) ).getNodeData().getEvent().isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g2.getNode( "A1" ), g2.getNode( "B" ) ).getNodeData().getEvent().isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g2.getNode( "A1" ), g2.getNode( "C" ) ).getNodeData().getEvent()
+            //                    .isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g2.getNode( "A1" ), g2.getNode( "D" ) ).getNodeData().getEvent().isSpeciation() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g3 = TestGSDI
+            //                    .createPhylogeny( "((((A2[&&NHX:S=A2],A1[&&NHX:S=A1]),C[&&NHX:S=C]),B[&&NHX:S=B]),D[&&NHX:S=D])" );
+            //            final GSDI sdi3 = new GSDI( g3, s1, false );
+            //            if ( sdi3.getDuplicationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g3.getNode( "A1" ), g3.getNode( "A2" ) ).getNodeData().getEvent().isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g3.getNode( "A1" ), g3.getNode( "C" ) ).getNodeData().getEvent().isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g3.getNode( "A1" ), g3.getNode( "B" ) ).getNodeData().getEvent()
+            //                    .isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g3.getNode( "A1" ), g3.getNode( "D" ) ).getNodeData().getEvent().isSpeciation() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g4 = TestGSDI
+            //                    .createPhylogeny( "(((B[&&NHX:S=B],C1[&&NHX:S=C]),C2[&&NHX:S=C]),D[&&NHX:S=D])" );
+            //            final GSDI sdi4 = new GSDI( g4, s1, false );
+            //            if ( sdi4.getDuplicationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g4.getNode( "B" ), g4.getNode( "C1" ) ).getNodeData().getEvent().isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g4.getNode( "B" ), g4.getNode( "C2" ) ).getNodeData().getEvent().isDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g4.getNode( "B" ), g4.getNode( "D" ) ).getNodeData().getEvent().isSpeciation() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g5 = TestGSDI
+            //                    .createPhylogeny( "(((D1[&&NHX:S=D],A1[&&NHX:S=A1]),B[&&NHX:S=B]),((D2[&&NHX:S=D],D3[&&NHX:S=D]),C[&&NHX:S=C]))" );
+            //            final GSDI sdi5 = new GSDI( g5, s1, false );
+            //            if ( sdi5.getDuplicationsSum() != 3 ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g5.getNode( "D1" ), g5.getNode( "A1" ) ).getNodeData().getEvent().isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g5.getNode( "D1" ), g5.getNode( "B" ) ).getNodeData().getEvent().isDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g5.getNode( "D1" ), g5.getNode( "D2" ) ).getNodeData().getEvent().isDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g5.getNode( "D2" ), g5.getNode( "D3" ) ).getNodeData().getEvent().isDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g5.getNode( "C" ), g5.getNode( "D3" ) ).getNodeData().getEvent().isSpeciation() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny species7 = TestGSDI.createPhylogeny( "(((((((([&&NHX:S=a1],[&&NHX:S=a2]),"
+            //                    + "([&&NHX:S=b1],[&&NHX:S=b2])),[&&NHX:S=x]),(([&&NHX:S=m1],[&&NHX:S=m2]),"
+            //                    + "([&&NHX:S=n1],[&&NHX:S=n2]))),(([&&NHX:S=i1],[&&NHX:S=i2]),"
+            //                    + "([&&NHX:S=j1],[&&NHX:S=j2]))),(([&&NHX:S=e1],[&&NHX:S=e2]),"
+            //                    + "([&&NHX:S=f1],[&&NHX:S=f2]))),[&&NHX:S=y]),[&&NHX:S=z])" );
+            //            final Phylogeny gene7_2 = TestGSDI
+            //                    .createPhylogeny( "(((((((((a1[&&NHX:S=a1],a2[&&NHX:S=a2]),b1[&&NHX:S=b1]),x[&&NHX:S=x]),m1[&&NHX:S=m1]),i1[&&NHX:S=i1]),j2[&&NHX:S=j2]),e1[&&NHX:S=e1]),y[&&NHX:S=y]),z[&&NHX:S=z])" );
+            //            gene7_2.setRooted( true );
+            //            final GSDI sdi7_2 = new GSDI( gene7_2, species7, false );
+            //            if ( sdi7_2.getDuplicationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( gene7_2, "a1", "a2" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( gene7_2, "a1", "b1" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( gene7_2, "a1", "x" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( gene7_2, "a1", "m1" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( gene7_2, "a1", "i1" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( gene7_2, "a1", "j2" ).isDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( gene7_2, "a1", "e1" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( gene7_2, "a1", "y" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( gene7_2, "a1", "z" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_0 = TestGSDI.createPhylogeny( "(m1[&&NHX:S=m1],m3[&&NHX:S=m3])" );
+            //            final GSDI sdi2_0 = new GSDI( g2_0, s2, false );
+            //            if ( sdi2_0.getDuplicationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_0.getSpeciationOrDuplicationEventsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_0.getSpeciationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g2_0.getNode( "m1" ), g2_0.getNode( "m3" ) ).getNodeData().getEvent().isSpeciation() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_1 = TestGSDI.createPhylogeny( "(e2[&&NHX:S=e2],h2[&&NHX:S=h2])" );
+            //            final GSDI sdi2_1 = new GSDI( g2_1, s2, false );
+            //            if ( sdi2_1.getDuplicationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_1.getSpeciationOrDuplicationEventsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_1.getSpeciationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g2_1.getNode( "e2" ), g2_1.getNode( "h2" ) ).getNodeData().getEvent().isSpeciation() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_2 = TestGSDI.createPhylogeny( "(e2[&&NHX:S=e2],p4[&&NHX:S=p4])" );
+            //            final GSDI sdi2_2 = new GSDI( g2_2, s2, false );
+            //            if ( sdi2_2.getDuplicationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_2.getSpeciationOrDuplicationEventsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_2.getSpeciationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g2_2.getNode( "e2" ), g2_2.getNode( "p4" ) ).getNodeData().getEvent().isSpeciation() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_3 = TestGSDI.createPhylogeny( "(e2a[&&NHX:S=e2],e2b[&&NHX:S=e2])" );
+            //            final GSDI sdi2_3 = new GSDI( g2_3, s2, false );
+            //            if ( sdi2_3.getDuplicationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_3.getSpeciationOrDuplicationEventsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_3.getSpeciationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g2_3.getNode( "e2a" ), g2_3.getNode( "e2b" ) ).getNodeData().getEvent().isDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_4 = TestGSDI.createPhylogeny( "((j1[&&NHX:S=j1],j4[&&NHX:S=j4]),i3[&&NHX:S=i3])" );
+            //            final GSDI sdi2_4 = new GSDI( g2_4, s2, false );
+            //            if ( sdi2_4.getDuplicationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_4.getSpeciationOrDuplicationEventsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_4.getSpeciationsSum() != 2 ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g2_4.getNode( "j1" ), g2_4.getNode( "j4" ) ).getNodeData().getEvent().isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g2_4.getNode( "j1" ), g2_4.getNode( "i3" ) ).getNodeData().getEvent().isSpeciation() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_5 = TestGSDI.createPhylogeny( "((j1[&&NHX:S=j1],j4[&&NHX:S=j4]),f3[&&NHX:S=f3])" );
+            //            final GSDI sdi2_5 = new GSDI( g2_5, s2, false );
+            //            if ( sdi2_5.getDuplicationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_5.getSpeciationOrDuplicationEventsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_5.getSpeciationsSum() != 2 ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g2_5.getNode( "j1" ), g2_5.getNode( "j4" ) ).getNodeData().getEvent().isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g2_5.getNode( "j1" ), g2_5.getNode( "f3" ) ).getNodeData().getEvent().isSpeciation() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_6 = TestGSDI.createPhylogeny( "((j3[&&NHX:S=j3],i4[&&NHX:S=i4]),f3[&&NHX:S=f3])" );
+            //            final GSDI sdi2_6 = new GSDI( g2_6, s2, false );
+            //            if ( sdi2_6.getDuplicationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_6.getSpeciationOrDuplicationEventsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_6.getSpeciationsSum() != 2 ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g2_6.getNode( "j3" ), g2_6.getNode( "i4" ) ).getNodeData().getEvent().isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g2_6.getNode( "j3" ), g2_6.getNode( "f3" ) ).getNodeData().getEvent().isSpeciation() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_7 = TestGSDI.createPhylogeny( "((j1[&&NHX:S=j1],k1[&&NHX:S=k1]),i1[&&NHX:S=i1])" );
+            //            final GSDI sdi2_7 = new GSDI( g2_7, s2, false );
+            //            if ( sdi2_7.getDuplicationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_7.getSpeciationOrDuplicationEventsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_7.getSpeciationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g2_7.getNode( "j1" ), g2_7.getNode( "k1" ) ).getNodeData().getEvent().isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g2_7.getNode( "j1" ), g2_7.getNode( "i1" ) ).getNodeData().getEvent()
+            //                    .isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_8 = TestGSDI.createPhylogeny( "(j1[&&NHX:S=j1],(k1[&&NHX:S=k1],i1[&&NHX:S=i1]))" );
+            //            final GSDI sdi2_8 = new GSDI( g2_8, s2, false );
+            //            if ( sdi2_8.getDuplicationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_8.getSpeciationOrDuplicationEventsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_8.getSpeciationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g2_8.getNode( "j1" ), g2_8.getNode( "k1" ) ).getNodeData().getEvent()
+            //                    .isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !pm.obtainLCA( g2_8.getNode( "k1" ), g2_8.getNode( "i1" ) ).getNodeData().getEvent().isSpeciation() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_9 = TestGSDI.createPhylogeny( "((j1[&&NHX:S=j1],k4[&&NHX:S=k4]),f2[&&NHX:S=f2])" );
+            //            final GSDI sdi2_9 = new GSDI( g2_9, s2, false );
+            //            if ( sdi2_9.getDuplicationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_9.getSpeciationOrDuplicationEventsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_9.getSpeciationsSum() != 2 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_9, "j1", "k4" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_9, "j1", "f2" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_10 = TestGSDI.createPhylogeny( "((m1[&&NHX:S=m1],k4[&&NHX:S=k4]),f2[&&NHX:S=f2])" );
+            //            final GSDI sdi2_10 = new GSDI( g2_10, s2, false );
+            //            if ( sdi2_10.getDuplicationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_10.getSpeciationOrDuplicationEventsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_10.getSpeciationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_10, "m1", "k4" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_10, "m1", "f2" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_11 = TestGSDI.createPhylogeny( "((m1[&&NHX:S=m1],k4[&&NHX:S=k4]),x[&&NHX:S=x])" );
+            //            final GSDI sdi2_11 = new GSDI( g2_11, s2, false );
+            //            if ( sdi2_11.getDuplicationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_11.getSpeciationOrDuplicationEventsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_11.getSpeciationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_11, "m1", "k4" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_11, "m1", "x" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_12 = TestGSDI.createPhylogeny( "(m1[&&NHX:S=m1],(k4[&&NHX:S=k4],x[&&NHX:S=x]))" );
+            //            final GSDI sdi2_12 = new GSDI( g2_12, s2, false );
+            //            if ( sdi2_12.getDuplicationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_12.getSpeciationOrDuplicationEventsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_12.getSpeciationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_12, "x", "k4" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_12, "m1", "x" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_13 = TestGSDI.createPhylogeny( "(x[&&NHX:S=x],(y[&&NHX:S=y],z[&&NHX:S=z]))" );
+            //            final GSDI sdi2_13 = new GSDI( g2_13, s2, false );
+            //            if ( sdi2_13.getDuplicationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_13.getSpeciationOrDuplicationEventsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_13.getSpeciationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_13, "y", "z" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_13, "x", "z" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_14 = TestGSDI.createPhylogeny( "(a1_1[&&NHX:S=a1],(b1[&&NHX:S=b1],a1[&&NHX:S=a1]))" );
+            //            final GSDI sdi2_14 = new GSDI( g2_14, s2, false );
+            //            if ( sdi2_14.getDuplicationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_14.getSpeciationOrDuplicationEventsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_14.getSpeciationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_14, "b1", "a1" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_14, "b1", "a1_1" ).isDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_15 = TestGSDI.createPhylogeny( "(a2[&&NHX:S=a2],(b1[&&NHX:S=b1],a1[&&NHX:S=a1]))" );
+            //            final GSDI sdi2_15 = new GSDI( g2_15, s2, false );
+            //            if ( sdi2_15.getDuplicationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_15.getSpeciationOrDuplicationEventsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_15.getSpeciationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_15, "b1", "a1" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_15, "b1", "a2" ).isDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_16 = TestGSDI.createPhylogeny( "(n2[&&NHX:S=n2],(j3[&&NHX:S=j3],n1[&&NHX:S=n1]))" );
+            //            final GSDI sdi2_16 = new GSDI( g2_16, s2, false );
+            //            if ( sdi2_16.getDuplicationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_16.getSpeciationOrDuplicationEventsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_16.getSpeciationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_16, "j3", "n1" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_16, "j3", "n2" ).isDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_17 = TestGSDI.createPhylogeny( "(p4[&&NHX:S=p4],(j3[&&NHX:S=j3],n1[&&NHX:S=n1]))" );
+            //            final GSDI sdi2_17 = new GSDI( g2_17, s2, false );
+            //            if ( sdi2_17.getDuplicationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_17.getSpeciationOrDuplicationEventsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_17.getSpeciationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_17, "j3", "n1" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_17, "j3", "p4" ).isDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_18 = TestGSDI
+            //                    .createPhylogeny( "((n11[&&NHX:S=n1],n12[&&NHX:S=n1]),(n13[&&NHX:S=n1],n14[&&NHX:S=n1]))" );
+            //            final GSDI sdi2_18 = new GSDI( g2_18, s2, false );
+            //            if ( sdi2_18.getDuplicationsSum() != 3 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_18.getSpeciationOrDuplicationEventsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_18.getSpeciationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_18, "n11", "n12" ).isDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_18, "n13", "n14" ).isDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_18, "n11", "n13" ).isDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_19 = TestGSDI
+            //                    .createPhylogeny( "((n11[&&NHX:S=n1],n21[&&NHX:S=n2]),(n12[&&NHX:S=n1],n22[&&NHX:S=n2]))" );
+            //            final GSDI sdi2_19 = new GSDI( g2_19, s2, false );
+            //            if ( sdi2_19.getDuplicationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_19.getSpeciationOrDuplicationEventsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_19.getSpeciationsSum() != 2 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_19, "n11", "n21" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_19, "n12", "n22" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_19, "n11", "n12" ).isDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_20 = TestGSDI
+            //                    .createPhylogeny( "((n11[&&NHX:S=n1],n2[&&NHX:S=n2]),(n12[&&NHX:S=n1],n3[&&NHX:S=n3]))" );
+            //            final GSDI sdi2_20 = new GSDI( g2_20, s2, false );
+            //            if ( sdi2_20.getDuplicationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_20.getSpeciationOrDuplicationEventsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_20.getSpeciationsSum() != 2 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_20, "n11", "n2" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_20, "n12", "n3" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_20, "n11", "n12" ).isDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_21 = TestGSDI
+            //                    .createPhylogeny( "((n1[&&NHX:S=n1],n2[&&NHX:S=n2]),(n3[&&NHX:S=n3],a1[&&NHX:S=a1]))" );
+            //            final GSDI sdi2_21 = new GSDI( g2_21, s2, false );
+            //            if ( sdi2_21.getDuplicationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_21.getSpeciationOrDuplicationEventsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_21.getSpeciationsSum() != 2 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_21, "n1", "n2" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_21, "n3", "a1" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_21, "n2", "a1" ).isDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_22 = TestGSDI
+            //                    .createPhylogeny( "((n1[&&NHX:S=n1],n2[&&NHX:S=n2]),(n3[&&NHX:S=n3],n4[&&NHX:S=n4]))" );
+            //            final GSDI sdi2_22 = new GSDI( g2_22, s2, false );
+            //            //Archaeopteryx.createApplication( g2_22 );
+            //            //Archaeopteryx.createApplication( s2 );
+            //            if ( sdi2_22.getDuplicationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_22.getSpeciationOrDuplicationEventsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_22.getSpeciationsSum() != 2 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_22, "n1", "n2" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_22, "n3", "n4" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_22, "n1", "n3" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_23 = TestGSDI
+            //                    .createPhylogeny( "((a1[&&NHX:S=a1],b1[&&NHX:S=b1]),(c1[&&NHX:S=c1],d1[&&NHX:S=d1]))" );
+            //            final GSDI sdi2_23 = new GSDI( g2_23, s2, false );
+            //            if ( sdi2_23.getDuplicationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_23.getSpeciationOrDuplicationEventsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_23.getSpeciationsSum() != 2 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_23, "a1", "b1" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_23, "c1", "d1" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_23, "a1", "c1" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_24 = TestGSDI
+            //                    .createPhylogeny( "((a1[&&NHX:S=a1],e1[&&NHX:S=e1]),(i1[&&NHX:S=i1],m1[&&NHX:S=m1]))" );
+            //            final GSDI sdi2_24 = new GSDI( g2_24, s2, false );
+            //            if ( sdi2_24.getDuplicationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_24.getSpeciationOrDuplicationEventsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_24.getSpeciationsSum() != 2 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_24, "a1", "e1" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_24, "i1", "m1" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_24, "a1", "i1" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_25 = TestGSDI
+            //                    .createPhylogeny( "((a1[&&NHX:S=a1],a4[&&NHX:S=a4]),(b1[&&NHX:S=b1],c1[&&NHX:S=c1]))" );
+            //            final GSDI sdi2_25 = new GSDI( g2_25, s2, false );
+            //            if ( sdi2_25.getDuplicationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_25.getSpeciationOrDuplicationEventsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_25.getSpeciationsSum() != 2 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_25, "a1", "a4" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_25, "b1", "c1" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_25, "a1", "b1" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_26 = TestGSDI
+            //                    .createPhylogeny( "(((a1[&&NHX:S=a1],a4[&&NHX:S=a4]),b1[&&NHX:S=b1]),e1[&&NHX:S=e1])" );
+            //            final GSDI sdi2_26 = new GSDI( g2_26, s2, false );
+            //            if ( sdi2_26.getDuplicationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_26.getSpeciationOrDuplicationEventsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_26.getSpeciationsSum() != 3 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_26, "a1", "a4" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_26, "a1", "b1" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_26, "a1", "e1" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_27 = TestGSDI
+            //                    .createPhylogeny( "(((a1[&&NHX:S=a1],a4[&&NHX:S=a4]),b1[&&NHX:S=b1]),c1[&&NHX:S=c1])" );
+            //            final GSDI sdi2_27 = new GSDI( g2_27, s2, false );
+            //            if ( sdi2_27.getDuplicationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_27.getSpeciationOrDuplicationEventsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_27.getSpeciationsSum() != 2 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_27, "a1", "a4" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_27, "a1", "b1" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_27, "a1", "c1" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_28 = TestGSDI
+            //                    .createPhylogeny( "(((a1[&&NHX:S=a1],b1[&&NHX:S=b1]),c1[&&NHX:S=c1]),e1[&&NHX:S=e1])" );
+            //            final GSDI sdi2_28 = new GSDI( g2_28, s2, false );
+            //            if ( sdi2_28.getDuplicationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_28.getSpeciationOrDuplicationEventsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_28.getSpeciationsSum() != 2 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_28, "a1", "b1" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_28, "a1", "c1" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_28, "a1", "e1" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_29 = TestGSDI
+            //                    .createPhylogeny( "(((a1[&&NHX:S=a1],b1[&&NHX:S=b1]),c1[&&NHX:S=c1]),d1[&&NHX:S=d1])" );
+            //            final GSDI sdi2_29 = new GSDI( g2_29, s2, false );
+            //            if ( sdi2_29.getDuplicationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_29.getSpeciationOrDuplicationEventsSum() != 2 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_29.getSpeciationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_29, "a1", "b1" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_29, "a1", "c1" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_29, "a1", "d1" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_30 = TestGSDI
+            //                    .createPhylogeny( "(((a1[&&NHX:S=a1],b1[&&NHX:S=b1]),c1[&&NHX:S=c1]),a2[&&NHX:S=a2])" );
+            //            final GSDI sdi2_30 = new GSDI( g2_30, s2, false );
+            //            if ( sdi2_30.getDuplicationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_30.getSpeciationOrDuplicationEventsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_30.getSpeciationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_30, "a1", "b1" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_30, "a1", "c1" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_30, "a1", "a2" ).isDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_31 = TestGSDI
+            //                    .createPhylogeny( "(((a1[&&NHX:S=a1],b1[&&NHX:S=b1]),c1[&&NHX:S=c1]),c2[&&NHX:S=c2])" );
+            //            final GSDI sdi2_31 = new GSDI( g2_31, s2, false );
+            //            if ( sdi2_31.getDuplicationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_31.getSpeciationOrDuplicationEventsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_31.getSpeciationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_31, "a1", "b1" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_31, "a1", "c1" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_31, "a1", "c2" ).isDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_32 = TestGSDI
+            //                    .createPhylogeny( "((((((((((a1[&&NHX:S=a1],a2[&&NHX:S=a2]),b1[&&NHX:S=b1]),c1[&&NHX:S=c1]),d1[&&NHX:S=d1]),x[&&NHX:S=x]),p1[&&NHX:S=p1]),i1[&&NHX:S=i1]),e1[&&NHX:S=e1]),y[&&NHX:S=y]),z[&&NHX:S=z])" );
+            //            final GSDI sdi2_32 = new GSDI( g2_32, s2, false );
+            //            if ( sdi2_32.getDuplicationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_32.getSpeciationOrDuplicationEventsSum() != 7 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_32.getSpeciationsSum() != 3 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_32, "a1", "a2" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_32, "a1", "b1" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_32, "a1", "c1" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_32, "a1", "d1" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_32, "a1", "x" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_32, "a1", "p1" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_32, "a1", "i1" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_32, "a1", "e1" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_32, "a1", "y" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_32, "a1", "z" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            //            //-
+            //            final Phylogeny g2_33_d = TestGSDI
+            //                    .createPhylogeny( "((((((((((((a1[&&NHX:S=a1],a2[&&NHX:S=a2])[&&NHX:D=N],b1[&&NHX:S=b1])[&&NHX:D=N],c1[&&NHX:S=c1])[&&NHX:D=?],d1[&&NHX:S=d1])[&&NHX:D=?],x[&&NHX:S=x])[&&NHX:D=N],p1[&&NHX:S=p1])[&&NHX:D=?],i1[&&NHX:S=i1])[&&NHX:D=?],k2[&&NHX:S=k2])[&&NHX:D=Y],e1[&&NHX:S=e1])[&&NHX:D=Y],y[&&NHX:S=y])[&&NHX:D=Y],z[&&NHX:S=z])[&&NHX:D=?],(((((((((((a1[&&NHX:S=a1],a2[&&NHX:S=a2])[&&NHX:D=N],b1[&&NHX:S=b1])[&&NHX:D=N],c1[&&NHX:S=c1])[&&NHX:D=?],d1[&&NHX:S=d1])[&&NHX:D=?],x[&&NHX:S=x])[&&NHX:D=N],p1[&&NHX:S=p1])[&&NHX:D=?],i1[&&NHX:S=i1])[&&NHX:D=?],k2[&&NHX:S=k2])[&&NHX:D=Y],e1[&&NHX:S=e1])[&&NHX:D=Y],y[&&NHX:S=y])[&&NHX:D=Y],z[&&NHX:S=z])[&&NHX:D=?])" );
+            //            final GSDI sdi2_33_d = new GSDI( g2_33_d, s2, false );
+            //            Archaeopteryx.createApplication( g2_33_d );
+            //            //  Archaeopteryx.createApplication( s2 );
             //            //-
-            final Phylogeny g2_33_d = TestGSDI
-                    .createPhylogeny( "((((((((((((a1[&&NHX:S=a1],a2[&&NHX:S=a2])[&&NHX:D=N],b1[&&NHX:S=b1])[&&NHX:D=N],c1[&&NHX:S=c1])[&&NHX:D=?],d1[&&NHX:S=d1])[&&NHX:D=?],x[&&NHX:S=x])[&&NHX:D=N],p1[&&NHX:S=p1])[&&NHX:D=?],i1[&&NHX:S=i1])[&&NHX:D=?],k2[&&NHX:S=k2])[&&NHX:D=Y],e1[&&NHX:S=e1])[&&NHX:D=Y],y[&&NHX:S=y])[&&NHX:D=Y],z[&&NHX:S=z])[&&NHX:D=?],(((((((((((a1[&&NHX:S=a1],a2[&&NHX:S=a2])[&&NHX:D=N],b1[&&NHX:S=b1])[&&NHX:D=N],c1[&&NHX:S=c1])[&&NHX:D=?],d1[&&NHX:S=d1])[&&NHX:D=?],x[&&NHX:S=x])[&&NHX:D=N],p1[&&NHX:S=p1])[&&NHX:D=?],i1[&&NHX:S=i1])[&&NHX:D=?],k2[&&NHX:S=k2])[&&NHX:D=Y],e1[&&NHX:S=e1])[&&NHX:D=Y],y[&&NHX:S=y])[&&NHX:D=Y],z[&&NHX:S=z])[&&NHX:D=?])" );
-            final GSDI sdi2_33_d = new GSDI( g2_33_d, s2, false );
-            Archaeopteryx.createApplication( g2_33_d );
-            //  Archaeopteryx.createApplication( s2 );
-            //-
-            final Phylogeny g2_33 = TestGSDI
-                    .createPhylogeny( "(((((((((((a1[&&NHX:S=a1],a2[&&NHX:S=a2]),b1[&&NHX:S=b1]),c1[&&NHX:S=c1]),d1[&&NHX:S=d1]),x[&&NHX:S=x]),p1[&&NHX:S=p1]),i1[&&NHX:S=i1]),k2[&&NHX:S=k2]),e1[&&NHX:S=e1]),y[&&NHX:S=y]),z[&&NHX:S=z])" );
-            final GSDI sdi2_33 = new GSDI( g2_33, s2, false );
-            Archaeopteryx.createApplication( g2_33 );
-            // Archaeopteryx.createApplication( s2 );
-            if ( sdi2_33.getDuplicationsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_33.getSpeciationOrDuplicationEventsSum() != 7 ) {
-                return false;
-            }
-            if ( sdi2_33.getSpeciationsSum() != 3 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_33, "a1", "a2" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_33, "a1", "b1" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_33, "a1", "c1" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_33, "a1", "d1" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_33, "a1", "x" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_33, "a1", "p1" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_33, "a1", "i1" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_33, "a1", "k2" ).isDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_33, "a1", "e1" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_33, "a1", "y" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_33, "a1", "z" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_34 = TestGSDI
-                    .createPhylogeny( "(((n1_0[&&NHX:S=n1],n2_0[&&NHX:S=n2]),(n1_1[&&NHX:S=n1],n3_0[&&NHX:S=n3])),n4_0[&&NHX:S=n4])" );
-            final GSDI sdi2_34 = new GSDI( g2_34, s2, false );
-            if ( sdi2_34.getDuplicationsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_34.getSpeciationOrDuplicationEventsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_34.getSpeciationsSum() != 2 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_34, "n1_0", "n2_0" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_34, "n1_1", "n3_0" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_34, "n1_0", "n1_1" ).isDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_34, "n1_0", "n4_0" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_35 = TestGSDI
-                    .createPhylogeny( "((((n1_0[&&NHX:S=n1],n2_0[&&NHX:S=n2]),(n1_1[&&NHX:S=n1],n3_0[&&NHX:S=n3])),n4_0[&&NHX:S=n4]),a1_0[&&NHX:S=a1])" );
-            final GSDI sdi2_35 = new GSDI( g2_35, s2, false );
-            if ( sdi2_35.getDuplicationsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_35.getSpeciationOrDuplicationEventsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_35.getSpeciationsSum() != 3 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_35, "n1_0", "n2_0" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_35, "n1_1", "n3_0" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_35, "n1_0", "n1_1" ).isDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_35, "n1_0", "n4_0" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_35, "n1_0", "a1_0" ).isSpeciation() ) {
-                return false;
-            }
-            final Phylogeny g2_36 = TestGSDI
-                    .createPhylogeny( "(((a1_0[&&NHX:S=a1],b1_0[&&NHX:S=b1]),(a1_1[&&NHX:S=a1],c1_0[&&NHX:S=c1])),d1_0[&&NHX:S=d1])" );
-            final GSDI sdi2_36 = new GSDI( g2_36, s2, false );
-            if ( sdi2_36.getDuplicationsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_36.getSpeciationOrDuplicationEventsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_36.getSpeciationsSum() != 2 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_36, "a1_0", "b1_0" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_36, "a1_1", "c1_0" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_36, "a1_0", "c1_0" ).isDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_36, "a1_0", "d1_0" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_37 = TestGSDI
-                    .createPhylogeny( "(((a1_0[&&NHX:S=a1],b1_0[&&NHX:S=b1]),(a2_0[&&NHX:S=a2],c1_0[&&NHX:S=c1])),d1_0[&&NHX:S=d1])" );
-            final GSDI sdi2_37 = new GSDI( g2_37, s2, false );
-            if ( sdi2_37.getDuplicationsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_37.getSpeciationOrDuplicationEventsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_37.getSpeciationsSum() != 2 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_37, "a1_0", "b1_0" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_37, "a2_0", "c1_0" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_37, "a1_0", "c1_0" ).isDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_37, "a1_0", "d1_0" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_38 = TestGSDI
-                    .createPhylogeny( "(((([&&NHX:S=n1],[&&NHX:S=n1]),([&&NHX:S=n1],[&&NHX:S=n1])),[&&NHX:S=n1]),[&&NHX:S=n1])" );
-            final GSDI sdi2_38 = new GSDI( g2_38, s2, false );
-            if ( sdi2_38.getDuplicationsSum() != 5 ) {
-                return false;
-            }
-            if ( sdi2_38.getSpeciationOrDuplicationEventsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_38.getSpeciationsSum() != 0 ) {
-                return false;
-            }
-            final Phylogeny g2_100 = TestGSDI
-                    .createPhylogeny( "(((e1[&&NHX:S=e1],f2[&&NHX:S=f2]),(d3[&&NHX:S=d3],g4[&&NHX:S=g4])),(((a1[&&NHX:S=a1],h2[&&NHX:S=h2]),c3[&&NHX:S=c3]),(i4[&&NHX:S=i4],b1[&&NHX:S=b1])))" );
-            final GSDI sdi2_100 = new GSDI( g2_100, s2, false );
-            if ( sdi2_100.getDuplicationsSum() != 4 ) {
-                return false;
-            }
-            if ( sdi2_100.getSpeciationOrDuplicationEventsSum() != 0 ) {
-                return false;
-            }
-            if ( sdi2_100.getSpeciationsSum() != 4 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_100, "e1", "f2" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_100, "d3", "g4" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_100, "e1", "d3" ).isDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_100, "a1", "h2" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_100, "a1", "c3" ).isDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_100, "i4", "b1" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_100, "a1", "i4" ).isDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_100, "e1", "a1" ).isDuplication() ) {
-                return false;
-            }
-            final Phylogeny g2_101 = TestGSDI
-                    .createPhylogeny( "(((e1[&&NHX:S=e1],f2[&&NHX:S=f2]),(d3[&&NHX:S=d3],g4[&&NHX:S=g4])),(((a1[&&NHX:S=a1],b2[&&NHX:S=b2]),c3[&&NHX:S=c3]),(i4[&&NHX:S=i4],j1[&&NHX:S=j1])))" );
-            final GSDI sdi2_101 = new GSDI( g2_101, s2, false );
-            if ( sdi2_101.getDuplicationsSum() != 2 ) {
-                return false;
-            }
-            if ( sdi2_101.getSpeciationOrDuplicationEventsSum() != 1 ) {
-                return false;
-            }
-            if ( sdi2_101.getSpeciationsSum() != 5 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_101, "e1", "f2" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_101, "d3", "g4" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_101, "e1", "d3" ).isDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_101, "a1", "b2" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_101, "a1", "c3" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_101, "i4", "j1" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_101, "a1", "i4" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g2_101, "e1", "a1" ).isDuplication() ) {
-                return false;
-            }
-            final Phylogeny s_7_4 = DevelopmentTools.createBalancedPhylogeny( 7, 4 );
-            DevelopmentTools.numberSpeciesInOrder( s_7_4 );
-            final Phylogeny g_7_4_1 = TestGSDI
-                    .createPhylogeny( "(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((("
-                            + "1[&&NHX:S=1],2[&&NHX:S=2]),3[&&NHX:S=3]),4[&&NHX:S=4]),5[&&NHX:S=5]),"
-                            + "6[&&NHX:S=6]),7[&&NHX:S=7]),8[&&NHX:S=8]),9[&&NHX:S=9]),10[&&NHX:S=10]),11[&&NHX:S=11]),"
-                            + "12[&&NHX:S=12]),13[&&NHX:S=13]),14[&&NHX:S=14]),15[&&NHX:S=15]),16[&&NHX:S=16]),17[&&NHX:S=17]),"
-                            + "18[&&NHX:S=18]),19[&&NHX:S=19]),20[&&NHX:S=20]),21[&&NHX:S=21]),22[&&NHX:S=22]),23[&&NHX:S=23]),"
-                            + "24[&&NHX:S=24]),25[&&NHX:S=25]),26[&&NHX:S=26]),27[&&NHX:S=27]),28[&&NHX:S=28]),29[&&NHX:S=29]),"
-                            + "30[&&NHX:S=30]),31[&&NHX:S=31]),32[&&NHX:S=32]),33[&&NHX:S=33]),34[&&NHX:S=34]),35[&&NHX:S=35]),"
-                            + "36[&&NHX:S=36]),37[&&NHX:S=37]),38[&&NHX:S=38]),39[&&NHX:S=39]),40[&&NHX:S=40]),41[&&NHX:S=41]),"
-                            + "42[&&NHX:S=42]),43[&&NHX:S=43]),44[&&NHX:S=44]),45[&&NHX:S=45]),46[&&NHX:S=46]),47[&&NHX:S=47]),"
-                            + "48[&&NHX:S=48]),49[&&NHX:S=49]),50[&&NHX:S=50]),51[&&NHX:S=51]),52[&&NHX:S=52]),53[&&NHX:S=53]),"
-                            + "54[&&NHX:S=54]),55[&&NHX:S=55]),56[&&NHX:S=56]),57[&&NHX:S=57]),58[&&NHX:S=58]),59[&&NHX:S=59]),"
-                            + "60[&&NHX:S=60]),61[&&NHX:S=61]),62[&&NHX:S=62]),63[&&NHX:S=63]),64[&&NHX:S=64]),65[&&NHX:S=65])" );
-            final GSDI sdi7_4_1 = new GSDI( g_7_4_1, s_7_4, false );
-            if ( sdi7_4_1.getDuplicationsSum() != 54 ) {
-                return false;
-            }
-            if ( sdi7_4_1.getSpeciationOrDuplicationEventsSum() != 6 ) {
-                return false;
-            }
-            if ( sdi7_4_1.getSpeciationsSum() != 4 ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g_7_4_1, "1", "2" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g_7_4_1, "1", "3" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g_7_4_1, "1", "4" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g_7_4_1, "1", "5" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g_7_4_1, "1", "6" ).isDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g_7_4_1, "1", "9" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g_7_4_1, "1", "13" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g_7_4_1, "1", "17" ).isSpeciation() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g_7_4_1, "1", "33" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g_7_4_1, "1", "49" ).isSpeciationOrDuplication() ) {
-                return false;
-            }
-            if ( !TestGSDI.getEvent( g_7_4_1, "1", "65" ).isSpeciation() ) {
-                return false;
-            }
-            final Phylogeny g_7_4_2 = TestGSDI
-                    .createPhylogeny( "((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((("
-                            + "1[&&NHX:S=1],2[&&NHX:S=2]),3[&&NHX:S=3]),4[&&NHX:S=4]),5[&&NHX:S=5]),"
-                            + "6[&&NHX:S=6]),7[&&NHX:S=7]),8[&&NHX:S=8]),9[&&NHX:S=9]),10[&&NHX:S=10]),11[&&NHX:S=11]),"
-                            + "12[&&NHX:S=12]),13[&&NHX:S=13]),14[&&NHX:S=14]),15[&&NHX:S=15]),16[&&NHX:S=16]),17[&&NHX:S=17]),"
-                            + "18[&&NHX:S=18]),19[&&NHX:S=19]),20[&&NHX:S=20]),21[&&NHX:S=21]),22[&&NHX:S=22]),23[&&NHX:S=23]),"
-                            + "24[&&NHX:S=24]),25[&&NHX:S=25]),26[&&NHX:S=26]),27[&&NHX:S=27]),28[&&NHX:S=28]),29[&&NHX:S=29]),"
-                            + "30[&&NHX:S=30]),31[&&NHX:S=31]),32[&&NHX:S=32]),33[&&NHX:S=33]),34[&&NHX:S=34]),35[&&NHX:S=35]),"
-                            + "36[&&NHX:S=36]),37[&&NHX:S=37]),38[&&NHX:S=38]),39[&&NHX:S=39]),40[&&NHX:S=40]),41[&&NHX:S=41]),"
-                            + "42[&&NHX:S=42]),43[&&NHX:S=43]),44[&&NHX:S=44]),45[&&NHX:S=45]),46[&&NHX:S=46]),47[&&NHX:S=47]),"
-                            + "48[&&NHX:S=48]),49[&&NHX:S=49]),50[&&NHX:S=50]),51[&&NHX:S=51]),52[&&NHX:S=52]),53[&&NHX:S=53]),"
-                            + "54[&&NHX:S=54]),55[&&NHX:S=55]),56[&&NHX:S=56]),57[&&NHX:S=57]),58[&&NHX:S=58]),59[&&NHX:S=59]),"
-                            + "60[&&NHX:S=60]),61[&&NHX:S=61]),62[&&NHX:S=62]),63[&&NHX:S=63]),64[&&NHX:S=64]),65[&&NHX:S=65]),"
-                            + "66[&&NHX:S=66]),257[&&NHX:S=257]),258[&&NHX:S=258]),513[&&NHX:S=513]),514[&&NHX:S=514]),769[&&NHX:S=769]),770[&&NHX:S=770])" );
-            final GSDI sdi7_4_2 = new GSDI( g_7_4_2, s_7_4, false );
-            if ( sdi7_4_2.getDuplicationsSum() != 58 ) {
-                return false;
-            }
-            if ( sdi7_4_2.getSpeciationOrDuplicationEventsSum() != 8 ) {
-                return false;
-            }
-            if ( sdi7_4_2.getSpeciationsSum() != 5 ) {
-                return false;
-            }
+            //            final Phylogeny g2_33 = TestGSDI
+            //                    .createPhylogeny( "(((((((((((a1[&&NHX:S=a1],a2[&&NHX:S=a2]),b1[&&NHX:S=b1]),c1[&&NHX:S=c1]),d1[&&NHX:S=d1]),x[&&NHX:S=x]),p1[&&NHX:S=p1]),i1[&&NHX:S=i1]),k2[&&NHX:S=k2]),e1[&&NHX:S=e1]),y[&&NHX:S=y]),z[&&NHX:S=z])" );
+            //            final GSDI sdi2_33 = new GSDI( g2_33, s2, false );
+            //            Archaeopteryx.createApplication( g2_33 );
+            //            Archaeopteryx.createApplication( s2 );
+            //            if ( sdi2_33.getDuplicationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_33.getSpeciationOrDuplicationEventsSum() != 7 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_33.getSpeciationsSum() != 3 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_33, "a1", "a2" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_33, "a1", "b1" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_33, "a1", "c1" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_33, "a1", "d1" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_33, "a1", "x" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_33, "a1", "p1" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_33, "a1", "i1" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_33, "a1", "k2" ).isDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_33, "a1", "e1" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_33, "a1", "y" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_33, "a1", "z" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_34 = TestGSDI
+            //                    .createPhylogeny( "(((n1_0[&&NHX:S=n1],n2_0[&&NHX:S=n2]),(n1_1[&&NHX:S=n1],n3_0[&&NHX:S=n3])),n4_0[&&NHX:S=n4])" );
+            //            final GSDI sdi2_34 = new GSDI( g2_34, s2, false );
+            //            if ( sdi2_34.getDuplicationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_34.getSpeciationOrDuplicationEventsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_34.getSpeciationsSum() != 2 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_34, "n1_0", "n2_0" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_34, "n1_1", "n3_0" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_34, "n1_0", "n1_1" ).isDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_34, "n1_0", "n4_0" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_35 = TestGSDI
+            //                    .createPhylogeny( "((((n1_0[&&NHX:S=n1],n2_0[&&NHX:S=n2]),(n1_1[&&NHX:S=n1],n3_0[&&NHX:S=n3])),n4_0[&&NHX:S=n4]),a1_0[&&NHX:S=a1])" );
+            //            final GSDI sdi2_35 = new GSDI( g2_35, s2, false );
+            //            if ( sdi2_35.getDuplicationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_35.getSpeciationOrDuplicationEventsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_35.getSpeciationsSum() != 3 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_35, "n1_0", "n2_0" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_35, "n1_1", "n3_0" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_35, "n1_0", "n1_1" ).isDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_35, "n1_0", "n4_0" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_35, "n1_0", "a1_0" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_36 = TestGSDI
+            //                    .createPhylogeny( "(((a1_0[&&NHX:S=a1],b1_0[&&NHX:S=b1]),(a1_1[&&NHX:S=a1],c1_0[&&NHX:S=c1])),d1_0[&&NHX:S=d1])" );
+            //            final GSDI sdi2_36 = new GSDI( g2_36, s2, false );
+            //            if ( sdi2_36.getDuplicationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_36.getSpeciationOrDuplicationEventsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_36.getSpeciationsSum() != 2 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_36, "a1_0", "b1_0" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_36, "a1_1", "c1_0" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_36, "a1_0", "c1_0" ).isDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_36, "a1_0", "d1_0" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_37 = TestGSDI
+            //                    .createPhylogeny( "(((a1_0[&&NHX:S=a1],b1_0[&&NHX:S=b1]),(a2_0[&&NHX:S=a2],c1_0[&&NHX:S=c1])),d1_0[&&NHX:S=d1])" );
+            //            final GSDI sdi2_37 = new GSDI( g2_37, s2, false );
+            //            if ( sdi2_37.getDuplicationsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_37.getSpeciationOrDuplicationEventsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_37.getSpeciationsSum() != 2 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_37, "a1_0", "b1_0" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_37, "a2_0", "c1_0" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_37, "a1_0", "c1_0" ).isDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_37, "a1_0", "d1_0" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_38 = TestGSDI
+            //                    .createPhylogeny( "(((([&&NHX:S=n1],[&&NHX:S=n1]),([&&NHX:S=n1],[&&NHX:S=n1])),[&&NHX:S=n1]),[&&NHX:S=n1])" );
+            //            final GSDI sdi2_38 = new GSDI( g2_38, s2, false );
+            //            if ( sdi2_38.getDuplicationsSum() != 5 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_38.getSpeciationOrDuplicationEventsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_38.getSpeciationsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_100 = TestGSDI
+            //                    .createPhylogeny( "(((e1[&&NHX:S=e1],f2[&&NHX:S=f2]),(d3[&&NHX:S=d3],g4[&&NHX:S=g4])),(((a1[&&NHX:S=a1],h2[&&NHX:S=h2]),c3[&&NHX:S=c3]),(i4[&&NHX:S=i4],b1[&&NHX:S=b1])))" );
+            //            final GSDI sdi2_100 = new GSDI( g2_100, s2, false );
+            //            if ( sdi2_100.getDuplicationsSum() != 4 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_100.getSpeciationOrDuplicationEventsSum() != 0 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_100.getSpeciationsSum() != 4 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_100, "e1", "f2" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_100, "d3", "g4" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_100, "e1", "d3" ).isDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_100, "a1", "h2" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_100, "a1", "c3" ).isDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_100, "i4", "b1" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_100, "a1", "i4" ).isDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_100, "e1", "a1" ).isDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g2_101 = TestGSDI
+            //                    .createPhylogeny( "(((e1[&&NHX:S=e1],f2[&&NHX:S=f2]),(d3[&&NHX:S=d3],g4[&&NHX:S=g4])),(((a1[&&NHX:S=a1],b2[&&NHX:S=b2]),c3[&&NHX:S=c3]),(i4[&&NHX:S=i4],j1[&&NHX:S=j1])))" );
+            //            final GSDI sdi2_101 = new GSDI( g2_101, s2, false );
+            //            if ( sdi2_101.getDuplicationsSum() != 2 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_101.getSpeciationOrDuplicationEventsSum() != 1 ) {
+            //                return false;
+            //            }
+            //            if ( sdi2_101.getSpeciationsSum() != 5 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_101, "e1", "f2" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_101, "d3", "g4" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_101, "e1", "d3" ).isDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_101, "a1", "b2" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_101, "a1", "c3" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_101, "i4", "j1" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_101, "a1", "i4" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g2_101, "e1", "a1" ).isDuplication() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny s_7_4 = DevelopmentTools.createBalancedPhylogeny( 7, 4 );
+            //            DevelopmentTools.numberSpeciesInOrder( s_7_4 );
+            //            final Phylogeny g_7_4_1 = TestGSDI
+            //                    .createPhylogeny( "(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((("
+            //                            + "1[&&NHX:S=1],2[&&NHX:S=2]),3[&&NHX:S=3]),4[&&NHX:S=4]),5[&&NHX:S=5]),"
+            //                            + "6[&&NHX:S=6]),7[&&NHX:S=7]),8[&&NHX:S=8]),9[&&NHX:S=9]),10[&&NHX:S=10]),11[&&NHX:S=11]),"
+            //                            + "12[&&NHX:S=12]),13[&&NHX:S=13]),14[&&NHX:S=14]),15[&&NHX:S=15]),16[&&NHX:S=16]),17[&&NHX:S=17]),"
+            //                            + "18[&&NHX:S=18]),19[&&NHX:S=19]),20[&&NHX:S=20]),21[&&NHX:S=21]),22[&&NHX:S=22]),23[&&NHX:S=23]),"
+            //                            + "24[&&NHX:S=24]),25[&&NHX:S=25]),26[&&NHX:S=26]),27[&&NHX:S=27]),28[&&NHX:S=28]),29[&&NHX:S=29]),"
+            //                            + "30[&&NHX:S=30]),31[&&NHX:S=31]),32[&&NHX:S=32]),33[&&NHX:S=33]),34[&&NHX:S=34]),35[&&NHX:S=35]),"
+            //                            + "36[&&NHX:S=36]),37[&&NHX:S=37]),38[&&NHX:S=38]),39[&&NHX:S=39]),40[&&NHX:S=40]),41[&&NHX:S=41]),"
+            //                            + "42[&&NHX:S=42]),43[&&NHX:S=43]),44[&&NHX:S=44]),45[&&NHX:S=45]),46[&&NHX:S=46]),47[&&NHX:S=47]),"
+            //                            + "48[&&NHX:S=48]),49[&&NHX:S=49]),50[&&NHX:S=50]),51[&&NHX:S=51]),52[&&NHX:S=52]),53[&&NHX:S=53]),"
+            //                            + "54[&&NHX:S=54]),55[&&NHX:S=55]),56[&&NHX:S=56]),57[&&NHX:S=57]),58[&&NHX:S=58]),59[&&NHX:S=59]),"
+            //                            + "60[&&NHX:S=60]),61[&&NHX:S=61]),62[&&NHX:S=62]),63[&&NHX:S=63]),64[&&NHX:S=64]),65[&&NHX:S=65])" );
+            //            final GSDI sdi7_4_1 = new GSDI( g_7_4_1, s_7_4, false );
+            //            if ( sdi7_4_1.getDuplicationsSum() != 54 ) {
+            //                return false;
+            //            }
+            //            if ( sdi7_4_1.getSpeciationOrDuplicationEventsSum() != 6 ) {
+            //                return false;
+            //            }
+            //            if ( sdi7_4_1.getSpeciationsSum() != 4 ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g_7_4_1, "1", "2" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g_7_4_1, "1", "3" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g_7_4_1, "1", "4" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g_7_4_1, "1", "5" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g_7_4_1, "1", "6" ).isDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g_7_4_1, "1", "9" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g_7_4_1, "1", "13" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g_7_4_1, "1", "17" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g_7_4_1, "1", "33" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g_7_4_1, "1", "49" ).isSpeciationOrDuplication() ) {
+            //                return false;
+            //            }
+            //            if ( !TestGSDI.getEvent( g_7_4_1, "1", "65" ).isSpeciation() ) {
+            //                return false;
+            //            }
+            //            final Phylogeny g_7_4_2 = TestGSDI
+            //                    .createPhylogeny( "((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((("
+            //                            + "1[&&NHX:S=1],2[&&NHX:S=2]),3[&&NHX:S=3]),4[&&NHX:S=4]),5[&&NHX:S=5]),"
+            //                            + "6[&&NHX:S=6]),7[&&NHX:S=7]),8[&&NHX:S=8]),9[&&NHX:S=9]),10[&&NHX:S=10]),11[&&NHX:S=11]),"
+            //                            + "12[&&NHX:S=12]),13[&&NHX:S=13]),14[&&NHX:S=14]),15[&&NHX:S=15]),16[&&NHX:S=16]),17[&&NHX:S=17]),"
+            //                            + "18[&&NHX:S=18]),19[&&NHX:S=19]),20[&&NHX:S=20]),21[&&NHX:S=21]),22[&&NHX:S=22]),23[&&NHX:S=23]),"
+            //                            + "24[&&NHX:S=24]),25[&&NHX:S=25]),26[&&NHX:S=26]),27[&&NHX:S=27]),28[&&NHX:S=28]),29[&&NHX:S=29]),"
+            //                            + "30[&&NHX:S=30]),31[&&NHX:S=31]),32[&&NHX:S=32]),33[&&NHX:S=33]),34[&&NHX:S=34]),35[&&NHX:S=35]),"
+            //                            + "36[&&NHX:S=36]),37[&&NHX:S=37]),38[&&NHX:S=38]),39[&&NHX:S=39]),40[&&NHX:S=40]),41[&&NHX:S=41]),"
+            //                            + "42[&&NHX:S=42]),43[&&NHX:S=43]),44[&&NHX:S=44]),45[&&NHX:S=45]),46[&&NHX:S=46]),47[&&NHX:S=47]),"
+            //                            + "48[&&NHX:S=48]),49[&&NHX:S=49]),50[&&NHX:S=50]),51[&&NHX:S=51]),52[&&NHX:S=52]),53[&&NHX:S=53]),"
+            //                            + "54[&&NHX:S=54]),55[&&NHX:S=55]),56[&&NHX:S=56]),57[&&NHX:S=57]),58[&&NHX:S=58]),59[&&NHX:S=59]),"
+            //                            + "60[&&NHX:S=60]),61[&&NHX:S=61]),62[&&NHX:S=62]),63[&&NHX:S=63]),64[&&NHX:S=64]),65[&&NHX:S=65]),"
+            //                            + "66[&&NHX:S=66]),257[&&NHX:S=257]),258[&&NHX:S=258]),513[&&NHX:S=513]),514[&&NHX:S=514]),769[&&NHX:S=769]),770[&&NHX:S=770])" );
+            //            final GSDI sdi7_4_2 = new GSDI( g_7_4_2, s_7_4, false );
+            //            if ( sdi7_4_2.getDuplicationsSum() != 58 ) {
+            //                return false;
+            //            }
+            //            if ( sdi7_4_2.getSpeciationOrDuplicationEventsSum() != 8 ) {
+            //                return false;
+            //            }
+            //            if ( sdi7_4_2.getSpeciationsSum() != 5 ) {
+            //                return false;
+            //            }
             //---------------------
             //             final String g2_0_ =
             //             "(([&&NHX:S=a1],[&&NHX:S=a2]),([&&NHX:S=o2],[&&NHX:S=o4]))";
@@ -1233,6 +1234,9 @@ public final class TestGSDI {
         if ( !TestGSDI.testGSDI_general() ) {
             System.out.println( "general failed" );
         }
+        else {
+            System.out.println( "general OK" );
+        }
         //        boolean success = test();
         //        if ( success ) {
         //            System.out.println( "OK" );
index 8c62173..7ebf256 100644 (file)
@@ -376,6 +376,13 @@ public final class SequenceDbWsTools {
             }
         }
         in.close();
+        try {
+            // To prevent accessing online dbs in too quick succession. 
+            Thread.sleep( 20 );
+        }
+        catch ( InterruptedException e ) {
+            e.printStackTrace();
+        }
         return result;
     }