0001 
0002 /*
0003  *  JScripter Simulation 1.0 - For Java To Script
0004  *  Copyright (C) 2008-2011  J.J.Liu<jianjunliu@126.com> <http://www.jscripter.org>
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.jscripter.sim;
0021 
0022 import java.io.UnsupportedEncodingException;
0023 import java.net.URLDecoder;
0024 import java.net.URLEncoder;
0025 import java.util.Iterator;
0026 
0027 import javax.swing.JOptionPane;
0028 
0029 import js.*;
0030 import js.core.*;
0031 import js.user.JsXMLHttpRequest;
0032 import jsx.client.Browser;
0033 import jsx.core.ArrayLikes;
0034 
0035 /**
0036  * <p>An abstract <b>internal</b> class for JS Simulation.</p>
0037  * <p>This <b>internal</b> class is only extended internally in JS Simulation Library.</p>
0038  *
0039  * @author <a href="mailto:jianjunliu@126.com">J.J.Liu (Jianjun Liu)</a> at <a href="http://www.jscripter.org" target="_blank">http://www.jscripter.org</a>
0040  * 
0041  * @javascript Re-compilers must report error on resolving an <tt>internal</tt> class. 
0042  */
0043 public abstract class Simul extends Sim
0044 {
0045     /**
0046      * <p>Internally constructs a JS Simulation.</p>
0047      * @since 1.0
0048      * 
0049      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> constructor. 
0050      */
0051     protected Simul() {}
0052 
0053     /**
0054      * <p>Internally checks if the simulation is limited to JavaScript core features only.</p>
0055      * @return <tt>true</tt> if this is a core simulation; <tt>false</tt>, otherwise;
0056      * @since 1.0
0057      * 
0058      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0059      */
0060     protected abstract boolean isCore();
0061 
0062     /**
0063      * <p>Displays a simple message in a dialog box.</p>
0064      * <p>In JavaScript, this method displays the specified <tt>message</tt> to the 
0065      * user in a dialog box. The dialog box contains an OK button the user can click to 
0066      * dismiss it. The dialog box is typically modal, and the call to this function 
0067      * typically blocks until the dialog is dismissed.</p>
0068      * <p>Perhaps the most common use of this method is to display error messages when the 
0069      * user's input to some form element is invalid in some way. The alert dialog box can 
0070      * inform the user of the problem and explain what needs to be corrected to avoid the 
0071      * problem in the future</p>
0072      * <p>The appearance of the dialog box is platform-dependent, but it generally contains 
0073      * graphics that indicate an error, warning, or alert message of some kind. While it can 
0074      * display any desired message, the alert graphics of the dialog box mean that this 
0075      * method is not appropriate for simple informational messages like "Welcome to my blog"</p>
0076      * <p>Note that the <tt>message</tt> displayed in the dialog box is a string of 
0077      * plain text, not formatted HTML. You can use the newline character "\n" in your strings 
0078      * to break your message across multiple lines. You can also do some rudimentary 
0079      * formatting using spaces and can approximate horizontal rules with underscore characters, 
0080      * but the results depend greatly on the font used in the dialog box and thus are 
0081      * system-dependent.</p>
0082      * @param message The plain-text (not HTML) string to display in a dialog box popped up 
0083      * over the current window.
0084      * @see Js#alert(Object)
0085      * @see jsx.client.Global#alert(Object)
0086      * @see jsx.client.Client#alert(Object)
0087      * @since 1.0
0088      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0089      */
0090     @Override
0091     protected void alert(Object message) {
0092         JOptionPane.showMessageDialog(
0093                 null,
0094                 Js.toString(message),
0095                 "[JavaJavaScript Application]",
0096                 JOptionPane.WARNING_MESSAGE
0097         );
0098     }
0099 
0100     /**
0101      * <p>Asks a yes-or-no question with a dialog box.</p>
0102      * <p>In JavaScript, this method displays the specified question in a dialog box. The 
0103      * dialog box contains OK and Cancel buttons that the user can use to answer the 
0104      * question. If the user clicks the OK button, it returns <tt>true</tt>. If the 
0105      * user clicks Cancel, it returns <tt>false</tt>.</p>
0106      * <p>The dialog box that is displayed by the this method is modal. That is, it blocks 
0107      * all user input to the main browser window until the user dismisses the dialog box 
0108      * by clicking on the OK or Cancel buttons. Since this method returns a value depending 
0109      * on the user's response to the dialog box, JavaScript execution pauses in the call to 
0110      * this method, and subsequent statements are not executed until the user responds to 
0111      * the dialog box.</p>
0112      * <p>There is no way to change the labels that appear in the buttons of the dialog box 
0113      * (to make them read Yes and No, for example). Therefore, you should take care to 
0114      * phrase your question or message so that OK and Cancel are suitable responses.</p>
0115      * @param question The plain-text (not HTML) string to be displayed in the dialog box. 
0116      * It should generally express a question you want the user to answer.
0117      * @return <tt>true</tt> if the user clicks the OK button; <tt>false</tt> if 
0118      * the user clicks the Cancel button.
0119      * @see Js#confirm(Object)
0120      * @see jsx.client.Global#confirm(Object)
0121      * @see jsx.client.Client#confirm(Object)
0122      * @since 1.0
0123      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0124      */
0125     @Override
0126     protected boolean confirm(Object question) {
0127         return JOptionPane.showConfirmDialog(
0128                 null,
0129                 Js.toString(question),
0130                 "[JavaJavaScript Application]",
0131                 JOptionPane.YES_NO_OPTION,
0132                 JOptionPane.QUESTION_MESSAGE
0133         ) == JOptionPane.YES_OPTION;
0134     }
0135 
0136     /**
0137      * <p>Asks for simple string input with a dialog box.</p>
0138      * <p>This method displays text input field and OK and Cancel buttons in a dialog box. 
0139      * Platform-dependent graphics in the dialog box help indicate to the user that an 
0140      * input is desired.</p>
0141      * <p>If the user clicks the Cancel button, the method returns <tt>null</tt>. If 
0142      * the user clicks the OK button, it returns the text currently displayed in the 
0143      * input field.</p>
0144      * <p>The dialog box that is displayed by this method is modal. That is, it blocks all 
0145      * user input to the main browser window until the user dismisses the dialog box by 
0146      * clicking on the OK or Cancel buttons. Since this method returns a value depending 
0147      * on the user's response to the dialog box, JavaScript execution pauses in the call 
0148      * to this method, and subsequent statements are not executed until the user responds 
0149      * to the dialog box.</p>
0150      * @param message The plain-text (not HTML) string to be displayed in the dialog box. 
0151      * It should ask the user to enter the information you want.
0152      * @return The string entered by the user, the empty string if the user did not enter 
0153      * a string, or <tt>null</tt> if the user clicked Cancel.
0154      * @see #prompt(Object, Object)
0155      * @see Js#prompt(Object)
0156      * @see jsx.client.Global#prompt(Object)
0157      * @see jsx.client.Client#prompt(Object)
0158      * @since 1.0
0159      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0160      */
0161     @Override
0162     protected String prompt(Object message) {
0163         return JOptionPane.showInputDialog(
0164                 null,
0165                 Js.toString(message)
0166         );
0167     }
0168 
0169     /**
0170      * <p>Asks for simple string input with a dialog box.</p>
0171      * <p>This method displays the specified message in a dialog box that also contains a 
0172      * text input field and OK and Cancel buttons. Platform-dependent graphics in the 
0173      * dialog box help indicate to the user that an input is desired.</p>
0174      * <p>If the user clicks the Cancel button, the method returns <tt>null</tt>. If 
0175      * the user clicks the OK button, it returns the text currently displayed in the 
0176      * input field.</p>
0177      * <p>The dialog box that is displayed by this method is modal. That is, it blocks all 
0178      * user input to the main browser window until the user dismisses the dialog box by 
0179      * clicking on the OK or Cancel buttons. Since this method returns a value depending 
0180      * on the user's response to the dialog box, JavaScript execution pauses in the call 
0181      * to this method, and subsequent statements are not executed until the user responds 
0182      * to the dialog box.</p>
0183      * @param message The plain-text (not HTML) string to be displayed in the dialog box. 
0184      * It should ask the user to enter the information you want.
0185      * @param defaultInput A string that is displayed as the default input in the dialog 
0186      * box. Pass the empty string ("") to make the method display an empty input box.
0187      * @return The string entered by the user, the empty string if the user did not enter 
0188      * a string, or <tt>null</tt> if the user clicked Cancel.
0189      * @see #prompt(Object)
0190      * @see Js#prompt(Object, Object)
0191      * @see jsx.client.Global#prompt(Object, Object)
0192      * @see jsx.client.Client#prompt(Object, Object)
0193      * @since 1.0
0194      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0195      */
0196     @Override
0197     protected String prompt(Object message, Object defaultInput) {
0198         return JOptionPane.showInputDialog(
0199                 null,
0200                 Js.toString(message),
0201                 Js.toString(defaultInput)
0202         );
0203     }
0204 
0205     /**
0206      * <p>Cancels periodic execution of code.</p>
0207      * <p>This method stops the repeated execution of code that was started by a call to 
0208      * {@link #setInterval(JsFunction, Number)}. <tt>intervalId</tt> must be the value 
0209      * that was returned by a call to {@link #setInterval(JsFunction, Number)}.</p>
0210      * @param intervalId The value returned by the corresponding call to {@link #setInterval(JsFunction, Number)}.
0211      * @see #setInterval(JsFunction, Number)
0212      * @see Js#clearInterval(Object)
0213      * @see jsx.client.Global#clearInterval(Object)
0214      * @see jsx.client.Client#clearInterval(Object)
0215      * @see jsx.Interval
0216      * @since 1.0
0217      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0218      */
0219     @Override
0220     protected final void clearInterval(Object intervalId) {
0221         if (intervalId instanceof Thread) {
0222             ((SimThread)intervalId).clear();
0223         } else if (!isCore()) {
0224             Js.win().clearInterval(intervalId);
0225         }
0226     }
0227 
0228     /**
0229      * <p>Cancels a pending timeout operation.</p>
0230      * <p>This method cancels the execution of code that has been deferred with the 
0231      * {@link #setTimeout(JsFunction, Number)} method. The <tt>timeoutId</tt> argument 
0232      * is a value returned by the call to {@link #setTimeout(JsFunction, Number)} and 
0233      * identifies which deferred code to cancel.</p>
0234      * @param timeoutId A value returned by {@link #setTimeout(JsFunction, Number)} that 
0235      * identifies the timeout to be canceled.
0236      * @see #clearTimeout(Object)
0237      * @see Js#clearTimeout(Object)
0238      * @see jsx.client.Global#clearTimeout(Object)
0239      * @see jsx.client.Client#clearTimeout(Object)
0240      * @see jsx.Timeout
0241      * @since 1.0
0242      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0243      */
0244     @Override
0245     protected final void clearTimeout(Object timeoutId) {
0246         if (timeoutId instanceof Thread) {
0247             ((SimThread)timeoutId).clear();
0248         } else if (!isCore()) {
0249             Js.win().clearTimeout(timeoutId);
0250         }
0251     }
0252 
0253     /**
0254      * <p>Executes code at periodic intervals.</p>
0255      * <p>Note that the specified function is executed in the context of the Window object, 
0256      * that is, the Window object is the value of the <tt>this</tt> keyword of the 
0257      * executing context of the function. This is <tt>true</tt> even if the call to 
0258      * {@link #setTimeout(JsFunction, Number)} occurred within a function with a longer 
0259      * scope chain.</p>
0260      * @param f A function to be periodically invoked.
0261      * @param interval The interval, in milliseconds, between invocations of the function.
0262      * @return A value that can be passed to {@link #clearInterval(Object)} method to 
0263      * cancel the periodic execution of the function.
0264      * @see #clearInterval(Object)
0265      * @see Js#setInterval(JsFunction)
0266      * @see Js#setInterval(JsFunction, Number)
0267      * @see jsx.client.Global#setInterval(JsFunction)
0268      * @see jsx.client.Global#setInterval(JsFunction, Number)
0269      * @see jsx.client.Client#setInterval(JsFunction)
0270      * @see jsx.client.Client#setInterval(JsFunction, Number)
0271      * @see jsx.Interval
0272      * @since 1.0
0273      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0274      */
0275     @Override
0276     protected final Object setInterval(JsFunction<?> f, Number interval) {
0277         if (!isCore()) {
0278             if (Browser.isIE) {
0279                 return interval != null ? Js.win().setInterval(f, interval) : Js.win().setInterval(f, 1);
0280             }
0281         }
0282         return new SimInterval(f, interval);
0283     }
0284 
0285     /**
0286      * <p>Executes code after a specified amount of time elapses.</p>
0287      * <p>Note that this method executes the specified function only once. The function is 
0288      * executed in the context of the Window object, that is, the Window object is the 
0289      * value of the <tt>this</tt> keyword of the executing context of the function. 
0290      * This is <tt>true</tt> even if the call to {@link #setTimeout(JsFunction, Number)} 
0291      * occurred within a function with a longer scope chain.</p>
0292      * @param f A function to be invoked after the <tt>delay</tt> has elapsed.
0293      * @param delay The amount of time, in milliseconds, before the function should be executed.
0294      * @return A value that can be passed to the {@link #clearTimeout(Object)} method to 
0295      * cancel the execution of the function.
0296      * @see #clearTimeout(Object)
0297      * @see Js#setTimeout(JsFunction)
0298      * @see Js#setTimeout(JsFunction, Number)
0299      * @see jsx.client.Global#setTimeout(JsFunction)
0300      * @see jsx.client.Global#setTimeout(JsFunction, Number)
0301      * @see jsx.client.Client#setTimeout(JsFunction)
0302      * @see jsx.client.Client#setTimeout(JsFunction, Number)
0303      * @see jsx.Timeout
0304      * @since 1.0
0305      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0306      */
0307     @Override
0308     protected final Object setTimeout(JsFunction<?> f, Number delay) {
0309         if (!isCore()) {
0310             if (Browser.isIE) {
0311                 return delay != null ? Js.win().setTimeout(f, delay) : Js.win().setTimeout(f, 1);
0312             }
0313         }
0314         return new SimTimeout(f, delay);
0315     }
0316 
0317     /**
0318      * <p>Decodes a string escaped with {@link #encodeURI(Object)}.</p>
0319      * @param s A string that contains an encoded URI or other text to be decoded.
0320      * @return A copy of <tt>s</tt>, with any hexadecimal escape sequences replaced with 
0321      * the characters they represent.
0322      * @throws RuntimeException JavaScript throws a <tt>URIError</tt> if one or more of the 
0323      * escape sequences in <tt>s</tt> is malformed and cannot be correctly decoded. See 
0324      * {@link Js#err(Object)} and {@link js.core.JsURIError} for JS Simulation.
0325      * @see #encodeURI(Object)
0326      * @see Js#decodeURI(Object)
0327      * @see jsx.client.Global#decodeURI(Object)
0328      * @see jsx.client.Client#decodeURI(Object)
0329      * @since 1.0
0330      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0331      */
0332     @Override
0333     protected String decodeURI(Object s) {
0334         String str = Js.toString(s);
0335         if (str == null) {
0336             return null;
0337         }
0338         String res = null;
0339         try {
0340             res = URLDecoder.decode(str, "UTF-8");
0341         } catch (UnsupportedEncodingException e) {
0342             res = str;  
0343         }
0344         return res;
0345     }
0346 
0347     /**
0348      * <p>Decodes a string escaped with {@link #encodeURIComponent(Object)}.</p>
0349      * @param s A string that contains an encoded URI component or other text to be decoded.
0350      * @return A copy of <tt>s</tt>, with any hexadecimal escape sequences replaced 
0351      * with the characters they represent.
0352      * @throws RuntimeException JavaScript throws a <tt>URIError</tt> if one or more of the 
0353      * escape sequences in <tt>s</tt> is malformed and cannot be correctly decoded. See 
0354      * {@link Js#err(Object)} and {@link js.core.JsURIError} for JS Simulation.
0355      * @see #encodeURIComponent(Object)
0356      * @see Js#decodeURIComponent(Object)
0357      * @see jsx.client.Global#decodeURIComponent(Object)
0358      * @see jsx.client.Client#decodeURIComponent(Object)
0359      * @since 1.0
0360      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0361      */
0362     @Override
0363     protected String decodeURIComponent(Object s) {
0364         return decodeURI(s);
0365     }
0366 
0367     /**
0368      * <p>Encodes a URI by escaping certain characters.</p>
0369      * @param uri A string that contains the URI or other text to be encoded.
0370      * @return A copy of <tt>uri</tt>, with any hexadecimal escape sequences replaced 
0371      * with the characters they represent..
0372      * @throws RuntimeException JavaScript throws a <tt>URIError</tt> if <tt>s</tt> 
0373      * contains malformed unicode surrogate pairs and cannot be encoded. See 
0374      * {@link Js#err(Object)} and {@link js.core.JsURIError} for JS Simulation.
0375      * @see #decodeURI(Object)
0376      * @see Js#encodeURI(Object)
0377      * @see jsx.client.Global#encodeURI(Object)
0378      * @see jsx.client.Client#encodeURI(Object)
0379      * @since 1.0
0380      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0381      */
0382     @Override
0383     protected String encodeURI(Object uri) {
0384         String str = Js.toString(uri);
0385         String res = null;
0386         try {
0387             res = URLEncoder.encode(str, "UTF-8");
0388         } catch (UnsupportedEncodingException e) {
0389             res = str;
0390         }
0391         return res;
0392     }
0393 
0394     /**
0395      * <p>Encodes a URI component by escaping certain characters.</p>
0396      * @param uri A string that contains a portion of a URI or other text to be encoded.
0397      * @return The opaque global object with the client-side support.
0398      * @throws RuntimeException JavaScript throws a <tt>URIError</tt> if <tt>s</tt> 
0399      * contains malformed unicode surrogate pairs and cannot be encoded. See 
0400      * {@link Js#err(Object)} and {@link js.core.JsURIError} for JS Simulation.
0401      * @see #decodeURIComponent(Object)
0402      * @see Js#encodeURIComponent(Object)
0403      * @see jsx.client.Global#encodeURIComponent(Object)
0404      * @see jsx.client.Client#encodeURIComponent(Object)
0405      * @since 1.0
0406      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0407      */
0408     @Override
0409     protected String encodeURIComponent(Object uri) {
0410         String str = encodeURI(uri);
0411         return str == null ? null : str.replaceAll("\\+", "%20")
0412                                        .replaceAll("\\%21", "!")
0413                                        .replaceAll("\\%27", "'")
0414                                        .replaceAll("\\%28", "(")
0415                                        .replaceAll("\\%29", ")")
0416                                        .replaceAll("\\%7E", "~");
0417     }
0418 
0419     /**
0420      * <p>Encodes a string by replacing certain characters with escape sequences.</p>
0421      * @param s The string that is to be "escaped" or encoded.
0422      * @return An encoded copy of <tt>s</tt> in which certain characters have been 
0423      * replaced by hexadecimal escape sequences.
0424      * @see #unescape(Object)
0425      * @see Js#escape(Object)
0426      * @see jsx.client.Global#escape(Object)
0427      * @see jsx.client.Client#escape(Object)
0428      * @since 1.0
0429      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0430      */
0431     @Override
0432     protected String escape(Object s) {
0433         String str = Js.toString(s);
0434         StringBuilder sb = new StringBuilder();   
0435         sb.ensureCapacity(str.length() * 6);   
0436         for (int i = 0; i < str.length(); i++) {   
0437             char c = str.charAt(i);   
0438             if (Character.isDigit(c) ||
0439                 Character.isLowerCase(c) ||
0440                 Character.isUpperCase(c)) {   
0441                 sb.append(c);   
0442             } else if (c < 256) {   
0443                 sb.append("%");   
0444                 if (c < 16) {
0445                     sb.append("0");   
0446                 }
0447                 sb.append(Integer.toString(c, 16));   
0448             } else {   
0449                 sb.append("%u");   
0450                 sb.append(Integer.toString(c, 16));   
0451             }   
0452         }   
0453         return sb.toString();   
0454     }
0455 
0456     /**
0457      * <p>Decodes a string encoded with {@link #escape(Object)}.</p>
0458      * @param s The string that is to be decoded or "unescaped".
0459      * @return A decoded copy of <tt>s</tt>.
0460      * @see #escape(Object)
0461      * @see Js#unescape(Object)
0462      * @see jsx.client.Global#unescape(Object)
0463      * @see jsx.client.Client#unescape(Object)
0464      * @since 1.0
0465      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0466      */
0467     @Override
0468     protected String unescape(Object s) {
0469         String str = Js.toString(s);
0470         StringBuilder sb = new StringBuilder();   
0471         sb.ensureCapacity(str.length());   
0472         int pos = 0, cur = 0;   
0473         while (pos < str.length()) {   
0474             cur = str.indexOf("%", pos);   
0475             if (cur == pos) {   
0476                 if (str.charAt(cur + 1) == 'u') {   
0477                     sb.append(
0478                             (char)Integer.parseInt(
0479                                     str.substring(cur + 2, cur + 6),
0480                                     16
0481                             )
0482                     );   
0483                     pos = cur + 6;   
0484                 } else {   
0485                     sb.append(
0486                             (char)Integer.parseInt(
0487                                     str.substring(cur + 1, cur + 3),
0488                                     16
0489                             )
0490                     );   
0491                     pos = cur + 3;   
0492                 }   
0493             } else {   
0494                 if (cur == -1) {   
0495                     sb.append(str.substring(pos));   
0496                     pos = str.length();   
0497                 } else {   
0498                     sb.append(str.substring(pos, cur));   
0499                     pos = cur;   
0500                 }   
0501             }   
0502         }   
0503         return sb.toString();   
0504     }
0505 
0506     /**
0507      * <p>Evaluates the argument string as JavaScript code and returns the result.</p>
0508      * <p>In JavaScript, <tt>eval()</tt> is a global method that evaluates a string of 
0509      * JavaScript code in the current lexical scope. If the code contains an expression, 
0510      * eval evaluates the expression and returns its value. If the code contains a 
0511      * JavaScript statement or statements, it executes those statements and returns the 
0512      * value, if any, returned by the last statement. If the code does not return any 
0513      * value, <tt>eval()</tt> returns undefined. Finally, if code throws an exception, 
0514      * <tt>eval()</tt> passes that exception on to the caller.</p>
0515      * <p>The global function <tt>eval()</tt> provides a very powerful capability to 
0516      * the JavaScript language, but its use is infrequent in real-world programs. 
0517      * Obvious uses are to write programs that act as recursive JavaScript interpreters 
0518      * and to write programs that dynamically generate and evaluate JavaScript code.</p>
0519      * <p>Most JavaScript functions and methods that expect string arguments accept 
0520      * arguments of other types as well and simply convert those argument values to 
0521      * strings before proceeding. <tt>eval()</tt> does not behave like this. If the 
0522      * code argument is not a primitive string, it is simply returned unchanged. Be 
0523      * careful, therefore, that you do not inadvertently pass a String object to 
0524      * <tt>eval()</tt> when you intended to pass a primitive string value.</p>
0525      * <p>For purposes of implementation efficiency, the ECMAScript v3 standard places 
0526      * an unusual restriction on the use of <tt>eval()</tt>. An ECMAScript implementation 
0527      * is allowed to throw an <tt>EvalError</tt> exception if you attempt to overwrite 
0528      * the <tt>eval</tt> property or if you assign the <tt>eval()</tt> method to another 
0529      * property and attempt to invoke it through that property.</p>
0530      * @param s A string of JavaScript code.
0531      * @return The return value of the evaluated code, if any.
0532      * @throws RuntimeException JavaScript throws a <tt>SyntaxError</tt> if the argument string 
0533      * does not contain legal JavaScript, a <tt>EvalError</tt> if the <tt>eval</tt> function 
0534      * was called illegally, through an identifier other than "eval", or other JavaScript error 
0535      * generated by the code passed. See {@link Js#err(Object)}, {@link js.core.JsSyntaxError}, 
0536      * {@link js.core.JsEvalError}, and {@link js.core.JsError} for JS Simulation.
0537      * @since 1.0
0538      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0539      */
0540     @Override
0541     public Object eval(Object s) {
0542         return Js.core().eval(s);
0543     }
0544 
0545     /**
0546      * <p>Tests whether a value is a finite number.</p>
0547      * @param v The number to be tested.
0548      * @return <tt>true</tt> if <tt>v</tt> is (or can be converted to) a finite 
0549      * number, or <tt>false</tt> if <tt>v</tt> is <tt>NaN</tt> (not a number) 
0550      * or positive or negative infinity.
0551      * @see Js#isFinite(Object)
0552      * @see jsx.client.Global#isFinite(Object)
0553      * @see jsx.client.Client#isFinite(Object)
0554      * @since 1.0
0555      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0556      */
0557     @Override
0558     protected boolean isFinite(Object v) {
0559         return false;
0560     }
0561 
0562     /**
0563      * <p>Tests whether a value is the not-a-number value.</p>
0564      * <p>In JavaScript, This function tests its argument to determine whether it is the 
0565      * value <tt>NaN</tt>, which represents an illegal number (such as the result of 
0566      * division by zero). This function is required because comparing a <tt>NaN</tt> 
0567      * with any value, including itself, always returns <tt>false</tt>, so it is not 
0568      * possible to test for <tt>NaN</tt> with the == or === operators.</p>
0569      * <p>A common use in JavaScript of this function is to test the results of {@link #parseFloat(Object)} 
0570      * and {@link #parseInt(Object)} to determine if they represent legal numbers. You can 
0571      * also use {@link #isNaN(Object)} to check for arithmetic errors, such as division by 
0572      * zero</p>
0573      * @param v The value to be tested.
0574      * @return <tt>true</tt> if <tt>v</tt> is (or can be converted to) the special 
0575      * not-a-number value; <tt>false</tt> if <tt>v</tt> is any other value.
0576      * @see Js#isNaN(Object)
0577      * @see jsx.client.Global#isNaN(Object)
0578      * @see jsx.client.Client#isNaN(Object)
0579      * @since 1.0
0580      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0581      */
0582     @Override
0583     protected boolean isNaN(Object v) {
0584         return false;
0585     }
0586 
0587     /**
0588      * <p>Parses an integer from a string.</p>
0589      * <p>In JavaScript, this function parses and returns the first number (with an 
0590      * optional leading minus sign) that occurs in <tt>value</tt>. Parsing stops, and 
0591      * the value is returned, when it encounters a character in <tt>value</tt> that is 
0592      * not a valid digit for the specified radix. If <tt>value</tt> does not begin with 
0593      * a number that it can parse, the function returns the not-a-number value <tt>NaN</tt>. 
0594      * Use the {@link #isNaN(Object)} function to test for this return value.</p>
0595      * @param value The string to be parsed.
0596      * @return The parsed number, or <tt>NaN</tt> if <tt>value</tt> does not begin with 
0597      * a valid integer. In JavaScript 1.0, this function returns 0 instead of <tt>NaN</tt> 
0598      * when it cannot parse <tt>value</tt>.
0599      * @see #parseFloat(Object)
0600      * @see #parseInt(Object, int)
0601      * @see Js#parseInt(Object)
0602      * @see jsx.client.Global#parseInt(Object)
0603      * @see jsx.client.Client#parseInt(Object)
0604      * @since 1.0
0605      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0606      */
0607     @Override
0608     protected Integer parseInt(Object value) {
0609         String s = Js.toString(value);
0610         try {
0611             return Integer.parseInt(s);
0612         } catch (NumberFormatException nfe) {
0613             return null;
0614         }
0615     }
0616 
0617     /**
0618      * <p>Parses an integer from a string in a base specified.</p>
0619      * <p>In JavaScript, this function parses and returns the first number (with an 
0620      * optional leading minus sign) that occurs in <tt>value</tt>. Parsing stops, and 
0621      * the value is returned, when it encounters a character in <tt>value</tt> that is 
0622      * not a valid digit for the specified radix. If <tt>value</tt> does not begin with 
0623      * a number that it can parse, the function returns the not-a-number value <tt>NaN</tt>. 
0624      * Use the {@link #isNaN(Object)} function to test for this return value.</p>
0625      * <p>The <tt>radix</tt> argument specifies the base of the number to be parsed. 
0626      * Specifying 10 makes this function parse a decimal number. The value 8 specifies that 
0627      * an octal number (using digits 0 through 7) is to be parsed. The value 16 specifies 
0628      * a hexadecimal value, using digits 0 through 9 and letters A through F. <tt>radix</tt> 
0629      * can be any value between 2 and 36.</p>
0630      * <p>If <tt>radix</tt> is 0 or is undefined, this function tries to determine the 
0631      * radix of the number from <tt>value</tt>. If <tt>value</tt> begins (after an 
0632      * optional minus sign) with 0x, it parses the remainder of <tt>value</tt> as a 
0633      * hexadecimal number. If <tt>value</tt> begins with a 0, the ECMAScript v3 standard 
0634      * allows an implementation of this function to interpret the following characters as 
0635      * an octal number or as a decimal number. Otherwise, if <tt>value</tt> begins with 
0636      * a digit from 1 through 9, it parses it as a decimal number</p>
0637      * @param value The string to be parsed.
0638      * @param radix An optional integer argument that represents the radix (or base) of the 
0639      * number to be parsed. If this argument is undefined or is 0, the number is parsed in 
0640      * base 10 or in base 16 if it begins with 0x or 0X. If this argument is less than 2 or 
0641      * greater than 36, <tt>NaN</tt> is returned.
0642      * @return The parsed number, or <tt>NaN</tt> if <tt>value</tt> does not begin with 
0643      * a valid integer. In JavaScript 1.0, this function returns 0 instead of <tt>NaN</tt> 
0644      * when it cannot parse <tt>value</tt>.
0645      * @see #parseInt(Object)
0646      * @see Js#parseInt(Object, int)
0647      * @see jsx.client.Global#parseInt(Object, int)
0648      * @see jsx.client.Client#parseInt(Object, int)
0649      * @since 1.0
0650      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0651      */
0652     @Override
0653     protected Integer parseInt(Object value, int radix) {
0654         String s = Js.toString(value);
0655         try {
0656             return Integer.parseInt(s, radix);
0657         } catch (NumberFormatException nfe) {
0658             return null;
0659         }
0660     }
0661 
0662     /**
0663      * <p>Parses a number from a string.</p>
0664      * <p>In JavaScript, this function parses and returns the first number that occurs in 
0665      * <tt>value</tt>. Parsing stops, and the value is returned, when it encounters a 
0666      * character in <tt>value</tt> that is not a valid part of the number. If <tt>value</tt> 
0667      * does not begin with a number that it can parse, the function returns the not-a-number 
0668      * value <tt>NaN</tt>. Test for this return value with the {@link #isNaN(Object)} 
0669      * function. If you want to parse only the integer portion of a number, use {@link #parseInt(Object)} 
0670      * or {@link #parseInt(Object, int)} instead of this one.</p>
0671      * @param value The string to be parsed and converted to a number.
0672      * @return The parsed number, or <tt>NaN</tt> if <tt>value</tt> does not begin 
0673      * with a valid number. In JavaScript 1.0, this function returns 0 instead of <tt>NaN</tt> 
0674      * when <tt>value</tt> cannot be parsed as a number.
0675      * @see #parseInt(Object)
0676      * @see Js#parseFloat(Object)
0677      * @see jsx.client.Global#parseFloat(Object)
0678      * @see jsx.client.Client#parseFloat(Object)
0679      * @since 1.0
0680      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0681      */
0682     @Override
0683     protected Double parseFloat(Object value) {
0684         String s = Js.toString(value);
0685         try {
0686             return Double.parseDouble(s);
0687         } catch (NumberFormatException nfe) {
0688             return null;
0689         }
0690     }
0691 
0692     /**
0693      * <p>Returns an instance of XMLHttpRequest in Java version.</p>
0694      * @return The instance of XMLHttpRequest in Java version.
0695      * @see js.dom.DOM.XMLHttpRequest#create()
0696      * @see js.dom.DOM.XMLHttpRequest#invoke()
0697      * @since 1.0
0698      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0699      */
0700     @Override
0701     protected JsXMLHttpRequest http() {
0702         return Browser.isIE ? null : new SimXMLHttpRequest();
0703     }
0704 
0705     /**
0706      * <p>Creates an OLE Automation (ActiveX) object for Internet Explorer.</p>
0707      * @param cls The class of the OLE Automation (ActiveX) object being created.
0708      * @return The newly created OLE Automation (ActiveX) object.
0709      * @see js.dom.DOM.ActiveXObject#create(Object)
0710      * @see js.dom.DOM.ActiveXObject#create(String)
0711      * @see js.dom.DOM.ActiveXObject#create(Vars)
0712      * @since 1.0
0713      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0714      */
0715     @Override
0716     protected JsObject activeX(String cls) {
0717         if (Browser.isIE) {
0718             if ("MSXML2.XMLHTTP.5.0".equals(cls) ||
0719                 "MSXML2.XMLHTTP.4.0".equals(cls) ||
0720                 "MSXML2.XMLHTTP.3.0".equals(cls) ||
0721                 "MSXML2.XMLHTTP"    .equals(cls) ||
0722                 "Microsoft.XMLHTTP" .equals(cls)) {
0723                 return new SimXMLHttpRequest();
0724             }
0725         }
0726         return null;
0727     }
0728 
0729     /**
0730      * <p>Gets the list of the property names of an object.</p>
0731      * @param o The object.
0732      * @return The list of the property names of the object.
0733      * @since 1.0
0734      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0735      */
0736     protected abstract ArrayLike<String> keys(JsObject o);
0737 
0738     /**
0739      * <p>Gets an iterator of members of an object.</p>
0740      * @param o The object.
0741      * @return An {@link Iterator} of the {@link js.Var.Mid} of the object.
0742      * @since 1.0
0743      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0744      */
0745     public final Iterator<Mid> iterator(ObjectLike o) {
0746         return ((SimObjectLike)o).iterator();
0747     }
0748 
0749     /**
0750      * <p>Gets the list of the property names of an object.</p>
0751      * @param o The object.
0752      * @return The list of the property names of the object.
0753      * @since 1.0
0754      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0755      */
0756     @Override
0757     protected ArrayLike<String> keys(ObjectLike o) {
0758         if (o instanceof SimObjectLike) {
0759             ArrayLike<String> ret = new Vars<String>().var();
0760             Iterator<Mid> it = iterator((SimObjectLike)o);
0761             while (it.hasNext()) {
0762                 ret.push(it.next().toString());
0763             }
0764             return ret;
0765         }
0766         return keys((JsObject)o);
0767     }
0768 
0769     /**
0770      * <p>Copies all the properties of <tt>a</tt> to <tt>o</tt>.</p>
0771      * @param o The object that the properties being copied to.
0772      * @param a The object that the properties being copied from.
0773      * @since 1.0
0774      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0775      */
0776     protected abstract void apply(JsObject o, ObjectLike a);
0777 
0778     /**
0779      * <p>Copies all the properties of <tt>a</tt> to <tt>o</tt>.</p>
0780      * @param o The object that the properties being copied to.
0781      * @param a The object that the properties being copied from.
0782      * @since 1.0
0783      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0784      */
0785     @Override
0786     protected void apply(ObjectLike o, ObjectLike a) {
0787         if (isCore() || o instanceof SimObjectLike) {
0788             ArrayLike<String> keys = Js.keys(a);
0789             for (int i = 0, len = ArrayLikes.length(keys); i < len; i++) {
0790                 String k = keys.get(i);
0791                 o.var(k, a.var(k));
0792             }
0793         } else {
0794             apply((JsObject)o, a);
0795         }
0796     }
0797 
0798     /**
0799      * <p>Creates and return a <tt>Cases</tt> cache.</p>
0800      * @return The newly created <tt>Cases</tt> cache.
0801      * @since 1.0
0802      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0803      */
0804     @Override
0805     protected final Cases cases() {
0806         return new SimCases();
0807     }
0808 
0809     /**
0810      * <p>Creates an empty array.</p>
0811      * @return The empty array.
0812      * @see #array(Object[])
0813      * @see #array(boolean[])
0814      * @see #array(byte[])
0815      * @see #array(char[])
0816      * @see #array(short[])
0817      * @see #array(int[])
0818      * @see #array(long[])
0819      * @see #array(float[])
0820      * @see #array(double[])
0821      * @see Js#array()
0822      * @see Vars#var()
0823      * @see js.core.JsArray#JsArray()
0824      * @see js.core.JsGlobal.Array#create()
0825      * @since 1.0
0826      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0827      */
0828     @Override
0829     protected <T> ArrayLike<T> array() {
0830         return new SimArrayLike<T>(new SimArrayList<T>());
0831     }
0832 
0833     /**
0834      * <p>Gets the array-like representation of a generic array.</p>
0835      * @param a A generic array
0836      * @return The array-like representation.
0837      * @see #array(boolean[])
0838      * @see #array(byte[])
0839      * @see #array(char[])
0840      * @see #array(short[])
0841      * @see #array(int[])
0842      * @see #array(long[])
0843      * @see #array(float[])
0844      * @see #array(double[])
0845      * @see Js#array(Object[])
0846      * @see js.core.JsArray#JsArray(js.core.JsObject)
0847      * @see js.core.JsArray#JsArray(Object[])
0848      * @see js.core.JsGlobal.Array#create(Object)
0849      * @since 1.0
0850      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0851      */
0852     @Override
0853     protected <T> ArrayLike<T> array(T[] a) {
0854         return new SimArrayLike<T>(new SimArrayObject<T>(a));
0855     }
0856 
0857     /**
0858      * <p>Gets the array-like representation of a boolean array.</p>
0859      * @param a A boolean array
0860      * @return The array-like representation.
0861      * @see #array(Object[])
0862      * @see #array(byte[])
0863      * @see #array(char[])
0864      * @see #array(short[])
0865      * @see #array(int[])
0866      * @see #array(long[])
0867      * @see #array(float[])
0868      * @see #array(double[])
0869      * @see Js#array(boolean[])
0870      * @see js.core.JsArray#JsArray(boolean[])
0871      * @see js.core.JsArray#JsArray(js.core.JsObject)
0872      * @see js.core.JsGlobal.Array#create(Object)
0873      * @since 1.0
0874      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0875      */
0876     @Override
0877     protected ArrayLike<Boolean> array(boolean[] a) {
0878         return new SimArrayLike<Boolean>(new SimArrayBoolean(a));
0879     }
0880 
0881     /**
0882      * <p>Gets the array-like representation of a byte array.</p>
0883      * @param a A byte array
0884      * @return The array-like representation.
0885      * @see #array(Object[])
0886      * @see #array(boolean[])
0887      * @see #array(char[])
0888      * @see #array(short[])
0889      * @see #array(int[])
0890      * @see #array(long[])
0891      * @see #array(float[])
0892      * @see #array(double[])
0893      * @see Js#array(byte[])
0894      * @see js.core.JsArray#JsArray(byte[])
0895      * @see js.core.JsArray#JsArray(js.core.JsObject)
0896      * @see js.core.JsGlobal.Array#create(Object)
0897      * @since 1.0
0898      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0899      */
0900     @Override
0901     protected ArrayLike<Byte> array(byte[] a) {
0902         return new SimArrayLike<Byte>(new SimArrayByte(a));
0903     }
0904 
0905     /**
0906      * <p>Gets the array-like representation of a char array.</p>
0907      * @param a A char array
0908      * @return The array-like representation.
0909      * @see #array(Object[])
0910      * @see #array(boolean[])
0911      * @see #array(byte[])
0912      * @see #array(short[])
0913      * @see #array(int[])
0914      * @see #array(long[])
0915      * @see #array(float[])
0916      * @see #array(double[])
0917      * @see Js#array(char[])
0918      * @see js.core.JsArray#JsArray(char[])
0919      * @see js.core.JsArray#JsArray(js.core.JsObject)
0920      * @see js.core.JsGlobal.Array#create(Object)
0921      * @since 1.0
0922      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0923      */
0924     @Override
0925     protected ArrayLike<Character> array(char[] a) {
0926         return new SimArrayLike<Character>(new SimArrayCharacter(a));
0927     }
0928 
0929     /**
0930      * <p>Gets the array-like representation of a short array.</p>
0931      * @param a A short array
0932      * @return The array-like representation.
0933      * @see #array(Object[])
0934      * @see #array(boolean[])
0935      * @see #array(byte[])
0936      * @see #array(char[])
0937      * @see #array(int[])
0938      * @see #array(long[])
0939      * @see #array(float[])
0940      * @see #array(double[])
0941      * @see Js#array(short[])
0942      * @see js.core.JsArray#JsArray(short[])
0943      * @see js.core.JsArray#JsArray(js.core.JsObject)
0944      * @see js.core.JsGlobal.Array#create(Object)
0945      * @since 1.0
0946      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0947      */
0948     @Override
0949     protected ArrayLike<Short> array(short[] a) {
0950         return new SimArrayLike<Short>(new SimArrayShort(a));
0951     }
0952 
0953     /**
0954      * <p>Gets the array-like representation of an int array.</p>
0955      * @param a An int array
0956      * @return The array-like representation.
0957      * @see #array(Object[])
0958      * @see #array(boolean[])
0959      * @see #array(byte[])
0960      * @see #array(char[])
0961      * @see #array(short[])
0962      * @see #array(long[])
0963      * @see #array(float[])
0964      * @see #array(double[])
0965      * @see Js#array(int[])
0966      * @see js.core.JsArray#JsArray(int[])
0967      * @see js.core.JsArray#JsArray(js.core.JsObject)
0968      * @see js.core.JsGlobal.Array#create(Object)
0969      * @since 1.0
0970      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0971      */
0972     @Override
0973     protected ArrayLike<Integer> array(int[] a) {
0974         return new SimArrayLike<Integer>(new SimArrayInteger(a));
0975     }
0976 
0977     /**
0978      * <p>Gets the array-like representation of a long array.</p>
0979      * @param a A long array
0980      * @return The array-like representation.
0981      * @see #array(Object[])
0982      * @see #array(boolean[])
0983      * @see #array(byte[])
0984      * @see #array(char[])
0985      * @see #array(short[])
0986      * @see #array(int[])
0987      * @see #array(float[])
0988      * @see #array(double[])
0989      * @see Js#array(long[])
0990      * @see js.core.JsArray#JsArray(long[])
0991      * @see js.core.JsArray#JsArray(js.core.JsObject)
0992      * @see js.core.JsGlobal.Array#create(Object)
0993      * @since 1.0
0994      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
0995      */
0996     @Override
0997     protected ArrayLike<Long> array(long[] a) {
0998         return new SimArrayLike<Long>(new SimArrayLong(a));
0999     }
1000 
1001     /**
1002      * <p>Gets the array-like representation of a float array.</p>
1003      * @param a A float array
1004      * @return The array-like representation.
1005      * @see #array(Object[])
1006      * @see #array(boolean[])
1007      * @see #array(byte[])
1008      * @see #array(char[])
1009      * @see #array(short[])
1010      * @see #array(int[])
1011      * @see #array(long[])
1012      * @see #array(double[])
1013      * @see Js#array(float[])
1014      * @see js.core.JsArray#JsArray(float[])
1015      * @see js.core.JsArray#JsArray(js.core.JsObject)
1016      * @see js.core.JsGlobal.Array#create(Object)
1017      * @since 1.0
1018      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1019      */
1020     @Override
1021     protected ArrayLike<Float> array(float[] a) {
1022         return new SimArrayLike<Float>(new SimArrayFloat(a));
1023     }
1024 
1025     /**
1026      * <p>Gets the array-like representation of a double array.</p>
1027      * @param a A double array
1028      * @return The array-like representation.
1029      * @see #array(Object[])
1030      * @see #array(boolean[])
1031      * @see #array(byte[])
1032      * @see #array(char[])
1033      * @see #array(short[])
1034      * @see #array(int[])
1035      * @see #array(long[])
1036      * @see #array(float[])
1037      * @see Js#array(double[])
1038      * @see js.core.JsArray#JsArray(double[])
1039      * @see js.core.JsArray#JsArray(js.core.JsObject)
1040      * @see js.core.JsGlobal.Array#create(Object)
1041      * @since 1.0
1042      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1043      */
1044     @Override
1045     protected ArrayLike<Double> array(double[] a) {
1046         return new SimArrayLike<Double>(new SimArrayDouble(a));
1047     }
1048 
1049     /**
1050      * <p>Creates a date object set to the current system date and time.</p>
1051      * @return The newly created date object.
1052      * @see #date(Number)
1053      * @see #date(String)
1054      * @see Js#date()
1055      * @see js.core.JsGlobal.Date#create()
1056      * @see js.core.JsGlobal.Date#create(Vars)
1057      * @since 1.0
1058      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1059      */
1060     @Override
1061     protected DateLike date() {
1062         return new SimDateLike();
1063     }
1064     /**
1065      * <p>Creates a date object from a numeric representation in milliseconds.</p>
1066      * @param n A numeric representation of date in milliseconds.
1067      * @return The newly created date object.
1068      * @see #date()
1069      * @see #date(String)
1070      * @see Js#date(Number)
1071      * @see js.core.JsDate#JsDate(Number)
1072      * @see js.core.JsDate#JsDate(NumberLike)
1073      * @see js.core.JsGlobal.Date#create(Number)
1074      * @see js.core.JsGlobal.Date#create(NumberLike)
1075      * @see js.core.JsGlobal.Date#create(Vars)
1076      * @since 1.0
1077      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1078      */
1079     @Override
1080     protected DateLike date(Number n) {
1081         return new SimDateLike(n);
1082     }
1083     /**
1084      * <p>Creates a date object from a string representation.</p>
1085      * @param s A string representation of date.
1086      * @return The newly created date object.
1087      * @see #date()
1088      * @see #date(Number)
1089      * @see Js#date(String)
1090      * @see js.core.JsDate#JsDate(String)
1091      * @see js.core.JsDate#JsDate(StringLike)
1092      * @see js.core.JsGlobal.Date#create(Object)
1093      * @see js.core.JsGlobal.Date#create(Vars)
1094      * @since 1.0
1095      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1096      */
1097     @Override
1098     protected DateLike date(String s) {
1099         return new SimDateLike(s);
1100     }
1101 
1102     /**
1103      * <p>Returns the math-like object.</p>
1104      * @return The math-like object.
1105      * @see Js#math()
1106      * @see js.core.JsGlobal.Math
1107      * @see jsx.core.Maths
1108      * @since 1.0
1109      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1110      */
1111     @Override
1112     protected MathLike math() {
1113         return SimMathLike.get();
1114     }
1115 
1116     /**
1117      * <p>Creates and returns a newly created object.</p>
1118      * @return The newly created object.
1119      * @see #object(Object)
1120      * @see Js#object()
1121      * @see Initializer#var()
1122      * @see js.core.JsObject#JsObject()
1123      * @see js.core.JsGlobal.Object#create()
1124      * @see js.core.JsGlobal.Object#invoke()
1125      * @since 1.0
1126      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1127      */
1128     @Override
1129     protected ObjectLike object() {
1130         return new SimObjectLike();
1131     }
1132 
1133     /**
1134      * <p>Converts a value to an object and returns it.</p>
1135      * @param o A value to be converted to object. If this argument is a primitive value, 
1136      * this method creates a corresponding object for it. Otherwise, the method returns 
1137      * the object itself.
1138      * @return The converted or created object. If the argument is a primitive value, 
1139      * this method returns a corresponding object for it. Otherwise, the method returns 
1140      * the object argument itself.
1141      * @see #object()
1142      * @see Js#object(Object)
1143      * @see js.core.JsObject#JsObject(JsObject)
1144      * @see js.core.JsGlobal.Object#create(Boolean)
1145      * @see js.core.JsGlobal.Object#create(JsBoolean)
1146      * @see js.core.JsGlobal.Object#create(Value)
1147      * @see js.core.JsGlobal.Object#create(Number)
1148      * @see js.core.JsGlobal.Object#create(NumberLike)
1149      * @see js.core.JsGlobal.Object#create(String)
1150      * @see js.core.JsGlobal.Object#create(StringLike)
1151      * @see js.core.JsGlobal.Object#invoke(Boolean)
1152      * @see js.core.JsGlobal.Object#invoke(JsBoolean)
1153      * @see js.core.JsGlobal.Object#invoke(Value)
1154      * @see js.core.JsGlobal.Object#invoke(Number)
1155      * @see js.core.JsGlobal.Object#invoke(NumberLike)
1156      * @see js.core.JsGlobal.Object#invoke(String)
1157      * @see js.core.JsGlobal.Object#invoke(StringLike)
1158      * @since 1.0
1159      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1160      */
1161     @Override
1162     protected ObjectLike object(Object o) {
1163         if (o == null) {
1164             return null;
1165         } else if (o instanceof ObjectLike) {
1166             return (ObjectLike)o;
1167         } else if (o instanceof Var<?>) {
1168             return object(((Var<?>)o).var());
1169         } else {
1170             return JsGlobal.Object.with().invoke(o);
1171         }
1172     }
1173 
1174     /**
1175      * <p>Creates a regular expression with the specified pattern.</p>
1176      * @param regex A string that specifies the pattern of the regular expression.
1177      * @return A new regular expression object, with the specified pattern.
1178      * @throws RuntimeException JavaScript throws a <tt>SyntaxError</tt> If <tt>regex</tt> 
1179      * is not a legal regular expression. See {@link Js#err(Object)} and {@link js.core.JsSyntaxError} 
1180      * for JS Simulation.
1181      * @see #re(String, String)
1182      * @see Js#re(String)
1183      * @see js.core.JsRegExp#JsRegExp(String)
1184      * @see js.core.JsGlobal.RegExp#create(Object)
1185      * @see js.core.JsGlobal.RegExp#create(Vars)
1186      * @see js.core.JsGlobal.RegExp#invoke(Object)
1187      * @see js.core.JsGlobal.RegExp#invoke(Vars)
1188      * @since 1.0
1189      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1190      */
1191     @Override
1192     protected RegExpLike re(String regex) {
1193         return new SimRegExpLike(regex);
1194     }
1195 
1196     /**
1197      * <p>Creates a regular expression with the specified pattern and flags.</p>
1198      * @param regex A string that specifies the pattern of the regular expression.
1199      * @param flags An optional string containing any of the "g", "i", and "m" attributes 
1200      * that specify global, case-insensitive, and multiline matches, respectively. The "m" 
1201      * attribute is not available prior to ECMAScript standardization.
1202      * @return A new regular expression object, with the specified pattern and flags.
1203      * @throws RuntimeException JavaScript throws a <tt>SyntaxError</tt> If <tt>regex</tt> 
1204      * is not a legal regular expression, or if <tt>flags</tt> contains characters other than 
1205      * "g", "i", and "m". See {@link Js#err(Object)} and {@link js.core.JsSyntaxError} for 
1206      * JS Simulation.
1207      * @see #re(String)
1208      * @see Js#re(String, String)
1209      * @see js.core.JsRegExp#JsRegExp(String, String)
1210      * @see js.core.JsGlobal.RegExp#create(Object, Object)
1211      * @see js.core.JsGlobal.RegExp#create(Vars)
1212      * @see js.core.JsGlobal.RegExp#invoke(Object, Object)
1213      * @see js.core.JsGlobal.RegExp#invoke(Vars)
1214      * @since 1.0
1215      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1216      */
1217     @Override
1218     protected RegExpLike re(String regex, String flags) {
1219         return new SimRegExpLike(regex, flags);
1220     }
1221 
1222     /**
1223      * <p>Converts a numeric value to a number object and returns it.</p>
1224      * @param n A numeric value to be converted to number object.
1225      * @return The number object.
1226      * @see js.core.JsNumber#JsNumber(Number)
1227      * @see js.core.JsNumber#JsNumber(Value)
1228      * @see js.core.JsGlobal.Number#create(Object)
1229      * @see js.core.JsGlobal.Number#create(Vars)
1230      * @see js.core.JsGlobal.Number#invoke(Object)
1231      * @see js.core.JsGlobal.Number#invoke(Vars)
1232      * @since 1.0
1233      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1234      */
1235     @Override
1236     protected <T extends Number> NumberLike<T> numberLike(T n) {
1237         return new SimNumberLike<T>(n);
1238     }
1239 
1240     /**
1241      * <p>Converts a string value to a string object and returns it.</p>
1242      * @param s A string value to be converted to string object.
1243      * @return The string object.
1244      * @see js.core.JsString#JsString(String)
1245      * @see js.core.JsString#JsString(Var)
1246      * @see js.core.JsGlobal.String#create(Object)
1247      * @see js.core.JsGlobal.String#create(Vars)
1248      * @see js.core.JsGlobal.String#invoke(Object)
1249      * @see js.core.JsGlobal.String#invoke(Vars)
1250      * @since 1.0
1251      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1252      */
1253     @Override
1254     protected StringLike stringLike(String s) {
1255         return new SimStringLike(s);
1256     }
1257 
1258     /**
1259      * <p>Connects to a Java class in an applet and returns a LiveConnect class.</p>
1260      * @param applet The applet ID where the Java class is to be connected to.
1261      * @param cls The Java class to be connected to.
1262      * @return The LiveConnect class connected to the Java class.
1263      * @see #connect(Object)
1264      * @see Js#connect(String, String)
1265      * @since 1.0
1266      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1267      */
1268     @Override
1269     protected LiveClass connect(String applet, String cls) {
1270         try {
1271             return new SimLiveClass(cls);
1272         } catch (ClassNotFoundException e) {
1273             throw new RuntimeException(e);
1274         }
1275     }
1276 
1277     /**
1278      * <p>Connects to a Java object and returns a LiveConnect object.</p>
1279      * @param obj The Java object to be connected to.
1280      * @return The LiveConnect object connected to the Java object.
1281      * @see #connect(String, String)
1282      * @see Js#connect(Object)
1283      * @since 1.0
1284      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1285      */
1286     @Override
1287     protected LiveObject connect(Object obj) {
1288         return new SimLiveObject(obj);
1289     }
1290 
1291     final static Class<?>[] aTypes(Vars<String> atypes) {
1292         ArrayLike<String> a = atypes.var();
1293         int len = a.length();
1294         Class<?>[] ret = new Class<?>[len];
1295         for (int i = 0; i < len; i++) {
1296             try {
1297                 ret[i] = Class.forName(a.get(i));
1298             } catch (ClassNotFoundException e) {
1299                 throw new RuntimeException(e);
1300             }
1301         }
1302         return ret;
1303     }
1304 
1305     final static Object[] args(Vars<?> args) {
1306         ArrayLike<?> arr = args.var();
1307         int len = arr.length();
1308         Object[] ret = new Object[len];
1309         for (int i = 0; i < len; i++) {
1310             ret[i] = Js.valueOf(arr.get(i));
1311         }
1312         return ret;
1313     }
1314 
1315     /**
1316      * <p>Creates an integer literal.</p>
1317      * <p>This method is used to create formatted integer literal in re-compiled JavaScript 
1318      * code. A re-compiler leaves the literal as it is without even parsing check but JS 
1319      * Simulations parse it to an integer and throws RuntimeException if it is malformatted.</p>
1320      * @param s The literal text of an integer.
1321      * @return The integer literal.
1322      * @since 1.0
1323      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1324      */
1325     @Override
1326     protected int integer(String s) {
1327         s = s.trim();
1328         if (s.startsWith("0x") || s.startsWith("0X")) {
1329             return Integer.parseInt(s.substring(2), 16);
1330         } else {
1331             return Integer.parseInt(s);
1332         }
1333     }
1334 
1335     /**
1336      * <p>Creates a number literal.</p>
1337      * <p>This method is used to create formatted number literal in re-compiled JavaScript 
1338      * code. A re-compiler leaves the literal as it is without even parsing check but JS 
1339      * Simulations parse it to a number and throws RuntimeException if it is malformatted.</p>
1340      * @param s The literal text of a number.
1341      * @return The numberer literal.
1342      * @since 1.0
1343      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1344      */
1345     @Override
1346     protected Number number(String s) {
1347         s = s.trim();
1348         if (s.startsWith("0x") || s.startsWith("0X")) {
1349             s = s.substring(2);
1350             try {
1351                 return Byte.parseByte(s, 16);
1352             } catch(NumberFormatException e) {
1353             }
1354             try {
1355                 return Short.parseShort(s, 16);
1356             } catch(NumberFormatException e) {
1357             }
1358             try {
1359                 return Integer.parseInt(s, 16);
1360             } catch(NumberFormatException e) {
1361             }
1362             return Long.parseLong(s, 16);
1363         } else {
1364             try {
1365                 return Byte.parseByte(s);
1366             } catch(NumberFormatException e) {
1367             }
1368             try {
1369                 return Short.parseShort(s);
1370             } catch(NumberFormatException e) {
1371             }
1372             try {
1373                 return Integer.parseInt(s);
1374             } catch(NumberFormatException e) {
1375             }
1376             try {
1377                 return Long.parseLong(s);
1378             } catch(NumberFormatException e) {
1379             }
1380             try {
1381                 return Float.parseFloat(s);
1382             } catch(NumberFormatException e) {
1383             }
1384             return Double.parseDouble(s);
1385         }
1386     }
1387 
1388     /**
1389      * <p>Gets the number representation of the argument if it is numeric.</p>
1390      * @param var Any variable
1391      * @return the number representation of the argument.
1392      * @since 1.0
1393      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1394      */
1395     @Override
1396     protected Number getNumber(Object var) {
1397         var = var instanceof Var<?> ? ((Var<?>)var).var() : var;
1398         var = Js.valueOf(var);
1399         return var instanceof String ? number((String)var) : SimUtil.getNumber(var);
1400     }
1401 
1402     /**
1403      * <p>Performs unary negation, resembling the unary minus operator in JavaScript.</p>
1404      * <p>This operation converts a positive value to an equivalently negative value, and 
1405      * vice versa. If the operand is not a number, it attempts to convert it to one.</p>
1406      * @param var Any numeric value.
1407      * @return The negation of the numeric value.
1408      * @since 1.0
1409      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1410      */
1411     @Override
1412     protected Number neg(Number var) {
1413         return SimUtil.neg(var);
1414     }
1415 
1416     /**
1417      * <p>Adds numeric operands, resembling the addition operator in JavaScript.</p>
1418      * <p>Object operands are converted to numbers. The conversion is performed by the 
1419      * {@link Js#valueOf(Object)} operation on the object.</p>
1420      * @param var Any numeric value.
1421      * @param other Any numeric value.
1422      * @return The sum of the two numeric values.
1423      * @since 1.0
1424      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1425      */
1426     @Override
1427     protected Number add(Number var, Number other) {
1428         return SimUtil.add(var, other);
1429     }
1430 
1431     /**
1432      * <p>Computes the first operand modulo the second operand, resembling the modulo 
1433      * operator in JavaScript.</p>
1434      * <p>The operation returns the remainder when the first operand is divided by the 
1435      * second operand a certain number of times. If used with non-numeric operands, the 
1436      * operation attempts to convert them to numbers. The sign of the result is the same 
1437      * as the sign of the first operand.</p>
1438      * <p>This operation is typically used with integer operands, it also works for 
1439      * floating-point values.</p>
1440      * @param var Any numeric value.
1441      * @param other Any numeric value.
1442      * @return The remainder.
1443      * @since 1.0
1444      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1445      */
1446     @Override
1447     protected Number mod(Number var, Number other) {
1448         return SimUtil.mod(var, other);
1449     }
1450 
1451     /**
1452      * <p>Multiplies the two operands, resembling the multiplication operator in JavaScript.</p>
1453      * <p>If used with non-numeric operands, this operation attempts to convert them to 
1454      * numbers.</p>
1455      * @param var Any numeric value.
1456      * @param other Any numeric value.
1457      * @return The product of the two operands.
1458      * @since 1.0
1459      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1460      */
1461     @Override
1462     protected Number mul(Number var, Number other) {
1463         return SimUtil.mul(var, other);
1464     }
1465 
1466     /**
1467      * <p>Divides the first operand by the second, resembling the multiplication operator 
1468      * in JavaScript.</p>
1469      * <p>Used with non-numeric operands, this operation attempts to convert them to 
1470      * numbers. If you are used to programming languages that distinguish between integer 
1471      * and floating-point numbers, you might expect to get an integer result when you 
1472      * divide one integer by another. In JavaScript, however, all numbers are floating-point, 
1473      * so all division operations have floating-point results. Division by zero yields positive 
1474      * or negative infinity, while <tt>0/0</tt> evaluates to <tt>NaN</tt>.</p>
1475      * @param var Any numeric value.
1476      * @param other Any numeric value.
1477      * @return The quotient of the two operands.
1478      * @since 1.0
1479      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1480      */
1481     @Override
1482     protected Number div(Number var, Number other) {
1483         return SimUtil.div(var, other);
1484     }
1485 
1486     /**
1487      * <p>Less-than operation, resembling that of JavaScript, evaluates to <tt>true</tt> if 
1488      * the first operand is less than the second operand; otherwise it evaluates to 
1489      * <tt>false</tt>.</p>
1490      * <p>The operands of this operation may be of any type. Comparison can be performed 
1491      * only on numbers and strings, however, so operands that are not numbers or strings 
1492      * are converted. Comparison and conversion occur as follows:</p>
1493      * <ul>
1494      * <li>If both operands are numbers, or if both convert to numbers, they are compared 
1495      * numerically.</li>
1496      * <li>If both operands are strings or convert to strings, they are compared as 
1497      * strings.</li>
1498      * <li>If one operand is or converts to a string, and one is or converts to a number, 
1499      * the operation attempts to convert the string to a number and performs a numerical 
1500      * comparison. If the string does not represent a number, it converts to <tt>NaN</tt>, 
1501      * and the comparison is <tt>false</tt>. In JavaScript 1.1, the string-to-number 
1502      * conversion causes an error instead of yielding <tt>NaN</tt>.</li>
1503      * <li>If an object can be converted to either a number or a string, JavaScript performs 
1504      * the numerical conversion. This means, for example, that Date objects are compared 
1505      * numerically, and it is meaningful to compare two dates to see whether one is earlier 
1506      * than the other.</li>
1507      * <li>If the operands of the comparison operations cannot both be successfully converted 
1508      * to numbers or to strings, these operations always return <tt>false</tt>.</li>
1509      * <li>If either operand is or converts to <tt>NaN</tt>, the comparison operation always 
1510      * yields <tt>false</tt>.</li>
1511      * </ul>
1512      * <p>Keep in mind that string comparison is done on a strict character-by-character 
1513      * basis using the numerical value of each character from the Unicode encoding. Although 
1514      * in some cases the Unicode standard allows equivalent strings to be encoded using 
1515      * different sequences of characters, the JavaScript comparison operations do not 
1516      * detect these encoding differences; they assume that all strings are expressed in 
1517      * normalized form. Note in particular that string comparison is case-sensitive, and 
1518      * in the Unicode encoding (at least for the ASCII subset), all capital letters are 
1519      * "less than" all lowercase letters. This rule can cause confusing results if you do 
1520      * not expect it.</p>
1521      * <p>For a more robust string-comparison algorithm, see the {@link StringLike#localeCompare(Object)} 
1522      * method, which also takes locale-specific definitions of alphabetical order into account. 
1523      * For case-insensitive comparisons, you must first convert the strings to all lowercase or 
1524      * all uppercase using {@link StringLike#toLowerCase()} or {@link StringLike#toUpperCase()}.</p>
1525      * <p>The less-than-or-equal and greater-than-or-equal operations do not rely on the 
1526      * equality or identity operations for determining whether two values are "equal." 
1527      * Instead, the less-than-or-equal operator is simply defined as "not greater than", 
1528      * and the greater-than-or-equal operator is defined as "not less than". The one 
1529      * exception occurs when either operand is (or converts to) <tt>NaN</tt>, in which case 
1530      * all comparison operations return <tt>false</tt>.</p>
1531      * @param v A value or object.
1532      * @param o A value or object.
1533      * @return <tt>true</tt> if the first operand is less than the second operand; 
1534      * otherwise <tt>false</tt>.
1535      * @since 1.0
1536      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1537      */
1538     @Override
1539     protected final boolean lt(Object v, Object o) {
1540         v = Js.valueOf(v);
1541         o = Js.valueOf(o);
1542         if (Js.undefined(v) || Js.undefined(o)) {
1543             return false;
1544         }
1545         if (v instanceof String && o instanceof String) {
1546             return ((String)v).compareTo((String)o) < 0;
1547         }
1548         try {
1549             return getNumber(v).doubleValue() < getNumber(o).doubleValue();
1550         } catch (Exception e1) {
1551             return Js.toString(v).compareTo(Js.toString(o)) < 0;
1552         }
1553     }
1554 
1555     /**
1556      * <p>Greater-than operation, resembling that of JavaScript, evaluates to <tt>true</tt> if 
1557      * the first operand is greater than the second operand; otherwise it evaluates to 
1558      * <tt>false</tt>.</p>
1559      * <p>The operands of this operation may be of any type. Comparison can be performed 
1560      * only on numbers and strings, however, so operands that are not numbers or strings 
1561      * are converted. Comparison and conversion occur as follows:</p>
1562      * <ul>
1563      * <li>If both operands are numbers, or if both convert to numbers, they are compared 
1564      * numerically.</li>
1565      * <li>If both operands are strings or convert to strings, they are compared as 
1566      * strings.</li>
1567      * <li>If one operand is or converts to a string, and one is or converts to a number, 
1568      * the operation attempts to convert the string to a number and performs a numerical 
1569      * comparison. If the string does not represent a number, it converts to <tt>NaN</tt>, 
1570      * and the comparison is <tt>false</tt>. In JavaScript 1.1, the string-to-number 
1571      * conversion causes an error instead of yielding <tt>NaN</tt>.</li>
1572      * <li>If an object can be converted to either a number or a string, JavaScript performs 
1573      * the numerical conversion. This means, for example, that Date objects are compared 
1574      * numerically, and it is meaningful to compare two dates to see whether one is earlier 
1575      * than the other.</li>
1576      * <li>If the operands of the comparison operations cannot both be successfully converted 
1577      * to numbers or to strings, these operations always return <tt>false</tt>.</li>
1578      * <li>If either operand is or converts to <tt>NaN</tt>, the comparison operation always 
1579      * yields <tt>false</tt>.</li>
1580      * </ul>
1581      * <p>Keep in mind that string comparison is done on a strict character-by-character 
1582      * basis using the numerical value of each character from the Unicode encoding. Although 
1583      * in some cases the Unicode standard allows equivalent strings to be encoded using 
1584      * different sequences of characters, the JavaScript comparison operations do not 
1585      * detect these encoding differences; they assume that all strings are expressed in 
1586      * normalized form. Note in particular that string comparison is case-sensitive, and 
1587      * in the Unicode encoding (at least for the ASCII subset), all capital letters are 
1588      * "less than" all lowercase letters. This rule can cause confusing results if you do 
1589      * not expect it.</p>
1590      * <p>For a more robust string-comparison algorithm, see the {@link StringLike#localeCompare(Object)} 
1591      * method, which also takes locale-specific definitions of alphabetical order into account. 
1592      * For case-insensitive comparisons, you must first convert the strings to all lowercase or 
1593      * all uppercase using {@link StringLike#toLowerCase()} or {@link StringLike#toUpperCase()}.</p>
1594      * <p>The less-than-or-equal and greater-than-or-equal operations do not rely on the 
1595      * equality or identity operations for determining whether two values are "equal." 
1596      * Instead, the less-than-or-equal operator is simply defined as "not greater than", 
1597      * and the greater-than-or-equal operator is defined as "not less than". The one 
1598      * exception occurs when either operand is (or converts to) <tt>NaN</tt>, in which case 
1599      * all comparison operations return <tt>false</tt>.</p>
1600      * @param v A value or object.
1601      * @param o A value or object.
1602      * @return <tt>true</tt> if the first operand is greater than the second operand; 
1603      * otherwise <tt>false</tt>.
1604      * @since 1.0
1605      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1606      */
1607     @Override
1608     protected final boolean gt(Object v, Object o) {
1609         v = Js.valueOf(v);
1610         o = Js.valueOf(o);
1611         if (Js.undefined(v) || Js.undefined(o)) {
1612             return false;
1613         }
1614         if (v instanceof String && o instanceof String) {
1615             return ((String)v).compareTo((String)o) > 0;
1616         }
1617         try {
1618             return getNumber(v).doubleValue() > getNumber(o).doubleValue();
1619         } catch (Exception e1) {
1620             return Js.toString(v).compareTo(Js.toString(o)) > 0;
1621         }
1622     }
1623 
1624     /**
1625      * <p>Less-than-or-equal operation, resembling that of JavaScript, evaluates to 
1626      * <tt>true</tt> if the first operand is less than or equal to the second operand; 
1627      * otherwise it evaluates to <tt>false</tt>.</p>
1628      * <p>The operands of this operation may be of any type. Comparison can be performed 
1629      * only on numbers and strings, however, so operands that are not numbers or strings 
1630      * are converted. Comparison and conversion occur as follows:</p>
1631      * <ul>
1632      * <li>If both operands are numbers, or if both convert to numbers, they are compared 
1633      * numerically.</li>
1634      * <li>If both operands are strings or convert to strings, they are compared as 
1635      * strings.</li>
1636      * <li>If one operand is or converts to a string, and one is or converts to a number, 
1637      * the operation attempts to convert the string to a number and performs a numerical 
1638      * comparison. If the string does not represent a number, it converts to <tt>NaN</tt>, 
1639      * and the comparison is <tt>false</tt>. In JavaScript 1.1, the string-to-number 
1640      * conversion causes an error instead of yielding <tt>NaN</tt>.</li>
1641      * <li>If an object can be converted to either a number or a string, JavaScript performs 
1642      * the numerical conversion. This means, for example, that Date objects are compared 
1643      * numerically, and it is meaningful to compare two dates to see whether one is earlier 
1644      * than the other.</li>
1645      * <li>If the operands of the comparison operations cannot both be successfully converted 
1646      * to numbers or to strings, these operations always return <tt>false</tt>.</li>
1647      * <li>If either operand is or converts to <tt>NaN</tt>, the comparison operation always 
1648      * yields <tt>false</tt>.</li>
1649      * </ul>
1650      * <p>Keep in mind that string comparison is done on a strict character-by-character 
1651      * basis using the numerical value of each character from the Unicode encoding. Although 
1652      * in some cases the Unicode standard allows equivalent strings to be encoded using 
1653      * different sequences of characters, the JavaScript comparison operations do not 
1654      * detect these encoding differences; they assume that all strings are expressed in 
1655      * normalized form. Note in particular that string comparison is case-sensitive, and 
1656      * in the Unicode encoding (at least for the ASCII subset), all capital letters are 
1657      * "less than" all lowercase letters. This rule can cause confusing results if you do 
1658      * not expect it.</p>
1659      * <p>For a more robust string-comparison algorithm, see the {@link StringLike#localeCompare(Object)} 
1660      * method, which also takes locale-specific definitions of alphabetical order into account. 
1661      * For case-insensitive comparisons, you must first convert the strings to all lowercase or 
1662      * all uppercase using {@link StringLike#toLowerCase()} or {@link StringLike#toUpperCase()}.</p>
1663      * <p>The less-than-or-equal and greater-than-or-equal operations do not rely on the 
1664      * equality or identity operations for determining whether two values are "equal." 
1665      * Instead, the less-than-or-equal operator is simply defined as "not greater than", 
1666      * and the greater-than-or-equal operator is defined as "not less than". The one 
1667      * exception occurs when either operand is (or converts to) <tt>NaN</tt>, in which case 
1668      * all comparison operations return <tt>false</tt>.</p>
1669      * @param v A value or object.
1670      * @param o A value or object.
1671      * @return <tt>true</tt> if the first operand is less than or equal to the second 
1672      * operand; otherwise <tt>false</tt>.
1673      * @since 1.0
1674      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1675      */
1676     @Override
1677     protected final boolean lte(Object v, Object o) {
1678         v = Js.valueOf(v);
1679         o = Js.valueOf(o);
1680         if (Js.undefined(v) || Js.undefined(o)) {
1681             return false;
1682         }
1683         if (v instanceof String && o instanceof String) {
1684             return ((String)v).compareTo((String)o) <= 0;
1685         }
1686         try {
1687             return !(getNumber(v).doubleValue() > getNumber(o).doubleValue());
1688         } catch (Exception e1) {
1689             return Js.toString(v).compareTo(Js.toString(o)) <= 0;
1690         }
1691     }
1692 
1693     /**
1694      * <p>Greater-than-or-equal operation, resembling that of JavaScript, evaluates to 
1695      * <tt>true</tt> if the first operand is greater than or equal to the second operand; 
1696      * otherwise it evaluates to <tt>false</tt>.</p>
1697      * <p>The operands of this operation may be of any type. Comparison can be performed 
1698      * only on numbers and strings, however, so operands that are not numbers or strings 
1699      * are converted. Comparison and conversion occur as follows:</p>
1700      * <ul>
1701      * <li>If both operands are numbers, or if both convert to numbers, they are compared 
1702      * numerically.</li>
1703      * <li>If both operands are strings or convert to strings, they are compared as 
1704      * strings.</li>
1705      * <li>If one operand is or converts to a string, and one is or converts to a number, 
1706      * the operation attempts to convert the string to a number and performs a numerical 
1707      * comparison. If the string does not represent a number, it converts to <tt>NaN</tt>, 
1708      * and the comparison is <tt>false</tt>. In JavaScript 1.1, the string-to-number 
1709      * conversion causes an error instead of yielding <tt>NaN</tt>.</li>
1710      * <li>If an object can be converted to either a number or a string, JavaScript performs 
1711      * the numerical conversion. This means, for example, that Date objects are compared 
1712      * numerically, and it is meaningful to compare two dates to see whether one is earlier 
1713      * than the other.</li>
1714      * <li>If the operands of the comparison operations cannot both be successfully converted 
1715      * to numbers or to strings, these operations always return <tt>false</tt>.</li>
1716      * <li>If either operand is or converts to <tt>NaN</tt>, the comparison operation always 
1717      * yields <tt>false</tt>.</li>
1718      * </ul>
1719      * <p>Keep in mind that string comparison is done on a strict character-by-character 
1720      * basis using the numerical value of each character from the Unicode encoding. Although 
1721      * in some cases the Unicode standard allows equivalent strings to be encoded using 
1722      * different sequences of characters, the JavaScript comparison operations do not 
1723      * detect these encoding differences; they assume that all strings are expressed in 
1724      * normalized form. Note in particular that string comparison is case-sensitive, and 
1725      * in the Unicode encoding (at least for the ASCII subset), all capital letters are 
1726      * "less than" all lowercase letters. This rule can cause confusing results if you do 
1727      * not expect it.</p>
1728      * <p>For a more robust string-comparison algorithm, see the {@link StringLike#localeCompare(Object)} 
1729      * method, which also takes locale-specific definitions of alphabetical order into account. 
1730      * For case-insensitive comparisons, you must first convert the strings to all lowercase or 
1731      * all uppercase using {@link StringLike#toLowerCase()} or {@link StringLike#toUpperCase()}.</p>
1732      * <p>The less-than-or-equal and greater-than-or-equal operations do not rely on the 
1733      * equality or identity operations for determining whether two values are "equal." 
1734      * Instead, the less-than-or-equal operator is simply defined as "not greater than", 
1735      * and the greater-than-or-equal operator is defined as "not less than". The one 
1736      * exception occurs when either operand is (or converts to) <tt>NaN</tt>, in which case 
1737      * all comparison operations return <tt>false</tt>.</p>
1738      * @param v A value or object.
1739      * @param o A value or object.
1740      * @return <tt>true</tt> if the first operand is greater than or equal to the second 
1741      * operand; otherwise <tt>false</tt>.
1742      * @since 1.0
1743      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1744      */
1745     @Override
1746     protected final boolean gte(Object v, Object o) {
1747         v = Js.valueOf(v);
1748         o = Js.valueOf(o);
1749         if (Js.undefined(v) || Js.undefined(o)) {
1750             return false;
1751         }
1752         if (v instanceof String && o instanceof String) {
1753             return ((String)v).compareTo((String)o) >= 0;
1754         }
1755         try {
1756             return !(getNumber(v).doubleValue() < getNumber(o).doubleValue());
1757         } catch (Exception e1) {
1758             return Js.toString(v).compareTo(Js.toString(o)) >= 0;
1759         }
1760     }
1761 
1762     private static final boolean isNumerical(Object o) {
1763         return o instanceof Number || o instanceof Character;
1764     }
1765 
1766     /**
1767      * <p>Checks whether the two operands are "equal" using a more relaxed definition of 
1768      * sameness that allows type conversions, resembling the equality operator in 
1769      * JavaScript.</p>
1770      * <p>The equality and identity operations check whether two values are the same, using 
1771      * two different definitions of sameness. Both operations accept operands of any type, 
1772      * and both return <tt>true</tt> if their operands are the same and <tt>false</tt> 
1773      * if they are different. The identity operation checks whether its two operands are 
1774      * "identical" using a strict definition of sameness. The equality operation checks 
1775      * whether its two operands are "equal" using a more relaxed definition of sameness 
1776      * that allows type conversions.</p>
1777      * <p>The identity operation is standardized by ECMAScript v3 and implemented in 
1778      * JavaScript 1.3 and later. Be sure you understand the differences between the 
1779      * assignment, equality, and identity operations, and be careful to use the correct one 
1780      * when coding! Although it is tempting to call all three operations "equals," it may 
1781      * help to reduce confusion if you read "gets or is assigned" for assignment operation, 
1782      * "is equal to" for equality operation, and "is identical to" for identity operation.</p>
1783      * <p>In JavaScript, numbers, strings, and boolean values are compared by value. In this 
1784      * case, two separate values are involved, and the equality and identity operations 
1785      * check that these two values are identical. This means that two variables are equal 
1786      * or identical only if they contain the same value. For example, two strings are equal 
1787      * only if they each contain exactly the same characters.</p>
1788      * <p>On the other hand, objects, arrays, and functions are compared by reference. This 
1789      * means that two variables are equal only if they refer to the same object. Two 
1790      * separate arrays are never equal or identical, even if they contain equal or identical 
1791      * elements. Two variables that contain references to objects, arrays, or functions are 
1792      * equal only if they refer to the same object, array, or function. If you want to test 
1793      * that two distinct objects contain the same properties or that two distinct arrays 
1794      * contain the same elements, you'll have to check the properties or elements individually 
1795      * for equality or identity. And, if any of the properties or elements are themselves 
1796      * objects or arrays, you'll have to decide how deep you want the comparison to go.</p>
1797      * <p>The following rules determine whether two values are equal according to the 
1798      * equality operation:
1799      * <ul>
1800      * <li>If the two values have the same type, test them for identity. If the values are 
1801      * identical, they are equal; if they are not identical, they are not equal.</li>
1802      * <li>If the two values do not have the same type, they may still be equal. Use the 
1803      * following rules and type conversions to check for equality:</li>
1804      * <ul>
1805      * <li>If one value is null and the other is undefined, they are equal.</li>
1806      * <li>If one value is a number and the other is a string, convert the string to a 
1807      * number and try the comparison again, using the converted value.</li>
1808      * <li>If either value is <tt>true</tt>, convert it to 1 and try the comparison 
1809      * again. If either value is <tt>false</tt>, convert it to 0 and try the comparison 
1810      * again.</li>
1811      * <li>If one value is an object and the other is a number or string, convert the 
1812      * object to a primitive and try the comparison again. An object is converted to a 
1813      * primitive value by either its <tt>toString()</tt> method or its <tt>valueOf()</tt> 
1814      * method. The built-in classes of core JavaScript attempt <tt>valueOf()</tt> 
1815      * conversion before <tt>toString()</tt> conversion, except for the Date class, 
1816      * which performs <tt>toString()</tt> conversion. Objects that are not part of core 
1817      * JavaScript may convert themselves to primitive values in an implementation-defined 
1818      * way.</li>
1819      * <li>Any other combinations of values are not equal.</li>
1820      * </ul>
1821      * </ul>
1822      * @param v Any value or object.
1823      * @param o Any value or object.
1824      * @return <tt>true</tt> if the first operand equals the second; <tt>false</tt>, 
1825      * otherwise;
1826      * @since 1.0
1827      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
1828      */
1829     protected final boolean eqv(Object v, Object o) {
1830         if (v.getClass() == o.getClass()) {
1831             return v.equals(o);
1832         } else if (isNumerical(v) && o instanceof String) {
1833             try {
1834                 return eqv(v, Double.parseDouble((String)o));
1835             } catch (NumberFormatException nfe) {
1836                 return false;
1837             }
1838         } else if (v instanceof String && isNumerical(o)) {
1839             try {
1840                 return eqv(Double.parseDouble((String)v), o);
1841             } catch (NumberFormatException nfe) {
1842                 return false;
1843             }
1844         } else if (isNumerical(v) && isNumerical(o)) {
1845             return SimUtil.getNumber(v).doubleValue() ==
1846                    SimUtil.getNumber(o).doubleValue();
1847         } else if (v instanceof Boolean) {
1848             boolean b = (Boolean)v;
1849             return eqv(b ? 1 : 0, o);
1850         } else if (o instanceof Boolean) {
1851             boolean b = (Boolean)o;
1852             return eqv(v, b ? 1 : 0);
1853         } else if (v instanceof String) {
1854             return eqv(v, Js.toString(o));
1855         } else if (o instanceof String) {
1856             return eqv(Js.toString(v), o);
1857         } else {
1858             return false;
1859         }
1860     }
1861 }