0001 
0002 /*
0003  *  Descripter 1.0 - Java Script Engines
0004  *  Copyright (C) 2010-2015  Jianjun Liu (J.J.Liu)
0005  *  
0006  *  This program is free software: you can redistribute it and/or modify
0007  *  it under the terms of the GNU Affero General Public License as published by
0008  *  the Free Software Foundation, either version 3 of the License, or
0009  *  (at your option) any later version.
0010  *  
0011  *  This program is distributed in the hope that it will be useful,
0012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014  *  GNU Affero General Public License for more details.
0015  *  
0016  *  You should have received a copy of the GNU Affero General Public License
0017  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
0018  */
0019 
0020 package org.descripter.js.api.core;
0021 
0022 import java.util.Locale;
0023 import java.util.regex.Matcher;
0024 
0025 import org.descripter.js.api.Function;
0026 
0027 /**
0028  * <p>Emulates JavaScript String objects.</p>
0029  * 
0030  * @author <a href="mailto:jianjunliu@126.com">J.J.Liu (Jianjun Liu)</a> at <a href="http://www.descripter.org" target="_blank">http://www.descripter.org</a>
0031  * @since Descripter 1.0
0032  */
0033 public class CString extends CObject
0034 {
0035     private final String value;
0036 
0037     /**
0038      * <p>Constructs a {@link CObject} context of this type.</p>
0039      * @param constructor The constructor {@link Function} object.
0040      * @param value The initial value
0041      * @since Descripter 1.0
0042      */
0043     public CString(Function<?> constructor, Object value) {
0044         super(constructor);
0045         this.value = value == null ? "" : toString(value);
0046     }
0047 
0048     /**
0049      * <p>Gets the length of the current string, an integer that indicates the number of 
0050      * characters in the current string. For any string <tt>s</tt>, the index of the 
0051      * last character is <tt>s.length() - 1</tt>. The length property of a string may 
0052      * not be deleted.</p>
0053      * @return The length of the current string.
0054      * @since Descripter 1.0
0055      */
0056     public final int length() {
0057         return value.length();
0058     }
0059 
0060     /**
0061      * <p>Returns the character string of length 1 at the specified <tt>index</tt> within 
0062      * the current string. An index ranges from 0 to <tt>length() - 1</tt>. The first 
0063      * character of the sequence is at index 0, the next at index 1, and so on, as for 
0064      * array indexing. If <tt>index</tt> is not between 0 and <tt>length() - 1</tt>, 
0065      * this invocation returns an empty string.</p>
0066      * @param index The index of the character
0067      * @return The character string of length 1 at the specified index of the current string
0068      * @see #charCodeAt(Object)
0069      * @see #indexOf(Object)
0070      * @see #indexOf(Object, Object)
0071      * @see #lastIndexOf(Object)
0072      * @see #lastIndexOf(Object, Object)
0073      * @since Descripter 1.0
0074      */
0075     public final String charAt(Object index) {
0076         return new String(new char[]{value.charAt(intValue(index))});
0077     }
0078 
0079     /**
0080      * <p>Returns the character encoding at a specific <tt>index</tt> within the current 
0081      * string. An index ranges from 0 to <tt>length() - 1</tt>. The first 
0082      * character of the sequence is at index 0, the next at index 1, and so on, as for 
0083      * array indexing. If <tt>index</tt> is not between 0 and <tt>length() - 1</tt>, 
0084      * this invocation returns <tt>NaN</tt>.</p>
0085      * @param index The index of the character
0086      * @return The Unicode encoding of the character within the current string. The return 
0087      * value is a 16-bit integer between 0 and 65535.
0088      * @see #charAt(Object)
0089      * @see #indexOf(Object)
0090      * @see #indexOf(Object, Object)
0091      * @see #lastIndexOf(Object)
0092      * @see #lastIndexOf(Object, Object)
0093      * @since Descripter 1.0
0094      */
0095     public final char charCodeAt(Object index) {
0096         return value.charAt(intValue(index));
0097     }
0098 
0099     /**
0100      * <p>Converts the argument to a string (if necessary) and appends them, in order, to 
0101      * the end of the current string and returns the resulting concatenation.</p>
0102      * <p>Note that the current string itself is not modified.</p>
0103      * <p>This method is an analog to {@link CArray#concat(CArray)}. Note that it is 
0104      * often easier to use {@link org.descripter.js.api.Objective#add(Object, Object)} perform string concatenation.</p>
0105      * @param other A value to be concatenated to the current string
0106      * @return A new string that results from concatenating the argument to the current 
0107      * string.
0108      * @see CArray#concat(CArray)
0109      * @since Descripter 1.0
0110      */
0111     public final String concat(Object other) {
0112         return value.concat(toString(other));
0113     }
0114 
0115     /**
0116      * <p>Converts the arguments to a string (if necessary) and appends them, in order, to 
0117      * the end of the current string and returns the resulting concatenation.</p>
0118      * <p>Note that the current string itself is not modified.</p>
0119      * <p>This method is an analog to {@link CArray#concat(CArray)}. Note that it is 
0120      * often easier to use {@link org.descripter.js.api.Objective#add(Object, Object)} perform string concatenation.</p>
0121      * @param args An array of values to be concatenated to the current string
0122      * @return A new string that results from concatenating the argument to the current 
0123      * string.
0124      * @since Descripter 1.0
0125      */
0126     public final String concat(CArray args) {
0127         StringBuilder sb = new StringBuilder(value);
0128         for (int i = 0, len = args.length(); i < len; i++) {
0129             sb.append(args.get(i));
0130         }
0131         return sb.toString();
0132     }
0133 
0134     /**
0135      * <p>Searches the current string instance from beginning to end to see if it contains 
0136      * an occurrence of the substring <tt>other</tt>. The search begins at position 
0137      * <tt>pos</tt> within string, or at the beginning of string if <tt>pos</tt> is  
0138      * undefined. If an occurrence of the substring is found, this invocation returns the 
0139      * position of the first character of the first occurrence of the substring within 
0140      * the current string. Character positions within string are numbered starting with 
0141      * zero. If no occurrence of substring is found within the current string, this invocation 
0142      * returns -1.</p>
0143      * @param args An array of arguments:<ul><li><tt>
0144      * other</tt>, The substring that is to be searched for within the current string</li><li><tt>
0145      * pos</tt>, An optional integer argument that specifies the position within the 
0146      * current string at which the search is to start. Legal values are 0 (the position of 
0147      * the first character in the string) to <tt>length() - 1</tt> (the position of 
0148      * the last character in the string). If this argument is undefined, the search begins 
0149      * at the first character of the string</li></ul>
0150      * @return The position of the first occurrence of <tt>other</tt> within string that 
0151      * appears after the <tt>pos</tt> position, if any, or -1 if no such occurrence 
0152      * is found.
0153      * @see #indexOf(Object)
0154      * @see #indexOf(Object, Object)
0155      * @see #charAt(Object)
0156      * @see #lastIndexOf(CArray)
0157      * @see #lastIndexOf(Object)
0158      * @see #lastIndexOf(Object, Object)
0159      * @see #substr(CArray)
0160      * @see #substr(Object)
0161      * @see #substr(Object, Object)
0162      * @see #substring(CArray)
0163      * @see #substring(Object)
0164      * @see #substring(Object, Object)
0165      * @since Descripter 1.0
0166      */
0167     public final int indexOf(CArray args) {
0168         if (args.length() > 1) {
0169             return indexOf(args.get(0), args.get(1));
0170         }
0171         return indexOf(args.get(0));
0172     }
0173 
0174     /**
0175      * <p>Searches the current string instance from beginning to end to see if it contains 
0176      * an occurrence of the substring <tt>other</tt>. The search begins at the beginning 
0177      * of the current string. If an occurrence of the substring is found, this invocation 
0178      * returns the position of the first character of the first occurrence of the substring 
0179      * within the current string. Character positions within string are numbered starting with 
0180      * zero. If no occurrence of substring is found within the current string, this invocation 
0181      * returns -1.</p>
0182      * @param other The substring that is to be searched for within the current string
0183      * @return The position of the first occurrence of <tt>other</tt> within string, if 
0184      * any, or -1 if no such occurrence is found.
0185      * @see #indexOf(CArray)
0186      * @see #indexOf(Object, Object)
0187      * @see #charAt(Object)
0188      * @see #lastIndexOf(CArray)
0189      * @see #lastIndexOf(Object)
0190      * @see #lastIndexOf(Object, Object)
0191      * @see #substr(CArray)
0192      * @see #substr(Object)
0193      * @see #substr(Object, Object)
0194      * @see #substring(CArray)
0195      * @see #substring(Object)
0196      * @see #substring(Object, Object)
0197      * @since Descripter 1.0
0198      */
0199     public final int indexOf(Object other) {
0200         return value.indexOf(toString(other));
0201     }
0202 
0203     /**
0204      * <p>Searches the current string instance from beginning to end to see if it contains 
0205      * an occurrence of the substring <tt>other</tt>. The search begins at position 
0206      * <tt>pos</tt> within string, or at the beginning of string if <tt>pos</tt> is  
0207      * undefined. If an occurrence of the substring is found, this invocation returns the 
0208      * position of the first character of the first occurrence of the substring within 
0209      * the current string. Character positions within string are numbered starting with 
0210      * zero. If no occurrence of substring is found within the current string, this invocation 
0211      * returns -1.</p>
0212      * @param other The substring that is to be searched for within the current string
0213      * @param pos An optional integer argument that specifies the position within the 
0214      * current string at which the search is to start. Legal values are 0 (the position of 
0215      * the first character in the string) to <tt>length() - 1</tt> (the position of 
0216      * the last character in the string). If this argument is undefined, the search begins 
0217      * at the first character of the string
0218      * @return The position of the first occurrence of <tt>other</tt> within string that 
0219      * appears after the <tt>pos</tt> position, if any, or -1 if no such occurrence 
0220      * is found.
0221      * @see #indexOf(CArray)
0222      * @see #indexOf(Object)
0223      * @see #charAt(Object)
0224      * @see #lastIndexOf(CArray)
0225      * @see #lastIndexOf(Object)
0226      * @see #lastIndexOf(Object, Object)
0227      * @see #substr(CArray)
0228      * @see #substr(Object)
0229      * @see #substr(Object, Object)
0230      * @see #substring(CArray)
0231      * @see #substring(Object)
0232      * @see #substring(Object, Object)
0233      * @since Descripter 1.0
0234      */
0235     public final int indexOf(Object other, Object pos) {
0236         return value.indexOf(toString(other), intValue(pos));
0237     }
0238 
0239     /**
0240      * <p>Searches the current string instance from end to beginning to see if it contains 
0241      * an occurrence of the substring <tt>other</tt>. The search begins at position 
0242      * <tt>pos</tt> within string, or at the end of string if <tt>pos</tt> is  
0243      * undefined. If an occurrence of the substring is found, this invocation returns the 
0244      * position of the first character that occurrence. Since this method 
0245      * searches from end to beginning of the string, the first occurrence found is the last 
0246      * one in the string that occurs before the <tt>pos</tt> position. If no occurrence 
0247      * of substring is found within the current string, this invocation returns -1.</p>
0248      * @param args An array of arguments:<ul><li><tt>
0249      * other</tt>, The substring that is to be searched for within the current string</li><li><tt>
0250      * pos</tt>, An optional integer argument that specifies the position within the 
0251      * current string at which the search is to start. Legal values are 0 (the position of 
0252      * the first character in the string) to <tt>length() - 1</tt> (the position of 
0253      * the last character in the string). If this argument is undefined, the search begins 
0254      * at the last character of the string</li></ul>
0255      * @return The position of the last occurrence of <tt>other</tt> within string that 
0256      * appears before the <tt>pos</tt> position, if any, or -1 if no such occurrence 
0257      * is found.
0258      * @see #lastIndexOf(Object)
0259      * @see #lastIndexOf(Object, Object)
0260      * @see #charAt(Object)
0261      * @see #indexOf(CArray)
0262      * @see #indexOf(Object)
0263      * @see #indexOf(Object, Object)
0264      * @see #substr(CArray)
0265      * @see #substr(Object)
0266      * @see #substr(Object, Object)
0267      * @see #substring(CArray)
0268      * @see #substring(Object)
0269      * @see #substring(Object, Object)
0270      * @since Descripter 1.0
0271      */
0272     public final int lastIndexOf(CArray args) {
0273         if (args.length() > 1) {
0274             return lastIndexOf(args.get(0), args.get(1));
0275         }
0276         return lastIndexOf(args.get(0));
0277     }
0278 
0279     /**
0280      * <p>Searches the current string instance from end to beginning to see if it contains 
0281      * an occurrence of the substring <tt>other</tt>. The search begins at the end 
0282      * of the current string. If an occurrence of the substring is found, this invocation 
0283      * returns the position of the first character of that occurrence. If no occurrence of 
0284      * substring is found within the current string, this invocation returns -1.</p>
0285      * @param other The substring that is to be searched for within the current string
0286      * @return The position of the last occurrence of <tt>other</tt> within string, if 
0287      * any, or -1 if no such occurrence is found.
0288      * @see #lastIndexOf(CArray)
0289      * @see #lastIndexOf(Object, Object)
0290      * @see #charAt(Object)
0291      * @see #indexOf(CArray)
0292      * @see #indexOf(Object)
0293      * @see #indexOf(Object, Object)
0294      * @see #substr(CArray)
0295      * @see #substr(Object)
0296      * @see #substr(Object, Object)
0297      * @see #substring(CArray)
0298      * @see #substring(Object)
0299      * @see #substring(Object, Object)
0300      * @since Descripter 1.0
0301      */
0302     public final int lastIndexOf(Object other) {
0303         return value.lastIndexOf(toString(other));
0304     }
0305 
0306     /**
0307      * <p>Searches the current string instance from end to beginning to see if it contains 
0308      * an occurrence of the substring <tt>other</tt>. The search begins at position 
0309      * <tt>pos</tt> within string, or at the end of string if <tt>pos</tt> is  
0310      * undefined. If an occurrence of the substring is found, this invocation returns the 
0311      * position of the first character that occurrence. Since this method 
0312      * searches from end to beginning of the string, the first occurrence found is the last 
0313      * one in the string that occurs before the <tt>pos</tt> position. If no occurrence 
0314      * of substring is found within the current string, this invocation returns -1.</p>
0315      * @param other The substring that is to be searched for within the current string
0316      * @param pos An optional integer argument that specifies the position within the 
0317      * current string at which the search is to start. Legal values are 0 (the position of 
0318      * the first character in the string) to <tt>length() - 1</tt> (the position of 
0319      * the last character in the string). If this argument is undefined, the search begins 
0320      * at the last character of the string
0321      * @return The position of the last occurrence of <tt>other</tt> within string that 
0322      * appears before the <tt>pos</tt> position, if any, or -1 if no such occurrence 
0323      * is found.
0324      * @see #lastIndexOf(CArray)
0325      * @see #lastIndexOf(Object)
0326      * @see #charAt(Object)
0327      * @see #indexOf(CArray)
0328      * @see #indexOf(Object)
0329      * @see #indexOf(Object, Object)
0330      * @see #substr(CArray)
0331      * @see #substr(Object)
0332      * @see #substr(Object, Object)
0333      * @see #substring(CArray)
0334      * @see #substring(Object)
0335      * @see #substring(Object, Object)
0336      * @since Descripter 1.0
0337      */
0338     public final int lastIndexOf(Object other, Object pos) {
0339         return value.lastIndexOf(toString(other), intValue(pos));
0340     }
0341 
0342     /**
0343      * <p>Compares strings taking the collation order of the default locale into account.</p>
0344      * <p>The ECMAScript standard does not specify how the locale-specific comparison is done; 
0345      * it merely specifies that this function utilize the collation order provided by the 
0346      * underlying operating system.</p>
0347      * @param other A string to be compared, in a locale-sensitive fashion, with the current string
0348      * @return An integer number that indicates the result of the comparison. If the current 
0349      * string is "less than" the string <tt>other</tt>, this invocation returns a 
0350      * number less than zero. If the current string is "greater than" <tt>other</tt>, 
0351      * it returns a integer number greater than zero. And if the strings are identical or 
0352      * indistinguishable according to the locale ordering conventions, the method returns 0.
0353      * @since Descripter 1.0
0354      */
0355     public final int localeCompare(Object other) {
0356         return value.compareTo(toString(other));
0357     }
0358 
0359     /**
0360      * <p>Searches the current string for one or more matches of <tt>regexp</tt>. 
0361      * The behavior of this invocation depends significantly on whether <tt>regexp</tt> 
0362      * has the "g" attribute or not .</p>
0363      * <p>If <tt>regexp</tt> does not have the "g" attribute, this invocation searches 
0364      * string for a single match. If no match is found, it returns <tt>null</tt>. 
0365      * Otherwise, it returns an array containing information about the match that it found. 
0366      * Element 0 of the array contains the matched text. The remaining elements contain 
0367      * the text that matches any parenthesized subexpressions within the regular expression. 
0368      * In addition to these normal array elements, the returned array also has two object 
0369      * properties. The <tt>index</tt> property (see {@link CArray#index()}) of the array  
0370      * specifies the character position within string of the start of the matched text. Also, 
0371      * the <tt>input</tt> property (see {@link CArray#input()}) of the returned array 
0372      * is a reference to string itself.</p>
0373      * <p>If <tt>regexp</tt> has the "g" flag, this invocation does a global search, 
0374      * searching string for all matching substrings. It returns <tt>null</tt> if no 
0375      * match is found, and it returns an array if one or more matches are found. The 
0376      * contents of this returned array are quite different for global matches, however. In 
0377      * this case, the array elements contain each of the matched substrings within string. 
0378      * The returned array does not have <tt>index</tt> (see {@link CArray#index()}) 
0379      * or <tt>input</tt> (see {@link CArray#input()}) properties in this case. Note 
0380      * that for global matches, this invocation does not provide information about 
0381      * parenthesized subexpressions, nor does it specify where within string each match 
0382      * occurred. If you need to obtain this information for a global search, you can use 
0383      * {@link CRegExp#exec(Object)}.</p>
0384      * @param regexp A RegExp object that specifies the pattern to be matched
0385      * @return An array containing the results of the match. The contents of the array 
0386      * depend on whether regexp has the global "g" attribute set.
0387      * @see #replace(CRegExp, String)
0388      * @see #search(CRegExp)
0389      * @see CArray#index()
0390      * @see CArray#input()
0391      * @see org.descripter.js.api.Script#re(String)
0392      * @see org.descripter.js.api.Script#re(String, String)
0393      * @see CRegExp#exec(Object)
0394      * @see CRegExp#test(Object)
0395      * @since Descripter 1.0
0396      */
0397     public final CArray match(CRegExp regexp) {
0398         return regexp.exec(this);
0399     }
0400 
0401     /**
0402      * <p>Performs a search-and-replace operation on the current string.</p>
0403      * <p>This invocation searches the current string for one or more substrings that 
0404      * match <tt>regexp</tt> and replaces them with the replacement string 
0405      * <tt>newSubStr</tt>.</p>
0406      * <p>If <tt>regexp</tt> has the global "g" attribute specified, this invocation 
0407      * replaces all matching substrings. Otherwise, it replaces only the first matching 
0408      * substring.</p>
0409      * <p>Note that the $ character has special meaning within the replacement string 
0410      * <tt>newSubStr</tt>. As shown in the following, it indicates that a string 
0411      * derived from the pattern match is used in the replacement.</p>
0412      * <ul>
0413      * <li>$1, $2, ..., $99 The text that matched the 1st through 99th parenthesized 
0414      * subexpression within <tt>regexp</tt></li>
0415      * <li>$& The substring that matched <tt>regexp</tt></li>
0416      * <li>$' The text to the left of the matched substring</li>
0417      * <li>$' The text to the right of the matched substring</li>
0418      * <li>$$ A literal dollar sign</li>
0419      * </ul>
0420      * @param args An array of arguments:<ul><li><tt>
0421      * regexp</tt>, The RegExp object that specifies the pattern to be replaced</li><li><tt>
0422      * newSubStr</tt>, A string that specifies the replacement text</li></ul>
0423      * @return A new string, with the first match, or all matches, of <tt>regexp</tt> 
0424      * replaced with the replacement.
0425      * @see #replace(CRegExp, String)
0426      * @see #replace(CRegExp, Function)
0427      * @see #match(CRegExp)
0428      * @see #search(CRegExp)
0429      * @see org.descripter.js.api.Script#re(String)
0430      * @see org.descripter.js.api.Script#re(String, String)
0431      * @see CRegExp#exec(Object)
0432      * @see CRegExp#test(Object)
0433      * @since Descripter 1.0
0434      */
0435     public final String replace(CArray args) {
0436         CRegExp regexp = (CRegExp)args.get(0);
0437         Object arg = args.get(1);
0438         if (arg instanceof Function<?>) {
0439             return replace(regexp, (Function<?>)arg);
0440         }
0441         return replace(regexp, toString(arg));
0442     }
0443 
0444     /**
0445      * <p>Performs a search-and-replace operation on the current string.</p>
0446      * <p>This invocation searches the current string for one or more substrings that 
0447      * match <tt>regexp</tt> and replaces them with the replacement string 
0448      * <tt>newSubStr</tt>.</p>
0449      * <p>If <tt>regexp</tt> has the global "g" attribute specified, this invocation 
0450      * replaces all matching substrings. Otherwise, it replaces only the first matching 
0451      * substring.</p>
0452      * <p>Note that the $ character has special meaning within the replacement string 
0453      * <tt>newSubStr</tt>. As shown in the following, it indicates that a string 
0454      * derived from the pattern match is used in the replacement.</p>
0455      * <ul>
0456      * <li>$1, $2, ..., $99 The text that matched the 1st through 99th parenthesized 
0457      * subexpression within <tt>regexp</tt></li>
0458      * <li>$& The substring that matched <tt>regexp</tt></li>
0459      * <li>$' The text to the left of the matched substring</li>
0460      * <li>$' The text to the right of the matched substring</li>
0461      * <li>$$ A literal dollar sign</li>
0462      * </ul>
0463      * @param regexp The RegExp object that specifies the pattern to be replaced
0464      * @param newSubStr A string that specifies the replacement text
0465      * @return A new string, with the first match, or all matches, of <tt>regexp</tt> 
0466      * replaced with the replacement.
0467      * @see #replace(CArray)
0468      * @see #replace(CRegExp, String)
0469      * @see #replace(CRegExp, Function)
0470      * @see #match(CRegExp)
0471      * @see #search(CRegExp)
0472      * @see org.descripter.js.api.Script#re(String)
0473      * @see org.descripter.js.api.Script#re(String, String)
0474      * @see CRegExp#exec(Object)
0475      * @see CRegExp#test(Object)
0476      * @since Descripter 1.0
0477      */
0478     public final String replace(CRegExp regexp, String newSubStr) {
0479         Matcher m = regexp.pattern().matcher(value);
0480         return regexp.global() ? m.replaceAll(newSubStr) : m.replaceFirst(newSubStr);
0481     }
0482 
0483     /**
0484      * <p>Performs a search-and-replace operation on the current string.</p>
0485      * <p>This invocation searches the current string for one or more substrings that 
0486      * match <tt>regexp</tt> and replaces them with the replacement string generated by 
0487      * <tt>lambda</tt>.</p>
0488      * <p>If <tt>regexp</tt> has the global "g" attribute specified, this invocation 
0489      * replaces all matching substrings. Otherwise, it replaces only the first matching 
0490      * substring.</p>
0491      * @param regexp The RegExp object that specifies the pattern to be replaced
0492      * @param lambda A function that is invoked to generate the replacement text
0493      * @return A new string, with the first match, or all matches, of <tt>regexp</tt> 
0494      * replaced with the replacement.
0495      * @see #replace(CArray)
0496      * @see #replace(CRegExp, String)
0497      * @see #match(CRegExp)
0498      * @see #search(CRegExp)
0499      * @see org.descripter.js.api.Script#re(String)
0500      * @see org.descripter.js.api.Script#re(String, String)
0501      * @see CRegExp#exec(Object)
0502      * @see CRegExp#test(Object)
0503      * @since Descripter 1.0
0504      */
0505     public final String replace(CRegExp regexp, Function<?> lambda) {
0506         return replace(regexp, toString(core().call(lambda)));
0507     }
0508 
0509     /**
0510      * <p>Looks for a substring matching <tt>regexp</tt> within the current string 
0511      * and returns the position of the first character of the matching substring, 
0512      * or -1 if no match was found.</p>
0513      * <p>This invocation does not do global matches; it ignores the "g" flag of 
0514      * <tt>regexp</tt>. It also ignores the <tt>lastIndex</tt> property 
0515      * (see {@link CRegExp#lastIndex()} of 
0516      * <tt>regexp</tt> and always searches from the beginning of the string, which 
0517      * means that it always returns the position of the first match in the string.</p>
0518      * @param regexp A RegExp object that specifies the pattern to be searched for in the current string.
0519      * @return The position of the start of the first substring of the current string 
0520      * that matches <tt>regexp</tt>, or -1 if no match is found.
0521      * @see #replace(CRegExp, String)
0522      * @see #replace(CRegExp, Function)
0523      * @see #match(CRegExp)
0524      * @see org.descripter.js.api.Script#re(String)
0525      * @see org.descripter.js.api.Script#re(String, String)
0526      * @see CRegExp#exec(Object)
0527      * @see CRegExp#test(Object)
0528      * @since Descripter 1.0
0529      */
0530     public final int search(CRegExp regexp) {
0531         Matcher m = regexp.pattern().matcher(value);
0532         boolean res = m.find();
0533         return res ? m.start() : -1;
0534     }
0535 
0536     /**
0537      * <p>Returns a string containing a slice, or substring, of the current string without 
0538      * modify it.</p>
0539      * @param args An array of arguments:<ul><li><tt>
0540      * begin</tt>, The string index where the slice is to begin. If negative, this argument 
0541      * specifies a position measured from the end of the string. That is, -1 indicates the 
0542      * last character, -2 indicates the second from last character, and so on.</li><li><tt>
0543      * end</tt>, The string index immediately after the end of the slice. If undefined, 
0544      * the slice includes all characters from <tt>begin</tt> to the end of the string. 
0545      * If this argument is negative, it specifies a position measured from the end of the 
0546      * string.</li></ul>
0547      * @return A new string that contains all the characters of string from and including 
0548      * <tt>begin</tt>, and up to but not including <tt>end</tt>.
0549      * @see #slice(Object)
0550      * @see #slice(Object, Object)
0551      * @see #substr(CArray)
0552      * @see #substr(Object)
0553      * @see #substr(Object, Object)
0554      * @see #substring(CArray)
0555      * @see #substring(Object)
0556      * @see #substring(Object, Object)
0557      * @see CArray#slice(CArray)
0558      * @see CArray#slice(int)
0559      * @see CArray#slice(int, int)
0560      * @since Descripter 1.0
0561      */
0562     public final String slice(CArray args) {
0563         if (args.length() > 1) {
0564             return slice(args.get(0), args.get(1));
0565         }
0566         return slice(args.get(0));
0567     }
0568 
0569     /**
0570      * <p>Returns a string containing a slice, or substring, of the current string without 
0571      * modify it.</p>
0572      * @param begin The string index where the slice is to begin. If negative, this argument 
0573      * specifies a position measured from the end of the string. That is, -1 indicates the 
0574      * last character, -2 indicates the second from last character, and so on.
0575      * @return A new string that contains all the characters of string from and including 
0576      * <tt>begin</tt>.
0577      * @see #slice(CArray)
0578      * @see #slice(Object, Object)
0579      * @see #substr(CArray)
0580      * @see #substr(Object)
0581      * @see #substr(Object, Object)
0582      * @see #substring(CArray)
0583      * @see #substring(Object)
0584      * @see #substring(Object, Object)
0585      * @see CArray#slice(CArray)
0586      * @see CArray#slice(int)
0587      * @see CArray#slice(int, int)
0588      * @since Descripter 1.0
0589      */
0590     public final String slice(Object begin) {
0591         int from = intValue(begin);
0592         from = from < 0 ? length() + from : from;
0593         return value.substring(from);
0594     }
0595 
0596     /**
0597      * <p>Returns a string containing a slice, or substring, of the current string without 
0598      * modify it.</p>
0599      * @param begin The string index where the slice is to begin. If negative, this argument 
0600      * specifies a position measured from the end of the string. That is, -1 indicates the 
0601      * last character, -2 indicates the second from last character, and so on.
0602      * @param end The string index immediately after the end of the slice. If undefined, 
0603      * the slice includes all characters from <tt>begin</tt> to the end of the string. 
0604      * If this argument is negative, it specifies a position measured from the end of the 
0605      * string.
0606      * @return A new string that contains all the characters of string from and including 
0607      * <tt>begin</tt>, and up to but not including <tt>end</tt>.
0608      * @see #slice(CArray)
0609      * @see #slice(Object)
0610      * @see #substr(CArray)
0611      * @see #substr(Object)
0612      * @see #substr(Object, Object)
0613      * @see #substring(CArray)
0614      * @see #substring(Object)
0615      * @see #substring(Object, Object)
0616      * @see CArray#slice(CArray)
0617      * @see CArray#slice(int)
0618      * @see CArray#slice(int, int)
0619      * @since Descripter 1.0
0620      */
0621     public final String slice(Object begin, Object end) {
0622         int length = length();
0623         int from = intValue(begin);
0624         from = from < 0 ? length + from : from;
0625         int to = intValue(end);
0626         to = to == 0 ? length : to < 0 ? to + length : to;
0627         return value.substring(from, to);
0628     }
0629 
0630     /**
0631      * <p>Creates and returns an array of as many as <tt>limit</tt> substrings of the 
0632      * current string. These substrings are created by searching the string from start to 
0633      * end for text that matches <tt>separator</tt> and breaking the string before and 
0634      * after that matching text. The <tt>separator</tt> text is not included in any of 
0635      * the returned substrings, except as noted at the end of this section. Note that if 
0636      * the <tt>separator</tt> matches the beginning of the string, the first element 
0637      * of the returned array will be an empty string, the text that appears before the 
0638      * <tt>separator</tt>. Similarly, if the <tt>separator</tt> matches the end of 
0639      * the string, the last element of the array (assuming no conflicting <tt>limit</tt>) 
0640      * will be the empty string.</p>
0641      * <p>If <tt>separator</tt> is undefined, the current string is not split at all, 
0642      * and the returned array contains only a single, unbroken string element. If 
0643      * <tt>separator</tt> is the empty string or a regular expression that matches 
0644      * the empty string, the string is broken between each character, and the returned 
0645      * array has the same length as the string does, assuming no smaller <tt>limit</tt> 
0646      * is specified. Note that this is a special case because the empty strings before 
0647      * the first character and after the last character are not matched.</p>
0648      * <p>As noted earlier, the substrings in the array returned by this invocation do not 
0649      * contain the delimiting text <tt>separator</tt> used to split the string. However, 
0650      * if <tt>separator</tt> is a regular expression that contains parenthesized 
0651      * subexpressions, the substrings that match those parenthesized subexpressions 
0652      * (but not the text that matches the regular expression as a whole) are included in 
0653      * the returned array.</p>
0654      * <p>Note that this method is the inverse of the {@link CArray#join()} or 
0655      * {@link CArray#join(String)} method.</p>
0656      * @param args An array of arguments:<ul><li><tt>
0657      * separator</tt>, The string or regular expression at which the current string splits.</li><li><tt>
0658      * limit</tt>, This optional integer specifies the maximum length of the returned 
0659      * array. If defined, no more than this number of substrings will be returned. 
0660      * If undefined, the entire string will be split, regardless of its length.</li></ul>
0661      * @return An array of strings, created by splitting string into substrings at the 
0662      * boundaries specified by <tt>separator</tt>. The substrings in the returned 
0663      * array do not include <tt>separator</tt> itself, except in the case noted in the 
0664      * above description.
0665      * @see #split(Object)
0666      * @see #split(Object, Object)
0667      * @see CArray#join()
0668      * @see CArray#join(String)
0669      * @since Descripter 1.0
0670      */
0671     public final CArray split(CArray args) {
0672         if (args.length() > 1) {
0673             return split(args.get(0), args.get(1));
0674         }
0675         return split(args.get(0));
0676     }
0677 
0678     /**
0679      * <p>Creates and returns an array of substrings of the current string. These 
0680      * substrings are created by searching the string from start to end for text that 
0681      * matches <tt>separator</tt> and breaking the string before and after that 
0682      * matching text. The <tt>separator</tt> text is not included in any of the 
0683      * returned substrings, except as noted at the end of this section. Note that if the 
0684      * <tt>separator</tt> matches the beginning of the string, the first element of 
0685      * the returned array will be an empty string, the text that appears before the 
0686      * <tt>separator</tt>. Similarly, if the <tt>separator</tt> matches the end of 
0687      * the string, the last element of the array will be the empty string.</p>
0688      * <p>If <tt>separator</tt> is undefined, the current string is not split at all, 
0689      * and the returned array contains only a single, unbroken string element. If 
0690      * <tt>separator</tt> is the empty string or a regular expression that matches 
0691      * the empty string, the string is broken between each character, and the returned 
0692      * array has the same length as the string does. Note that this is a special case 
0693      * because the empty strings before the first character and after the last character 
0694      * are not matched.</p>
0695      * <p>As noted earlier, the substrings in the array returned by this invocation do not 
0696      * contain the delimiting text <tt>separator</tt> used to split the string. However, 
0697      * if <tt>separator</tt> is a regular expression that contains parenthesized 
0698      * subexpressions, the substrings that match those parenthesized subexpressions 
0699      * (but not the text that matches the regular expression as a whole) are included in 
0700      * the returned array.</p>
0701      * <p>Note that this method is the inverse of the {@link CArray#join()} or 
0702      * {@link CArray#join(String)} method.</p>
0703      * @param separator The string or regular expression at which the current string splits.
0704      * @return An array of strings, created by splitting string into substrings at the 
0705      * boundaries specified by <tt>separator</tt>. The substrings in the returned 
0706      * array do not include <tt>separator</tt> itself, except in the case noted in the 
0707      * above description.
0708      * @see #split(CArray)
0709      * @see #split(Object, Object)
0710      * @see CArray#join()
0711      * @see CArray#join(String)
0712      * @since Descripter 1.0
0713      */
0714     public final CArray split(Object separator) {
0715         separator = valueOf(separator);
0716         return separator instanceof CRegExp ?
0717                 core().array((Object[])((CRegExp)separator).pattern().split(value)) :
0718                 core().array((Object[])value.split(toString(separator)));
0719     }
0720 
0721     /**
0722      * <p>Creates and returns an array of as many as <tt>limit</tt> substrings of the 
0723      * current string. These substrings are created by searching the string from start to 
0724      * end for text that matches <tt>separator</tt> and breaking the string before and 
0725      * after that matching text. The <tt>separator</tt> text is not included in any of 
0726      * the returned substrings, except as noted at the end of this section. Note that if 
0727      * the <tt>separator</tt> matches the beginning of the string, the first element 
0728      * of the returned array will be an empty string, the text that appears before the 
0729      * <tt>separator</tt>. Similarly, if the <tt>separator</tt> matches the end of 
0730      * the string, the last element of the array (assuming no conflicting <tt>limit</tt>) 
0731      * will be the empty string.</p>
0732      * <p>If <tt>separator</tt> is undefined, the current string is not split at all, 
0733      * and the returned array contains only a single, unbroken string element. If 
0734      * <tt>separator</tt> is the empty string or a regular expression that matches 
0735      * the empty string, the string is broken between each character, and the returned 
0736      * array has the same length as the string does, assuming no smaller <tt>limit</tt> 
0737      * is specified. Note that this is a special case because the empty strings before 
0738      * the first character and after the last character are not matched.</p>
0739      * <p>As noted earlier, the substrings in the array returned by this invocation do not 
0740      * contain the delimiting text <tt>separator</tt> used to split the string. However, 
0741      * if <tt>separator</tt> is a regular expression that contains parenthesized 
0742      * subexpressions, the substrings that match those parenthesized subexpressions 
0743      * (but not the text that matches the regular expression as a whole) are included in 
0744      * the returned array.</p>
0745      * <p>Note that this method is the inverse of the {@link CArray#join()} or 
0746      * {@link CArray#join(String)} method.</p>
0747      * @param separator The string or regular expression at which the current string splits.
0748      * @param limit This optional integer specifies the maximum length of the returned 
0749      * array. If defined, no more than this number of substrings will be returned. 
0750      * If undefined, the entire string will be split, regardless of its length.
0751      * @return An array of strings, created by splitting string into substrings at the 
0752      * boundaries specified by <tt>separator</tt>. The substrings in the returned 
0753      * array do not include <tt>separator</tt> itself, except in the case noted in the 
0754      * above description.
0755      * @see #split(CArray)
0756      * @see #split(Object)
0757      * @see CArray#join()
0758      * @see CArray#join(String)
0759      * @since Descripter 1.0
0760      */
0761     public final CArray split(Object separator, Object limit) {
0762         int lim = intValue(limit);
0763         separator = valueOf(separator);
0764         return separator instanceof CRegExp ?
0765                 core().array((Object[])((CRegExp)separator).pattern().split(value, lim)) :
0766                 core().array((Object[])value.split(toString(separator), lim));
0767     }
0768 
0769     /**
0770      * <p>Extracts and returns a substring of the current string without modifying it.</p>
0771      * <p>Note this method specifies the desired substring with a character position and a 
0772      * <tt>length</tt>. This provides a useful alternative to 
0773      * {@link #substring(Object, Object)}, which specify a substring with two 
0774      * character positions. Note, however, that this method has not been standardized by 
0775      * ECMAScript and is therefore deprecated</p>
0776      * @param args An array of arguments:<ul><li><tt>
0777      * start</tt>, The start position of the substring. If this argument is negative, it 
0778      * specifies a position measured from the end of the string: -1 specifies the last character, 
0779      * -2 specifies the second-to-last character, and so on.</li><li><tt>
0780      * length</tt>, The number of characters in the substring. If this argument is undefined, 
0781      * the returned substring includes all characters from the starting position to the end of 
0782      * the string.</li></ul>
0783      * @return A copy of the portion of the current string starting at and including the character 
0784      * specified by <tt>start</tt> and continuing for <tt>length</tt> characters, 
0785      * or to the end of the string if <tt>length</tt> is undefined.
0786      * @see #substr(Object)
0787      * @see #substr(Object, Object)
0788      * @see #slice(CArray)
0789      * @see #slice(Object)
0790      * @see #slice(Object, Object)
0791      * @see #substring(CArray)
0792      * @see #substring(Object)
0793      * @see #substring(Object, Object)
0794      * @since Descripter 1.0
0795      */
0796     public final String substr(CArray args) {
0797         if (args.length() > 1) {
0798             return substr(args.get(0), args.get(1));
0799         }
0800         return substr(args.get(0));
0801     }
0802 
0803     /**
0804      * <p>Extracts and returns a substring of the current string without modifying it.</p>
0805      * <p>Note that this method has not been standardized by ECMAScript and is therefore 
0806      * deprecated</p>
0807      * @param start The start position of the substring. If this argument is negative, it 
0808      * specifies a position measured from the end of the string: -1 specifies the last character, 
0809      * -2 specifies the second-to-last character, and so on.
0810      * @return A copy of the portion of the current string starting at and including the character 
0811      * specified by <tt>start</tt> to the end of the string.
0812      * @see #substr(CArray)
0813      * @see #substr(Object, Object)
0814      * @see #slice(CArray)
0815      * @see #slice(Object)
0816      * @see #slice(Object, Object)
0817      * @see #substring(CArray)
0818      * @see #substring(Object)
0819      * @see #substring(Object, Object)
0820      * @since Descripter 1.0
0821      */
0822     public final String substr(Object start) {
0823         int from = intValue(start);
0824         from = from < 0 ? length() + from : from;
0825         return value.substring(from);
0826     }
0827 
0828     /**
0829      * <p>Extracts and returns a substring of the current string without modifying it.</p>
0830      * <p>Note this method specifies the desired substring with a character position and a 
0831      * <tt>length</tt>. This provides a useful alternative to 
0832      * {@link #substring(Object, Object)}, which specify a substring with two 
0833      * character positions. Note, however, that this method has not been standardized by 
0834      * ECMAScript and is therefore deprecated</p>
0835      * @param start The start position of the substring. If this argument is negative, it 
0836      * specifies a position measured from the end of the string: -1 specifies the last character, 
0837      * -2 specifies the second-to-last character, and so on.
0838      * @param length The number of characters in the substring. If this argument is undefined, 
0839      * the returned substring includes all characters from the starting position to the end of 
0840      * the string.
0841      * @return A copy of the portion of the current string starting at and including the character 
0842      * specified by <tt>start</tt> and continuing for <tt>length</tt> characters, 
0843      * or to the end of the string if <tt>length</tt> is undefined.
0844      * @see #substr(CArray)
0845      * @see #substr(Object)
0846      * @see #slice(CArray)
0847      * @see #slice(Object)
0848      * @see #slice(Object, Object)
0849      * @see #substring(CArray)
0850      * @see #substring(Object)
0851      * @see #substring(Object, Object)
0852      * @since Descripter 1.0
0853      */
0854     public final String substr(Object start, Object length) {
0855         int from = intValue(start);
0856         from = from < 0 ? length() + from : from;
0857         int to = from + intValue(length);
0858         return value.substring(from, to);
0859     }
0860 
0861     /**
0862      * <p>Returns a substring of the current string consisting of the characters between 
0863      * positions <tt>from</tt> and <tt>to</tt>. The character at position <tt>from</tt> 
0864      * is included, but the character at position <tt>to</tt> is not included.</p>
0865      * <p>If <tt>from</tt> equals <tt>to</tt>, this method returns an empty 
0866      * (length 0) string. If <tt>from</tt> is greater than <tt>to</tt>, this method 
0867      * first swaps the two arguments and then returns the substring between them.</p>
0868      * <p>It is important to remember that the character at position <tt>from</tt> is 
0869      * included in the substring but that the character at position <tt>to</tt> is 
0870      * not included in the substring. While this may seem arbitrary or counter-intuitive, 
0871      * a notable feature of this system is that the length of the returned substring is 
0872      * always equal to <tt>to - from</tt>.</p>
0873      * <p>Note that {@link #slice(Object, Object)} and the nonstandard 
0874      * {@link #substr(Object, Object)} can also extract substrings from a string. 
0875      * Unlike those methods, this method does not accept negative arguments.</p>
0876      * @param args An array of arguments:<ul><li><tt>
0877      * from</tt>, A nonnegative integer that specifies the position within the current 
0878      * string of the first character of the desired substring.</li><li><tt>
0879      * to</tt>, A nonnegative optional integer that is one greater than the position of 
0880      * the last character of the desired substring. If this argument is undefined, the 
0881      * returned substring runs to the end of the string.</li></ul>
0882      * @return A new string, of length <tt>to - from</tt>, which contains a substring 
0883      * of the current string. The new string contains characters copied from positions 
0884      * <tt>from</tt> to <tt>to</tt> - 1 of the string.
0885      * @see #substring(Object)
0886      * @see #substring(Object, Object)
0887      * @see #charAt(Object)
0888      * @see #indexOf(CArray)
0889      * @see #indexOf(Object)
0890      * @see #indexOf(Object, Object)
0891      * @see #lastIndexOf(CArray)
0892      * @see #lastIndexOf(Object)
0893      * @see #lastIndexOf(Object, Object)
0894      * @see #slice(CArray)
0895      * @see #slice(Object)
0896      * @see #slice(Object, Object)
0897      * @see #substr(CArray)
0898      * @see #substr(Object)
0899      * @see #substr(Object, Object)
0900      * @since Descripter 1.0
0901      */
0902     public final String substring(CArray args) {
0903         if (args.length() > 1) {
0904             return substring(args.get(0), args.get(1));
0905         }
0906         return substring(args.get(0));
0907     }
0908 
0909     /**
0910      * <p>Returns a substring of the current string consisting of the characters from 
0911      * position <tt>from</tt> to the end of the string. The character at position 
0912      * <tt>from</tt> is included.</p>
0913      * <p>It is important to remember that the character at position <tt>from</tt> is 
0914      * included in the substring.</p>
0915      * <p>Note that {@link #slice(Object)} and the nonstandard 
0916      * {@link #substr(Object)} can also extract substrings from a string. 
0917      * Unlike those methods, this method does not accept negative arguments.</p>
0918      * @param from A nonnegative integer that specifies the position within the current 
0919      * string of the first character of the desired substring.
0920      * @return  A substring of the current string containing characters copied from 
0921      * position <tt>from</tt> to the end of the current string.
0922      * @see #substring(CArray)
0923      * @see #substring(Object, Object)
0924      * @see #charAt(Object)
0925      * @see #indexOf(CArray)
0926      * @see #indexOf(Object)
0927      * @see #indexOf(Object, Object)
0928      * @see #lastIndexOf(CArray)
0929      * @see #lastIndexOf(Object)
0930      * @see #lastIndexOf(Object, Object)
0931      * @see #slice(CArray)
0932      * @see #slice(Object)
0933      * @see #slice(Object, Object)
0934      * @see #substr(CArray)
0935      * @see #substr(Object)
0936      * @see #substr(Object, Object)
0937      * @since Descripter 1.0
0938      */
0939     public final String substring(Object from) {
0940         return value.substring(intValue(from));
0941     }
0942 
0943     /**
0944      * <p>Returns a substring of the current string consisting of the characters between 
0945      * positions <tt>from</tt> and <tt>to</tt>. The character at position <tt>from</tt> 
0946      * is included, but the character at position <tt>to</tt> is not included.</p>
0947      * <p>If <tt>from</tt> equals <tt>to</tt>, this method returns an empty 
0948      * (length 0) string. If <tt>from</tt> is greater than <tt>to</tt>, this method 
0949      * first swaps the two arguments and then returns the substring between them.</p>
0950      * <p>It is important to remember that the character at position <tt>from</tt> is 
0951      * included in the substring but that the character at position <tt>to</tt> is 
0952      * not included in the substring. While this may seem arbitrary or counter-intuitive, 
0953      * a notable feature of this system is that the length of the returned substring is 
0954      * always equal to <tt>to - from</tt>.</p>
0955      * <p>Note that {@link #slice(Object, Object)} and the nonstandard 
0956      * {@link #substr(Object, Object)} can also extract substrings from a string. 
0957      * Unlike those methods, this method does not accept negative arguments.</p>
0958      * @param from A nonnegative integer that specifies the position within the current 
0959      * string of the first character of the desired substring.
0960      * @param to A nonnegative optional integer that is one greater than the position of 
0961      * the last character of the desired substring. If this argument is undefined, the 
0962      * returned substring runs to the end of the string.
0963      * @return A new string, of length <tt>to - from</tt>, which contains a substring 
0964      * of the current string. The new string contains characters copied from positions 
0965      * <tt>from</tt> to <tt>to</tt> - 1 of the string.
0966      * @see #substring(CArray)
0967      * @see #substring(Object)
0968      * @see #charAt(Object)
0969      * @see #indexOf(CArray)
0970      * @see #indexOf(Object)
0971      * @see #indexOf(Object, Object)
0972      * @see #lastIndexOf(CArray)
0973      * @see #lastIndexOf(Object)
0974      * @see #lastIndexOf(Object, Object)
0975      * @see #slice(CArray)
0976      * @see #slice(Object)
0977      * @see #slice(Object, Object)
0978      * @see #substr(CArray)
0979      * @see #substr(Object)
0980      * @see #substr(Object, Object)
0981      * @since Descripter 1.0
0982      */
0983     public final String substring(Object from, Object to) {
0984         return value.substring(
0985                 intValue(from),
0986                 intValue(to  )
0987         );
0988     }
0989 
0990     /**
0991      * <p>Converts the current object instance to a string, localized as appropriate 
0992      * for the current locale.</p>
0993      * @return A string representing the current object instance, localized as 
0994      * appropriate for the current locale.
0995      * @since Descripter 1.0
0996      */
0997     @Override
0998     public final String toLocaleString() {
0999         return value.toString();
1000     }
1001 
1002     /**
1003      * <p>Returns a copy of the current string, converted to lower-case letters in a 
1004      * locale-specific way. Only a few languages, such as Turkish, have locale-specific 
1005      * case mappings, so this method usually returns the same value as 
1006      * {@link #toLowerCase()}.</p>
1007      * @return A copy of the current string, converted to lower-case letters in a 
1008      * locale-specific way.
1009      * @see #toLocaleUpperCase()
1010      * @see #toLowerCase()
1011      * @see #toUpperCase()
1012      * @since Descripter 1.0
1013      */
1014     public final String toLocaleLowerCase() {
1015         return value.toLowerCase();
1016     }
1017 
1018     /**
1019      * <p>Returns a copy of the current string, converted to upper-case letters in a 
1020      * locale-specific way. Only a few languages, such as Turkish, have locale-specific 
1021      * case mappings, so this method usually returns the same value as 
1022      * {@link #toUpperCase()}.</p>
1023      * @return A copy of the current string, converted to upper-case letters in a 
1024      * locale-specific way.
1025      * @see #toLocaleLowerCase()
1026      * @see #toLowerCase()
1027      * @see #toUpperCase()
1028      * @since Descripter 1.0
1029      */
1030     public final String toLocaleUpperCase() {
1031         return value.toUpperCase();
1032     }
1033 
1034     /**
1035      * <p>Returns a copy of string, with each upper-case letter converted to its lower-case 
1036      * equivalent, if it has one.</p>
1037      * @return A copy of string, with each upper-case letter converted to its lower-case 
1038      * equivalent, if it has one.
1039      * @see #toLocaleLowerCase()
1040      * @see #toLocaleUpperCase()
1041      * @see #toUpperCase()
1042      * @since Descripter 1.0
1043      */
1044     public final String toLowerCase() {
1045         return value.toLowerCase(Locale.ENGLISH);
1046     }
1047 
1048     /**
1049      * <p>Returns a copy of string, with each lower-case letter converted to its upper-case 
1050      * equivalent, if it has one.</p>
1051      * @return A copy of string, with each lower-case letter converted to its upper-case 
1052      * equivalent, if it has one.
1053      * @see #toLocaleLowerCase()
1054      * @see #toLocaleUpperCase()
1055      * @see #toLowerCase()
1056      * @since Descripter 1.0
1057      */
1058     public final String toUpperCase() {
1059         return value.toUpperCase(Locale.ENGLISH);
1060     }
1061 
1062     /**
1063      * <p>Returns a string representation of the current object.</p>
1064      * @return The string representation of the current object
1065      * @since Descripter 1.0
1066      */
1067     @Override
1068     public final String toString() {
1069         return value.toString();
1070     }
1071 
1072     /**
1073      * <p>Returns the primitive value associated with this object, if there is one. </p>
1074      * @return The primitive value associated with this object, if there is one, or this object itself.
1075      * @since Descripter 1.0
1076      */
1077     @Override
1078     public final String valueOf() {
1079         return value;
1080     }
1081 }