+ if ( !match && ( ndf == NDF.MolecularSequence ) && node.getNodeData().isHasSequence()
+ && match( node.getNodeData().getSequence().getMolecularSequence(),
+ my_query,
+ case_sensitive,
+ true,
+ regex ) ) {
+ match = true;
+ }
+ if ( match ) {
+ nodes.add( node.getId() );
+ }
+ }
+ return nodes;
+ }
+
+ public static List<Long> searchDataLogicalAnd( final String[] queries,
+ final Phylogeny phy,
+ final boolean case_sensitive,
+ final boolean partial,
+ final boolean search_domains,
+ final double domains_confidence_threshold ) {
+ final List<Long> nodes = new ArrayList<Long>();
+ if ( phy.isEmpty() || ( queries == null ) || ( queries.length < 1 ) ) {
+ return nodes;
+ }
+ for( final PhylogenyNodeIterator iter = phy.iteratorPreorder(); iter.hasNext(); ) {
+ final PhylogenyNode node = iter.next();
+ boolean all_matched = true;
+ for( String query : queries ) {
+ if ( query == null ) {
+ continue;
+ }
+ query = query.trim();
+ NDF ndf = null;
+ if ( ( query.length() > 2 ) && ( query.indexOf( ":" ) == 2 ) ) {
+ ndf = NDF.fromString( query );
+ if ( ndf != null ) {
+ query = query.substring( 3 );
+ }
+ }
+ boolean match = false;
+ if ( ForesterUtil.isEmpty( query ) ) {
+ continue;
+ }
+ if ( ( ( ndf == null ) || ( ndf == NDF.NodeName ) )
+ && match( node.getName(), query, case_sensitive, partial, false ) ) {
+ match = true;
+ }
+ else if ( ( ( ndf == null ) || ( ndf == NDF.TaxonomyCode ) ) && node.getNodeData().isHasTaxonomy()
+ && match( node.getNodeData().getTaxonomy().getTaxonomyCode(),
+ query,
+ case_sensitive,
+ partial,
+ false ) ) {
+ match = true;
+ }
+ else if ( ( ( ndf == null ) || ( ndf == NDF.TaxonomyCommonName ) ) && node.getNodeData().isHasTaxonomy()
+ && match( node.getNodeData().getTaxonomy().getCommonName(),
+ query,
+ case_sensitive,
+ partial,
+ false ) ) {
+ match = true;
+ }
+ else if ( ( ( ndf == null ) || ( ndf == NDF.TaxonomyScientificName ) )
+ && node.getNodeData().isHasTaxonomy()
+ && match( node.getNodeData().getTaxonomy().getScientificName(),
+ query,
+ case_sensitive,
+ partial,
+ false ) ) {
+ match = true;
+ }
+ else if ( ( ( ndf == null ) || ( ndf == NDF.TaxonomyIdentifier ) ) && node.getNodeData().isHasTaxonomy()
+ && ( node.getNodeData().getTaxonomy().getIdentifier() != null )
+ && match( node.getNodeData().getTaxonomy().getIdentifier().getValue(),
+ query,
+ case_sensitive,
+ partial,
+ false ) ) {
+ match = true;
+ }
+ else if ( ( ( ndf == null ) || ( ndf == NDF.TaxonomySynonym ) ) && node.getNodeData().isHasTaxonomy()
+ && !node.getNodeData().getTaxonomy().getSynonyms().isEmpty() ) {
+ final List<String> syns = node.getNodeData().getTaxonomy().getSynonyms();
+ I: for( final String syn : syns ) {
+ if ( match( syn, query, case_sensitive, partial, false ) ) {
+ match = true;
+ break I;
+ }
+ }
+ }
+ if ( !match && ( ( ndf == null ) || ( ndf == NDF.SequenceName ) ) && node.getNodeData().isHasSequence()
+ && match( node.getNodeData().getSequence().getName(),
+ query,
+ case_sensitive,
+ partial,
+ false ) ) {
+ match = true;
+ }
+ if ( !match && ( ( ndf == null ) || ( ndf == NDF.GeneName ) ) && node.getNodeData().isHasSequence()
+ && match( node.getNodeData().getSequence().getGeneName(),
+ query,
+ case_sensitive,
+ partial,
+ false ) ) {
+ match = true;
+ }
+ if ( !match && ( ( ndf == null ) || ( ndf == NDF.SequenceSymbol ) )
+ && node.getNodeData().isHasSequence() && match( node.getNodeData().getSequence().getSymbol(),
+ query,
+ case_sensitive,
+ partial,
+ false ) ) {
+ match = true;
+ }
+ if ( !match && ( ( ndf == null ) || ( ndf == NDF.SequenceAccession ) )
+ && node.getNodeData().isHasSequence()
+ && ( node.getNodeData().getSequence().getAccession() != null )
+ && match( node.getNodeData().getSequence().getAccession().getValue(),
+ query,
+ case_sensitive,
+ partial,
+ false ) ) {
+ match = true;
+ }
+ if ( !match && ( ( ( ndf == null ) && search_domains ) || ( ndf == NDF.Domain ) )
+ && node.getNodeData().isHasSequence()
+ && ( node.getNodeData().getSequence().getDomainArchitecture() != null ) ) {
+ final DomainArchitecture da = node.getNodeData().getSequence().getDomainArchitecture();
+ I: for( int i = 0; i < da.getNumberOfDomains(); ++i ) {
+ if ( ( da.getDomain( i ).getConfidence() <= domains_confidence_threshold )
+ && match( da.getDomain( i ).getName(), query, case_sensitive, partial, false ) ) {
+ match = true;
+ break I;
+ }
+ }
+ }
+ if ( !match && ( ( ndf == null ) || ( ndf == NDF.Annotation ) ) && node.getNodeData().isHasSequence()
+ && ( node.getNodeData().getSequence().getAnnotations() != null ) ) {
+ for( final Annotation ann : node.getNodeData().getSequence().getAnnotations() ) {
+ if ( match( ann.getDesc(), query, case_sensitive, partial, false ) ) {
+ match = true;
+ break;
+ }
+ if ( match( ann.getRef(), query, case_sensitive, partial, false ) ) {
+ match = true;
+ break;
+ }
+ }
+ }
+ if ( !match && ( ( ndf == null ) || ( ndf == NDF.CrossRef ) ) && node.getNodeData().isHasSequence()
+ && ( node.getNodeData().getSequence().getCrossReferences() != null ) ) {
+ for( final Accession x : node.getNodeData().getSequence().getCrossReferences() ) {
+ if ( match( x.getComment(), query, case_sensitive, partial, false ) ) {
+ match = true;
+ break;
+ }
+ if ( match( x.getSource(), query, case_sensitive, partial, false ) ) {
+ match = true;
+ break;
+ }
+ if ( match( x.getValue(), query, case_sensitive, partial, false ) ) {
+ match = true;
+ break;
+ }
+ }
+ }
+ if ( !match && ( ( ndf == null ) || ( ndf == NDF.BinaryCharacter ) )
+ && ( node.getNodeData().getBinaryCharacters() != null ) ) {
+ Iterator<String> it = node.getNodeData().getBinaryCharacters().getPresentCharacters().iterator();
+ I: while ( it.hasNext() ) {
+ if ( match( it.next(), query, case_sensitive, partial, false ) ) {
+ match = true;
+ break I;
+ }
+ }
+ it = node.getNodeData().getBinaryCharacters().getGainedCharacters().iterator();
+ I: while ( it.hasNext() ) {
+ if ( match( it.next(), query, case_sensitive, partial, false ) ) {
+ match = true;
+ break I;
+ }
+ }
+ }
+ if ( !match && ( ndf == NDF.MolecularSequence ) && node.getNodeData().isHasSequence()
+ && match( node.getNodeData().getSequence().getMolecularSequence(),
+ query,
+ case_sensitive,
+ true,
+ false ) ) {
+ match = true;
+ }
+ if ( !match ) {
+ all_matched = false;
+ break;
+ }
+ }
+ if ( all_matched ) {
+ nodes.add( node.getId() );
+ }
+ }
+ return nodes;
+ }
+
+ public static void setAllIndicatorsToZero( final Phylogeny phy ) {
+ for( final PhylogenyNodeIterator it = phy.iteratorPostorder(); it.hasNext(); ) {
+ it.next().setIndicator( ( byte ) 0 );
+ }
+ }
+
+ /**
+ * Convenience method.
+ * Sets value for the first confidence value (created if not present, values overwritten otherwise).
+ */
+ public static void setBootstrapConfidence( final PhylogenyNode node, final double bootstrap_confidence_value ) {
+ setConfidence( node, bootstrap_confidence_value, "bootstrap" );
+ }
+
+ public static void setBranchColorValue( final PhylogenyNode node, final Color color ) {
+ if ( node.getBranchData().getBranchColor() == null ) {
+ node.getBranchData().setBranchColor( new BranchColor() );
+ }
+ node.getBranchData().getBranchColor().setValue( color );
+ }
+
+ /**
+ * Convenience method
+ */
+ public static void setBranchWidthValue( final PhylogenyNode node, final double branch_width_value ) {
+ node.getBranchData().setBranchWidth( new BranchWidth( branch_width_value ) );
+ }
+
+ /**
+ * Convenience method.
+ * Sets value for the first confidence value (created if not present, values overwritten otherwise).
+ */
+ public static void setConfidence( final PhylogenyNode node, final double confidence_value ) {
+ setConfidence( node, confidence_value, "" );
+ }
+
+ /**
+ * Convenience method.
+ * Sets value for the first confidence value (created if not present, values overwritten otherwise).
+ */
+ public static void setConfidence( final PhylogenyNode node, final double confidence_value, final String type ) {
+ Confidence c = null;
+ if ( node.getBranchData().getNumberOfConfidences() > 0 ) {
+ c = node.getBranchData().getConfidence( 0 );
+ }
+ else {
+ c = new Confidence();
+ node.getBranchData().addConfidence( c );
+ }
+ c.setType( type );
+ c.setValue( confidence_value );
+ }
+
+ public static void setScientificName( final PhylogenyNode node, final String scientific_name ) {
+ if ( !node.getNodeData().isHasTaxonomy() ) {
+ node.getNodeData().setTaxonomy( new Taxonomy() );
+ }
+ node.getNodeData().getTaxonomy().setScientificName( scientific_name );
+ }
+
+ /**
+ * Convenience method to set the taxonomy code of a phylogeny node.
+ *
+ *
+ * @param node
+ * @param taxonomy_code
+ * @throws PhyloXmlDataFormatException
+ */
+ public static void setTaxonomyCode( final PhylogenyNode node, final String taxonomy_code )
+ throws PhyloXmlDataFormatException {
+ if ( !node.getNodeData().isHasTaxonomy() ) {
+ node.getNodeData().setTaxonomy( new Taxonomy() );
+ }
+ node.getNodeData().getTaxonomy().setTaxonomyCode( taxonomy_code );
+ }
+
+ final static public void sortNodeDescendents( final PhylogenyNode node, final DESCENDANT_SORT_PRIORITY pri ) {
+ 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 transferInternalNamesToConfidenceValues( final Phylogeny phy,
+ final String confidence_type ) {
+ 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, confidence_type ) );
+ n.setName( "" );
+ }
+ }
+ }
+ }
+
+ final static public boolean isInternalNamesLookLikeConfidences( final Phylogeny phy ) {
+ final PhylogenyNodeIterator it = phy.iteratorPostorder();
+ while ( it.hasNext() ) {
+ final PhylogenyNode n = it.next();
+ if ( !n.isExternal() && !n.isRoot() ) {
+ if ( !ForesterUtil.isEmpty( n.getName() ) ) {
+ double value = -1;
+ try {
+ value = Double.parseDouble( n.getName() );
+ }
+ catch ( final NumberFormatException e ) {
+ return false;
+ }
+ if ( ( value < 0.0 ) || ( value > 100 ) ) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ final static public void transferInternalNodeNamesToConfidence( final Phylogeny phy,
+ final String confidence_type ) {
+ final PhylogenyNodeIterator it = phy.iteratorPostorder();
+ while ( it.hasNext() ) {
+ transferInternalNodeNameToConfidence( confidence_type, it.next() );
+ }
+ }
+
+ private static void transferInternalNodeNameToConfidence( final String confidence_type, final PhylogenyNode n ) {
+ if ( !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, confidence_type ) );
+ n.setName( "" );
+ }
+ }
+ }
+ }
+
+ final static public void transferNodeNameToField( final Phylogeny phy,
+ final PhylogenyNodeField field,
+ final boolean external_only )
+ throws PhyloXmlDataFormatException {
+ final PhylogenyNodeIterator it = phy.iteratorPostorder();
+ while ( it.hasNext() ) {
+ final PhylogenyNode n = it.next();
+ if ( external_only && n.isInternal() ) {
+ continue;
+ }
+ final String name = n.getName().trim();
+ if ( !ForesterUtil.isEmpty( name ) ) {
+ switch ( field ) {
+ case TAXONOMY_CODE:
+ n.setName( "" );
+ 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( 0, i );
+ }
+ 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( i + 1, name.length() );
+ }
+ else {
+ n.setName( "" );
+ }
+ n.getNodeData().getTaxonomy()
+ .setIdentifier( new Identifier( id, PhyloXmlUtil.UNIPROT_TAX_PROVIDER ) );
+ break;
+ }
+ case TAXONOMY_ID: {
+ if ( !n.getNodeData().isHasTaxonomy() ) {
+ n.getNodeData().setTaxonomy( new Taxonomy() );
+ }
+ n.getNodeData().getTaxonomy().setIdentifier( new Identifier( name ) );
+ break;
+ }
+ case CLADE_NAME:
+ n.setName( name );
+ break;
+ default: {
+ throw new IllegalArgumentException( "don't know what to do with " + field );
+ }
+ }
+ }
+ }
+ }
+
+ static double addPhylogenyDistances( final double a, final double b ) {
+ if ( ( a >= 0.0 ) && ( b >= 0.0 ) ) {
+ return a + b;
+ }
+ else if ( a >= 0.0 ) {
+ return a;
+ }
+ else if ( b >= 0.0 ) {
+ return b;
+ }
+ return PhylogenyDataUtil.BRANCH_LENGTH_DEFAULT;
+ }
+
+ static double calculateDistanceToAncestor( final PhylogenyNode anc, PhylogenyNode desc ) {
+ double d = 0;
+ boolean all_default = true;
+ while ( anc != desc ) {
+ if ( desc.getDistanceToParent() != PhylogenyDataUtil.BRANCH_LENGTH_DEFAULT ) {
+ d += desc.getDistanceToParent();
+ if ( all_default ) {
+ all_default = false;
+ }
+ }
+ desc = desc.getParent();
+ }
+ if ( all_default ) {
+ return PhylogenyDataUtil.BRANCH_LENGTH_DEFAULT;
+ }
+ return d;
+ }
+
+ public static double calculateAverageTreeHeight( final PhylogenyNode node ) {
+ final List<PhylogenyNode> ext = node.getAllExternalDescendants();
+ double s = 0;
+ for( PhylogenyNode n : ext ) {
+ while ( n != node ) {
+ if ( n.getDistanceToParent() > 0 ) {
+ s += n.getDistanceToParent();
+ }
+ n = n.getParent();
+ }
+ }
+ return s / ext.size();
+ }
+
+ /**
+ * Deep copies the phylogeny originating from this node.
+ */
+ static PhylogenyNode copySubTree( final PhylogenyNode source ) {
+ if ( source == null ) {
+ return null;
+ }
+ else {
+ final PhylogenyNode newnode = source.copyNodeData();
+ if ( !source.isExternal() ) {
+ for( int i = 0; i < source.getNumberOfDescendants(); ++i ) {
+ newnode.setChildNode( i, PhylogenyMethods.copySubTree( source.getChildNode( i ) ) );
+ }
+ }
+ return newnode;
+ }
+ }
+
+ /**
+ * Shallow copies the phylogeny originating from this node.
+ */
+ static PhylogenyNode copySubTreeShallow( final PhylogenyNode source ) {
+ if ( source == null ) {
+ return null;
+ }
+ else {
+ final PhylogenyNode newnode = source.copyNodeDataShallow();
+ if ( !source.isExternal() ) {
+ for( int i = 0; i < source.getNumberOfDescendants(); ++i ) {
+ newnode.setChildNode( i, PhylogenyMethods.copySubTreeShallow( source.getChildNode( i ) ) );
+ }
+ }
+ return newnode;
+ }
+ }
+
+ private final static List<PhylogenyNode> divideIntoSubTreesHelper( final PhylogenyNode node,
+ final double min_distance_to_root ) {
+ final List<PhylogenyNode> l = new ArrayList<PhylogenyNode>();
+ final PhylogenyNode r = moveTowardsRoot( node, min_distance_to_root );
+ for( final PhylogenyNode ext : r.getAllExternalDescendants() ) {
+ if ( ext.getIndicator() != 0 ) {
+ throw new RuntimeException( "this should not have happened" );
+ }
+ ext.setIndicator( ( byte ) 1 );
+ l.add( ext );
+ }
+ return l;
+ }
+
+ /**
+ * Calculates the distance between PhylogenyNodes n1 and n2.
+ * PRECONDITION: n1 is a descendant of n2.
+ *
+ * @param n1
+ * a descendant of n2
+ * @param n2
+ * @return distance between n1 and n2
+ */
+ private static double getDistance( PhylogenyNode n1, final PhylogenyNode n2 ) {
+ double d = 0.0;
+ while ( n1 != n2 ) {
+ if ( n1.getDistanceToParent() > 0.0 ) {
+ d += n1.getDistanceToParent();
+ }
+ n1 = n1.getParent();
+ }
+ return d;
+ }
+
+ private static boolean match( final String s,
+ final String query,
+ final boolean case_sensitive,
+ final boolean partial,
+ final boolean regex ) {
+ if ( ForesterUtil.isEmpty( s ) || ForesterUtil.isEmpty( query ) ) {
+ return false;
+ }
+ String my_s = s.trim();
+ String my_query = query.trim();
+ if ( !case_sensitive && !regex ) {
+ my_s = my_s.toLowerCase();
+ my_query = my_query.toLowerCase();
+ }
+ if ( regex ) {
+ Pattern p = null;
+ try {
+ if ( case_sensitive ) {
+ p = Pattern.compile( my_query );
+ }
+ else {
+ p = Pattern.compile( my_query, Pattern.CASE_INSENSITIVE );
+ }
+ }
+ catch ( final PatternSyntaxException e ) {
+ return false;