+ return 0;
+ }
+ }
+ Comparator<PhylogenyNode> c;
+ switch ( pri ) {
+ case SEQUENCE:
+ c = new PhylogenyNodeSortSequencePriority();
+ break;
+ case NODE_NAME:
+ c = new PhylogenyNodeSortNodeNamePriority();
+ break;
+ default:
+ c = new PhylogenyNodeSortTaxonomyPriority();
+ }
+ final List<PhylogenyNode> descs = node.getDescendants();
+ Collections.sort( descs, c );
+ int i = 0;
+ for( final PhylogenyNode desc : descs ) {
+ node.setChildNode( i++, desc );
+ }
+ }
+
+ /**
+ * Removes from Phylogeny to_be_stripped all external Nodes which are
+ * associated with a species NOT found in Phylogeny reference.
+ *
+ * @param reference
+ * a reference Phylogeny
+ * @param to_be_stripped
+ * Phylogeny to be stripped
+ * @return nodes removed from to_be_stripped
+ */
+ public static List<PhylogenyNode> taxonomyBasedDeletionOfExternalNodes( final Phylogeny reference,
+ final Phylogeny to_be_stripped ) {
+ final Set<String> ref_ext_taxo = new HashSet<String>();
+ for( final PhylogenyNodeIterator it = reference.iteratorExternalForward(); it.hasNext(); ) {
+ final PhylogenyNode n = it.next();
+ if ( !n.getNodeData().isHasTaxonomy() ) {
+ throw new IllegalArgumentException( "no taxonomic data in node: " + n );
+ }
+ if ( !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getScientificName() ) ) {
+ ref_ext_taxo.add( n.getNodeData().getTaxonomy().getScientificName() );
+ }
+ if ( !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getTaxonomyCode() ) ) {
+ ref_ext_taxo.add( n.getNodeData().getTaxonomy().getTaxonomyCode() );
+ }
+ if ( ( n.getNodeData().getTaxonomy().getIdentifier() != null )
+ && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getIdentifier().getValue() ) ) {
+ ref_ext_taxo.add( n.getNodeData().getTaxonomy().getIdentifier().getValuePlusProvider() );
+ }
+ }
+ final ArrayList<PhylogenyNode> nodes_to_delete = new ArrayList<PhylogenyNode>();
+ for( final PhylogenyNodeIterator it = to_be_stripped.iteratorExternalForward(); it.hasNext(); ) {
+ final PhylogenyNode n = it.next();
+ if ( !n.getNodeData().isHasTaxonomy() ) {
+ nodes_to_delete.add( n );
+ }
+ else if ( !( ref_ext_taxo.contains( n.getNodeData().getTaxonomy().getScientificName() ) )
+ && !( ref_ext_taxo.contains( n.getNodeData().getTaxonomy().getTaxonomyCode() ) )
+ && !( ( n.getNodeData().getTaxonomy().getIdentifier() != null ) && ref_ext_taxo.contains( n
+ .getNodeData().getTaxonomy().getIdentifier().getValuePlusProvider() ) ) ) {
+ nodes_to_delete.add( n );
+ }
+ }
+ for( final PhylogenyNode n : nodes_to_delete ) {
+ to_be_stripped.deleteSubtree( n, true );
+ }
+ to_be_stripped.clearHashIdToNodeMap();
+ to_be_stripped.externalNodesHaveChanged();
+ return nodes_to_delete;
+ }
+
+ final static public void transferInternalNamesToBootstrapSupport( final Phylogeny phy ) {
+ final PhylogenyNodeIterator it = phy.iteratorPostorder();
+ while ( it.hasNext() ) {
+ final PhylogenyNode n = it.next();
+ if ( !n.isExternal() && !ForesterUtil.isEmpty( n.getName() ) ) {
+ double value = -1;
+ try {
+ value = Double.parseDouble( n.getName() );