import org.forester.util.ForesterUtil;
/**
- * Warning. Implementation of method 'compareTo' only looks at
+ * Warning. Implementation of method 'compareTo' only looks at
* node name. Thus, use of this class in SortedSets might lead
* to unexpected behavior.
*
*/
public final class PhylogenyNode implements Comparable<PhylogenyNode> {
- public enum NH_CONVERSION_SUPPORT_VALUE_STYLE {
- NONE, IN_SQUARE_BRACKETS, AS_INTERNAL_NODE_NAMES;
- }
private static long NODE_COUNT = 0;
- private byte _indicator;
- private long _id;
- private int _sum_ext_nodes;
- private float _x;
- private float _y;
- private double _distance_parent = PhylogenyDataUtil.BRANCH_LENGTH_DEFAULT;
+ private BranchData _branch_data;
private boolean _collapse;
- private PhylogenyNode _parent;
- private PhylogenyNode _link;
private ArrayList<PhylogenyNode> _descendants;
+ private double _distance_parent = PhylogenyDataUtil.BRANCH_LENGTH_DEFAULT;
+ private long _id;
+ private byte _indicator;
+ private PhylogenyNode _link;
private NodeData _node_data;
- private BranchData _branch_data;
+ private PhylogenyNode _parent;
+ private int _sum_ext_nodes;
+ private float _x;
private float _x_secondary;
+ private float _y;
private float _y_secondary;
/**
setSumExtNodes( 1 ); // For ext node, this number is 1 (not 0!!)
}
- public void removeConnections() {
- _parent = null;
- _link = null;
- _descendants = null;
+ public PhylogenyNode( final String node_name ) {
+ setId( PhylogenyNode.getNodeCount() );
+ PhylogenyNode.increaseNodeCount();
+ setSumExtNodes( 1 ); // For ext node, this number is 1 (not 0!!)
+ if ( node_name != null ) {
+ getNodeData().setNodeName( node_name );
+ }
+ }
+
+ private PhylogenyNode( final String nhx,
+ final NHXParser.TAXONOMY_EXTRACTION taxonomy_extraction,
+ final boolean replace_underscores ) throws NHXFormatException, PhyloXmlDataFormatException {
+ NHXParser.parseNHX( nhx, this, taxonomy_extraction, replace_underscores, false, false, false );
+ setId( PhylogenyNode.getNodeCount() );
+ PhylogenyNode.increaseNodeCount();
+ setSumExtNodes( 1 ); // For ext node, this number is 1 (not 0!!).
+ }
+
+ private PhylogenyNode( final String nhx,
+ final NHXParser.TAXONOMY_EXTRACTION taxonomy_extraction,
+ final boolean replace_underscores,
+ final boolean parse_extended_tags ) throws NHXFormatException, PhyloXmlDataFormatException {
+ NHXParser.parseNHX( nhx,
+ this,
+ taxonomy_extraction,
+ replace_underscores,
+ false,
+ false,
+ parse_extended_tags );
+ setId( PhylogenyNode.getNodeCount() );
+ PhylogenyNode.increaseNodeCount();
+ setSumExtNodes( 1 ); // For ext node, this number is 1 (not 0!!).
}
/**
* Adds PhylogenyNode n to the list of child nodes and sets the _parent of n
* to this.
- *
+ *
* @param n
* the PhylogenyNode to add
*/
n.setParent( this );
}
- /**
- * Adds PhylogenyNode n to the list of child nodes. But does NOT set the
- * _parent of n to this.
- *
- * @see addAsChild( PhylogenyNode n )
- * @param n
- * the PhylogenyNode to add
- */
- final private void addChildNode( final PhylogenyNode child ) {
- getDescendants().add( child );
+ public final int calculateDepth() {
+ PhylogenyNode n = this;
+ int steps = 0;
+ while ( n._parent != null ) {
+ steps++;
+ n = n._parent;
+ }
+ return steps;
+ }
+
+ public final double calculateDistanceToRoot() {
+ PhylogenyNode n = this;
+ double d = 0.0;
+ while ( n._parent != null ) {
+ if ( n._distance_parent > 0.0 ) {
+ d += n._distance_parent;
+ }
+ n = n._parent;
+ }
+ return d;
}
@Override
return getName().compareTo( n.getName() );
}
- // ---------------------------------------------------------
- // Copy and delete Nodes, copy subtress
- // ---------------------------------------------------------
/**
* Returns a new PhylogenyNode which has its data copied from this
* PhylogenyNode. Links to the other Nodes in the same Phylogeny are NOT
* copied (e.g. _link to _parent). Field "_link" IS copied.
- *
- * @see #getLink()
+ *
+ * @see #getLink()
*/
final public PhylogenyNode copyNodeData() {
final PhylogenyNode node = new PhylogenyNode();
* Returns a new PhylogenyNode which has the same data as this
* PhylogenyNode. Links to the other Nodes in the same Phylogeny are NOT
* copied (e.g. _link to _parent). Field "_link" IS copied.
- *
- * @see #getLink()
+ *
+ * @see #getLink()
*/
final public PhylogenyNode copyNodeDataShallow() {
final PhylogenyNode node = new PhylogenyNode();
@Override
/**
* Based on node name, sequence, and taxonomy.
- *
- *
+ *
+ *
*/
final public boolean equals( final Object o ) {
if ( this == o ) {
}
}
- // ---------------------------------------------------------
- // Obtaining of Nodes
- // ---------------------------------------------------------
+ final public List<PhylogenyNode> getAllDescendants() {
+ return _descendants;
+ }
+
/**
* Returns a List containing references to all external children of this
* PhylogenyNode.
- *
+ *
* @return List of references to external Nodes
*/
final public List<PhylogenyNode> getAllExternalDescendants() {
/**
* Returns a List containing references to all names of the external
* children of this PhylogenyNode.
- *
+ *
* @return List of references to names of external Nodes
*/
final public List<String> getAllExternalDescendantsNames() {
return _branch_data;
}
- final BranchData getBranchDataDirectly() {
- return _branch_data;
- }
-
/**
* This return child node n of this node.
- *
+ *
* @param n
* the index of the child to get
* @return the child node with index n
/**
* This gets the child node index of this node.
* <p>
- *
+ *
* @return the child node index of this node
* @throws UnsupportedOperationException
* if this node is a root node
* parent
* <p>
* [last modified Aug 14, 2006 by CMZ]
- *
+ *
* @return the child node index of this node
* @throws UnsupportedOperationException
* if this node is a root node
* Convenience method. Returns the first child node of this node.
* <p>
* [last modified May 18, 2005 by CMZ]
- *
+ *
* @return the first child node of this node
*/
public final PhylogenyNode getFirstChildNode() {
}
/**
+ * Returns the ID (int) of this PhylogenyNode.
+ */
+ final public long getId() {
+ return _id;
+ }
+
+ /**
* Returns the _indicator value of this PhylogenyNode.
*/
public final byte getIndicator() {
* Convenience method. Returns the last child node of this node.
* <p>
* [last modified May 18, 2005 by CMZ]
- *
+ *
* @return the last child node of this node
*/
public final PhylogenyNode getLastChildNode() {
return _link;
}
+ final public String getName() {
+ return getNodeData().getNodeName();
+ }
+
/**
* Returns a refernce to the next external PhylogenyNode of this
* PhylogenyNode. TODO should be in Phylogeny. Returns null if no next
return _node_data;
}
- final NodeData getNodeDataDirectly() {
- return _node_data;
- }
-
- // ---------------------------------------------------------
- // Set and get methods for Nodes
- // ---------------------------------------------------------
- /**
- * Returns the ID (int) of this PhylogenyNode.
- */
- final public long getId() {
- return _id;
- }
-
- final public String getName() {
- return getNodeData().getNodeName();
- }
-
- final public List<PhylogenyNode> getAllDescendants() {
- return _descendants;
- }
-
final public int getNumberOfDescendants() {
if ( _descendants == null ) {
return 0;
return result;
}
- // final private void init() {
- //_descendants = new ArrayList<PhylogenyNode>();
- // _parent = null; //TODO not needed?
- // _id = 0; //TODO not needed?
- //initializeData(); //TODO not needed?
- //}
- /**
- * Deletes data of this PhylogenyNode. Links to the other Nodes in the
- * Phylogeny, the ID and the sum of external nodes are NOT deleted. Field
- * "_link" (_link to Nodes in other Phylogeny) IS deleted.
- *
- * @see #getLink() (Last modified: 12/20/03)
- */
- // final private void initializeData() {
- // _indicator = 0;
- // _x = 0;
- // _y = 0;
- // //_node_name = "";
- // _distance_parent = PhylogenyDataUtil.BRANCH_LENGTH_DEFAULT;
- // _collapse = false;
- // _link = null;
- // _branch_data = null;
- // _node_data = null;
- // }
/**
* Returns whether this PhylogenyNode should be drawn as collapsed.
*/
return getNodeData().isHasEvent() && getNodeData().getEvent().isDuplication();
}
+ public boolean isEmpty() {
+ return ( ( _node_data == null ) || _node_data.isEmpty() );
+ }
+
/**
* Checks whether this PhylogenyNode is external (tip).
- *
+ *
* @return true if this PhylogenyNode is external, false otherwise
*/
final public boolean isExternal() {
return ( getNumberOfDescendants() < 1 );
}
- /**
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
final public boolean isFirstChildNode() {
if ( isRoot() /* and tree is rooted TODO */) {
throw new UnsupportedOperationException( "Cannot determine whether the root is the first child node of its _parent." );
return ( getChildNodeIndex() == 0 );
}
- /**
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
final public boolean isFirstExternalNode() {
if ( isInternal() ) {
return false;
/**
* Checks whether this PhylogenyNode is internal (tip).
- *
+ *
* @return true if this PhylogenyNode is external, false otherwise
*/
final public boolean isInternal() {
* Returns true if this node is the last child node of its _parent.
* <p>
* [last modified June 01, 2005 by CMZ]
- *
+ *
* @return true if this node is the last child node of its _parent, false
* otherwise
*/
return ( getChildNodeIndex() == ( getParent().getNumberOfDescendants() - 1 ) );
}
- /**
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
final public boolean isLastExternalNode() {
if ( isInternal() ) {
return false;
return true;
}
- public final int calculateDepth() {
- PhylogenyNode n = this;
- int steps = 0;
- while ( n._parent != null ) {
- steps++;
- n = n._parent;
- }
- return steps;
- }
-
- public final double calculateDistanceToRoot() {
- PhylogenyNode n = this;
- double d = 0.0;
- while ( n._parent != null ) {
- if ( n._distance_parent > 0.0 ) {
- d += n._distance_parent;
- }
- n = n._parent;
- }
- return d;
- }
-
/**
* Checks whether this PhylogenyNode is a root.
- *
+ *
* @return true if this PhylogenyNode is the root, false otherwise
*/
final public boolean isRoot() {
removeChildNode( remove_me.getChildNodeIndex() );
}
+ public void removeConnections() {
+ _parent = null;
+ _link = null;
+ _descendants = null;
+ }
+
final public void setBranchData( final BranchData branch_data ) {
_branch_data = branch_data;
}
* child nodes. This does not allow null slots in the list of child nodes:
* If i is larger than the number of child nodes, n is just added to the
* list, not place at index i.
- *
+ *
* @param i
* the index of position where to add the child
* @param n
}
}
- final void setChildNodeOnly( final int i, final PhylogenyNode node ) {
- if ( getNumberOfDescendants() <= i ) {
- addChildNode( node );
- }
- else {
- getDescendants().set( i, node );
- }
- }
-
/**
* Sets whether this PhylogenyNode should be drawn as collapsed.
*/
_indicator = i;
}
- // --------------------------------------------------------------------
- // Adjust methods (related to Phylogeny construction and
- // Phylogeny modification)
- // --------------------------------------------------------------------
- /**
- * Sets the indicators of all the children of this PhylogenyNode to zero.
- */
- final void setIndicatorsToZero() {
- for( final PreorderTreeIterator it = new PreorderTreeIterator( this ); it.hasNext(); ) {
- it.next().setIndicator( ( byte ) 0 );
- }
- }
-
/**
* Sets the linked PhylogenyNode of this PhylogenyNode to n. Currently, this
* method is only used for the speciation-_duplication assignment
}
/**
- * Sets the Id of this PhylogenyNode to i. In most cases, this number
- * should not be set to values lower than getNodeCount() -- which this method
- * does not allow.
- */
- synchronized final protected void setId( final long i ) {
- if ( i < getNodeCount() ) {
- throw new IllegalArgumentException( "attempt to set node id to a value less than total node count (thus violating the uniqueness of node ids)" );
- }
- _id = i;
- }
-
- /**
* Sets the _parent PhylogenyNode of this PhylogenyNode to n.
*/
final public void setParent( final PhylogenyNode n ) {
_y_secondary = y_secondary;
}
+ /**
+ * Swaps the the two childern of a PhylogenyNode node of this Phylogeny.
+ */
+ public final void swapChildren() throws RuntimeException {
+ if ( isExternal() ) {
+ throw new RuntimeException( "attempt to swap descendants of external node" );
+ }
+ if ( getNumberOfDescendants() != 2 ) {
+ throw new RuntimeException( "attempt to swap descendants of node with " + getNumberOfDescendants()
+ + " descendants" );
+ }
+ final PhylogenyNode a = getChildNode( 0 );
+ final PhylogenyNode b = getChildNode( 1 );
+ setChildNode( 0, b );
+ setChildNode( 1, a );
+ }
+
// ---------------------------------------------------------
// Writing of Nodes to Strings
// ---------------------------------------------------------
- final public String toNewHampshire( final boolean simple_nh,
- final boolean write_distance_to_parent,
+ final public String toNewHampshire( final boolean write_distance_to_parent,
final NH_CONVERSION_SUPPORT_VALUE_STYLE svs ) {
- final StringBuilder sb = new StringBuilder();
String data = "";
if ( ( svs == NH_CONVERSION_SUPPORT_VALUE_STYLE.AS_INTERNAL_NODE_NAMES ) && !isExternal() ) {
if ( getBranchData().isHasConfidences()
&& ( getBranchData().getConfidence( 0 ).getValue() != Confidence.CONFIDENCE_DEFAULT_VALUE ) ) {
data = Confidence.FORMATTER.format( ForesterUtil
- .round( getBranchData().getConfidence( 0 ).getValue(),
- PhyloXmlUtil.ROUNDING_DIGITS_FOR_PHYLOXML_DOUBLE_OUTPUT ) );
+ .round( getBranchData().getConfidence( 0 ).getValue(),
+ PhyloXmlUtil.ROUNDING_DIGITS_FOR_PHYLOXML_DOUBLE_OUTPUT ) );
}
}
else if ( !ForesterUtil.isEmpty( getName() ) ) {
else if ( !ForesterUtil.isEmpty( getNodeData().getTaxonomy().getCommonName() ) ) {
data = getNodeData().getTaxonomy().getCommonName();
}
- else if ( getNodeData().getTaxonomy().getTaxonomyCode() != null ) {
- data = getNodeData().getTaxonomy().getTaxonomyCode();
- }
}
else if ( getNodeData().isHasSequence() ) {
if ( !ForesterUtil.isEmpty( getNodeData().getSequence().getName() ) ) {
data = getNodeData().getSequence().getName();
}
- }
- if ( data.length() > 0 ) {
- data = ForesterUtil.replaceIllegalNhCharacters( data );
- if ( simple_nh && ( data.length() > 10 ) ) {
- data = data.substring( 0, 11 );
+ else if ( !ForesterUtil.isEmpty( getNodeData().getSequence().getSymbol() ) ) {
+ data = getNodeData().getSequence().getSymbol();
}
- if ( ForesterUtil.isContainsParanthesesableNhCharacter( data ) ) {
- sb.append( '\'' );
- sb.append( data );
- sb.append( '\'' );
- }
- else {
- sb.append( data );
+ else if ( !ForesterUtil.isEmpty( getNodeData().getSequence().getGeneName() ) ) {
+ data = getNodeData().getSequence().getGeneName();
}
}
+ final StringBuilder sb = ForesterUtil.santitizeStringForNH( data );
if ( write_distance_to_parent && ( getDistanceToParent() != PhylogenyDataUtil.BRANCH_LENGTH_DEFAULT ) ) {
sb.append( ":" );
sb.append( getDistanceToParent() );
&& ( getBranchData().getConfidence( 0 ).getValue() != Confidence.CONFIDENCE_DEFAULT_VALUE ) ) {
sb.append( "[" );
sb.append( Confidence.FORMATTER.format( ForesterUtil
- .round( getBranchData().getConfidence( 0 ).getValue(),
- PhyloXmlUtil.ROUNDING_DIGITS_FOR_PHYLOXML_DOUBLE_OUTPUT ) ) );
+ .round( getBranchData().getConfidence( 0 ).getValue(),
+ PhyloXmlUtil.ROUNDING_DIGITS_FOR_PHYLOXML_DOUBLE_OUTPUT ) ) );
sb.append( "]" );
}
return sb.toString();
}
/**
- * Swaps the the two childern of a PhylogenyNode node of this Phylogeny.
- */
- public final void swapChildren() throws RuntimeException {
- if ( isExternal() ) {
- throw new RuntimeException( "attempt to swap descendants of external node" );
- }
- if ( getNumberOfDescendants() != 2 ) {
- throw new RuntimeException( "attempt to swap descendants of node with " + getNumberOfDescendants()
- + " descendants" );
- }
- final PhylogenyNode a = getChildNode( 0 );
- final PhylogenyNode b = getChildNode( 1 );
- setChildNode( 0, b );
- setChildNode( 1, a );
- }
-
- /**
* Converts this PhylogenyNode to a New Hampshire X (NHX) String
* representation.
*/
final public String toNewHampshireX() {
- final StringBuffer sb = new StringBuffer();
+ final StringBuilder sb = new StringBuilder();
final StringBuffer s_nhx = new StringBuffer();
if ( !ForesterUtil.isEmpty( getName() ) ) {
- final String name = ForesterUtil.replaceIllegalNhCharacters( getName() );
- if ( ForesterUtil.isContainsParanthesesableNhCharacter( name ) ) {
- sb.append( '\'' );
- sb.append( name );
- sb.append( '\'' );
- }
- else {
- sb.append( name );
- }
+ sb.append( ForesterUtil.santitizeStringForNH( getName() ) );
}
if ( getDistanceToParent() != PhylogenyDataUtil.BRANCH_LENGTH_DEFAULT ) {
sb.append( ":" );
@Override
final public String toString() {
final StringBuilder sb = new StringBuilder();
+ if ( !ForesterUtil.isEmpty( getName() ) ) {
+ sb.append( getName() );
+ sb.append( " " );
+ }
if ( getNodeData().isHasTaxonomy() ) {
if ( !ForesterUtil.isEmpty( getNodeData().getTaxonomy().getScientificName() ) ) {
sb.append( getNodeData().getTaxonomy().getScientificName() );
sb.append( getNodeData().getSequence().getSymbol() );
sb.append( " " );
}
+ if ( !ForesterUtil.isEmpty( getNodeData().getSequence().getGeneName() ) ) {
+ sb.append( getNodeData().getSequence().getGeneName() );
+ sb.append( " " );
+ }
if ( getNodeData().getSequence().getAccession() != null ) {
sb.append( getNodeData().getSequence().getAccession().toString() );
sb.append( " " );
}
- }
- if ( ( sb.length() <= 1 ) && !ForesterUtil.isEmpty( getName() ) ) {
- sb.append( getName() );
- sb.append( " " );
+ if ( !ForesterUtil.isEmpty( getNodeData().getSequence().getMolecularSequence() ) ) {
+ sb.append( getNodeData().getSequence().getMolecularSequence() );
+ sb.append( " " );
+ }
}
if ( sb.length() <= 1 ) {
sb.append( "[" );
}
/**
- * Decreases the total number of all Nodes created so far by one.
+ * Sets the Id of this PhylogenyNode to i. In most cases, this number
+ * should not be set to values lower than getNodeCount() -- which this method
+ * does not allow.
*/
- final static synchronized void decreaseNodeCount() {
- --NODE_COUNT;
+ synchronized final protected void setId( final long i ) {
+ if ( i < getNodeCount() ) {
+ throw new IllegalArgumentException( "attempt to set node id to a value less than total node count (thus violating the uniqueness of node ids)" );
+ }
+ _id = i;
}
- /**
- * Returns the total number of all Nodes created so far.
- *
- * @return total number of Nodes (long)
- */
- synchronized final public static long getNodeCount() {
- return NODE_COUNT;
+ final BranchData getBranchDataDirectly() {
+ return _branch_data;
+ }
+
+ final NodeData getNodeDataDirectly() {
+ return _node_data;
+ }
+
+ final void setChildNodeOnly( final int i, final PhylogenyNode node ) {
+ if ( getNumberOfDescendants() <= i ) {
+ addChildNode( node );
+ }
+ else {
+ getDescendants().set( i, node );
+ }
}
/**
- * Increases the total number of all Nodes created so far by one.
+ * Sets the indicators of all the children of this PhylogenyNode to zero.
*/
- synchronized final private static void increaseNodeCount() {
- ++NODE_COUNT;
+ final void setIndicatorsToZero() {
+ for( final PreorderTreeIterator it = new PreorderTreeIterator( this ); it.hasNext(); ) {
+ it.next().setIndicator( ( byte ) 0 );
+ }
}
/**
- * Sets the total number of all Nodes created so far to i.
+ * Adds PhylogenyNode n to the list of child nodes. But does NOT set the
+ * _parent of n to this.
+ *
+ * @see addAsChild( PhylogenyNode n )
+ * @param n
+ * the PhylogenyNode to add
*/
- synchronized final static void setNodeCount( final long i ) {
- PhylogenyNode.NODE_COUNT = i;
+ final private void addChildNode( final PhylogenyNode child ) {
+ getDescendants().add( child );
}
public static PhylogenyNode createInstanceFromNhxString( final String nhx ) throws NHXFormatException,
- PhyloXmlDataFormatException {
+ PhyloXmlDataFormatException {
return new PhylogenyNode( nhx, NHXParser.TAXONOMY_EXTRACTION.NO, false );
}
public static PhylogenyNode createInstanceFromNhxString( final String nhx,
final NHXParser.TAXONOMY_EXTRACTION taxonomy_extraction )
- throws NHXFormatException, PhyloXmlDataFormatException {
+ throws NHXFormatException, PhyloXmlDataFormatException {
return new PhylogenyNode( nhx, taxonomy_extraction, false );
}
public static PhylogenyNode createInstanceFromNhxString( final String nhx,
final NHXParser.TAXONOMY_EXTRACTION taxonomy_extraction,
final boolean replace_underscores )
- throws NHXFormatException, PhyloXmlDataFormatException {
+ throws NHXFormatException, PhyloXmlDataFormatException {
return new PhylogenyNode( nhx, taxonomy_extraction, replace_underscores );
}
+
+ public static PhylogenyNode createInstanceFromNhxString( final String nhx,
+ final NHXParser.TAXONOMY_EXTRACTION taxonomy_extraction,
+ final boolean replace_underscores,
+ final boolean parse_extended_tags )
+ throws NHXFormatException, PhyloXmlDataFormatException {
+ return new PhylogenyNode( nhx, taxonomy_extraction, replace_underscores, parse_extended_tags );
+ }
- private PhylogenyNode( final String nhx,
- final NHXParser.TAXONOMY_EXTRACTION taxonomy_extraction,
- final boolean replace_underscores ) throws NHXFormatException, PhyloXmlDataFormatException {
- // init();
- NHXParser.parseNHX( nhx, this, taxonomy_extraction, replace_underscores );
- setId( PhylogenyNode.getNodeCount() );
- PhylogenyNode.increaseNodeCount();
- setSumExtNodes( 1 ); // For ext node, this number is 1 (not 0!!)
+ /**
+ * Returns the total number of all Nodes created so far.
+ *
+ * @return total number of Nodes (long)
+ */
+ synchronized final public static long getNodeCount() {
+ return NODE_COUNT;
+ }
+
+ /**
+ * Decreases the total number of all Nodes created so far by one.
+ */
+ final static synchronized void decreaseNodeCount() {
+ --NODE_COUNT;
+ }
+
+ /**
+ * Sets the total number of all Nodes created so far to i.
+ */
+ synchronized final static void setNodeCount( final long i ) {
+ PhylogenyNode.NODE_COUNT = i;
+ }
+
+ /**
+ * Increases the total number of all Nodes created so far by one.
+ */
+ synchronized final private static void increaseNodeCount() {
+ ++NODE_COUNT;
+ }
+
+ public enum NH_CONVERSION_SUPPORT_VALUE_STYLE {
+ AS_INTERNAL_NODE_NAMES, IN_SQUARE_BRACKETS, NONE;
}
}