in progress
[jalview.git] / forester / java / src / org / forester / util / ForesterUtil.java
index 957480b..ef30200 100644 (file)
@@ -38,6 +38,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.StringReader;
+import java.io.Writer;
 import java.math.BigDecimal;
 import java.net.URL;
 import java.text.DateFormat;
@@ -47,34 +48,23 @@ import java.text.NumberFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Date;
-import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Set;
 import java.util.SortedMap;
 import java.util.SortedSet;
 import java.util.TreeMap;
 import java.util.TreeSet;
-import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import org.forester.io.parsers.PhylogenyParser;
-import org.forester.io.parsers.nexus.NexusPhylogeniesParser;
-import org.forester.io.parsers.nhx.NHXParser;
-import org.forester.io.parsers.phyloxml.PhyloXmlParser;
-import org.forester.io.parsers.phyloxml.PhyloXmlUtil;
-import org.forester.io.parsers.tol.TolParser;
-import org.forester.phylogeny.Phylogeny;
-import org.forester.phylogeny.PhylogenyMethods;
 import org.forester.phylogeny.PhylogenyNode;
-import org.forester.phylogeny.data.Confidence;
 import org.forester.phylogeny.data.Distribution;
-import org.forester.phylogeny.data.Identifier;
 import org.forester.phylogeny.data.Sequence;
 import org.forester.phylogeny.data.Taxonomy;
-import org.forester.phylogeny.iterators.PhylogenyNodeIterator;
 
 public final class ForesterUtil {
 
@@ -105,34 +95,53 @@ public final class ForesterUtil {
     private ForesterUtil() {
     }
 
+    public static void ensurePresenceOfTaxonomy( final PhylogenyNode node ) {
+        if ( !node.getNodeData().isHasTaxonomy() ) {
+            node.getNodeData().setTaxonomy( new Taxonomy() );
+        }
+    }
+
+    public static void ensurePresenceOfSequence( final PhylogenyNode node ) {
+        if ( !node.getNodeData().isHasSequence() ) {
+            node.getNodeData().setSequence( new Sequence() );
+        }
+    }
+
+    final public static void ensurePresenceOfDistribution( final PhylogenyNode node ) {
+        if ( !node.getNodeData().isHasDistribution() ) {
+            node.getNodeData().setDistribution( new Distribution( "" ) );
+        }
+    }
+
+    final public static void ensurePresenceOfDate( final PhylogenyNode node ) {
+        if ( !node.getNodeData().isHasDate() ) {
+            node.getNodeData().setDate( new org.forester.phylogeny.data.Date() );
+        }
+    }
+
     final public static void appendSeparatorIfNotEmpty( final StringBuffer sb, final char separator ) {
         if ( sb.length() > 0 ) {
             sb.append( separator );
         }
     }
 
-    final public static boolean isEmpty( final List<?> l ) {
-        if ( ( l == null ) || l.isEmpty() ) {
-            return true;
-        }
-        for( final Object o : l ) {
-            if ( o != null ) {
-                return false;
-            }
-        }
-        return true;
+    public static boolean isWindowns() {
+        return ForesterUtil.OS_NAME.toLowerCase().indexOf( "win" ) > -1;
     }
 
-    final public static boolean isEmpty( final Set<?> s ) {
-        if ( ( s == null ) || s.isEmpty() ) {
+    final public static String getForesterLibraryInformation() {
+        return "forester " + ForesterConstants.FORESTER_VERSION + " (" + ForesterConstants.FORESTER_DATE + ")";
+    }
+
+    public static boolean seqIsLikelyToBeAa( final String s ) {
+        final String seq = s.toLowerCase();
+        if ( ( seq.indexOf( 'r' ) > -1 ) || ( seq.indexOf( 'd' ) > -1 ) || ( seq.indexOf( 'e' ) > -1 )
+                || ( seq.indexOf( 'q' ) > -1 ) || ( seq.indexOf( 'h' ) > -1 ) || ( seq.indexOf( 'k' ) > -1 )
+                || ( seq.indexOf( 'w' ) > -1 ) || ( seq.indexOf( 's' ) > -1 ) || ( seq.indexOf( 'm' ) > -1 )
+                || ( seq.indexOf( 'p' ) > -1 ) || ( seq.indexOf( 'v' ) > -1 ) ) {
             return true;
         }
-        for( final Object o : s ) {
-            if ( o != null ) {
-                return false;
-            }
-        }
-        return true;
+        return false;
     }
 
     /**
@@ -262,6 +271,27 @@ public final class ForesterUtil {
         return s.replaceAll( "[\\s]+", " " );
     }
 
+    final public static void collection2file( final File file, final Collection<?> data, final String separator )
+            throws IOException {
+        final Writer writer = new BufferedWriter( new FileWriter( file ) );
+        collection2writer( writer, data, separator );
+        writer.close();
+    }
+
+    final public static void collection2writer( final Writer writer, final Collection<?> data, final String separator )
+            throws IOException {
+        boolean first = true;
+        for( final Object object : data ) {
+            if ( !first ) {
+                writer.write( separator );
+            }
+            else {
+                first = false;
+            }
+            writer.write( object.toString() );
+        }
+    }
+
     final public static String colorToHex( final Color color ) {
         final String rgb = Integer.toHexString( color.getRGB() );
         return rgb.substring( 2, rgb.length() );
@@ -307,6 +337,14 @@ public final class ForesterUtil {
         return new BufferedWriter( new FileWriter( file ) );
     }
 
+    final public static EasyWriter createEasyWriter( final File file ) throws IOException {
+        return new EasyWriter( createBufferedWriter( file ) );
+    }
+
+    final public static BufferedWriter createEasyWriter( final String name ) throws IOException {
+        return createEasyWriter( createFileForWriting( name ) );
+    }
+
     final public static BufferedWriter createBufferedWriter( final String name ) throws IOException {
         return new BufferedWriter( new FileWriter( createFileForWriting( name ) ) );
     }
@@ -319,203 +357,6 @@ public final class ForesterUtil {
         return file;
     }
 
-    final public static PhylogenyParser createParserDependingFileContents( final File file,
-                                                                           final boolean phyloxml_validate_against_xsd )
-            throws FileNotFoundException, IOException {
-        PhylogenyParser parser = null;
-        final String first_line = ForesterUtil.getFirstLine( file ).trim().toLowerCase();
-        if ( first_line.startsWith( "<" ) ) {
-            parser = new PhyloXmlParser();
-            if ( phyloxml_validate_against_xsd ) {
-                final ClassLoader cl = PhyloXmlParser.class.getClassLoader();
-                final URL xsd_url = cl.getResource( ForesterConstants.LOCAL_PHYLOXML_XSD_RESOURCE );
-                if ( xsd_url != null ) {
-                    ( ( PhyloXmlParser ) parser ).setValidateAgainstSchema( xsd_url.toString() );
-                }
-                else {
-                    if ( ForesterConstants.RELEASE ) {
-                        throw new RuntimeException( "failed to get URL for phyloXML XSD from jar file from ["
-                                + ForesterConstants.LOCAL_PHYLOXML_XSD_RESOURCE + "]" );
-                    }
-                }
-            }
-        }
-        else if ( ( first_line.startsWith( "nexus" ) ) || ( first_line.startsWith( "#nexus" ) )
-                || ( first_line.startsWith( "# nexus" ) ) || ( first_line.startsWith( "begin" ) ) ) {
-            parser = new NexusPhylogeniesParser();
-        }
-        else {
-            parser = new NHXParser();
-        }
-        return parser;
-    }
-
-    final public static PhylogenyParser createParserDependingOnFileType( final File file,
-                                                                         final boolean phyloxml_validate_against_xsd )
-            throws FileNotFoundException, IOException {
-        PhylogenyParser parser = null;
-        parser = createParserDependingOnSuffix( file.getName(), phyloxml_validate_against_xsd );
-        if ( parser == null ) {
-            parser = createParserDependingFileContents( file, phyloxml_validate_against_xsd );
-        }
-        return parser;
-    }
-
-    /**
-     * Return null if it can not guess the parser to use based on name suffix.
-     * 
-     * @param filename
-     * @return
-     */
-    final public static PhylogenyParser createParserDependingOnSuffix( final String filename,
-                                                                       final boolean phyloxml_validate_against_xsd ) {
-        PhylogenyParser parser = null;
-        final String filename_lc = filename.toLowerCase();
-        if ( filename_lc.endsWith( ".tol" ) || filename_lc.endsWith( ".tolxml" ) || filename_lc.endsWith( ".tol.zip" ) ) {
-            parser = new TolParser();
-        }
-        else if ( filename_lc.endsWith( ".xml" ) || filename_lc.endsWith( ".px" ) || filename_lc.endsWith( "phyloxml" )
-                || filename_lc.endsWith( ".zip" ) ) {
-            parser = new PhyloXmlParser();
-            if ( phyloxml_validate_against_xsd ) {
-                final ClassLoader cl = PhyloXmlParser.class.getClassLoader();
-                final URL xsd_url = cl.getResource( ForesterConstants.LOCAL_PHYLOXML_XSD_RESOURCE );
-                if ( xsd_url != null ) {
-                    ( ( PhyloXmlParser ) parser ).setValidateAgainstSchema( xsd_url.toString() );
-                }
-                else {
-                    if ( ForesterConstants.RELEASE ) {
-                        throw new RuntimeException( "failed to get URL for phyloXML XSD from jar file from ["
-                                + ForesterConstants.LOCAL_PHYLOXML_XSD_RESOURCE + "]" );
-                    }
-                }
-            }
-        }
-        else if ( filename_lc.endsWith( ".nexus" ) || filename_lc.endsWith( ".nex" ) || filename_lc.endsWith( ".nx" ) ) {
-            parser = new NexusPhylogeniesParser();
-        }
-        else if ( filename_lc.endsWith( ".nhx" ) || filename_lc.endsWith( ".nh" ) || filename_lc.endsWith( ".newick" ) ) {
-            parser = new NHXParser();
-        }
-        return parser;
-    }
-
-    final public static PhylogenyParser createParserDependingOnUrlContents( final URL url,
-                                                                            final boolean phyloxml_validate_against_xsd )
-            throws FileNotFoundException, IOException {
-        final String lc_filename = url.getFile().toString().toLowerCase();
-        PhylogenyParser parser = createParserDependingOnSuffix( lc_filename, phyloxml_validate_against_xsd );
-        if ( ( parser != null ) && lc_filename.endsWith( ".zip" ) ) {
-            if ( parser instanceof PhyloXmlParser ) {
-                ( ( PhyloXmlParser ) parser ).setZippedInputstream( true );
-            }
-            else if ( parser instanceof TolParser ) {
-                ( ( TolParser ) parser ).setZippedInputstream( true );
-            }
-        }
-        if ( parser == null ) {
-            final String first_line = getFirstLine( url ).trim().toLowerCase();
-            if ( first_line.startsWith( "<" ) ) {
-                parser = new PhyloXmlParser();
-                if ( phyloxml_validate_against_xsd ) {
-                    final ClassLoader cl = PhyloXmlParser.class.getClassLoader();
-                    final URL xsd_url = cl.getResource( ForesterConstants.LOCAL_PHYLOXML_XSD_RESOURCE );
-                    if ( xsd_url != null ) {
-                        ( ( PhyloXmlParser ) parser ).setValidateAgainstSchema( xsd_url.toString() );
-                    }
-                    else {
-                        throw new RuntimeException( "failed to get URL for phyloXML XSD from jar file from ["
-                                + ForesterConstants.LOCAL_PHYLOXML_XSD_RESOURCE + "]" );
-                    }
-                }
-            }
-            else if ( ( first_line.startsWith( "nexus" ) ) || ( first_line.startsWith( "#nexus" ) )
-                    || ( first_line.startsWith( "# nexus" ) ) || ( first_line.startsWith( "begin" ) ) ) {
-                parser = new NexusPhylogeniesParser();
-            }
-            else {
-                parser = new NHXParser();
-            }
-        }
-        return parser;
-    }
-
-    final public static void ensurePresenceOfDate( final PhylogenyNode node ) {
-        if ( !node.getNodeData().isHasDate() ) {
-            node.getNodeData().setDate( new org.forester.phylogeny.data.Date() );
-        }
-    }
-
-    final public static void ensurePresenceOfDistribution( final PhylogenyNode node ) {
-        if ( !node.getNodeData().isHasDistribution() ) {
-            node.getNodeData().setDistribution( new Distribution( "" ) );
-        }
-    }
-
-    public static void ensurePresenceOfSequence( final PhylogenyNode node ) {
-        if ( !node.getNodeData().isHasSequence() ) {
-            node.getNodeData().setSequence( new Sequence() );
-        }
-    }
-
-    public static void ensurePresenceOfTaxonomy( final PhylogenyNode node ) {
-        if ( !node.getNodeData().isHasTaxonomy() ) {
-            node.getNodeData().setTaxonomy( new Taxonomy() );
-        }
-    }
-
-    /**
-     * Extracts a code if and only if:
-     * one and only one _, 
-     * shorter than 25, 
-     * no |, 
-     * no ., 
-     * if / present it has to be after the _, 
-     * if PFAM_STYLE_ONLY: / must be present,
-     * tax code can only contain uppercase letters and numbers,
-     * and must contain at least one uppercase letter.
-     * Return null if no code extractable.
-     * 
-     * @param name
-     * @param limit_to_five
-     * @return
-     */
-    public static String extractTaxonomyCodeFromNodeName( final String name,
-                                                          final boolean limit_to_five,
-                                                          final ForesterUtil.TAXONOMY_EXTRACTION taxonomy_extraction ) {
-        if ( ( name.indexOf( "_" ) > 0 )
-                && ( name.length() < 25 )
-                && ( name.lastIndexOf( "_" ) == name.indexOf( "_" ) )
-                && ( name.indexOf( "|" ) < 0 )
-                && ( name.indexOf( "." ) < 0 )
-                && ( ( taxonomy_extraction != ForesterUtil.TAXONOMY_EXTRACTION.PFAM_STYLE_ONLY ) || ( name
-                        .indexOf( "/" ) >= 0 ) )
-                && ( ( ( name.indexOf( "/" ) ) < 0 ) || ( name.indexOf( "/" ) > name.indexOf( "_" ) ) ) ) {
-            final String[] s = name.split( "[_/]" );
-            if ( s.length > 1 ) {
-                String str = s[ 1 ];
-                if ( limit_to_five ) {
-                    if ( str.length() > 5 ) {
-                        str = str.substring( 0, 5 );
-                    }
-                    else if ( ( str.length() < 5 ) && ( str.startsWith( "RAT" ) || str.startsWith( "PIG" ) ) ) {
-                        str = str.substring( 0, 3 );
-                    }
-                }
-                final Matcher letters_and_numbers = NHXParser.UC_LETTERS_NUMBERS_PATTERN.matcher( str );
-                if ( !letters_and_numbers.matches() ) {
-                    return null;
-                }
-                final Matcher numbers_only = NHXParser.NUMBERS_ONLY_PATTERN.matcher( str );
-                if ( numbers_only.matches() ) {
-                    return null;
-                }
-                return str;
-            }
-        }
-        return null;
-    }
-
     public static void fatalError( final String prg_name, final String message ) {
         System.err.println();
         System.err.println( "[" + prg_name + "] > " + message );
@@ -523,6 +364,16 @@ public final class ForesterUtil {
         System.exit( -1 );
     }
 
+    public static void fatalErrorIfFileNotReadable( final String prg_name, final File file ) {
+        final String error = isReadableFile( file );
+        if ( !isEmpty( error ) ) {
+            System.err.println();
+            System.err.println( "[" + prg_name + "] > " + error );
+            System.err.println();
+            System.exit( -1 );
+        }
+    }
+
     public static String[] file2array( final File file ) throws IOException {
         final List<String> list = file2list( file );
         final String[] ary = new String[ list.size() ];
@@ -624,27 +475,6 @@ public final class ForesterUtil {
         return ForesterUtil.LINE_SEPARATOR;
     }
 
-    /**
-     * Returns all custom data tag names of this Phylogeny as Hashtable. Tag
-     * names are keys, values are Boolean set to false.
-     */
-    final public static Hashtable<String, Boolean> getPropertyRefs( final Phylogeny phylogeny ) {
-        final Hashtable<String, Boolean> ht = new Hashtable<String, Boolean>();
-        if ( phylogeny.isEmpty() ) {
-            return ht;
-        }
-        for( final PhylogenyNodeIterator iter = phylogeny.iteratorPreorder(); iter.hasNext(); ) {
-            final PhylogenyNode current_node = iter.next();
-            if ( current_node.getNodeData().isHasProperties() ) {
-                final String[] tags = current_node.getNodeData().getProperties().getPropertyRefs();
-                for( int i = 0; i < tags.length; ++i ) {
-                    ht.put( tags[ i ], new Boolean( false ) );
-                }
-            }
-        }
-        return ht;
-    }
-
     final public static void increaseCountingMap( final Map<String, Integer> counting_map, final String item_name ) {
         if ( !counting_map.containsKey( item_name ) ) {
             counting_map.put( item_name, 1 );
@@ -654,23 +484,29 @@ public final class ForesterUtil {
         }
     }
 
-    final static public boolean isAllNonEmptyInternalLabelsArePositiveNumbers( final Phylogeny phy ) {
-        final PhylogenyNodeIterator it = phy.iteratorPostorder();
-        while ( it.hasNext() ) {
-            final PhylogenyNode n = it.next();
-            if ( !n.isRoot() && !n.isExternal() ) {
-                if ( !ForesterUtil.isEmpty( n.getName() ) ) {
-                    double d = -1.0;
-                    try {
-                        d = Double.parseDouble( n.getName() );
-                    }
-                    catch ( final Exception e ) {
-                        d = -1.0;
-                    }
-                    if ( d < 0.0 ) {
-                        return false;
-                    }
-                }
+    final public static boolean isContainsParanthesesableNhCharacter( final String nh ) {
+        return PARANTHESESABLE_NH_CHARS_PATTERN.matcher( nh ).find();
+    }
+
+    final public static boolean isEmpty( final List<?> l ) {
+        if ( ( l == null ) || l.isEmpty() ) {
+            return true;
+        }
+        for( final Object o : l ) {
+            if ( o != null ) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    final public static boolean isEmpty( final Set<?> s ) {
+        if ( ( s == null ) || s.isEmpty() ) {
+            return true;
+        }
+        for( final Object o : s ) {
+            if ( o != null ) {
+                return false;
             }
         }
         return true;
@@ -685,43 +521,7 @@ public final class ForesterUtil {
     }
 
     final public static boolean isEven( final int n ) {
-        return n % 2 == 0;
-    }
-
-    final static public boolean isHasAtLeastNodeWithEvent( final Phylogeny phy ) {
-        final PhylogenyNodeIterator it = phy.iteratorPostorder();
-        while ( it.hasNext() ) {
-            if ( it.next().getNodeData().isHasEvent() ) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Returns true if at least one branch has a length larger than zero.
-     * 
-     * 
-     * @param phy
-     */
-    final static public boolean isHasAtLeastOneBranchLengthLargerThanZero( final Phylogeny phy ) {
-        final PhylogenyNodeIterator it = phy.iteratorPostorder();
-        while ( it.hasNext() ) {
-            if ( it.next().getDistanceToParent() > 0.0 ) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    final static public boolean isHasAtLeastOneBranchWithSupportValues( final Phylogeny phy ) {
-        final PhylogenyNodeIterator it = phy.iteratorPostorder();
-        while ( it.hasNext() ) {
-            if ( it.next().getBranchData().isHasConfidences() ) {
-                return true;
-            }
-        }
-        return false;
+        return ( n % 2 ) == 0;
     }
 
     /**
@@ -741,10 +541,9 @@ public final class ForesterUtil {
         if ( ( a.length < 1 ) || ( b.length < 1 ) ) {
             return false;
         }
-        for( int i = 0; i < a.length; ++i ) {
-            final String ai = a[ i ];
-            for( int j = 0; j < b.length; ++j ) {
-                if ( ( ai != null ) && ( b[ j ] != null ) && ai.equals( b[ j ] ) ) {
+        for( final String ai : a ) {
+            for( final String element : b ) {
+                if ( ( ai != null ) && ( element != null ) && ai.equals( element ) ) {
                     return true;
                 }
             }
@@ -826,6 +625,33 @@ public final class ForesterUtil {
         return map;
     }
 
+    final public static void map2file( final File file,
+                                       final Map<?, ?> data,
+                                       final String entry_separator,
+                                       final String data_separator ) throws IOException {
+        final Writer writer = new BufferedWriter( new FileWriter( file ) );
+        map2writer( writer, data, entry_separator, data_separator );
+        writer.close();
+    }
+
+    final public static void map2writer( final Writer writer,
+                                         final Map<?, ?> data,
+                                         final String entry_separator,
+                                         final String data_separator ) throws IOException {
+        boolean first = true;
+        for( final Entry<?, ?> entry : data.entrySet() ) {
+            if ( !first ) {
+                writer.write( data_separator );
+            }
+            else {
+                first = false;
+            }
+            writer.write( entry.getKey().toString() );
+            writer.write( entry_separator );
+            writer.write( entry.getValue().toString() );
+        }
+    }
+
     final public static StringBuffer mapToStringBuffer( final Map map, final String key_value_separator ) {
         final StringBuffer sb = new StringBuffer();
         for( final Iterator iter = map.keySet().iterator(); iter.hasNext(); ) {
@@ -932,16 +758,6 @@ public final class ForesterUtil {
         return Integer.parseInt( str );
     }
 
-    final public static void postOrderRelabelInternalNodes( final Phylogeny phylogeny, final int starting_number ) {
-        int i = starting_number;
-        for( final PhylogenyNodeIterator it = phylogeny.iteratorPostorder(); it.hasNext(); ) {
-            final PhylogenyNode node = it.next();
-            if ( !node.isExternal() ) {
-                node.setName( String.valueOf( i++ ) );
-            }
-        }
-    }
-
     final public static void printArray( final Object[] a ) {
         for( int i = 0; i < a.length; ++i ) {
             System.out.println( "[" + i + "]=" + a[ i ] );
@@ -955,7 +771,7 @@ public final class ForesterUtil {
     }
 
     final public static void printErrorMessage( final String prg_name, final String message ) {
-        System.out.println( "[" + prg_name + "] > error: " + message );
+        System.err.println( "[" + prg_name + "] > error: " + message );
     }
 
     final public static void printProgramInformation( final String prg_name, final String prg_version, final String date ) {
@@ -969,20 +785,29 @@ public final class ForesterUtil {
     }
 
     final public static void printProgramInformation( final String prg_name,
+                                                      final String desc,
                                                       final String prg_version,
                                                       final String date,
                                                       final String email,
-                                                      final String www ) {
-        final int l = prg_name.length() + prg_version.length() + date.length() + 4;
+                                                      final String www,
+                                                      final String based_on ) {
+        String my_prg_name = new String( prg_name );
+        if ( !ForesterUtil.isEmpty( desc ) ) {
+            my_prg_name += ( " - " + desc );
+        }
+        final int l = my_prg_name.length() + prg_version.length() + date.length() + 4;
         System.out.println();
-        System.out.println( prg_name + " " + prg_version + " (" + date + ")" );
+        System.out.println( my_prg_name + " " + prg_version + " (" + date + ")" );
         for( int i = 0; i < l; ++i ) {
             System.out.print( "_" );
         }
         System.out.println();
         System.out.println();
-        System.out.println( "WWW    : " + www );
-        System.out.println( "Contact: " + email );
+        System.out.println( "WWW     : " + www );
+        System.out.println( "Contact : " + email );
+        if ( !ForesterUtil.isEmpty( based_on ) ) {
+            System.out.println( "Based on: " + based_on );
+        }
         if ( !ForesterUtil.isEmpty( ForesterUtil.JAVA_VERSION ) && !ForesterUtil.isEmpty( ForesterUtil.JAVA_VENDOR ) ) {
             System.out.println();
             System.out.println( "[running on Java " + ForesterUtil.JAVA_VERSION + " " + ForesterUtil.JAVA_VENDOR + "]" );
@@ -990,6 +815,14 @@ public final class ForesterUtil {
         System.out.println();
     }
 
+    final public static void printProgramInformation( final String prg_name,
+                                                      final String prg_version,
+                                                      final String date,
+                                                      final String email,
+                                                      final String www ) {
+        printProgramInformation( prg_name, null, prg_version, date, email, www, null );
+    }
+
     final public static void printWarningMessage( final String prg_name, final String message ) {
         System.out.println( "[" + prg_name + "] > warning: " + message );
     }
@@ -1013,7 +846,7 @@ public final class ForesterUtil {
      */
     final public static String removeWhiteSpace( String s ) {
         int i;
-        for( i = 0; i <= s.length() - 1; i++ ) {
+        for( i = 0; i <= ( s.length() - 1 ); i++ ) {
             if ( ( s.charAt( i ) == ' ' ) || ( s.charAt( i ) == '\t' ) || ( s.charAt( i ) == '\n' )
                     || ( s.charAt( i ) == '\r' ) ) {
                 s = s.substring( 0, i ) + s.substring( i + 1 );
@@ -1023,10 +856,6 @@ public final class ForesterUtil {
         return s;
     }
 
-    final public static boolean isContainsParanthesesableNhCharacter( final String nh ) {
-        return PARANTHESESABLE_NH_CHARS_PATTERN.matcher( nh ).find();
-    }
-
     final public static String replaceIllegalNhCharacters( final String nh ) {
         if ( nh == null ) {
             return "";
@@ -1058,6 +887,10 @@ public final class ForesterUtil {
         return ( int ) ( f + 0.5f );
     }
 
+    final public static short roundToShort( final double d ) {
+        return ( short ) ( d + 0.5 );
+    }
+
     final public static String sanitizeString( final String s ) {
         if ( s == null ) {
             return "";
@@ -1073,143 +906,50 @@ public final class ForesterUtil {
     }
 
     final public static String stringArrayToString( final String[] a ) {
-        final StringBuffer sb = new StringBuffer();
+        return stringArrayToString( a, ", " );
+    }
+
+    final public static String stringArrayToString( final String[] a, final String separator ) {
+        final StringBuilder sb = new StringBuilder();
         if ( ( a != null ) && ( a.length > 0 ) ) {
-            for( int i = 0; i < a.length - 1; ++i ) {
-                sb.append( a[ i ] + ", " );
+            for( int i = 0; i < ( a.length - 1 ); ++i ) {
+                sb.append( a[ i ] + separator );
             }
             sb.append( a[ a.length - 1 ] );
         }
         return sb.toString();
     }
 
-    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() );
-                }
-                catch ( final NumberFormatException e ) {
-                    throw new IllegalArgumentException( "failed to parse number from [" + n.getName() + "]: "
-                            + e.getLocalizedMessage() );
-                }
-                if ( value >= 0.0 ) {
-                    n.getBranchData().addConfidence( new Confidence( value, "bootstrap" ) );
-                    n.setName( "" );
-                }
+    final public static String[] stringListToArray( final List<String> list ) {
+        if ( list != null ) {
+            final String[] str = new String[ list.size() ];
+            int i = 0;
+            for( final String l : list ) {
+                str[ i++ ] = l;
             }
+            return str;
         }
+        return null;
     }
 
-    final static public void transferInternalNodeNamesToConfidence( final Phylogeny phy ) {
-        final PhylogenyNodeIterator it = phy.iteratorPostorder();
-        while ( it.hasNext() ) {
-            final PhylogenyNode n = it.next();
-            if ( !n.isRoot() && !n.isExternal() && !n.getBranchData().isHasConfidences() ) {
-                if ( !ForesterUtil.isEmpty( n.getName() ) ) {
-                    double d = -1.0;
-                    try {
-                        d = Double.parseDouble( n.getName() );
-                    }
-                    catch ( final Exception e ) {
-                        d = -1.0;
-                    }
-                    if ( d >= 0.0 ) {
-                        n.getBranchData().addConfidence( new Confidence( d, "" ) );
-                        n.setName( "" );
-                    }
-                }
+    final public static String stringListToString( final List<String> l, final String separator ) {
+        final StringBuilder sb = new StringBuilder();
+        if ( ( l != null ) && ( l.size() > 0 ) ) {
+            for( int i = 0; i < ( l.size() - 1 ); ++i ) {
+                sb.append( l.get( i ) + separator );
             }
+            sb.append( l.get( l.size() - 1 ) );
         }
+        return sb.toString();
     }
 
-    final static public void transferNodeNameToField( final Phylogeny phy, final PhylogenyNodeField field ) {
-        final PhylogenyNodeIterator it = phy.iteratorPostorder();
-        while ( it.hasNext() ) {
-            final PhylogenyNode n = it.next();
-            final String name = n.getName().trim();
-            if ( !ForesterUtil.isEmpty( name ) ) {
-                switch ( field ) {
-                    case TAXONOMY_CODE:
-                        //temp hack
-                        //                        if ( name.length() > 5 ) {
-                        //                            n.setName( "" );
-                        //                            if ( !n.getNodeData().isHasTaxonomy() ) {
-                        //                                n.getNodeData().setTaxonomy( new Taxonomy() );
-                        //                            }
-                        //                            n.getNodeData().getTaxonomy().setScientificName( name );
-                        //                            break;
-                        //                        }
-                        //
-                        n.setName( "" );
-                        PhylogenyMethods.setTaxonomyCode( n, name );
-                        break;
-                    case TAXONOMY_SCIENTIFIC_NAME:
-                        n.setName( "" );
-                        if ( !n.getNodeData().isHasTaxonomy() ) {
-                            n.getNodeData().setTaxonomy( new Taxonomy() );
-                        }
-                        n.getNodeData().getTaxonomy().setScientificName( name );
-                        break;
-                    case TAXONOMY_COMMON_NAME:
-                        n.setName( "" );
-                        if ( !n.getNodeData().isHasTaxonomy() ) {
-                            n.getNodeData().setTaxonomy( new Taxonomy() );
-                        }
-                        n.getNodeData().getTaxonomy().setCommonName( name );
-                        break;
-                    case SEQUENCE_SYMBOL:
-                        n.setName( "" );
-                        if ( !n.getNodeData().isHasSequence() ) {
-                            n.getNodeData().setSequence( new Sequence() );
-                        }
-                        n.getNodeData().getSequence().setSymbol( name );
-                        break;
-                    case SEQUENCE_NAME:
-                        n.setName( "" );
-                        if ( !n.getNodeData().isHasSequence() ) {
-                            n.getNodeData().setSequence( new Sequence() );
-                        }
-                        n.getNodeData().getSequence().setName( name );
-                        break;
-                    case TAXONOMY_ID_UNIPROT_1: {
-                        if ( !n.getNodeData().isHasTaxonomy() ) {
-                            n.getNodeData().setTaxonomy( new Taxonomy() );
-                        }
-                        String id = name;
-                        final int i = name.indexOf( '_' );
-                        if ( i > 0 ) {
-                            id = name.substring( i, name.length() );
-                        }
-                        else {
-                            n.setName( "" );
-                        }
-                        n.getNodeData().getTaxonomy()
-                                .setIdentifier( new Identifier( id, PhyloXmlUtil.UNIPROT_TAX_PROVIDER ) );
-                        break;
-                    }
-                    case TAXONOMY_ID_UNIPROT_2: {
-                        if ( !n.getNodeData().isHasTaxonomy() ) {
-                            n.getNodeData().setTaxonomy( new Taxonomy() );
-                        }
-                        String id = name;
-                        final int i = name.indexOf( '_' );
-                        if ( i > 0 ) {
-                            id = name.substring( 0, i );
-                        }
-                        else {
-                            n.setName( "" );
-                        }
-                        n.getNodeData().getTaxonomy()
-                                .setIdentifier( new Identifier( id, PhyloXmlUtil.UNIPROT_TAX_PROVIDER ) );
-                        break;
-                    }
-                }
-            }
+    final public static String[] stringSetToArray( final Set<String> strings ) {
+        final String[] str_array = new String[ strings.size() ];
+        int i = 0;
+        for( final String e : strings ) {
+            str_array[ i++ ] = e;
         }
+        return str_array;
     }
 
     final public static void unexpectedFatalError( final String prg_name, final Exception e ) {
@@ -1253,7 +993,7 @@ public final class ForesterUtil {
                 ls = -1;
                 start = i + 1;
             }
-            if ( i > start + width - 1 ) {
+            if ( i > ( ( start + width ) - 1 ) ) {
                 if ( ls != -1 ) {
                     sb.setCharAt( ls, '\n' );
                     start = ls + 1;
@@ -1268,19 +1008,4 @@ public final class ForesterUtil {
         }
         return sb.toString();
     }
-
-    public static enum PhylogenyNodeField {
-        CLADE_NAME,
-        TAXONOMY_CODE,
-        TAXONOMY_SCIENTIFIC_NAME,
-        TAXONOMY_COMMON_NAME,
-        SEQUENCE_SYMBOL,
-        SEQUENCE_NAME,
-        TAXONOMY_ID_UNIPROT_1,
-        TAXONOMY_ID_UNIPROT_2;
-    }
-
-    public static enum TAXONOMY_EXTRACTION {
-        NO, YES, PFAM_STYLE_ONLY;
-    }
 }