JAL-1807 update
[jalviewjs.git] / site / js / j2sjmol.js
1 // j2sjmol.js 
2
3 // latest author: Bob Hanson, St. Olaf College, hansonr@stolaf.edu
4  
5 // Requires JSmolCore.js and (for now; probably) JSmol.js
6 // This version of j2slib requires jQuery and works in both Chrome and MSIE locally,
7 // though Chrome cannot read local data files, and MSIE cannot read local binary data files.
8
9 // Java programming notes by Bob Hanson:
10 //   
11 //   There are a few motifs to avoid when optimizing Java code to work smoothly
12 //   with the J2S compiler:
13 //   
14 //   arrays: 
15 //   
16 // 1. an array with null elements cannot be typed and must be avoided.
17 // 2. instances of Java "instance of" involving arrays must be found and convered to calls to Clazz.isA...
18 // 3. new int[n][] must not be used. Use instead JU.AU.newInt2(n);
19 // 4. new int[] { 1, 2, 3 } has problems because it creates simply [ ] and not IntArray32
20 //   
21 //   numbers:
22 //   
23 // 1. Remember that EVERY number in JavaScript is a double -- doesn't matter if it is in IntArray32 or not. 
24 // 2. You cannot reliably use Java long, because doubles consume bits for the exponent which cannot be tested.
25 // 3. Bit 31 of an integer is unreliable, since (int) -1 is now  , not just 0zFFFFFFFF, and 
26 //    FFFFFFFF + 1 = 100000000, not 0. In JavaScript, 0xFFFFFFFF is 4294967295, not -1.
27 //    This means that writeInt(b) will fail if b is negative. What you need is instead
28 //    writeInt((int)(b & 0xFFFFFFFFl) so that JavaScript knocks off the high bits explicitly. 
29 //
30 //   general:
31 //
32 // 1. j2sRequireImport xxxx is needed if xxxx is a method used in a static function
33 // 2. URL.getContent() is not supported. Use other means based on URL.toString()
34 // 3. It is critical for performance to avoid any significant amount of function overloading.
35 //    In particular, methods such as xxx(int a, int b) and xxx(float a, int b) MUST be renamed,
36 //    because JavaScript only has Number, and there is absolutely no way to tell these apart.
37 //    It's probably bad Java programming, anyway.
38 // 4. Calls to super(...) can almost always be avoided. These trigger the SAEM
39 //    (searchAndExecuteMethod) call, and it is very destructive to performance.
40 //    Just find another way to do it.   
41
42  // NOTES by Bob Hanson: 
43  
44  // J2S class changes:
45
46  // BH 7/19/2015 6:18:17 PM added os.name, line.separator, etc. to System.getProperty()
47  // BH 7/19/2015 5:39:10 PM added java.lang.System = System
48  // BH 7/19/2015 10:33:10 AM fix for SAEM equating "null" with number or boolean
49  // BH 7/18/2015 6:08:05 PM for Jmol I was able to remove the $private/$fx business, but now
50  //    I see that in general that cannot be done. Thinking about a strategy...
51  // BH 7/18/2015 4:43:38 PM better handling of TypeError and InternalError for e.getMessage() and e.getStackTrace()
52  // BH 7/17/2015 11:51:15 AM adds class.getResource(name) and class.getResourceAsStream(name) 
53  // BH 7/16/2015 7:56:49 PM general instantiation using any constructor (in Java here):
54  // BH  x = class.forName("my.class.name").newInstance()
55  // BH or
56  // BH  x = class.forName("my.class.name").getConstructor(String.class,String.class).newInstance(new Object[] {"test", "now"})
57  // BH 7/15/2015 11:34:58 PM adding System.lineSeparator()
58  // BH 7/15/2015 7:32:41 AM adding class.getCanonicalName == getName
59  // BH 5/31/2015 5:38:14 PM  NPEExceptionPredicate fix
60  // BH 4/25/2015 9:16:12 AM SAEM misrepresnting Number as Object in parameters and Integer as Number 
61  // BH 4/24/2015 7:32:54 AM Object.hashCode() and System.getIdentityHashCode() fail. changed to:     return this._$hashcode || (this._$hashcode = ++Clazz._hashCode)
62  // BH 4/23/2015 9:08:59 AM Clazz.instanceOf(a, b) needs to check for a == b.   
63  // BH 4/23/2015 9:08:59 AM xx.getContentType() is nonfunctional. Array.newInstance now defines a wrapper for .getClass().getComponentType() that works  
64  // BH 4/12/2015 11:48:03 AM added Clazz.getStackTrace(-n) -- reports actual parameter values for n levels
65  // BH 4/10/2015 8:23:05 AM adding Int32Array.prototype.clone and Float64.prototype.clone
66  // BH 4/5/2015 8:12:57 AM refactoring j2slib (this file) to make private functions really private using var
67  // BH 4/3/2015 6:14:34 AM adding anonymous local "ClazzLoader" (Clazz._Loader) --> "_Loader"
68  // BH 4/3/2015 6:14:34 AM adding Clazz._Loader._classPending, Clazz._Loader._classCount
69  // BH 4/3/2015 6:14:34 AM adding Clazz._Loader._checkLoad 
70  //  -- forces asynchronous class loading
71  //  -- builds Clazz._Loader._classPending and Clazz._classCount
72  //  -- allows reporting 
73  
74  // BH 3/24/2015 4:11:26 AM better file load failure message in _Loader.evaluate 
75  // BH 2/28/2015 7:30:25 AM corrects newIntArray32() and newArray() for pre-defined arrays 
76  //             int[] a =  new int[] {1,2,3,343};
77  //             int[][] b = new int[][] {new int[]{4,5},new int[]{5,6}}; 
78
79  // BH 9/29/2014 11:34:19 PM removing support for getClass().isArray() 
80  // BH 8/29/2014 9:15:57 AM total reworking of Java2Script in preparation for all-asynchronous loading
81  //                         (currently sync loading is only for 
82  //                                                                                                LOAD command and load() function without ASYNC
83  //                            getInterface() 
84  //                         see JSmol.js and Jmol._isAsync flag
85  // BH 5/11/2015 5:58:42 AM adding __signatures for debugging SAEM issues 
86  // BH 3/29/2015 8:12:44 PM System.getProperty(x, "") does not return ""
87  // BH 8/23/2014 10:04:19 AM cleaning up a few general methods; Clazz.removeArrayItem
88  // BH 6/1/2014 10:58:46 AM fix for Clazz.isAP() not working
89  // BH 5/26/2014 5:19:29 PM removing superConstructor call in creating Enum constants
90  // BH 4/1/2014 7:55:54 PM removing all $fz references and instances where sub/super classes have same private function names
91  // BH 4/1/2014 4:47:30 PM all $_X removed; this is taken care of by Google Closure Compiler
92  // BH 4/1/2014 6:40:08 AM removing ClassLoader -- equals Clazz._Loader
93  // BH 4/1/2014 6:40:08 AM removing ClassLoaderProgressMonitor -- equals _LoaderProgressMonitor
94  // BH 4/1/2014 6:17:21 AM removing Class  -- only used for "Class.forName" in Jmol, which ANT will now change to "Clazz._4Name"
95  // BH 3/7/2014 9:05:06 AM Array.prototype.toString should not be aliased. -- http://sourceforge.net/p/jmol/bugs/560/ with Google Visualization
96
97  // BH 1/30/2014 12:54:22 PM gave all field variables prefix underscore. This allows Google Closure Compiler to skip them.  
98  // BH 12/3/2013 3:39:57 PM window["j2s.lib"].base implemented
99  // BH 12/1/2013 5:34:21 AM removed _LoaderProgressMonitor.initialize and all Clazz.event business; handled by Jmol.clearVars()
100  // BH 11/30/2013 12:43:58 PM adding Clazz.arrayIs() -- avoids Number.constructor.toString() infinite recursion
101  // BH 11/29/2013 6:33:51 AM adding Clazz._profiler -- reports use of SAEM
102  // BH 11/10/2013 9:02:20 AM fixing fading in MSIE  
103  // BH 11/3/2013 7:21:39 AM additional wrapping functions for better compressibility
104  // BH 10/30/2013 8:10:58 AM added getClass().getResource() -- returning a relative string, not a URL
105  // BH 10/30/2013 6:43:00 AM removed second System def and added System.$props and default System.property "line.separator" 
106  // BH 6/15/2013 8:02:07 AM corrections to Class.isAS to return true if first element is null
107  // BH 6/14/2013 4:41:09 PM corrections to Clazz.isAI and related methods to include check for null object
108  // BH 3/17/2013 11:54:28 AM adds stackTrace for ERROR 
109
110  // BH 3/13/2013 6:58:26 PM adds Clazz.clone(me) for BS clone 
111  // BH 3/12/2013 6:30:53 AM fixes Clazz.exceptionOf for ERROR condition trapping
112  // BH 3/2/2013 9:09:53 AM delete globals c$ and $fz
113  // BH 3/2/2013 9:10:45 AM optimizing defineMethod using "look no further" "@" parameter designation (see "\\@" below -- removed 3/23/13)
114  // BH 2/27/2013 optimizing Clazz.getParamsType for common cases () and (Number)
115  // BH 2/27/2013 optimizing SAEM delegation for hashCode and equals -- disallows overloading of equals(Object)
116  
117  // BH 2/23/2013 found String.replaceAll does not work -- solution was to never call it.
118  // BH 2/9/2013 9:18:03 PM Int32Array/Float64Array fixed for MSIE9
119  // BH 1/25/2013 1:55:31 AM moved package.js from j2s/java to j2s/core 
120  // BH 1/17/2013 4:37:17 PM String.compareTo() added
121  // BH 1/17/2013 4:52:22 PM Int32Array and Float64Array may not have .prototype.sort method
122  // BH 1/16/2013 6:20:34 PM Float64Array not available in Safari 5.1
123  // BH 1/14/2013 11:28:58 PM  Going to all doubles in JavaScript (Float64Array, not Float32Array)
124  //   so that (new float[] {13.48f})[0] == 13.48f, effectively
125
126  // BH 1/14/2013 12:53:41 AM  Fix for Opera 10 not loading any files
127  // BH 1/13/2013 11:50:11 PM  Fix for MSIE not loading (nonbinary) files locally
128  
129  // BH 12/1/2012 9:52:26 AM Compiler note: Thread.start() cannot be executed within the constructor;
130  
131  // BH 11/24/2012 11:08:39 AM removed unneeded sections
132  // BH 11/24/2012 10:23:22 AM  all XHR uses sync loading (_Loader.setLoadingMode)
133  // BH 11/21/2012 7:30:06 PM    if (base)       map["@" + pkg] = base;  critical for multiple applets
134
135  // BH 10/8/2012 3:27:41 PM         if (clazzName.indexOf("Array") >= 0) return "Array"; in Clazz.getClassName for function
136  // BH removed Clazz.ie$plit = "\\2".split (/\\/).length == 1; unnecessary; using RegEx slows process significantly in all browsers
137  // BH 10/6/12 added Int32Array, Float32Array, newArrayBH, upgraded java.lang and java.io
138  // BH added Integer.bitCount in core.z.js
139  // BH changed alert to Clazz.alert in java.lang.Class.js *.ClassLoader.js, java.lang.thread.js
140  // BH removed toString from innerFunctionNames due to infinite recursion
141  // BH note: Logger.error(null, e) does not work -- get no constructor for (String) (TypeError)
142  // BH added j2s.lib.console
143  // BH allowed for alias="."
144  // BH removed alert def --> Clazz.alert
145  // BH added wrapper at line 2856 
146  // BH newArray fix at line 2205
147  // BH System.getProperty fix at line 6693
148  // BH added Enum .value() method at line 2183
149  // BH added System.getSecurityManager() at end
150  // BH added String.contains() at end
151  // BH added System.gc() at end
152  // BH added Clazz.exceptionOf = updated
153  // BH added String.getBytes() at end
154  
155
156 LoadClazz = function() {
157
158 // BH This is the ONLY global used in J2S now. I do not think it is necessary,
159 // but it is created by the compiler, and I have not found a work-around.
160 // it is used as a local variable in class definitions to point to the 
161 // current method. See Clazz.p0p and Clazz.pu$h
162
163 c$ = null;
164
165 if (!window["j2s.clazzloaded"])
166         window["j2s.clazzloaded"] = false;
167
168 if (window["j2s.clazzloaded"])return;
169
170 window["j2s.clazzloaded"] = true;
171
172 window["j2s.object.native"] = true;
173
174  // Clazz changes:
175
176  /* http://j2s.sf.net/ *//******************************************************************************
177  * Copyright (c) 2007 java2script.org and others.
178  * All rights reserved. This program and the accompanying materials
179  * are made available under the terms of the Eclipse Public License v1.0
180  * which accompanies this distribution, and is available at
181  * http://www.eclipse.org/legal/epl-v10.html
182  *
183  * Contributors:
184  *     Zhou Renjian - initial API and implementation
185  *****************************************************************************/
186 /*******
187  * @author zhou renjian
188  * @create Nov 5, 2005
189  *******/
190  
191
192 /**
193  * Class Clazz. All the methods are static in this class.
194  */
195 /* static */
196 /*Class = */ Clazz = {
197   _isQuiet: false
198 };
199
200 ;(function(Clazz, Jmol) {
201
202 var __debuggingBH = false;
203 var _globals = ["j2s.clazzloaded", "j2s.object.native"];
204 Clazz.setGlobal = function(a, v) {
205         _globals.push(a);
206         window[a] = v;
207 }
208
209 Clazz.getGlobals = function() {
210         return _globals.sort().join("\n");
211 }
212
213 Clazz.setConsoleDiv = function(d) {
214         window["j2s.lib"] && (window["j2s.lib"].console = d);
215 };
216
217 // BH Clazz.getProfile monitors exactly what is being delegated with SAEM,
218 // which could be a bottle-neck for function calling.
219 // This is critical for performance optimization.
220
221 // Jmol.getProfile()
222
223 var _profile = (window["j2s.doProfile"]  && self.JSON ? {} : null);
224
225 NullObject = function () {};
226
227 /* protected */
228 Clazz._supportsNativeObject = window["j2s.object.native"];
229
230 if (Clazz._supportsNativeObject) {
231         Clazz._O = function () {};
232         Clazz._O.__CLASS_NAME__ = "Object";
233         Clazz._O["getClass"] = function () { return Clazz._O; }; 
234 } else {
235         Clazz._O = Object;
236 }
237
238 Clazz.Console = {};
239 Clazz.dateToString = Date.prototype.toString;
240 Clazz._hashCode = 0;
241
242 var addProto = function(proto, name, func) {
243         return proto[name] = func;
244 };
245
246 ;(function(proto) {
247         addProto(proto, "equals", function (obj) {
248                 return this == obj;
249         });
250
251         addProto(proto, "hashCode", function () {
252   
253     return this._$hashcode || (this._$hashcode = ++Clazz._hashCode)
254
255   
256                 try {
257                         return this.toString ().hashCode ();
258                 } catch (e) {
259                         var str = ":";
260                         for (var s in this) {
261                                 str += s + ":"
262                         }
263                         return str.hashCode ();
264                 }
265         });
266
267         addProto(proto, "getClass", function () { return Clazz.getClass (this); });
268
269         addProto(proto, "clone", function () { return Clazz.clone(this); });
270
271         Clazz.clone = function(me) {
272                 // BH allows @j2sNative access without super constructor
273                 var o = new me.constructor();
274                 for (var i in me) {
275                         o[i] = me[i];
276       }
277                 return o;
278         }
279 /*
280  * Methods for thread in Object
281  */
282         addProto(proto, "finalize", function () {});
283         addProto(proto, "notify", function () {});
284         addProto(proto, "notifyAll", function () {});
285         addProto(proto, "wait", function () {});
286         addProto(proto, "to$tring", Object.prototype.toString);
287         addProto(proto, "toString", function () { return (this.__CLASS_NAME__ ? "[" + this.__CLASS_NAME__ + " object]" : this.to$tring.apply(this, arguments)); });
288         Clazz._extendedObjectMethods = [ "equals", "hashCode", "getClass", "clone", "finalize", "notify", "notifyAll", "wait", "to$tring", "toString" ];
289
290 })(Clazz._O.prototype);
291
292 Clazz.extendJO = function(c, name) {  
293         if (name)
294                 c.__CLASS_NAME__ = c.prototype.__CLASS_NAME__ = name;
295         if (Clazz._supportsNativeObject) {
296                 for (var i = 0; i < Clazz._extendedObjectMethods.length; i++) {
297                         var p = Clazz._extendedObjectMethods[i];
298                         addProto(c.prototype, p, Clazz._O.prototype[p]);
299                 }
300         }
301 };
302
303 /**
304  * Try to fix bug on Safari
305  */
306 //InternalFunction = Object;
307
308 Clazz.extractClassName = function(clazzStr) {
309         // [object Int32Array]
310         var clazzName = clazzStr.substring (1, clazzStr.length - 1);
311         return (clazzName.indexOf("Array") >= 0 ? "Array" // BH -- for Float64Array and Int32Array
312                 : clazzName.indexOf ("object ") >= 0 ? clazzName.substring (7) // IE
313                 : clazzName);
314 }
315 /**
316  * Return the class name of the given class or object.
317  *
318  * @param clazzHost given class or object
319  * @return class name
320  */
321 /* public */
322 Clazz.getClassName = function (obj) {
323         if (obj == null)
324                 return "NullObject";
325         if (obj instanceof Clazz.CastedNull)
326                 return obj.clazzName;
327         switch(typeof obj) {
328         case "number":
329                 return "n";
330         case "boolean":
331                 return "b";
332         case "string":
333                 // Always treat the constant string as String object.
334                 // This will be compatiable with Java String instance.
335                 return "String";
336         case "function":
337                 if (obj.__CLASS_NAME__)
338                         return (arguments[1] ? obj.__CLASS_NAME__ : "Class"); /* user defined class name */
339                 var s = obj.toString();
340                 var idx0 = s.indexOf("function");
341                 if (idx0 < 0)
342                         return (s.charAt(0) == '[' ? Clazz.extractClassName(s) : s.replace(/[^a-zA-Z0-9]/g, ''));
343                 var idx1 = idx0 + 8;
344                 var idx2 = s.indexOf ("(", idx1);
345                 if (idx2 < 0)
346                         return "Object";
347                 s = s.substring (idx1, idx2);
348                 if (s.indexOf("Array") >= 0)
349                         return "Array"; 
350                 s = s.replace (/^\s+/, "").replace (/\s+$/, "");
351                 return (s == "anonymous" || s == "" ? "Function" : s);
352         case "object":
353                 if (obj.__CLASS_NAME__) // user defined class name
354                         return obj.__CLASS_NAME__;
355                 if (!obj.constructor)
356                         return "Object"; // For HTML Element in IE
357                 if (!obj.constructor.__CLASS_NAME__) {
358                         if (obj instanceof Number)
359                                 return "Number";
360                         if (obj instanceof Boolean)
361                                 return "Boolean";
362                         if (obj instanceof Array)
363                                 return "Array";
364                         var s = obj.toString();
365       // "[object Int32Array]"
366                         if (s.charAt(0) == '[')
367                                 return Clazz.extractClassName(s);
368                 }
369         return Clazz.getClassName (obj.constructor, true);
370         }
371   // some new, unidentified class
372   return "Object";
373 };
374 /**
375  * Return the class of the given class or object.
376  *
377  * @param clazzHost given class or object
378  * @return class name
379  */
380 /* public */
381 Clazz.getClass = function (clazzHost) {
382         if (!clazzHost)
383                 return Clazz._O;        // null/undefined is always treated as Object
384         if (typeof clazzHost == "function")
385                 return clazzHost;
386         var clazzName;
387         if (clazzHost instanceof Clazz.CastedNull) {
388                 clazzName = clazzHost.clazzName;
389         } else {
390                 switch (typeof clazzHost) {
391                 case "string":
392                         return String;
393           case "object":
394                         if (!clazzHost.__CLASS_NAME__)
395                                 return (clazzHost.constructor || Clazz._O);
396                         clazzName = clazzHost.__CLASS_NAME__;
397                 break;
398                 default:
399                         return clazzHost.constructor;
400                 }
401         }
402         return Clazz.evalType(clazzName, true);
403 };
404
405
406 /* private */
407 var checkInnerFunction = function (hostSuper, funName) {
408         for (var k = 0; k < Clazz.innerFunctionNames.length; k++)
409                 if (funName == Clazz.innerFunctionNames[k] && 
410                                 Clazz._innerFunctions[funName] === hostSuper[funName])
411                         return true;
412         return false;
413 };
414
415 var args4InheritClass = function () {};
416
417 Clazz.inheritArgs = new args4InheritClass ();
418
419 /**
420  * Inherit class with "extends" keyword and also copy those static members. 
421  * Example, as in Java, if NAME is a static member of ClassA, and ClassB 
422  * extends ClassA then ClassB.NAME can be accessed in some ways.
423  *
424  * @param clazzThis child class to be extended
425  * @param clazzSuper super class which is inherited from
426  * @param objSuper super class instance
427  */
428 /* protected */
429 Clazz.inheritClass = function (clazzThis, clazzSuper, objSuper) {
430         //var thisClassName = Clazz.getClassName (clazzThis);
431         for (var o in clazzSuper) {
432                 if (o != "b$" && o != "prototype" && o != "superClazz"
433                                 && o != "__CLASS_NAME__" && o != "implementz"
434                                 && !checkInnerFunction (clazzSuper, o)) {
435                         clazzThis[o] = clazzSuper[o];
436                 }
437         }
438         if (Clazz.unloadedClasses[Clazz.getClassName(clazzThis, true)]) {
439                 // Don't change clazzThis.protoype! Keep it!
440         } else if (objSuper) {
441                 // ! Unsafe reference prototype to an instance!
442                 // Feb 19, 2006 --josson
443                 // OK for this reference to an instance, as this is anonymous instance,
444                 // which is not referenced elsewhere.
445                 // March 13, 2006
446                 clazzThis.prototype = objSuper; 
447         } else if (clazzSuper !== Number) {
448                 clazzThis.prototype = new clazzSuper (Clazz.inheritArgs);
449         } else { // Number
450                 clazzThis.prototype = new Number ();
451         }
452         clazzThis.superClazz = clazzSuper;
453         /*
454          * Is it necessary to reassign the class name?
455          * Mar 10, 2006 --josson
456          */
457         //clazzThis.__CLASS_NAME__ = thisClassName;
458         clazzThis.prototype.__CLASS_NAME__ = clazzThis.__CLASS_NAME__;
459 };
460
461 /**
462  * Implementation of Java's keyword "implements".
463  * As in JavaScript there are on "implements" keyword implemented, a property
464  * of "implementz" is added to the class to record the interfaces the class
465  * is implemented.
466  * 
467  * @param clazzThis the class to implement
468  * @param interfacez Array of interfaces
469  */
470 /* public */
471 Clazz.implementOf = function (clazzThis, interfacez) {
472         if (arguments.length >= 2) {
473                 if (!clazzThis.implementz)
474                         clazzThis.implementz = [];
475                 var impls = clazzThis.implementz;
476                 if (arguments.length == 2) {
477                         if (typeof interfacez == "function") {
478                                 impls.push(interfacez);
479                                 copyProperties(clazzThis, interfacez);
480                         } else if (interfacez instanceof Array) {
481                                 for (var i = 0; i < interfacez.length; i++) {
482                                         impls.push(interfacez[i]);
483                                         copyProperties(clazzThis, interfacez[i]);
484                                 }
485                         }
486                 } else {
487                         for (var i = 1; i < arguments.length; i++) {
488                                 impls.push(arguments[i]);
489                                 copyProperties(clazzThis, arguments[i]);
490                         }
491                 }
492         }
493 };
494
495 /*
496  * Copy members of interface
497  */
498 /* private */
499 var copyProperties = function(clazzThis, clazzSuper) {
500         for (var o in clazzSuper)
501                 if (o != "b$" 
502                                 && o != "prototype" && o != "superClazz"
503                                 && o != "__CLASS_NAME__" && o != "implementz"
504                                 && (typeof clazzSuper[o] != "function" || !checkInnerFunction(clazzSuper, o)))
505                         clazzThis[o] = clazzThis.prototype[o] = clazzSuper[o];
506 };
507
508 /**
509  * TODO: More should be done for interface's inheritance
510  */
511 /* public */
512 Clazz.extendInterface = Clazz.implementOf;
513
514 /* protected */
515 Clazz.equalsOrExtendsLevel = function (clazzThis, clazzAncestor) {
516         if (clazzThis === clazzAncestor)
517                 return 0;
518         if (clazzThis.implementz) {
519                 var impls = clazzThis.implementz;
520                 for (var i = 0; i < impls.length; i++) {
521                         var level = Clazz.equalsOrExtendsLevel (impls[i], clazzAncestor);
522                         if (level >= 0)
523                                 return level + 1;
524                 }
525         }
526         return -1;
527 };
528
529 /* protected */
530 Clazz.getInheritedLevel = function (clazzTarget, clazzBase) {
531         if (clazzTarget === clazzBase)
532                 return 0;
533         var isTgtStr = (typeof clazzTarget == "string");
534         if (isTgtStr && ("void" == clazzTarget || "unknown" == clazzTarget))
535                 return -1;
536         var isBaseStr = (typeof clazzBase == "string");
537         if (isBaseStr && ("void" == clazzBase || "unknown" == clazzBase))
538                 return -1;
539         if (clazzTarget === (isTgtStr ? "NullObject" : NullObject)) {
540                 switch (clazzBase) {
541     case "n":
542     case "b":
543       return -1;
544                 case Number:
545                 case Boolean:
546                 case NullObject:
547                         break;
548                 default:
549                         return 0;
550                 }
551         }
552         if (isTgtStr)
553                 clazzTarget = Clazz.evalType(clazzTarget);
554         if (isBaseStr)
555                 clazzBase = Clazz.evalType(clazzBase);
556         if (!clazzBase || !clazzTarget)
557                 return -1;
558         var level = 0;
559         var zzalc = clazzTarget; // zzalc <--> clazz
560         while (zzalc !== clazzBase && level < 10) {
561                 /* maybe clazzBase is interface */
562                 if (zzalc.implementz) {
563                         var impls = zzalc.implementz;
564                         for (var i = 0; i < impls.length; i++) {
565                                 var implsLevel = Clazz.equalsOrExtendsLevel (impls[i], clazzBase);
566                                 if (implsLevel >= 0)
567                                         return level + implsLevel + 1;
568                         }
569                 }
570                 zzalc = zzalc.superClazz;
571                 if (!zzalc)
572                         return (clazzBase === Object || clazzBase === Clazz._O ? 
573                                 // getInheritedLevel(String, CharSequence) == 1
574                                 // getInheritedLevel(String, Object) == 1.5
575                                 // So if both #test(CharSequence) and #test(Object) existed,
576                                 // #test("hello") will correctly call #test(CharSequence)
577                                 // instead of #test(Object).
578                                 level + 1.5 // 1.5! Special!
579                         : -1);
580                 level++;
581         }
582         return level;
583 };
584
585
586 /**
587  * Implements Java's keyword "instanceof" in JavaScript's way.
588  * As in JavaScript part of the object inheritance is implemented in only-
589  * JavaScript way.
590  *
591  * @param obj the object to be tested
592  * @param clazz the class to be checked
593  * @return whether the object is an instance of the class
594  */
595 /* public */
596 Clazz.instanceOf = function (obj, clazz) {
597   // allows obj to be a class already, from arrayX.getClass().isInstance(y)
598         return (obj != null && clazz && (obj == clazz || obj instanceof clazz || Clazz.getInheritedLevel(Clazz.getClassName(obj), clazz) >= 0));
599 };
600
601 /**
602  * Call super method of the class. 
603  * The same effect as Java's expression:
604  * <code> super.* () </code>
605  * 
606  * @param objThis host object
607  * @param clazzThis class of declaring method scope. It's hard to determine 
608  * which super class is right class for "super.*()" call when it's in runtime
609  * environment. For example,
610  * 1. ClasssA has method #run()
611  * 2. ClassB extends ClassA overriding method #run() with "super.run()" call
612  * 3. ClassC extends ClassB
613  * 4. objC is an instance of ClassC
614  * Now we have to decide which super #run() method is to be invoked. Without
615  * explicit clazzThis parameter, we only know that objC.getClass() is ClassC 
616  * and current method scope is #run(). We do not known we are in scope 
617  * ClassA#run() or scope of ClassB#run(). if ClassB is given, Clazz can search
618  * all super methods that are before ClassB and get the correct super method.
619  * This is the reason why there must be an extra clazzThis parameter.
620  * @param funName method name to be called
621  * @param funParams Array of method parameters
622  */
623 /* public */
624 Clazz.superCall = function (objThis, clazzThis, funName, funParams) {
625         var fx = null;
626         var i = -1;
627         var clazzFun = objThis[funName];
628         if (clazzFun) {
629                 if (clazzFun.claxxOwner) { 
630                         // claxxOwner is a mark for methods that is single.
631                         if (clazzFun.claxxOwner !== clazzThis) {
632                                 // This is a single method, call directly!
633                                 fx = clazzFun;
634         
635                         }
636                 } else if (!clazzFun.stacks && !(clazzFun.lastClaxxRef
637                                         && clazzFun.lastClaxxRef.prototype[funName]
638                                         && clazzFun.lastClaxxRef.prototype[funName].stacks)) { // super.toString
639                         fx = clazzFun;
640                 } else { // normal wrapped method
641                         var stacks = clazzFun.stacks;
642                         if (!stacks)
643                                 stacks = clazzFun.lastClaxxRef.prototype[funName].stacks;
644                         for (i = stacks.length; --i >= 0;) {
645                                 /*
646                                  * Once super call is computed precisely, there are no need 
647                                  * to calculate the inherited level but just an equals
648                                  * comparision
649                                  */
650                                 //var level = Clazz.getInheritedLevel (clazzThis, stacks[i]);
651                                 if (clazzThis === stacks[i]) { // level == 0
652                                         if (i > 0) {
653                                                 fx = stacks[--i].prototype[funName];
654                                         } else {
655                                                 /*
656                                                  * Will this case be reachable?
657                                                  * March 4, 2006
658                                                  * Should never reach here if all things are converted
659                                                  * by Java2Script
660                                                  */
661                                                 fx = stacks[0].prototype[funName]["\\unknown"];
662                                         }
663                                         break;
664                                 } else if (Clazz.getInheritedLevel (clazzThis, stacks[i]) > 0) {
665                                         fx = stacks[i].prototype[funName];
666                                         break;
667                                 }
668                         } // end of for loop
669                 } // end of normal wrapped method
670         } // end of clazzFun
671         if (!fx) {
672                 if (funName != "construct") {
673                         Clazz.alert (["j2slib","no class found",(funParams).typeString])
674                         newMethodNotFoundException(objThis, clazzThis, funName, 
675                                         Clazz.getParamsType(funParams).typeString);     
676                 }
677                 /* there are members which are initialized out of the constructor */
678                 /* No super constructor! */
679                 return;
680         }
681         /* there are members which are initialized out of the constructor */
682         if (i == 0 && funName == "construct") {
683                 var ss = clazzFun.stacks;
684                 if (ss && !ss[0].superClazz && ss[0].con$truct)
685                         ss[0].con$truct.apply (objThis, []);
686         }
687         /*# {$no.debug.support} >>x #*/
688         /* not used in Jmol
689         if (Clazz.tracingCalling) {
690                 var caller = arguments.callee.caller;
691                 if (caller === Clazz.superConstructor) {
692                         caller = caller.arguments.callee.caller;
693                 }
694                 Clazz._callingStackTraces.push(new Clazz.callingStack (caller, clazzThis));
695                 var ret = fx.apply (objThis, (funParams == null) ? [] : funParams);
696                 Clazz._callingStackTraces.pop();
697                 return ret;
698         }
699         */
700         /*# x<< #*/
701         return fx.apply (objThis, funParams || []);
702 };
703
704 /**
705  * Call super constructor of the class. 
706  * The same effect as Java's expression: 
707  * <code> super () </code>
708  */
709 /* public */
710 Clazz.superConstructor = function (objThis, clazzThis, funParams) {
711         Clazz.superCall (objThis, clazzThis, "construct", funParams);
712         /* If there are members which are initialized out of the constructor */
713         if (clazzThis.con$truct) {
714                 clazzThis.con$truct.apply (objThis, []);
715         }
716 };
717
718 /**
719  * Class for null with a given class as to be casted.
720  * This class will be used as an implementation of Java's casting way.
721  * For example,
722  * <code> this.call ((String) null); </code>
723  */
724 /* public */
725 Clazz.CastedNull = function (asClazz) {
726         if (asClazz) {
727                 if (asClazz instanceof String) {
728                         this.clazzName = asClazz;
729                 } else if (asClazz instanceof Function) {
730                         this.clazzName = Clazz.getClassName (asClazz, true);
731                 } else {
732                         this.clazzName = "" + asClazz;
733                 }
734         } else {
735                 this.clazzName = "Object";
736         }
737         this.toString = function () {
738                 return null;
739         };
740         this.valueOf = function () {
741                 return null;
742         };
743 };
744
745 /**
746  * API for Java's casting null.
747  * @see Clazz.CastedNull
748  *
749  * @param asClazz given class
750  * @return an instance of class Clazz.CastedNull
751  */
752 /* public */
753 Clazz.castNullAs = function (asClazz) {
754         return new Clazz.CastedNull (asClazz);
755 };
756
757 /////////////////////////// Exception handling ////////////////////////////
758
759 /*
760  * Use to mark that the Throwable instance is created or not.
761  * 
762  * Called from java.lang.Throwable, as defined in JSmolJavaExt.js
763  * 
764  * The underscore is important - it tells the JSmol ANT task to NOT 
765  * turn this into Clazz_initializingException, because coreBottom2.js does 
766  * not include that call, and so Google Closure Compiler does not minify it.
767  *        
768  */
769 /* public */
770 Clazz._initializingException = false;
771
772 /**
773  * BH: used in Throwable
774  *  
775  */  
776 /* public */
777 Clazz._callingStackTraces = [];
778
779 /** 
780  * MethodException will be used as a signal to notify that the method is
781  * not found in the current clazz hierarchy.
782  */
783 /* private */
784 var MethodException = function () {
785         this.toString = function () {
786                 return "J2S MethodException";
787         };
788 };
789 /* private */
790 //var MethodNotFoundException = function () {
791 //      this.toString = function () {
792 //              return "J2S MethodNotFoundException";
793 //      };
794 //};
795
796   var _isNPEExceptionPredicate;
797
798 /* super private */
799 ;(function() { 
800   /* sgurin: native exception detection mechanism. Only NullPointerException detected and wrapped to java excepions */
801   /** private utility method for creating a general regexp that can be used later  
802    * for detecting a certain kind of native exceptions. use with error messages like "blabla IDENTIFIER blabla"
803    * @param msg String - the error message
804    * @param spliterName String, must be contained once in msg
805    * spliterRegex String, a string with the regexp literal for identifying the spitter in exception further error messages.
806    */
807   // reproduce NullPointerException for knowing how to detect them, and create detector function Clazz._isNPEExceptionPredicate
808   var $$o$$ = null;
809   
810   try {
811         $$o$$.hello();
812   } catch (e) {
813     var _ex_reg = function(msg, spliterName, spliterRegex) {
814         if(!spliterRegex) 
815                 spliterRegex="[^\\s]+"; 
816         var idx = msg.indexOf (spliterName), 
817                 str = msg.substring (0, idx) + spliterRegex + msg.substring(idx + spliterName.length), 
818                 regexp = new RegExp("^"+str+"$");
819         return regexp;
820     };
821         if(/Opera[\/\s](\d+\.\d+)/.test(navigator.userAgent)) {// opera throws an exception with fixed messages like "Statement on line 23: Cannot convert undefined or null to Object Backtrace: Line....long text... " 
822                 var idx1 = e.message.indexOf(":"), idx2 = e.message.indexOf(":", idx1+2);
823                 var _NPEMsgFragment = e.message.substr(idx1+1, idx2-idx1-20);
824                 _isNPEExceptionPredicate = function(e) { return e.message.indexOf(_NPEMsgFragment)!=-1; };
825         }       else if(navigator.userAgent.toLowerCase().indexOf("webkit")!=-1) { //webkit, google chrome prints the property name accessed. 
826                 var _exceptionNPERegExp = _ex_reg(e.message, "hello");
827                 _isNPEExceptionPredicate = function(e) { return _exceptionNPERegExp.test(e.message); };
828         }       else {// ie, firefox and others print the name of the object accessed: 
829                 var _exceptionNPERegExp = _ex_reg(e.message, "$$o$$");
830                 _isNPEExceptionPredicate = function(e) { return _exceptionNPERegExp.test(e.message); };
831         }               
832   };
833 })();
834
835 /**sgurin
836  * Implements Java's keyword "instanceof" in JavaScript's way **for exception objects**.
837  * 
838  * calls Clazz.instanceOf if e is a Java exception. If not, try to detect known native 
839  * exceptions, like native NullPointerExceptions and wrap it into a Java exception and 
840  * call Clazz.instanceOf again. if the native exception can't be wrapped, false is returned.
841  * 
842  * @param obj the object to be tested
843  * @param clazz the class to be checked
844  * @return whether the object is an instance of the class
845  * @author: sgurin
846  */
847 Clazz.exceptionOf = function(e, clazz) {
848         if(e.__CLASS_NAME__)
849                 return Clazz.instanceOf(e, clazz);
850   if (!e.getMessage) {
851     e.getMessage = function() {return "" + this};
852   }
853   if (!e.printStackTrace) {
854     e.printStackTrace = function(){};
855     alert(e + " try/catch path:" + Clazz.getStackTrace(-10));
856   }
857         if(clazz == Error) {
858                 if (("" + e).indexOf("Error") < 0)
859       return false;
860                 System.out.println (Clazz.getStackTrace());
861     return true;
862                 // everything here is a Java Exception, not a Java Error
863         }
864         return (clazz == Exception || clazz == Throwable
865                 || clazz == NullPointerException && _isNPEExceptionPredicate(e));
866 };
867
868 /**
869  * BH need to limit this, as JavaScript call stack may be recursive
870  */ 
871 Clazz.getStackTrace = function(n) {
872         n || (n = 25);
873   // updateNode and updateParents cause infinite loop here
874         var s = "\n";
875         var c = arguments.callee;
876   var showParams = (n < 0);
877   if (showParams)
878     n = -n;
879         for (var i = 0; i < n; i++) {
880                 if (!(c = c.caller))
881       break;
882     var sig = (c.toString ? c.toString().substring(0, c.toString().indexOf("{")) : "<native method>");
883                 s += i + " " + (c.exName ? (c.claxxOwner ? c.claxxOwner.__CLASS_NAME__ + "."  : "") + c.exName  + sig.replace(/function /,""): sig) + "\n";
884                 if (c == c.caller) {
885       s += "<recursing>\n";
886       break;
887     }
888     if (showParams) {
889       var args = c.arguments;
890       for (var j = 0; j < args.length; j++) {
891         var sa = "" + args[j];
892         if (sa.length > 60)
893           sa = sa.substring(0, 60) + "...";
894         s += " args[" + j + "]=" + sa.replace(/\s+/g," ") + "\n";
895       }
896     }
897         }
898         return s;
899 }
900
901 ///////////////////// method creation ////////////////////////////////
902
903 /**
904  * Make constructor for the class with the given function body and parameters
905  * signature.
906  * 
907  * @param clazzThis host class
908  * @param funBody constructor body
909  * @param funParams constructor parameters signature
910  */
911 /* public */
912 Clazz.makeConstructor = function (clazzThis, funBody, funParams) {
913         Clazz.defineMethod (clazzThis, "construct", funBody, funParams);
914         if (clazzThis.con$truct) {
915                 clazzThis.con$truct.index = clazzThis.con$truct.stacks.length;
916         }
917         //clazzThis.con$truct = clazzThis.prototype.con$truct = null;
918 };
919
920 /**
921  * Override constructor for the class with the given function body and
922  * parameters signature.
923  * 
924  * @param clazzThis host class
925  * @param funBody constructor body
926  * @param funParams constructor parameters signature
927  */
928 /* public */
929 Clazz.overrideConstructor = function (clazzThis, funBody, funParams) {
930         Clazz.overrideMethod (clazzThis, "construct", funBody, funParams);
931         if (clazzThis.con$truct) {
932                 clazzThis.con$truct.index = clazzThis.con$truct.stacks.length;
933         }
934         //clazzThis.con$truct = clazzThis.prototype.con$truct = null;
935 };
936
937
938 /*
939  * Define method for the class with the given method name and method
940  * body and method parameter signature.
941  *
942  * @param clazzThis host class in which the method to be defined
943  * @param funName method name
944  * @param funBody function object, e.g function () { ... }
945  * @param funParams paramether signature, e.g ["string", "number"]
946  * @return method of the given name. The method may be funBody or a wrapper
947  * of the given funBody.
948  */
949 /* public */
950 Clazz.defineMethod = function (clazzThis, funName, funBody, funParams) {
951         if (Clazz.assureInnerClass) 
952     Clazz.assureInnerClass(clazzThis, funBody);
953         funBody.exName = funName;
954         var fpName = formatParameters(funParams);
955         var proto = clazzThis.prototype;
956         var f$ = proto[funName];
957   if (Clazz._Loader._checkLoad)
958     checkDuplicate(clazzThis, funName, fpName);
959         if (!f$ || (f$.claxxOwner === clazzThis && f$.funParams == fpName)) {
960                 // property "funParams" will be used as a mark of only-one method
961                 funBody.funParams = fpName; 
962                 funBody.claxxOwner = clazzThis;
963                 funBody.exClazz = clazzThis; // make it traceable
964                 return addProto(proto, funName, funBody);
965         }
966   // we have found a duplicate
967         var oldFun = null;
968         var oldStacks = f$.stacks;
969                 if (!oldStacks) {
970                         /* method is not defined by Clazz.defineMethod () */
971       oldStacks = [];
972                         oldFun = f$;
973                         if (f$.claxxOwner) {
974                                 oldStacks[0] = oldFun.claxxOwner;
975                         }
976                 }
977                 /*
978          * Method that is already defined in super class will be overridden
979          * with a new proxy method with class hierarchy stored in a stack.
980          * That is to say, the super methods are lost in this class' proxy
981          * method. 
982          * When method are being called, methods defined in the new proxy 
983          * method will be searched through first. And if no method fitted,
984          * it will then try to search method in the super class stacks.
985          */
986         if (!f$.stacks || f$.claxxReference !== clazzThis) {
987                 //Generate a new delegating method for the class                
988     var id = ++SAEMid;
989         var delegate = function () {
990                 return searchAndExecuteMethod(id, this, arguments.callee.claxxReference, arguments.callee.methodName, arguments);
991         };
992         delegate.methodName = funName;
993         delegate.claxxReference = clazzThis;
994                 f$ = addProto(proto, funName, delegate);                                
995                 // Keep the class inheritance stacks
996                 var arr = [];
997                 for (var i = 0; i < oldStacks.length; i++)
998                         arr[i] = oldStacks[i];
999                 f$.stacks = arr;
1000         }
1001         var ss = f$.stacks;
1002         if (findArrayItem(ss, clazzThis) < 0) ss.push(clazzThis);
1003
1004         if (oldFun) {
1005                 if (oldFun.claxxOwner === clazzThis) {
1006                         f$[oldFun.funParams] = oldFun;
1007                         oldFun.claxxOwner = null;
1008                         // property "funParams" will be used as a mark of only-one method
1009                         oldFun.funParams = null; // null ? safe ? // safe for != null
1010                 } else if (!oldFun.claxxOwner) {
1011                         /*
1012                          * The function is not defined Clazz.defineMethod ().
1013                          * Try to fixup the method ...
1014                          * As a matter of lost method information, I just suppose
1015                          * the method to be fixed is with void parameter!
1016                          */
1017                         f$["\\unknown"] = oldFun;
1018                 }
1019         }
1020         funBody.exClazz = clazzThis; // make it traceable
1021         f$[fpName] = funBody;
1022         return f$;
1023 };                                                
1024
1025 duplicatedMethods = {};
1026
1027 var checkDuplicate = function(clazzThis, funName, fpName) {
1028         var proto = clazzThis.prototype;
1029         var f$ = proto[funName];
1030   if (f$ && (f$.claxxOwner || f$.claxxReference) === clazzThis) {
1031     key = clazzThis.__CLASS_NAME__ + "." + funName + fpName;
1032     var m = duplicatedMethods[key];
1033     if (m) {
1034       var s = "Warning! Duplicate method found for " + key;
1035       System.out.println(s);
1036       Clazz.alert(s);
1037       duplicatedMethods[key] = m + 1; 
1038     } else {
1039       duplicatedMethods[key] = 1;
1040     }
1041   }
1042 }
1043
1044 Clazz.showDuplicates = function(quiet) {
1045   var s = "";
1046   var a = duplicatedMethods;
1047   var n = 0;
1048   for (var key in a)
1049     if (a[key] > 1) {
1050       s += a[key] + "\t" + key + "\n";
1051       n++;
1052     }
1053   s = "Duplicates: " + n + "\n\n" + s;
1054   System.out.println(s);
1055   if (!quiet)
1056     alert(s);
1057 }
1058
1059 var findArrayItem = function(arr, item) {
1060         if (arr && item)
1061                 for (var i = arr.length; --i >= 0;)
1062                         if (arr[i] === item)
1063                                 return i;
1064         return -1;
1065 }
1066
1067 var removeArrayItem = function(arr, item) {
1068         var i = findArrayItem(arr, item);
1069         if (i >= 0) {
1070                 var n = arr.length - 1;
1071                 for (; i < n; i++)
1072                         arr[i] = arr[i + 1];
1073                 arr.length--;
1074                 return true;
1075         }
1076 }
1077
1078 /*
1079  * Other developers may need to extend this formatParameters method
1080  * to deal complicated situation.
1081  */
1082 /* protected */
1083 var formatParameters = function (funParams) {
1084         return (funParams ? funParams.replace (/~([NABSO])/g, 
1085       function ($0, $1) {
1086         switch ($1) {
1087         case 'N':
1088                 return "n";
1089         case 'B':
1090                 return "b";
1091         case 'S':
1092                 return "String";
1093         case 'O':
1094                 return "Object";
1095         case 'A':
1096                 return "Array";
1097         }
1098         return "Unknown";
1099       }).replace (/\s+/g, "").replace (/^|,/g, "\\").replace (/\$/g, "org.eclipse.s") : "\\void");
1100 };
1101
1102 /*
1103  * Override the existed methods which are in the same name.
1104  * Overriding methods is provided for the purpose that the JavaScript
1105  * does not need to search the whole hierarchied methods to find the
1106  * correct method to execute.
1107  * Be cautious about this method. Incorrectly using this method may
1108  * break the inheritance system.
1109  *
1110  * @param clazzThis host class in which the method to be defined
1111  * @param funName method name
1112  * @param funBody function object, e.g function () { ... }
1113  * @param funParams paramether signature, e.g ["string", "number"]
1114  */
1115 /* public */
1116 Clazz.overrideMethod = function(clazzThis, funName, funBody, funParams) {
1117         if (Clazz.assureInnerClass) Clazz.assureInnerClass (clazzThis, funBody);
1118         funBody.exName = funName;
1119         var fpName = formatParameters(funParams);
1120   if (Clazz._Loader._checkLoad)
1121     checkDuplicate(clazzThis, funName, fpName);
1122         /*
1123          * Replace old methods with new method. No super methods are kept.
1124          */
1125         funBody.funParams = fpName; 
1126         funBody.claxxOwner = clazzThis;
1127         return addProto(clazzThis.prototype, funName, funBody);
1128 };
1129
1130 //////////////  Overridden and Overloaded Java Method Handling //////////////////
1131 //                       SAEM (SearchAndExecuteMethod)
1132 // adapted by BH
1133 //
1134
1135 /*
1136  * BH Clazz.getProfile monitors exactly what is being delegated with SAEM,
1137  * which could be a bottle-neck for function calling.
1138  * This is critical for performance optimization.
1139  */ 
1140
1141   var __signatures = ""; 
1142
1143 Clazz.getProfile = function() {
1144         var s = "";
1145         if (_profile) {
1146                 var l = [];
1147                 for (var i in _profile) {
1148                         var n = "" + _profile[i];
1149                         l.push("        ".substring(n.length) + n + "\t" + i);
1150                 }
1151                 s = l.sort().reverse().join("\r\n");
1152                 _profile = {};
1153         }
1154         return s + __signatures;
1155 }
1156
1157 var addProfile = function(c, f, p, id) {
1158         var s = id + " " + c.__CLASS_NAME__ + " " + f + " ";// + JSON.stringify(p);
1159   if (__signatures.indexOf(s) < 0)
1160     __signatures += s + "\n";    
1161         _profile[s] || (_profile[s] = 0);
1162         _profile[s]++;
1163 }
1164
1165 /**
1166  * Called also by Throwable
1167  *  
1168 /* public */
1169 Clazz.getParamsType = function (funParams) {
1170         // bh: optimization here for very common cases
1171         var n = funParams.length;
1172         switch (n) {
1173         case 0:
1174                 var params = ["void"];
1175                 params.typeString = "\\void";
1176                 return params;
1177         case 1:
1178           // BH just so common
1179     switch (typeof obj) {
1180     case "number":
1181                         var params = ["n"];
1182                         params.typeString = "\\n";
1183                         return params;
1184     case "boolean":
1185                         var params = ["b"];
1186                         params.typeString = "\\b";
1187                         return params;
1188                 }
1189         }
1190
1191         var params = [];
1192         params.hasCastedNull = false;
1193         if (funParams) {
1194                 for (var i = 0; i < n; i++) {
1195                         params[i] = Clazz.getClassName (funParams[i]);
1196                         if (funParams[i] instanceof Clazz.CastedNull) {
1197                                 params.hasCastedNull = true;
1198                         }
1199                 }
1200         }
1201         params.typeString = "\\" + params.join ('\\');
1202         return params;
1203 };
1204
1205 var SAEMid = 0;
1206 xxxSAEMlist = "";
1207
1208 //var SAEMarray = [];
1209 /**
1210  * BH: OK, this was an idea that doesn't work. The idea was to tag SAEM calls
1211  * and then refer back to an array. But the id number cannot be put in the right place.
1212  * 
1213  * Say we have this:
1214  * 
1215  * StringBuffer sb = new StringBuffer(); 
1216  * sb.append("").append(1);
1217  * 
1218  * Here we have two different append methods to call. They are saved under two
1219  * names:  StringBuffer.prototype.append["\\String"] 
1220  *     and StringBuffer.prototype.append["\\Number"]
1221  * 
1222  * The job of generateDelegatingMethod is to discriminate between those two. We can do
1223  * that, but the real issue is that we have to do that EVERY time a call is made.
1224  * This is a problem that must be handled at compile time. There is no way to 
1225  * make .append("") to go one way the first time and another way the second time. 
1226  * What we need at run time is something like this:
1227  * 
1228  * Clazz.delegate(sb.append,1,[""]) and Clazz.delegate(sb.append,2,[1])
1229  * The we would be able to log those numbers at run time and refer to them.
1230  *                     
1231  * The only real way to avoid SAEM is: 
1232  * 
1233  * 1) to never call super() -- always call a differently named function in a superclass.
1234  * 2) don't overload functions 
1235  *  
1236  */   
1237
1238
1239 /**
1240  * Search the given class prototype, find the method with the same
1241  * method name and the same parameter signatures by the given 
1242  * parameters, and then run the method with the given parameters.
1243  *
1244  * @param objThis the current host object
1245  * @param claxxRef the current host object's class
1246  * @param fxName the method name
1247  * @param funParams the given arguments
1248  * @return the result of the specified method of the host object,
1249  * the return maybe void.
1250  * @throws MethodNotFoundException if no matched method is found
1251  */
1252 /* protected */
1253 var searchAndExecuteMethod = function (id, objThis, claxxRef, fxName, args, _saem) {
1254
1255 //  var fx = SAEMarray[id];
1256 //  if (fx) {
1257 //    return fx.apply(objThis, args);
1258 //  }
1259
1260
1261         fx = objThis[fxName];
1262         var params = Clazz.getParamsType(args);
1263
1264
1265 var s = "SAEM " + claxxRef.__CLASS_NAME__ + "." + fxName + "(" + params+ ")\n";
1266 if (xxxSAEMlist.length > 300)xxxSAEMlist = "";
1267 xxxSAEMlist += s;
1268  
1269
1270   if (!fx)    
1271     try {System.out.println(Clazz.getStackTrace(5))} catch (e){}
1272         _profile && addProfile(claxxRef, fxName, params, id);
1273         // Cache last matched method
1274         if (fx.lastParams == params.typeString && fx.lastClaxxRef === claxxRef) {
1275                 var methodParams;
1276                 if (params.hasCastedNull) {
1277                         methodParams = [];
1278                         // For Clazz.CastedNull instances, the type name is
1279                         // already used to indentified the method in searchMethod.
1280                         for (var k = 0; k < args.length; k++)
1281                                 methodParams[k] = (args[k] instanceof Clazz.CastedNull ? null : args[k]);
1282                 } else {
1283 //      if (fx.lastMethod) SAEMarray[id] = fx.lastMethod;
1284                         methodParams = args;
1285                 }
1286                 return (fx.lastMethod ? fx.lastMethod.apply(objThis, methodParams) : null);
1287         }
1288         fx.lastParams = params.typeString;
1289         fx.lastClaxxRef = claxxRef;
1290
1291         var stacks = fx.stacks;
1292         if (!stacks)
1293                 stacks = claxxRef.prototype[fxName].stacks;
1294         var length = stacks.length;
1295
1296         /*
1297          * Search the inheritance stacks to get the given class' function
1298          */
1299         var began = false; // began to search its super classes
1300         for (var i = length; --i >= 0;) {
1301                 if (began || stacks[i] === claxxRef) {
1302                         /*
1303                          * First try to search method within the same class scope
1304                          * with stacks[i] === claxxRef
1305                          */
1306                         var clazzFun = stacks[i].prototype[fxName];
1307                         var ret = tryToSearchAndExecute(id, fxName, objThis, clazzFun, params,
1308                                         args, fx);
1309                         if (!(ret instanceof MethodException)) {
1310                                 return ret;
1311                         }
1312                         /*
1313                          * As there are no such methods in current class, Clazz will try 
1314                          * to search its super class stacks. Here variable began indicates
1315                          * that super searchi is began, and there is no need checking
1316                          * <code>stacks[i] === claxxRef</code>
1317                          */
1318                         began = true; 
1319                 } // end of if
1320         } // end of for
1321         if ("construct" == fxName) {
1322                 /*
1323                  * For non existed constructors, just return without throwing
1324                  * exceptions. In Java codes, extending Object can call super
1325                  * default Object#constructor, which is not defined in JS.
1326                  */
1327                 return;
1328         }
1329         newMethodNotFoundException(objThis, claxxRef, 
1330                         fxName, params.typeString);
1331 };
1332
1333
1334 /* private */
1335 var tryToSearchAndExecute = function(id, fxName, objThis, clazzFun, params, args, fx, _ttsaem) {
1336         var method = [];
1337         var generic = true;
1338         for (var fn in clazzFun) {
1339                 if (fn.charCodeAt(0) == 92) { // 92 == '\\'.charCodeAt (0)
1340                         var ps = fn.substring(1).split("\\");
1341                         (ps.length == params.length) && method.push(ps);
1342                 generic = false;
1343                         continue;
1344                 }
1345                 /*
1346                  * When there is only one method in the class, use the args
1347                  * to identify the parameter type.
1348                  *
1349                  * AbstractCollection.remove (Object)
1350                  * AbstractList.remove (int)
1351                  * ArrayList.remove (int)
1352                  *
1353                  * Then calling #remove (Object) method on ArrayList instance will 
1354                  * need to search up to the AbstractCollection.remove (Object),
1355                  * which contains only one method.
1356                  */
1357                 /*
1358                  * See Clazz#defineMethod --Mar 10, 2006, josson
1359                  */
1360                 if (generic && fn == "funParams" && clazzFun.funParams) {
1361                         fn = clazzFun.funParams;
1362                         var ps = fn.substring(1).split ("\\");
1363                         (ps.length == params.length) && (method[0] = ps);
1364                         break;
1365                 }
1366         }
1367   var debug = false;//(method.length > 1 && method.join().indexOf("Listen")< 0 && params.join().indexOf("Null") >= 0)
1368   if (debug)alert(fxName + " -- " + method.join("|") + " -- searching for method with " + params)
1369   if (method.length == 0 || !(method = searchMethod(method, params, debug)))
1370           return new MethodException();
1371   if (debug) alert("OK: \\" + method)
1372         var f = (generic ? clazzFun : clazzFun["\\" + method]);
1373         //if (generic) 
1374   //{ /* Use the generic method */
1375                 /*
1376                  * Will this case be reachable?
1377                  * March 4, 2006 josson
1378                  * 
1379                  * Reachable for calling #remove (Object) method on 
1380                  * ArrayList instance
1381                  * May 5, 2006 josson
1382                  */
1383         var methodParams = null;
1384         if (params.hasCastedNull) {
1385                 methodParams = [];
1386                 for (var k = 0; k < args.length; k++) {
1387                         if (args[k] instanceof Clazz.CastedNull) {
1388                                 /*
1389                                  * For Clazz.CastedNull instances, the type name is
1390                                  * already used to indentify the method in searchMethod.
1391                                  */
1392                                 methodParams[k] = null;
1393                         } else {
1394                                 methodParams[k] = args[k];
1395                         }
1396                 }
1397         } else {
1398                 methodParams = args;
1399         }
1400         fx.lastMethod = f;
1401   //if (!params.hasCastedNull) SAEMarray[id] = f;
1402         return f.apply(objThis, methodParams);
1403 };
1404
1405 /**
1406  * Search the existed polymorphic methods to get the matched method with
1407  * the given parameter types.
1408  *
1409  * @param existedMethods Array of string which contains method parameters
1410  * @param paramTypes Array of string that is parameter type.
1411  * @return string of method parameters seperated by "\\"
1412  */
1413 /* private */
1414 var searchMethod = function(roundOne, paramTypes, debug) {
1415
1416 // Filter out all the fitted methods for the given parameters
1417         var roundTwo = [];
1418         var len = roundOne.length;
1419         for (var i = 0; i < len; i++) {
1420                 var fittedLevel = [];
1421                 var isFitted = true;
1422                 var len2 = roundOne[i].length;
1423                 for (var j = 0; j < len2; j++) {
1424     
1425                         fittedLevel[j] = Clazz.getInheritedLevel (paramTypes[j], 
1426                                         roundOne[i][j]);
1427       //if (debug)alert([paramTypes[j],fittedLevel[j],roundOne[i][j]])    
1428                         if (fittedLevel[j] < 0) {
1429                                 isFitted = false;
1430                                 break;
1431                         }
1432                 }
1433                 if (isFitted) {
1434                         fittedLevel[paramTypes.length] = i; // Keep index for later use
1435                         roundTwo.push(fittedLevel);
1436                 }
1437         }
1438         if (roundTwo.length == 0)
1439                 return null;
1440         // Find out the best method according to the inheritance.
1441         var resultTwo = roundTwo;
1442         var min = resultTwo[0];
1443         for (var i = 1; i < resultTwo.length; i++) {
1444                 var isVectorLesser = true;
1445                 for (var j = 0; j < paramTypes.length; j++) {
1446                         if (min[j] < resultTwo[i][j]) {
1447                                 isVectorLesser = false;;
1448                                 break;
1449                         }
1450                 }
1451                 if (isVectorLesser)
1452                         min = resultTwo[i];
1453         }
1454         var index = min[paramTypes.length]; // Get the previously stored index
1455         /*
1456          * Return the method parameters' type string as indentifier of the
1457          * choosen method.
1458          */
1459         return roundOne[index].join ('\\');
1460 };
1461
1462 ////////////////////////////////// package loading ///////////////////////
1463
1464 /*
1465  * all root packages. e.g. java.*, org.*, com.*
1466  */
1467 /* protected */
1468 Clazz.allPackage = {};
1469
1470 /**
1471  * Will be used to keep value of whether the class is defined or not.
1472  */
1473 /* protected */
1474 Clazz.allClasses = {};
1475
1476 Clazz.lastPackageName = null;
1477 Clazz.lastPackage = null;
1478
1479 /* protected */
1480 Clazz.unloadedClasses = [];
1481
1482 /* public */
1483 Clazz.declarePackage = function (pkgName) {
1484         if (Clazz.lastPackageName == pkgName)
1485                 return Clazz.lastPackage;
1486         if (pkgName && pkgName.length) {
1487                 var pkgFrags = pkgName.split (/\./);
1488                 var pkg = Clazz.allPackage;
1489                 for (var i = 0; i < pkgFrags.length; i++) {
1490                         if (!pkg[pkgFrags[i]]) {
1491                                 pkg[pkgFrags[i]] = { 
1492                                         __PKG_NAME__ : (pkg.__PKG_NAME__ ? 
1493                                                 pkg.__PKG_NAME__ + "." + pkgFrags[i] : pkgFrags[i])
1494                                 }; 
1495                                 // pkg[pkgFrags[i]] = {};
1496                                 if (i == 0) {
1497                                         // eval ...
1498                                         Clazz.setGlobal(pkgFrags[i], pkg[pkgFrags[i]]);
1499                                 }
1500                         }
1501                         pkg = pkg[pkgFrags[i]]
1502                 }
1503                 Clazz.lastPackageName = pkgName;
1504                 Clazz.lastPackage = pkg;
1505                 return pkg;
1506         }
1507 };
1508
1509 /* protected */
1510 Clazz.evalType = function (typeStr, isQualified) {
1511         var idx = typeStr.lastIndexOf(".");
1512         if (idx != -1) {
1513                 var pkgName = typeStr.substring (0, idx);
1514                 var pkg = Clazz.declarePackage (pkgName);
1515                 var clazzName = typeStr.substring (idx + 1);
1516                 return pkg[clazzName];
1517         } 
1518         if (isQualified)
1519                 return window[typeStr];
1520         switch (typeStr) {
1521         case "string":
1522                 return String;
1523         case "number":
1524                 return Number;
1525   case "object":
1526                 return Clazz._O;
1527         case "boolean":
1528                 return Boolean;
1529         case "function":
1530                 return Function;
1531   case "void":
1532   case "undefined":
1533   case "unknown":
1534                 return typeStr;
1535         case "NullObject":
1536                 return NullObject;
1537         default:
1538                 return window[typeStr];
1539         }
1540 };
1541
1542 /**
1543  * Define a class or interface.
1544  *
1545  * @param qClazzName String presents the qualified name of the class
1546  * @param clazzFun Function of the body
1547  * @param clazzParent Clazz to inherit from, may be null
1548  * @param interfacez Clazz may implement one or many interfaces
1549  *   interfacez can be Clazz object or Array of Clazz objects.
1550  * @return Ruturn the modified Clazz object
1551  */
1552 /* public */
1553 Clazz.defineType = function (qClazzName, clazzFun, clazzParent, interfacez) {
1554         var cf = Clazz.unloadedClasses[qClazzName];
1555         if (cf) {
1556                 clazzFun = cf;
1557         }
1558         var idx = qClazzName.lastIndexOf (".");
1559         if (idx != -1) {
1560                 var pkgName = qClazzName.substring (0, idx);
1561                 var pkg = Clazz.declarePackage (pkgName);
1562                 var clazzName = qClazzName.substring (idx + 1);
1563                 if (pkg[clazzName]) {
1564                         // already defined! Should throw exception!
1565                         return pkg[clazzName];
1566                 }
1567                 pkg[clazzName] = clazzFun;
1568         } else {
1569                 if (window[qClazzName]) {
1570                         // already defined! Should throw exception!
1571                         return window[qClazzName];
1572                 }
1573                 Clazz.setGlobal(qClazzName, clazzFun);
1574         }
1575         Clazz.decorateAsType(clazzFun, qClazzName, clazzParent, interfacez);
1576         /*# {$no.javascript.support} >>x #*/
1577         var iFun = Clazz._innerFunctions;
1578         clazzFun.defineMethod = iFun.defineMethod;
1579         clazzFun.defineStaticMethod = iFun.defineStaticMethod;
1580         clazzFun.makeConstructor = iFun.makeConstructor;
1581         /*# x<< #*/
1582         return clazzFun;
1583 };
1584
1585 var isSafari = (navigator.userAgent.indexOf ("Safari") != -1);
1586 var isSafari4Plus = false;
1587 if (isSafari) {
1588         var ua = navigator.userAgent;
1589         var verIdx = ua.indexOf("Version/");
1590         if (verIdx  != -1) {
1591                 var verStr = ua.substring(verIdx + 8);
1592                 var verNumber = parseFloat(verStr);
1593                 isSafari4Plus = verNumber >= 4.0;
1594         }
1595 }
1596
1597 /* public */
1598 Clazz.instantialize = function (objThis, args) {
1599
1600
1601         if (args && args.length == 1 && args[0] 
1602                         && args[0] instanceof args4InheritClass) {
1603                 return;
1604         }
1605         if (objThis instanceof Number) {
1606                 objThis.valueOf = function () {
1607                         return this;
1608                 };
1609         }
1610         if (isSafari4Plus) { // Fix bug of Safari 4.0+'s over-optimization
1611                 var argsClone = [];
1612                 for (var k = 0; k < args.length; k++) {
1613                         argsClone[k] = args[k];
1614                 }
1615                 args = argsClone;
1616         }
1617
1618         var c = objThis.construct;
1619         if (c) {
1620                 if (!objThis.con$truct) { // no need to init fields
1621                         c.apply (objThis, args);
1622                 } else if (!objThis.getClass ().superClazz) { // the base class
1623                         objThis.con$truct.apply (objThis, []);
1624                         c.apply (objThis, args);
1625                 } else if ((c.claxxOwner 
1626                                 && c.claxxOwner === objThis.getClass ())
1627                                 || (c.stacks 
1628                                 && c.stacks[c.stacks.length - 1] == objThis.getClass ())) {
1629                         /*
1630                          * This #construct is defined by this class itself.
1631                          * #construct will call Clazz.superConstructor, which will
1632                          * call #con$truct back
1633                          */
1634                         c.apply (objThis, args);
1635                 } else { // constructor is a super constructor
1636                         if (c.claxxOwner && !c.claxxOwner.superClazz 
1637                                                 && c.claxxOwner.con$truct) {
1638                                 c.claxxOwner.con$truct.apply (objThis, []);
1639                         } else if (c.stacks && c.stacks.length == 1
1640                                         && !c.stacks[0].superClazz) {
1641                                 c.stacks[0].con$truct.apply (objThis, []);
1642                         }
1643                         c.apply (objThis, args);
1644                         objThis.con$truct.apply (objThis, []);
1645                 }
1646         } else if (objThis.con$truct) {
1647                 objThis.con$truct.apply (objThis, []);
1648         }
1649 };
1650
1651 /**
1652  * Once there are other methods registered to the Function.prototype, 
1653  * those method names should be add to the following Array.
1654  */
1655 /*
1656  * static final member of interface may be a class, which may
1657  * be function.
1658  */
1659 /* protected */
1660 Clazz.innerFunctionNames = [
1661         "isInstance", "equals", "hashCode", /*"toString",*/ "getName", "getCanonicalName", "getClassLoader", "getResource", "getResourceAsStream" /*# {$no.javascript.support} >>x #*/, "defineMethod", "defineStaticMethod",
1662         "makeConstructor" /*# x<< #*/
1663 ];
1664
1665 /*
1666  * Static methods
1667  */
1668 Clazz._innerFunctions = {
1669         /*
1670          * Similar to Object#equals
1671          */
1672    
1673   isInstance: function(c) {
1674     return Clazz.instanceOf(c, this);
1675   },
1676   
1677         equals : function (aFun) {
1678                 return this === aFun;
1679         },
1680
1681         hashCode : function () {
1682                 return this.getName ().hashCode ();
1683         },
1684
1685         toString : function () {
1686                 return "class " + this.getName ();
1687         },
1688
1689         /*
1690          * Similar to Class#getName
1691          */
1692         getName : function () {
1693                 return Clazz.getClassName (this, true);
1694         },
1695         getCanonicalName : function () {
1696                 return this.__CLASS_NAME__;
1697         },
1698         getClassLoader : function () {
1699                 var clazzName = this.__CLASS_NAME__;
1700                 var baseFolder = Clazz._Loader.getClasspathFor(clazzName);
1701                 var x = baseFolder.lastIndexOf (clazzName.replace (/\./g, "/"));
1702                 if (x != -1) {
1703                         baseFolder = baseFolder.substring (0, x);
1704                 } else {
1705                         baseFolder = Clazz._Loader.getClasspathFor(clazzName, true);
1706                 }
1707                 var loader = Clazz._Loader.requireLoaderByBase(baseFolder);
1708                 loader.getResourceAsStream = Clazz._innerFunctions.getResourceAsStream;
1709                 loader.getResource = Clazz._innerFunctions.getResource; // BH
1710                 return loader;
1711         },
1712
1713         getResource : function(name) {
1714                 var stream = this.getResourceAsStream(name);
1715     return (stream ? stream.url : null);
1716         },
1717
1718         getResourceAsStream : function (name) {
1719                 if (!name)
1720                         return null;
1721                 name = name.replace (/\\/g, '/');
1722                 var baseFolder = null;
1723     var fname = name;
1724                 var clazzName = this.__CLASS_NAME__;
1725                 if (arguments.length == 2 && name.indexOf ('/') != 0) { // additional argument
1726                         name = "/" + name;
1727                 }
1728                 if (name.indexOf ('/') == 0) {
1729                         //is.url = name.substring (1);
1730                         if (arguments.length == 2) { // additional argument
1731                                 baseFolder = arguments[1];
1732                                 if (!baseFolder)
1733                                         baseFolder = Clazz.binaryFolders[0];
1734                         } else if (Clazz._Loader) {
1735                                 baseFolder = Clazz._Loader.getClasspathFor(clazzName, true);
1736                         }
1737                         if (!baseFolder) {
1738                                 fname = name.substring (1);
1739                         } else {
1740                                 baseFolder = baseFolder.replace (/\\/g, '/');
1741                                 var length = baseFolder.length;
1742                                 var lastChar = baseFolder.charAt (length - 1);
1743                                 if (lastChar != '/') {
1744                                         baseFolder += "/";
1745                                 }
1746                                 fname = baseFolder + name.substring (1);
1747                         }
1748                 } else {
1749                         if (this.base) {
1750                                 baseFolder = this.base;
1751                         } else if (Clazz._Loader) {
1752                                 baseFolder = Clazz._Loader.getClasspathFor(clazzName);
1753                                 var x = baseFolder.lastIndexOf (clazzName.replace (/\./g, "/"));
1754                                 if (x != -1) {
1755                                         baseFolder = baseFolder.substring (0, x);
1756                                 } else {
1757                                         //baseFolder = null;
1758                                         var y = -1;
1759                                         if (baseFolder.indexOf (".z.js") == baseFolder.length - 5
1760                                                         && (y = baseFolder.lastIndexOf ("/")) != -1) {
1761                                                 baseFolder = baseFolder.substring (0, y + 1);
1762                                                 var pkgs = clazzName.split (/\./);
1763                                                 for (var k = 1; k < pkgs.length; k++) {
1764                                                         var pkgURL = "/";
1765                                                         for (var j = 0; j < k; j++) {
1766                                                                 pkgURL += pkgs[j] + "/";
1767                                                         }
1768                                                         if (pkgURL.length > baseFolder.length) {
1769                                                                 break;
1770                                                         }
1771                                                         if (baseFolder.indexOf (pkgURL) == baseFolder.length - pkgURL.length) {
1772                                                                 baseFolder = baseFolder.substring (0, baseFolder.length - pkgURL.length + 1);
1773                                                                 break;
1774                                                         }
1775                                                 }
1776                                         } else {
1777                                                 baseFolder = Clazz._Loader.getClasspathFor(clazzName, true);
1778                                         }
1779                                 }
1780                         } else {
1781                                 var bins = Clazz.binaryFolders;
1782                                 if (bins && bins.length) {
1783                                         baseFolder = bins[0];
1784                                 }
1785                         }
1786                         if (!baseFolder)
1787                                 baseFolder = "j2s/";
1788                         baseFolder = baseFolder.replace (/\\/g, '/');
1789                         var length = baseFolder.length;
1790                         var lastChar = baseFolder.charAt (length - 1);
1791                         if (lastChar != '/') {
1792                                 baseFolder += "/";
1793                         }
1794                         if (this.base) {
1795                                 fname = baseFolder + name;
1796                         } else {
1797                                 var idx = clazzName.lastIndexOf ('.');
1798                                 if (idx == -1 || this.base) {
1799                                         fname = baseFolder + name;
1800                                 } else {
1801                                         fname = baseFolder + clazzName.substring (0, idx)
1802                                                         .replace (/\./g, '/') +  "/" + name;
1803                                 }
1804                         }            
1805                 }
1806     var url = null;
1807     try {
1808       if (fname.indexOf(":/") < 0) {
1809         var d = document.location.href.split("?")[0].split("/");
1810         d[d.length - 1] = fname;
1811         fname = d.join("/");
1812       }
1813       url = new java.net.URL(fname);
1814     } catch (e) {
1815     }
1816                 var data = (url == null ? null : Jmol._getFileData(fname.toString()));
1817     if (!data || data == "error" || data.indexOf("[Exception") == 0)
1818       return null;
1819     var bytes = new java.lang.String(data).getBytes();      
1820     var is = new java.io.BufferedInputStream ( new java.io.ByteArrayInputStream (bytes)); 
1821     is.url = url;
1822                 return is;
1823         }/*# {$no.javascript.support} >>x #*/,
1824
1825         /*
1826          * For JavaScript programmers
1827          */
1828         defineMethod : function (methodName, funBody, paramTypes) {
1829                 Clazz.defineMethod (this, methodName, funBody, paramTypes);
1830         },
1831
1832         /*
1833          * For JavaScript programmers
1834          */
1835         defineStaticMethod : function (methodName, funBody, paramTypes) {
1836                 Clazz.defineMethod (this, methodName, funBody, paramTypes);
1837                 this[methodName] = this.prototype[methodName];
1838         },
1839
1840         /*
1841          * For JavaScript programmers
1842          */
1843         makeConstructor : function (funBody, paramTypes) {
1844                 Clazz.makeConstructor (this, funBody, paramTypes);
1845         }
1846         /*# x<< #*/
1847 };
1848
1849
1850 var cStack = [];
1851
1852 /**
1853  * BH: I would like to be able to remove "self.c$" here, but that is tricky.
1854  */
1855   
1856 Clazz.pu$h = function (c) {
1857   c || (c = self.c$); // old style
1858         c && cStack.push(c);
1859 };
1860
1861 Clazz.p0p = function () {
1862         return cStack.pop();
1863 };
1864
1865 /* protected */
1866 Clazz.decorateAsClass = function (clazzFun, prefix, name, clazzParent, 
1867                 interfacez, parentClazzInstance, _decorateAsClass) {
1868     
1869         var prefixName = null;
1870         if (prefix) {
1871                 prefixName = prefix.__PKG_NAME__;
1872                 if (!prefixName)
1873                         prefixName = prefix.__CLASS_NAME__;      
1874         }
1875         var qName = (prefixName ? prefixName + "." : "") + name;
1876   
1877     if (Clazz._Loader._classPending[qName]) {
1878       delete Clazz._Loader._classPending[qName];
1879       Clazz._Loader._classCountOK++;
1880       Clazz._Loader._classCountPending--;
1881     }
1882   if (Clazz._Loader && Clazz._Loader._checkLoad) {
1883     System.out.println("decorating class " + prefixName + "." + name);
1884   }
1885         var cf = Clazz.unloadedClasses[qName];
1886         if (cf) {
1887                 clazzFun = cf;
1888         }
1889         var qName = null;
1890         decorateFunction(clazzFun, prefix, name);
1891         if (parentClazzInstance) {
1892                 Clazz.inheritClass (clazzFun, clazzParent, parentClazzInstance);
1893         } else if (clazzParent) {
1894                 Clazz.inheritClass (clazzFun, clazzParent);
1895         }
1896         if (interfacez) {
1897                 Clazz.implementOf (clazzFun, interfacez);
1898         }
1899         return clazzFun;
1900 };
1901
1902 /* private */
1903 var decorateFunction = function (clazzFun, prefix, name, _decorateFunction) {
1904         var qName;
1905         if (!prefix) {
1906                 // e.g. Clazz.declareInterface (null, "ICorePlugin", org.eclipse.ui.IPlugin);
1907                 qName = name;
1908                 Clazz.setGlobal(name, clazzFun);
1909         } else if (prefix.__PKG_NAME__) {
1910                 // e.g. Clazz.declareInterface (org.eclipse.ui, "ICorePlugin", org.eclipse.ui.IPlugin);
1911                 qName = prefix.__PKG_NAME__ + "." + name;
1912                 prefix[name] = clazzFun;
1913                 if (prefix === java.lang)
1914                         Clazz.setGlobal(name, clazzFun);
1915         } else {
1916                 // e.g. Clazz.declareInterface (org.eclipse.ui.Plugin, "ICorePlugin", org.eclipse.ui.IPlugin);
1917                 qName = prefix.__CLASS_NAME__ + "." + name;
1918                 prefix[name] = clazzFun;
1919         }
1920         Clazz.extendJO(clazzFun, qName);
1921         var inF = Clazz.innerFunctionNames;
1922         for (var i = 0; i < inF.length; i++) {
1923                 clazzFun[inF[i]] = Clazz._innerFunctions[inF[i]];
1924         }
1925
1926         if (Clazz._Loader) 
1927     Clazz._Loader.updateNodeForFunctionDecoration(qName);
1928 };
1929
1930 /* protected */
1931 Clazz.declareInterface = function (prefix, name, interfacez, _declareInterface) {
1932         var clazzFun = function () {};
1933         decorateFunction(clazzFun, prefix, name);
1934         if (interfacez) {
1935                 Clazz.implementOf (clazzFun, interfacez);
1936         }
1937         return clazzFun;
1938 };
1939
1940 /* public */
1941 Clazz.declareType = function (prefix, name, clazzParent, interfacez, 
1942                 parentClazzInstance, _declareType) {
1943         var f = function () {
1944                 Clazz.instantialize (this, arguments);
1945         };
1946         return Clazz.decorateAsClass (f, prefix, name, clazzParent, interfacez, 
1947                         parentClazzInstance);
1948 };
1949
1950 /* public */
1951 Clazz.declareAnonymous = function (prefix, name, clazzParent, interfacez, 
1952                 parentClazzInstance, _declareAnonymous) {
1953         var f = function () {
1954                 Clazz.prepareCallback(this, arguments);
1955                 Clazz.instantialize (this, arguments);
1956         };
1957         return Clazz.decorateAsClass (f, prefix, name, clazzParent, interfacez, 
1958                         parentClazzInstance);
1959 };
1960
1961 /* public */
1962 Clazz.decorateAsType = function (clazzFun, qClazzName, clazzParent, 
1963                 interfacez, parentClazzInstance, inheritClazzFuns, _decorateAsType) {
1964         Clazz.extendJO(clazzFun, qClazzName);
1965         clazzFun.equals = Clazz._innerFunctions.equals;
1966         clazzFun.getName = Clazz._innerFunctions.getName;
1967         if (inheritClazzFuns) {
1968                 for (var i = 0; i < Clazz.innerFunctionNames.length; i++) {
1969                         var methodName = Clazz.innerFunctionNames[i];
1970                         clazzFun[methodName] = Clazz._innerFunctions[methodName];
1971                 }
1972         }
1973         if (parentClazzInstance) {
1974                 Clazz.inheritClass (clazzFun, clazzParent, parentClazzInstance);
1975         } else if (clazzParent) {
1976                 Clazz.inheritClass (clazzFun, clazzParent);
1977         }
1978         if (interfacez) {
1979                 Clazz.implementOf (clazzFun, interfacez);
1980         }
1981         return clazzFun;
1982 };
1983
1984
1985 ////////////////////////// default package declarations ////////////////////////
1986
1987 /* sgurin: preserve Number.prototype.toString */
1988 Number.prototype._numberToString=Number.prototype.toString;
1989
1990
1991 Clazz.declarePackage ("java.io");
1992 //Clazz.declarePackage ("java.lang");
1993 Clazz.declarePackage ("java.lang.annotation"); // java.lang
1994 Clazz.declarePackage ("java.lang.instrument"); // java.lang
1995 Clazz.declarePackage ("java.lang.management"); // java.lang
1996 Clazz.declarePackage ("java.lang.reflect"); // java.lang
1997 Clazz.declarePackage ("java.lang.ref");  // java.lang.ref
1998 java.lang.ref.reflect = java.lang.reflect;
1999 Clazz.declarePackage ("java.util");
2000 //var reflect = Clazz.declarePackage ("java.lang.reflect");
2001 Clazz.declarePackage ("java.security");
2002
2003
2004 /*
2005  * Consider these interfaces are basic!
2006  */
2007 Clazz.declareInterface (java.io,"Closeable");
2008 Clazz.declareInterface (java.io,"DataInput");
2009 Clazz.declareInterface (java.io,"DataOutput");
2010 Clazz.declareInterface (java.io,"Externalizable");
2011 Clazz.declareInterface (java.io,"Flushable");
2012 Clazz.declareInterface (java.io,"Serializable");
2013 Clazz.declareInterface (java.lang,"Iterable");
2014 Clazz.declareInterface (java.lang,"CharSequence");
2015 Clazz.declareInterface (java.lang,"Cloneable");
2016 Clazz.declareInterface (java.lang,"Appendable");
2017 Clazz.declareInterface (java.lang,"Comparable");
2018 Clazz.declareInterface (java.lang,"Runnable");
2019 Clazz.declareInterface (java.util,"Comparator");
2020
2021 java.lang.ClassLoader = {
2022         __CLASS_NAME__ : "ClassLoader"
2023 };
2024
2025 /******************************************************************************
2026  * Copyright (c) 2007 java2script.org and others.
2027  * All rights reserved. This program and the accompanying materials
2028  * are made available under the terms of the Eclipse Public License v1.0
2029  * which accompanies this distribution, and is available at
2030  * http://www.eclipse.org/legal/epl-v10.html
2031  *
2032  * Contributors:
2033  *     Zhou Renjian - initial API and implementation
2034  *****************************************************************************/
2035 /*******
2036  * @author zhou renjian
2037  * @create March 10, 2006
2038  *******/
2039
2040 /**
2041  * Once ClassExt.js is part of Class.js.
2042  * In order to make the Class.js as small as possible, part of its content
2043  * is moved into this ClassExt.js.
2044  *
2045  * See also http://j2s.sourceforge.net/j2sclazz/
2046  */
2047  
2048 /**
2049  * Clazz.MethodNotFoundException is used to notify the developer about calling
2050  * methods with incorrect parameters.
2051  */
2052 /* protected */
2053 // Override the Clazz.MethodNotFoundException in Class.js to give details
2054 var newMethodNotFoundException = function (obj, clazz, method, params) {
2055         var paramStr = "";
2056         if (params) {
2057                 paramStr = params.substring (1).replace (/\\/g, ",");
2058         }
2059         var leadingStr = "";
2060         if (method && method != "construct") {
2061                 leadingStr = "Method";
2062         } else {
2063                 leadingStr = "Constructor";
2064         }
2065         var message = leadingStr + " " + Clazz.getClassName (clazz, true) + "." 
2066                                         + method + "(" + paramStr + ") is not found!";
2067   throw new java.lang.NoSuchMethodException(message);        
2068 };
2069
2070 /**
2071  * Prepare "callback" for instance of anonymous Class.
2072  * For example for the callback:
2073  *     this.callbacks.MyEditor.sayHello();
2074  *     
2075  * This is specifically for inner classes that are referring to 
2076  * outer class methods and fields.   
2077  *
2078  * @param objThis the host object for callback
2079  * @param args arguments object. args[0] will be classThisObj -- the "this"
2080  * object to be hooked
2081  * 
2082  * Attention: parameters should not be null!
2083  */
2084 /* protected */
2085 Clazz.prepareCallback = function (innerObj, args) {
2086         var outerObj = args[0];
2087         var cbName = "b$"; // "callbacks";
2088         if (innerObj && outerObj && outerObj !== window) {
2089                 var className = Clazz.getClassName(outerObj, true);             
2090                 var obs = {};
2091                 if (innerObj[cbName]) // must make a copy!
2092                         for (var s in innerObj[cbName])
2093                                 obs[s] = innerObj[cbName][s];
2094                 innerObj[cbName] = obs;
2095                 
2096                 /*
2097                  * TODO: the following line is SWT-specific! Try to move it out!
2098                  */
2099                 //                      obs[className.replace (/org\.eclipse\.swt\./, "$wt.")] = outerObj;
2100
2101         // all references to outer class and its superclass objects must be here as well
2102                 obs[className] = outerObj;
2103                 var clazz = Clazz.getClass(outerObj);
2104                 while (clazz.superClazz) {
2105                         clazz = clazz.superClazz;
2106                         /*
2107                          * TODO: the following line is SWT-specific! Try to move it out!
2108                          */
2109                         //                              obs[Clazz.getClassName (clazz, true)
2110                         //                                              .replace (/org\.eclipse\.swt\./, "$wt.")] = outerObj;
2111                         obs[Clazz.getClassName(clazz, true)] = outerObj;
2112                 }
2113                 var cbs = outerObj[cbName];
2114                 if (cbs)
2115                         for (var s in cbs)
2116                                 obs[s] = cbs[s];
2117         }
2118         // remove "this" argument
2119         // note that args is an instance of arguments -- NOT an array; does not have the .shift() method!
2120         for (var i = 0; i < args.length - 1; i++)
2121                 args[i] = args[i + 1];
2122         args.length--;
2123 };
2124
2125 /**
2126  * Construct instance of the given inner class.
2127  *
2128  * @param classInner given inner class, alway with name like "*$*"
2129  * @param innerObj this instance which can be used to call back.
2130  * @param finalVars final variables which the inner class may use
2131  * @return the constructed object
2132  *
2133  * @see Clazz#cloneFinals
2134  */
2135 /* public */
2136 Clazz.innerTypeInstance = function (clazzInner, innerObj, finalVars) {
2137         if (!clazzInner)
2138                 clazzInner = arguments.callee.caller;
2139         var obj;
2140         if (finalVars || innerObj.$finals) {
2141                         obj = new clazzInner(innerObj, Clazz.inheritArgs);
2142                 // f$ is short for the once choosen "$finals"
2143                 if (finalVars) {
2144                         if (innerObj.f$) {
2145                                 var o = {};
2146                                 for (var attr in innerObj.f$)
2147                                         o[attr] = innerObj.f$[attr];
2148                                 for (var attr in finalVars)
2149                                         o[attr] = finalVars[attr];
2150                                 obj.f$ = o;
2151                         } else {
2152                                 obj.f$ = finalVars;
2153                         }
2154                 } else if (innerObj.f$) {
2155                         obj.f$ = innerObj.f$;
2156                 }
2157         } else {
2158                 switch (arguments.length) {
2159                 case 3:
2160                         return new clazzInner(innerObj);
2161                 case 4:
2162                         return (innerObj.__CLASS_NAME__ == clazzInner.__CLASS_NAME__
2163                                         && arguments[3] === Clazz.inheritArgs ? innerObj : new clazzInner(innerObj, arguments[3]));
2164                 case 5:
2165                         return new clazzInner(innerObj, arguments[3], arguments[4]);
2166                 case 6:
2167                         return new clazzInner(innerObj, arguments[3], arguments[4], 
2168                                         arguments[5]);
2169                 case 7:
2170                         return new clazzInner(innerObj, arguments[3], arguments[4], 
2171                                         arguments[5], arguments[6]);
2172                 case 8:
2173                         return new clazzInner(innerObj, arguments[3], arguments[4], 
2174                                         arguments[5], arguments[6], arguments[7]);
2175                 case 9:
2176                         return new clazzInner(innerObj, arguments[3], arguments[4], 
2177                                         arguments[5], arguments[6], arguments[7], arguments[8]);
2178                 case 10:
2179                         return new clazzInner(innerObj, arguments[3], arguments[4], 
2180                                         arguments[5], arguments[6], arguments[7], arguments[8],
2181                                         arguments[9]);
2182                 default:
2183                         //Should construct instance manually.
2184                         obj = new clazzInner(innerObj, Clazz.inheritArgs);
2185                         break;
2186                 }
2187         }
2188         var n = arguments.length - 3;
2189         var args = new Array(n);
2190         for (var i = n; --i >= 0;)
2191                 args[i] = arguments[i + 3];
2192         Clazz.instantialize(obj, args);
2193         return obj;
2194 };
2195
2196 /**
2197  * Clone variables whose modifier is "final".
2198  * Usage: var o = Clazz.cloneFinals ("name", name, "age", age);
2199  *
2200  * @return Object with all final variables
2201  */
2202 /* public */
2203 Clazz.cloneFinals = function () {
2204         var o = {};
2205         var len = arguments.length / 2;
2206         for (var i = len; --i >= 0;)
2207                 o[arguments[i + i]] = arguments[i + i + 1];
2208         return o;
2209 };
2210
2211 /* public */
2212 Clazz.isClassDefined = Clazz.isDefinedClass = function(clazzName) {
2213         if (!clazzName) 
2214                 return false;           /* consider null or empty name as non-defined class */
2215         if (Clazz.allClasses[clazzName])
2216                 return true;
2217         var pkgFrags = clazzName.split (/\./);
2218         var pkg = null;
2219         for (var i = 0; i < pkgFrags.length; i++)
2220                 if (!(pkg = (pkg ? pkg[pkgFrags[i]] : Clazz.allPackage[pkgFrags[0]]))) {
2221                         return false;
2222     }
2223   return (pkg && (Clazz.allClasses[clazzName] = true));
2224 };
2225 /**
2226  * Define the enum constant.
2227  * @param classEnum enum type
2228  * @param enumName enum constant
2229  * @param enumOrdinal enum ordinal
2230  * @param initialParams enum constant constructor parameters
2231  * @return return defined enum constant
2232  */
2233 /* public */
2234 Clazz.defineEnumConstant = function (clazzEnum, enumName, enumOrdinal, initialParams, clazzEnumExt) {
2235         var o = (clazzEnumExt ? new clazzEnumExt() : new clazzEnum());
2236         // BH avoids unnecessary calls to SAEM
2237         o.$name = enumName;
2238         o.$ordinal = enumOrdinal;
2239         //Clazz.superConstructor (o, clazzEnum, [enumName, enumOrdinal]);
2240         if (initialParams && initialParams.length)
2241                 o.construct.apply (o, initialParams);
2242         clazzEnum[enumName] = o;
2243         clazzEnum.prototype[enumName] = o;
2244         if (!clazzEnum["$ values"]) {         // BH added
2245                 clazzEnum["$ values"] = []          // BH added
2246                 clazzEnum.values = function() {     // BH added
2247                         return this["$ values"];          // BH added
2248                 };                                  // BH added
2249         }
2250         clazzEnum["$ values"].push(o);
2251         return o;
2252 };
2253
2254 //////// (int) conversions //////////
2255
2256 Clazz.floatToInt = function (x) {
2257         return x < 0 ? Math.ceil(x) : Math.floor(x);
2258 };
2259
2260 Clazz.floatToByte = Clazz.floatToShort = Clazz.floatToLong = Clazz.floatToInt;
2261 Clazz.doubleToByte = Clazz.doubleToShort = Clazz.doubleToLong = Clazz.doubleToInt = Clazz.floatToInt;
2262
2263 Clazz.floatToChar = function (x) {
2264         return String.fromCharCode (x < 0 ? Math.ceil(x) : Math.floor(x));
2265 };
2266
2267 Clazz.doubleToChar = Clazz.floatToChar;
2268
2269
2270
2271 ///////////////////////////////// Array additions //////////////////////////////
2272 //
2273 // BH: these are necessary for integer processing, especially
2274 //
2275 //
2276
2277 var getArrayClone = function(nbits) {
2278   return function() {
2279     var me = this;
2280     var n = me.length;
2281     var a = (nbits == 32 ? new Int32Array(n) : new Float64Array(n));
2282     for (var i = n; --i >= 0;)
2283       a[i] = me[i];
2284     return a; 
2285   }
2286 }
2287
2288 if (self.Int32Array && self.Int32Array != Array) {
2289         Clazz.haveInt32 = true;
2290         if (!Int32Array.prototype.sort)
2291                 Int32Array.prototype.sort = Array.prototype.sort
2292         if (!Int32Array.prototype.clone)
2293                 Int32Array.prototype.clone = getArrayClone(32);
2294 } else {
2295         Int32Array = function(n) {
2296                 if (!n) n = 0;
2297                 var b = new Array(n);
2298                 b.toString = function(){return "[object Int32Array]"}
2299                 for (var i = 0; i < n; i++)b[i] = 0
2300                 return b;
2301         }
2302         Clazz.haveInt32 = false;
2303         Int32Array.prototype.sort = Array.prototype.sort
2304         Int32Array.prototype.clone = getArrayClone(32);
2305         Int32Array.prototype.int32Fake = function(){};
2306 }
2307
2308 if (self.Float64Array && self.Float64Array != Array) {
2309         Clazz.haveFloat64 = true;
2310         if (!Float64Array.prototype.sort)
2311                 Float64Array.prototype.sort = Array.prototype.sort
2312         if (!Float64Array.prototype.clone)
2313                 Float64Array.prototype.clone = getArrayClone(64);
2314 } else {
2315         Clazz.haveFloat64 = false;
2316         Float64Array = function(n) {
2317                 if (!n) n = 0;
2318                 var b = new Array(n);
2319                 for (var i = 0; i < n; i++)b[i] = 0.0
2320                 return b;
2321         };
2322         Float64Array.prototype.sort = Array.prototype.sort
2323         Float64Array.prototype.clone = getArrayClone(64);
2324         Float64Array.prototype.float64Fake = function() {}; // "present"
2325         Float64Array.prototype.toString = function() {return "[object Float64Array]"};
2326 // Darn! Mozilla makes this a double, not a float. It's 64-bit.
2327 // and Safari 5.1 doesn't have Float64Array 
2328 }
2329
2330 /**
2331  * Make arrays.
2332  *
2333  * @return the created Array object
2334  */
2335 /* public */
2336 Clazz.newArray  = function () {
2337         if (arguments[0] instanceof Array) {
2338                 // recursive, from newArray(n,m,value)
2339                 // as newArray([m, value], newInt32Array)
2340                 var args = arguments[0];
2341                 var f = arguments[1];
2342         } else {
2343                 var args = arguments;
2344                 var f = Array;
2345         }
2346         var dim = args[0];
2347         if (typeof dim == "string") {
2348                 dim = dim.charCodeAt (0); // char
2349         }
2350         var len = args.length - 1;
2351         var val = args[len];
2352   switch (args.length) {
2353   case 0: // never
2354   case 1:
2355                 return []; // maybe never?
2356   case 2:
2357                 if (val == null)
2358                 return new Array(dim);
2359           if (f === true && Clazz.haveInt32) return new Int32Array(dim);
2360           if (f === false && Clazz.haveFloat64) return new Float64Array(dim);
2361                 var arr = (f === true ? new Int32Array() : f === false ? new Float64Array() : dim < 0 ? val : new Array(dim));
2362                 for (var i = dim; --i >= 0;)
2363                 arr[i] = val;
2364           return arr;
2365   default:
2366         var xargs = new Array (len);
2367         for (var i = 0; i < len; i++) {
2368                 xargs[i] = args[i + 1];
2369         }
2370         var arr = new Array (dim);
2371         if (val == null || val >= 0 || len > 2)
2372                 for (var i = 0; i < dim; i++) {
2373                 // Call recursively!
2374                         arr[i] = Clazz.newArray (xargs, f);
2375                 }
2376         return arr;
2377         }
2378 };
2379
2380 Clazz.newArray32 = function(args, isInt32) {
2381         var dim = args[0];
2382         if (typeof dim == "string")
2383                 dim = dim.charCodeAt (0); // char
2384         var len = args.length - 1;
2385         var val = args[len];
2386         switch (args.length) {
2387         case 0:
2388         case 1:  
2389                 alert ("ERROR IN newArray32 -- args.length < 2");
2390                 return new Array(0);
2391         case 2:
2392     var isDefined = (dim < 0);
2393     if (isDefined)
2394       dim = val.length;
2395     var a = (val < 0 ? new Array(dim) : isInt32 ? new Int32Array(dim) : new Float64Array(dim));
2396     if (isDefined)
2397       for (var i = dim; --i >= 0;)
2398         a[i] = val[i];
2399     return a;
2400         }
2401         var xargs = new Array(len);
2402         for (var i = len; --i >= 0;) {
2403                 xargs[i] = args[i + 1];
2404         }
2405         var arr = new Array (dim);
2406         for (var i = 0; i < dim; i++) {
2407                 // Call newArray referencing this array type
2408                 // only for the final iteration, and only if val === 0
2409                 arr[i] = Clazz.newArray (xargs, isInt32);
2410         }
2411         return arr;
2412 };
2413
2414
2415 /**
2416  * Make arrays.
2417  *
2418  * @return the created Array object
2419  */
2420 /* public */
2421 Clazz.newInt32Array  = function () {
2422         return Clazz.newArray32(arguments, true);
2423 }
2424
2425 /**
2426  * Make arrays.
2427  *
2428  * @return the created Array object
2429  */
2430 /* public */
2431 Clazz.newFloat64Array  = function () {
2432         return Clazz.newArray32(arguments, false);
2433 }
2434
2435 Clazz.newFloatArray = Clazz.newDoubleArray = Clazz.newFloat64Array;
2436 Clazz.newIntArray = Clazz.newLongArray = Clazz.newShortArray = Clazz.newByteArray = Clazz.newInt32Array;
2437 Clazz.newCharArray = Clazz.newBooleanArray = Clazz.newArray;
2438
2439 //$_AI=Clazz.newIntArray;
2440 //$_AF=Clazz.newFloatArray;
2441 //$_AD=Clazz.newDoubleArray;
2442 //$_AL=Clazz.newLongArray;
2443 //$_AS=Clazz.newShortArray;
2444 //$_AB=Clazz.newByteArray;
2445 //$_AC=Clazz.newCharArray;
2446 //$_Ab=Clazz.newBooleanArray;
2447
2448
2449 var arrayIs = function(a, what) {
2450         // for some reason, Number.constructor.toString() now gives "too much recursion"
2451         return a.constructor && a.constructor != Number && a.constructor.toString().indexOf(what) >= 0
2452 }
2453
2454 Clazz.isAS = function(a) { // just checking first parameter
2455         return (a && typeof a == "object" && arrayIs(a, " Array") && (typeof a[0] == "string" || typeof a[0] == "undefined"));
2456 }
2457
2458 Clazz.isASS = function(a) {
2459         return (a && typeof a == "object" && Clazz.isAS(a[0]));
2460 }
2461
2462 Clazz.isAP = function(a) {
2463         return (a && Clazz.getClassName(a[0]) == "JU.P3");
2464 }
2465
2466 Clazz.isAI = function(a) {
2467         return (a && typeof a == "object" && (Clazz.haveInt32 ? arrayIs(a, "Int32Array") : a.int32Fake ? true : false));
2468 }
2469
2470 Clazz.isAII = function(a) { // assumes non-null a[0]
2471         return (a && typeof a == "object" && Clazz.isAI(a[0]));
2472 }
2473
2474 Clazz.isAF = function(a) {
2475         return (a && typeof a == "object" && (Clazz.haveFloat64 ? arrayIs(a, "Float64Array") : a.float64Fake ? true : false));
2476 }
2477
2478 Clazz.isAFF = function(a) { // assumes non-null a[0]
2479         return (a && typeof a == "object" && Clazz.isAF(a[0]));
2480 }
2481
2482 Clazz.isAFFF = function(a) { // assumes non-null a[0]
2483         return (a && typeof a == "object" && Clazz.isAFF(a[0]));
2484 }
2485
2486 Clazz.isAFloat = function(a) { // just checking first parameter
2487         return (a && typeof a == "object" && arrayIs(a, " Array") && Clazz.instanceOf(a[0], Float));
2488 }
2489
2490
2491 /**
2492  * Make the RunnableCompatiability instance as a JavaScript function.
2493  *
2494  * @param jsr Instance of RunnableCompatiability
2495  * @return JavaScript function instance represents the method run of jsr.
2496  */
2497 /* public */
2498 /*
2499 Clazz.makeFunction = function (jsr) {
2500 // never used in Jmol -- called by Enum, but not accessible to it -- part of SWT
2501         return function(e) {
2502                 if (!e)
2503                         e = window.event;
2504                 if (jsr.setEvent)
2505                         jsr.setEvent(e);
2506                 jsr.run();
2507                 switch (jsr.returnSet) {
2508                 case 1: 
2509                         return jsr.returnNumber;
2510                 case 2:
2511                         return jsr.returnBoolean;
2512                 case 3:
2513                         return jsr.returnObject;
2514                 }
2515         };
2516 };
2517 */
2518
2519 /* protected */
2520 Clazz.defineStatics = function (clazz) {
2521         for (var j = arguments.length, i = (j - 1) / 2; --i >= 0;) {
2522                 var val = arguments[--j]
2523                 var name = arguments[--j];
2524                 clazz[name] = clazz.prototype[name] = val;
2525         }
2526 };
2527
2528 /* public */
2529 Clazz.prepareFields = function (clazz, fieldsFun) {
2530         var stacks = [];
2531         if (clazz.con$truct) {
2532                 var ss = clazz.con$truct.stacks;
2533                 var idx = 0;//clazz.con$truct.index;
2534                 for (var i = idx; i < ss.length; i++) {
2535                         stacks[i] = ss[i];
2536                 }
2537         }
2538         addProto(clazz.prototype, "con$truct", clazz.con$truct = function () {
2539                 var stacks = arguments.callee.stacks;
2540                 if (stacks) {
2541                         for (var i = 0; i < stacks.length; i++) {
2542                                 stacks[i].apply (this, []);
2543                         }
2544                 }
2545         });
2546         stacks.push(fieldsFun);
2547         clazz.con$truct.stacks = stacks;
2548         clazz.con$truct.index = 0;
2549 };
2550
2551 /*
2552  * Serialize those public or protected fields in class 
2553  * net.sf.j2s.ajax.SimpleSerializable.
2554  */
2555 /* protected */
2556 /*
2557 Clazz.registerSerializableFields = function (clazz) {
2558         var args = arguments;
2559         var length = args.length;
2560         var newArr = [];
2561         if (clazz.declared$Fields) {
2562                 for (var i = 0; i < clazz.declared$Fields.length; i++) {
2563                         newArr[i] = clazz.declared$Fields[i];
2564                 }
2565         }
2566         clazz.declared$Fields = newArr;
2567
2568         if (length > 0 && length % 2 == 1) {
2569                 var fs = clazz.declared$Fields;
2570                 var n = (length - 1) / 2;
2571                 for (var i = 1; i <= n; i++) {
2572                         var o = { name : args[i + i - 1], type : args[i + i] };
2573                         var existed = false;
2574                         for (var j = 0; j < fs.length; j++) {
2575                                 if (fs[j].name == o.name) { // reloaded classes
2576                                         fs[j].type = o.type; // update type
2577                                         existed = true;
2578                                         break;
2579                                 }
2580                         }
2581                         if (!existed)
2582                                 fs.push(o);
2583                 }
2584         }
2585 };
2586 */
2587 /*
2588  * Get the caller method for those methods that are wrapped by 
2589  * Clazz.searchAndExecuteMethod.
2590  *
2591  * @param args caller method's arguments
2592  * @return caller method, null if there is not wrapped by 
2593  * Clazz.searchAndExecuteMethod or is called directly.
2594  */
2595 /* protected */
2596 /*
2597 Clazz.getMixedCallerMethod = function (args) {
2598         var o = {};
2599         var argc = args.callee.caller; // tryToSearchAndExecute
2600         if (argc && argc !== tryToSearchAndExecute) // inherited method's apply
2601                 argc = argc.arguments.callee.caller;
2602         if (argc !== tryToSearchAndExecute
2603                 || (argc = argc.arguments.callee.caller) !== Clazz.searchAndExecuteMethod)
2604                 return null;
2605         o.claxxRef = argc.arguments[1];
2606         o.fxName = argc.arguments[2];
2607         o.paramTypes = Clazz.getParamsType(argc.arguments[3]);  
2608         argc = argc.arguments.callee.caller // Clazz.generateDelegatingMethod 
2609                                         && argc.arguments.callee.caller; // the private method's caller
2610         if (!argc)
2611                 return null;
2612         o.caller = argc;
2613         return o;
2614 };
2615 */
2616 /* BH -- The issue here is a subclass calling its private method FOO when
2617  *       there is also a private method of the same name in its super class.
2618  *       This can ALWAYS be avoided and, one could argue, is bad 
2619  *       program design anyway. In Jmol, the presence of this possibility
2620  *       creates over 8000 references to the global $fx, which was only
2621  *       checked in a few rare cases. We can then also remove $fz references.
2622  *         
2623  */
2624
2625 /*
2626  * Check and return super private method.
2627  * In order make private methods be executed correctly, some extra javascript
2628  * must be inserted into the beggining of the method body of the non-private 
2629  * methods that with the same method signature as following:
2630  * <code>
2631  *                      var $private = Clazz.checkPrivateMethod (arguments);
2632  *                      if ($private) {
2633  *                              return $private.apply (this, arguments);
2634  *                      }
2635  * </code>
2636  * Be cautious about this. The above codes should be insert by Java2Script
2637  * compiler or with double checks to make sure things work correctly.
2638  *
2639  * @param args caller method's arguments
2640  * @return private method if there are private method fitted for the current 
2641  * calling environment
2642  */
2643 /* public */
2644
2645 Clazz.checkPrivateMethod = function () {
2646   // get both this one and the one calling it
2647   me = arguments.callee.caller;
2648   caller = arguments.callee.caller.caller;
2649   var stack = me.stacks;
2650   // if their classes are the same, no issue
2651   var mySig = "\\" + Clazz.getParamsType(arguments[0]).join("\\")
2652   if (!me.privateNote) {
2653     me.privateNote = "You are seeing this note because the method " 
2654     + me.exName + mySig + " in class " 
2655     + me.exClazz.__CLASS_NAME__
2656     + " has a superclass method by the same name (possibly with the same parameters) that is private and "
2657     + " therefore might be called improperly from this class. If your "
2658     + " code does not run properly, or you want to make it run faster, change the name of this method to something else."
2659     System.out.println(me.privateNote);
2660     alert(me.privateNote);
2661   }
2662   /*
2663   alert([me.exClazz.__CLASS_NAME__, me.exName,
2664     caller.exClazz.__CLASS_NAME__, caller.exName,stack,mySig])
2665   if (stack == null || caller.exClazz == me.exClazz)
2666     return null;
2667   // I am being called by a different class...
2668   
2669   for (var i = stack.length; --i >= 0;) {
2670     if (stacks[i] != caller.claxxRef)
2671       continue;
2672     // and it is on MY class stack
2673 //    if (
2674      
2675   }
2676   */
2677   
2678 /*      var m = Clazz.getMixedCallerMethod (args);
2679         if (m == null) return null;
2680         var callerFx = m.claxxRef.prototype[m.caller.exName];
2681         if (callerFx == null) return null; // may not be in the class hierarchies
2682         var ppFun = null;
2683         if (callerFx.claxxOwner ) {
2684                 ppFun = callerFx.claxxOwner.prototype[m.fxName];
2685         } else {
2686                 var stacks = callerFx.stacks;
2687                 for (var i = stacks.length - 1; i >= 0; i--) {
2688                         var fx = stacks[i].prototype[m.caller.exName];
2689                         if (fx === m.caller) {
2690                                 ppFun = stacks[i].prototype[m.fxName];
2691                         } else if (fx ) {
2692                                 for (var fn in fx) {
2693                                         if (fn.indexOf ('\\') == 0 && fx[fn] === m.caller) {
2694                                                 ppFun = stacks[i].prototype[m.fxName];
2695                                                 break;
2696                                         }
2697                                 }
2698                         }
2699                         if (ppFun) {
2700                                 break;
2701                         }
2702                 }
2703         }
2704         if (ppFun && ppFun.claxxOwner == null) {
2705                 ppFun = ppFun["\\" + m.paramTypes];
2706         }
2707         if (ppFun && ppFun.isPrivate && ppFun !== args.callee) {
2708                 return ppFun;
2709         }
2710 */  
2711         return null;
2712 };
2713
2714
2715 //$fz = null; // for private method declaration
2716
2717
2718 // /*# {$no.debug.support} >>x #*/
2719 // /*
2720 //  * Option to switch on/off of stack traces.
2721 //  */
2722 // /* protect */
2723 //Clazz.tracingCalling = false;
2724
2725 // /* private */
2726 // Clazz.callingStack = function (caller, owner) {
2727 //      this.caller = caller;
2728 //      this.owner = owner;
2729 // };
2730
2731 /*# x<< #*/
2732
2733 /**
2734  * The first folder is considered as the primary folder.
2735  * And try to be compatiable with _Loader system.
2736  */
2737 /* private */
2738
2739
2740 /*** not used in Jmol
2741  * *
2742 if (window["_Loader"] && _Loader.binaryFolders) {
2743         Clazz.binaryFolders = _Loader.binaryFolders;
2744 } else {
2745         Clazz.binaryFolders = ["j2s/", "", "j2slib/"];
2746 }
2747
2748 Clazz.addBinaryFolder = function (bin) {
2749         if (bin) {
2750                 var bins = Clazz.binaryFolders;
2751                 for (var i = 0; i < bins.length; i++) {
2752                         if (bins[i] == bin) {
2753                                 return ;
2754                         }
2755                 }
2756                 bins[bins.length] = bin;
2757         }
2758 };
2759 Clazz.removeBinaryFolder = function (bin) {
2760         if (bin) {
2761                 var bins = Clazz.binaryFolders;
2762                 for (var i = 0; i < bins.length; i++) {
2763                         if (bins[i] == bin) {
2764                                 for (var j = i; j < bins.length - 1; j++) {
2765                                         bins[j] = bins[j + 1];
2766                                 }
2767                                 bins.length--;
2768                                 return bin;
2769                         }
2770                 }
2771         }
2772         return null;
2773 };
2774 Clazz.setPrimaryFolder = function (bin) {
2775         if (bin) {
2776                 Clazz.removeBinaryFolder (bin);
2777                 var bins = Clazz.binaryFolders;
2778                 for (var i = bins.length - 1; i >= 0; i--) {
2779                         bins[i + 1] = bins[i];
2780                 }
2781                 bins[0] = bin;
2782         }
2783 };
2784
2785 ***/
2786
2787
2788 ///////////////// special definitions of standard Java class methods ///////////
2789
2790 /**
2791  * This is a simple implementation for Clazz#load. It just ignore dependencies
2792  * of the class. This will be fine for jar *.z.js file.
2793  * It will be overriden by _Loader#load.
2794  * For more details, see _Loader.js
2795  */
2796 /* protected */
2797 /*
2798 Clazz.load = function (musts, clazz, optionals, declaration) {
2799         // not used in Jmol
2800         if (declaration)
2801                 declaration ();
2802 };
2803 */
2804
2805 /*
2806  * Invade the Object prototype!
2807  * TODO: make sure that invading Object prototype does not affect other
2808  * existed library, such as Dojo, YUI, Prototype, ...
2809  */
2810 java.lang.Object = Clazz._O;
2811
2812 Clazz._O.getName = Clazz._innerFunctions.getName;
2813
2814
2815 java.lang.System = System = {
2816         props : null, //new java.util.Properties (),
2817         $props : {},
2818         arraycopy : function (src, srcPos, dest, destPos, length) {
2819                 if (src !== dest) {
2820                         for (var i = 0; i < length; i++) {
2821                                 dest[destPos + i] = src[srcPos + i];
2822                         }
2823                 } else {
2824                         var swap = [];
2825                         for (var i = 0; i < length; i++) {
2826                                 swap[i] = src[srcPos + i];
2827                         }
2828                         for (var i = 0; i < length; i++) {
2829                                 dest[destPos + i] = swap[i];
2830                         }
2831                 }
2832         },
2833         currentTimeMillis : function () {
2834                 return new Date ().getTime ();
2835         },
2836         gc : function() {}, // bh
2837         getProperties : function () {
2838                 return System.props;
2839         },
2840         getProperty : function (key, def) {
2841                 if (System.props)
2842                         return System.props.getProperty (key, def);
2843                 var v = System.$props[key];
2844     if (typeof v != "undefined")
2845       return v;
2846     if (key.indexOf(".") > 0) {
2847       v = null;    
2848       switch (key) {
2849       case "java.version":
2850         v = "1.6";
2851       case "file.separator":
2852       case "path.separator":
2853         v = "/";
2854         break;        
2855       case "line.separator":
2856         v = (navigator.userAgent.indexOf("Windows") >= 0 ? "\r\n" : "\n");
2857         break;
2858       case "os.name":
2859       case "os.version":
2860         v = navigator.userAgent;
2861         break;
2862       }
2863       if (v)
2864         return System.$props[key] = v;
2865     }
2866     return (arguments.length == 1 ? null : def == null ? key : def); // BH
2867         },
2868         getSecurityManager : function() { return null },  // bh
2869         setProperties : function (props) {
2870                 System.props = props;
2871         },
2872   lineSeparator : function() { return '\n' }, // bh
2873         setProperty : function (key, val) {
2874                 if (!System.props)
2875                         return System.$props[key] = val; // BH
2876                 System.props.setProperty (key, val);
2877         }
2878 };
2879
2880 System.identityHashCode=function(obj){
2881   if(obj==null)
2882     return 0;
2883     
2884         return obj._$hashcode || (obj._$hashcode = ++Clazz._hashCode)
2885
2886 /*    
2887   try{
2888     return obj.toString().hashCode();
2889   }catch(e){
2890     var str=":";
2891     for(var s in obj){
2892      str+=s+":"
2893     }
2894     return str.hashCode();
2895   }
2896 */  
2897 }
2898
2899 System.out = new Clazz._O ();
2900 System.out.__CLASS_NAME__ = "java.io.PrintStream";
2901 System.out.print = function () {};
2902 System.out.printf = function () {};
2903 System.out.println = function () {};
2904 System.out.write = function () {};
2905
2906 System.err = new Clazz._O ();
2907 System.err.__CLASS_NAME__ = "java.io.PrintStream";
2908 System.err.print = function () {};
2909 System.err.printf = function () {};
2910 System.err.println = function () {};
2911 System.err.write = function () {};
2912
2913 Clazz.popup = Clazz.assert = Clazz.log = Clazz.error = window.alert;
2914
2915 Thread = function () {};
2916 Thread.J2S_THREAD = Thread.prototype.J2S_THREAD = new Thread ();
2917 Thread.currentThread = Thread.prototype.currentThread = function () {
2918         return this.J2S_THREAD;
2919 };
2920
2921 /* not used in Jmol
2922 Clazz.intCast = function (n) { // 32bit
2923         var b1 = (n & 0xff000000) >> 24;
2924         var b2 = (n & 0xff0000) >> 16;
2925         var b3 = (n & 0xff00) >> 8;
2926         var b4 = n & 0xff;
2927         if ((b1 & 0x80) != 0) {
2928                 return -(((b1 & 0x7f) << 24) + (b2 << 16) + (b3 << 8) + b4 + 1);
2929         } else {
2930                 return (b1 << 24) + (b2 << 16) + (b3 << 8) + b4;
2931         }
2932 };
2933 Clazz.shortCast = function (s) { // 16bit
2934         var b1 = (n & 0xff00) >> 8;
2935         var b2 = n & 0xff;
2936         if ((b1 & 0x80) != 0) {
2937                 return -(((b1 & 0x7f) << 8) + b2 + 1);
2938         } else {
2939                 return (b1 << 8) + b4;
2940         }
2941 };
2942
2943 Clazz.byteCast = function (b) { // 8bit
2944         if ((b & 0x80) != 0) {
2945                 return -((b & 0x7f) + 1);
2946         } else {
2947                 return b & 0xff;
2948         }
2949 };
2950
2951 Clazz.charCast = function (c) { // 8bit
2952         return String.fromCharCode (c & 0xff).charAt (0);
2953 };
2954
2955 Clazz.floatCast = function (f) { // 32bit
2956         return f;
2957 };
2958
2959 */
2960
2961
2962 /*
2963  * Try to fix JavaScript's shift operator defects on long type numbers.
2964  */
2965
2966 /* not used in Jmol
2967
2968 Clazz.longMasks = [];
2969
2970 Clazz.longReverseMasks = [];
2971
2972 Clazz.longBits = [];
2973
2974 ;(function () {
2975         var arr = [1];
2976         for (var i = 1; i < 53; i++) {
2977                 arr[i] = arr[i - 1] + arr[i - 1]; // * 2 or << 1
2978         }
2979         Clazz.longBits = arr;
2980         Clazz.longMasks[52] = arr[52];
2981         for (var i = 51; i >= 0; i--) {
2982                 Clazz.longMasks[i] = Clazz.longMasks[i + 1] + arr[i];
2983         }
2984         Clazz.longReverseMasks[0] = arr[0];
2985         for (var i = 1; i < 52; i++) {
2986                 Clazz.longReverseMasks[i] = Clazz.longReverseMasks[i - 1] + arr[i];
2987         }
2988 }) ();
2989
2990
2991 Clazz.longLeftShift = function (l, o) { // 64bit
2992         if (o == 0) return l;
2993         if (o >= 64) return 0;
2994         if (o > 52) {
2995                 error ("[Java2Script] Error : JavaScript does not support long shift!");
2996                 return l;
2997         }
2998         if ((l & Clazz.longMasks[o - 1]) != 0) {
2999                 error ("[Java2Script] Error : Such shift operator results in wrong calculation!");
3000                 return l;
3001         }
3002         var high = l & Clazz.longMasks[52 - 32 + o];
3003         if (high != 0) {
3004                 return high * Clazz.longBits[o] + (l & Clazz.longReverseMasks[32 - o]) << 0;
3005         } else {
3006                 return l << o;
3007         }
3008 };
3009
3010 Clazz.intLeftShift = function (n, o) { // 32bit
3011         return (n << o) & 0xffffffff;
3012 };
3013
3014 Clazz.longRightShift = function (l, o) { // 64bit
3015         if ((l & Clazz.longMasks[52 - 32]) != 0) {
3016                 return Math.round((l & Clazz.longMasks[52 - 32]) / Clazz.longBits[32 - o]) + (l & Clazz.longReverseMasks[o]) >> o;
3017         } else {
3018                 return l >> o;
3019         }
3020 };
3021
3022 Clazz.intRightShift = function (n, o) { // 32bit
3023         return n >> o; // no needs for this shifting wrapper
3024 };
3025
3026 Clazz.long0RightShift = function (l, o) { // 64bit
3027         return l >>> o;
3028 };
3029
3030 Clazz.int0RightShift = function (n, o) { // 64bit
3031         return n >>> o; // no needs for this shifting wrapper
3032 };
3033
3034 */
3035 // Compress the common public API method in shorter name
3036 //$_L=Clazz.load;
3037 //$_W=Clazz.declareAnonymous;$_T=Clazz.declareType;
3038 //$_J=Clazz.declarePackage;$_C=Clazz.decorateAsClass;
3039 //$_Z=Clazz.instantialize;$_I=Clazz.declareInterface;$_D=Clazz.isClassDefined;
3040 //$_H=Clazz.pu$h;$_P=Clazz.p0p;$_B=Clazz.prepareCallback;
3041 //$_N=Clazz.innerTypeInstance;$_K=Clazz.makeConstructor;$_U=Clazz.superCall;$_R=Clazz.superConstructor;
3042 //$_M=Clazz.defineMethod;$_V=Clazz.overrideMethod;$_S=Clazz.defineStatics;
3043 //$_E=Clazz.defineEnumConstant;
3044 //$_F=Clazz.cloneFinals;
3045 //$_Y=Clazz.prepareFields;$_A=Clazz.newArray;$_O=Clazz.instanceOf;
3046 //$_G=Clazz.inheritArgs;$_X=Clazz.checkPrivateMethod;$_Q=Clazz.makeFunction;
3047 //$_s=Clazz.registerSerializableFields;
3048 //$_k=Clazz.overrideConstructor;
3049
3050
3051 /////////////////////// inner function support /////////////////////////////////
3052
3053 /* public */
3054 Clazz.innerFunctionNames = Clazz.innerFunctionNames.concat ([
3055     "getSuperclass", "isAssignableFrom", 
3056     "getConstructor", 
3057     "getDeclaredMethod", "getDeclaredMethods",
3058     "getMethod", "getMethods",   
3059                 "getModifiers", /*"isArray",*/ "newInstance"]);
3060
3061 /* public */
3062 Clazz._innerFunctions.getSuperclass = function () {
3063         return this.superClazz; 
3064 };
3065
3066 /* public */
3067 Clazz._innerFunctions.isAssignableFrom = function (clazz) {
3068         return Clazz.getInheritedLevel (clazz, this) >= 0;      
3069 };
3070
3071 /* public */
3072 Clazz._innerFunctions.getConstructor = function () {
3073         return new java.lang.reflect.Constructor (this, [], [], 
3074                         java.lang.reflect.Modifier.PUBLIC);
3075 };
3076 /**
3077  * TODO: fix bug for polymorphic methods!
3078  */
3079 /* public */
3080 Clazz._innerFunctions.getDeclaredMethods = Clazz._innerFunctions.getMethods = function () {
3081         var ms = [];
3082         var p = this.prototype;
3083         for (var attr in p) {
3084                 if (typeof p[attr] == "function" && !p[attr].__CLASS_NAME__) {
3085                         /* there are polynormical methods. */
3086                         ms.push(new java.lang.reflect.Method (this, attr,
3087                                         [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC));
3088                 }
3089         }
3090         p = this;
3091         for (var attr in p) {
3092                 if (typeof p[attr] == "function" && !p[attr].__CLASS_NAME__) {
3093                         ms.push(new java.lang.reflect.Method (this, attr,
3094                                         [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC
3095                                         | java.lang.reflect.Modifier.STATIC));
3096                 }
3097         }
3098         return ms;
3099 };
3100 /* public */
3101 Clazz._innerFunctions.getDeclaredMethod = Clazz._innerFunctions.getMethod = function (name, clazzes) {
3102         var p = this.prototype;
3103         for (var attr in p) {
3104                 if (name == attr && typeof p[attr] == "function" 
3105                                 && !p[attr].__CLASS_NAME__) {
3106                         /* there are polynormical methods. */
3107                         return new java.lang.reflect.Method (this, attr,
3108                                         [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC);
3109                 }
3110         }
3111         p = this;
3112         for (var attr in p) {
3113                 if (name == attr && typeof p[attr] == "function" 
3114                                 && !p[attr].__CLASS_NAME__) {
3115                         return new java.lang.reflect.Method (this, attr,
3116                                         [], java.lang.Void, [], java.lang.reflect.Modifier.PUBLIC
3117                                         | java.lang.reflect.Modifier.STATIC);
3118                 }
3119         }
3120         return null;
3121 };
3122 /* public */
3123 Clazz._innerFunctions.getModifiers = function () {
3124         return java.lang.reflect.Modifier.PUBLIC;
3125 };
3126
3127 Clazz._innerFunctions.newInstance = function (a) {
3128         var clz = this;
3129   switch(a == null ? 0 : a.length) {
3130   case 0:
3131     return new clz();
3132   case 1:
3133         return new clz(a[0]);
3134   case 2:
3135         return new clz(a[0], a[1]);
3136   case 3:
3137         return new clz(a[0], a[1], a[2]);
3138   case 4:
3139         return new clz(a[0], a[1], a[2], a[3]);
3140   default:
3141     var x = "new " + clz.__CLASS_NAME__ + "(";
3142     for (var i = 0; i < a.length; i++)
3143      x += (i == 0 ? "" : ",") + "a[" + i + "]";
3144     x += ")";
3145     return eval(x);
3146   }
3147 };
3148
3149 //Object.newInstance = Clazz._innerFunctions.newInstance;
3150 ;(function(){  // BH added wrapper here
3151         var inF = Clazz.innerFunctionNames;
3152         for (var i = 0; i < inF.length; i++) {
3153                 Clazz._O[inF[i]] = Clazz._innerFunctions[inF[i]];
3154                 Array[inF[i]] = Clazz._innerFunctions[inF[i]];
3155         }
3156         //Array["isArray"] = function () {
3157         //      return true;
3158         //};
3159 })();
3160
3161 //////////////////////////// hotspot and unloading /////////////////////////////
3162 /* For hotspot and unloading */
3163
3164 if (window["Clazz"] && !window["Clazz"].unloadClass) {
3165
3166 /* public */
3167 Clazz.unloadClass = function (qClazzName) {
3168         var cc = Clazz.evalType (qClazzName);
3169         if (cc) {
3170                 Clazz.unloadedClasses[qClazzName] = cc;
3171                 var clazzName = qClazzName;
3172                 var pkgFrags = clazzName.split (/\./);
3173                 var pkg = null;
3174                 for (var i = 0; i < pkgFrags.length - 1; i++)
3175                         pkg = (pkg ? pkg[pkgFrags[i]] : Clazz.allPackage[pkgFrags[0]]);
3176                 if (!pkg) {
3177                         Clazz.allPackage[pkgFrags[0]] = null;
3178                         window[pkgFrags[0]] = null;
3179                         // also try to unload inner or anonymous classes
3180                         for (var c in window) {
3181                                 if (c.indexOf (qClazzName + "$") == 0) {
3182                                         Clazz.unloadClass (c);
3183                                         window[c] = null;
3184                                 }
3185                         }
3186                 } else {
3187                         pkg[pkgFrags[pkgFrags.length - 1]] = null;
3188                         // also try to unload inner or anonymous classes
3189                         for (var c in pkg) {
3190                                 if (c.indexOf (pkgFrags[pkgFrags.length - 1] + "$") == 0) {
3191                                         Clazz.unloadClass (pkg.__PKG_NAME__ + "." + c);
3192                                         pkg[c] = null;
3193                                 }
3194                         }
3195                 }
3196
3197                 if (Clazz.allClasses[qClazzName]) {
3198                         Clazz.allClasses[qClazzName] = false;
3199                         // also try to unload inner or anonymous classes
3200                         for (var c in Clazz.allClasses) {
3201                                 if (c.indexOf (qClazzName + "$") == 0) {
3202                                         Clazz.allClasses[c] = false;
3203                                 }
3204                         }
3205                 }
3206
3207                 for (var m in cc) {
3208                         cleanDelegateMethod (cc[m]);
3209                 }
3210                 for (var m in cc.prototype) {
3211                         cleanDelegateMethod (cc.prototype[m]);
3212                 }
3213
3214                 if (Clazz._Loader) {
3215                         Clazz._Loader.unloadClassExt(qClazzName);
3216                 }
3217
3218                 return true;
3219         }
3220         return false;
3221 };
3222
3223 /* private */
3224 var cleanDelegateMethod = function (m) {
3225         if (!m) 
3226                 return;
3227         if (typeof m == "function" && m.lastMethod
3228                         && m.lastParams && m.lastClaxxRef) {
3229                 m.lastMethod = null;
3230                 m.lastParams = null;
3231                 m.lastClaxxRef = null;
3232         }
3233 };
3234
3235 } // if (window["Clazz"] && !window["Clazz"].unloadClass)
3236
3237 /******************************************************************************
3238  * Copyright (c) 2007 java2script.org and others.
3239  * All rights reserved. This program and the accompanying materials
3240  * are made available under the terms of the Eclipse Public License v1.0
3241  * which accompanies this distribution, and is available at
3242  * http://www.eclipse.org/legal/epl-v10.html
3243  *
3244  * Contributors:
3245  *     Zhou Renjian - initial API and implementation
3246  *****************************************************************************/
3247 /*******
3248  * @author zhou renjian
3249  * @create July 10, 2006
3250  *******/
3251
3252 //if (window["ClazzNode"] == null) {
3253 /**
3254  * TODO:
3255  * Make optimization over class dependency tree.
3256  */
3257
3258 /*
3259  * ClassLoader Summary
3260  * 
3261  * ClassLoader creates SCRIPT elements and setup class path and onload 
3262  * callback to continue class loading.
3263  *
3264  * In the onload callbacks, _Loader will try to calculate the next-to-be-
3265  * load *.js and load it. In *.js, it will contains some codes like
3266  * Clazz.load (..., "$wt.widgets.Control", ...);
3267  * to provide information to build up the class dependency tree.
3268  *
3269  * Some known problems of different browsers:
3270  * 1. In IE, loading *.js through SCRIPT will first triggers onreadstatechange 
3271  * event, and then executes inner *.js source.
3272  * 2. In Firefox, loading *.js will first executes *.js source and then 
3273  * triggers onload event.
3274  * 3. In Opera, similar to IE, but trigger onload event. (TODO: More details 
3275  * should be studied. Currently, Opera supports no multiple-thread-loading)
3276  * 
3277  * For class dependency tree, actually, it is not a tree. It is a reference
3278  * net with nodes have n parents and n children. There is a root, which 
3279  * ClassLoader knows where to start searching and loading classes, for such
3280  * a net. Each node is a class. Each class may require a set of must-classes, 
3281  * which must be loaded before itself getting initialized, and also need a set
3282  * of optional classes, which also be loaded before being called.
3283  *
3284  * The class loading status will be in 6 stages.
3285  * 1. Unknown, the class is newly introduced by other class.
3286  * 2. Known, the class is already mentioned by other class.
3287  * 3. Loaded, *.js source is in memory, but may not be initialized yet. It 
3288  * requires all its must-classes be intiailized, which is in the next stage.
3289  * 4. Musts loaded, all must classes is already loaded and declared.
3290  * 5. Delcared, the class is already declared (_Loader#isClassDefined).
3291  * 6. Optionals loaded, all optional classes is loaded and declared.
3292  *
3293  * The ClassLoader tries to load all necessary classes in order, and intialize
3294  * them in order. For such job, it will traverse the dependency tree, and try 
3295  * to next class to-be-loaded. Sometime, the class dependencies may be in one
3296  * or more cycles, which must be broken down so classes is loaded in correct
3297  * order.
3298  *
3299  * Loading order and intializing order is very important for the ClassLoader.
3300  * The following technical options are considered:
3301  * 1. SCRIPT is loading asynchronously, which means controling order must use
3302  * callback methods to continue.
3303  * 2. Multiple loading threads are later introduced, which requires the 
3304  * ClassLoader should use variables to record the class status.
3305  * 3. Different browsers have different loading orders, which means extra tests
3306  * should be tested to make sure loading order won't be broken.
3307  * 4. Java2Script simulator itself have some loading orders that must be 
3308  * honored, which means it should be integrated seamlessly to Clazz system.
3309  * 5. Packed *.z.js is introduced to avoid lots of small *.js which requires 
3310  * lots of HTTP connections, which means that packed *.z.js should be treated
3311  * specially (There will be mappings for such packed classes).
3312  * 6. *.js or *.css loading may fail according to network status, which means
3313  * another loading try should be performed, so _Loader is more robust.
3314  * 7. SWT lazy loading is later introduced, which means that class loading
3315  * process may be paused and should be resumed later.
3316  *
3317  * Some known bugs:
3318  * <code>$_L(["$wt.graphics.Drawable","$wt.widgets.Widget"],
3319  *  "$wt.widgets.Control", ...</code>
3320  * has errors while must classes in different order such as
3321  * <code>$_L(["$wt.widgets.Widget", "$wt.graphics.Drawable"],
3322  *  "$wt.widgets.Control", ...</code>
3323  * has no error.
3324  * 
3325  * Other maybe bug scenarios:
3326  * 1. In <code>_Loader.maxLoadingThreads = 1;</code> single loading thread 
3327  * mode, there are no errors, but in default multiple thread loading mode, 
3328  * there are errors.
3329  * 2. No errors in one browser, but has errors on other browsers (Browser 
3330  * script loading order differences).
3331  * 3. First time loading has errors, but reloading it gets no errors (Maybe 
3332  * HTTP connections timeout, but should not accur in local file system, or it
3333  * is a loading bug by using JavaScript timeout thread).
3334  */
3335
3336 /*
3337  * The following comments with "#" are special configurations for a much
3338  * smaller *.js file size.
3339  *
3340  * @see net.sf.j2s.lib/src/net/sf/j2s/lib/build/SmartJSCompressor.java
3341  */
3342 /**
3343  * Static class loader class
3344  */
3345 Clazz._Loader = Clazz.ClazzLoader = function () {};
3346
3347 /**
3348  * Class dependency tree node
3349  */
3350 /* private */
3351 var Node = function () {
3352         this.parents = [];
3353         this.musts = [];
3354         this.optionals = [];
3355         this.declaration = null;
3356         this.name = null; // id
3357         this.path = null;
3358 //      this.requires = null;
3359 //      this.requiresMap = null;
3360         this.onLoaded = null;
3361         this.status = 0;
3362         this.random = 0.13412;
3363 };
3364
3365
3366 ;(function(Clazz, _Loader) {
3367
3368 _Loader._checkLoad = Jmol._checkLoad;
3369  
3370 _Loader.updateNodeForFunctionDecoration = function(qName) {
3371         var node = findNode(qName);
3372         if (node && node.status == Node.STATUS_KNOWN) {
3373                 window.setTimeout((function(nnn) {
3374                         return function() {
3375                                 updateNode(nnn);
3376                         };
3377                 })(node), 1);
3378         }
3379 }
3380
3381 Node.prototype.toString = function() {
3382         return this.name || this.path || "ClazzNode";
3383 }
3384
3385 Node.STATUS_UNKNOWN = 0;
3386 Node.STATUS_KNOWN = 1;
3387 Node.STATUS_CONTENT_LOADED = 2;
3388 Node.STATUS_MUSTS_LOADED = 3;
3389 Node.STATUS_DECLARED = 4;
3390 Node.STATUS_LOAD_COMPLETE = 5;
3391
3392                                                  
3393 var loaders = [];
3394
3395 /* public */
3396 _Loader.requireLoaderByBase = function (base) {
3397         for (var i = 0; i < loaders.length; i++) {
3398                 if (loaders[i].base == base) {
3399                         return loaders[i];
3400                 }
3401         }
3402         var loader = new _Loader ();
3403         loader.base = base; 
3404         loaders.push(loader);
3405         return loader;
3406 };
3407
3408 /**
3409  * Class dependency tree
3410  */
3411 var clazzTreeRoot = new Node();
3412
3413 /**
3414  * Used to keep the status whether a given *.js path is loaded or not.
3415  */
3416 /* private */
3417 var loadedScripts = {};
3418
3419 /**
3420  * Multiple threads are used to speed up *.js loading.
3421  */
3422 /* private */
3423 var inLoadingThreads = 0;
3424
3425 /**
3426  * Maximum of loading threads
3427  */
3428 /* private */
3429 var maxLoadingThreads = 6;
3430
3431 var userAgent = navigator.userAgent.toLowerCase ();
3432 var isOpera = (userAgent.indexOf ("opera") != -1);
3433 var isIE = (userAgent.indexOf ("msie") != -1) && !isOpera;
3434 var isGecko = (userAgent.indexOf ("gecko") != -1);
3435
3436 /*
3437  * Opera has different loading order which will result in performance degrade!
3438  * So just return to single thread loading in Opera!
3439  *
3440  * FIXME: This different loading order also causes bugs in single thread!
3441  */
3442 if (isOpera) {
3443         maxLoadingThreads = 1;
3444         var index = userAgent.indexOf ("opera/");
3445         if (index != -1) {
3446                 var verNumber = 9.0;
3447                 try {
3448                         verNumber = parseFloat(userAgent.subString (index + 6));
3449                 } catch (e) {}
3450                 if (verNumber >= 9.6) {
3451                         maxLoadingThreads = 6;
3452                 }
3453         } 
3454 }
3455
3456 /**
3457  * Try to be compatiable with Clazz system.
3458  * In original design _Loader and Clazz are independent!
3459  *  -- zhourenjian @ December 23, 2006
3460  */
3461 var isClassdefined;
3462 var definedClasses;
3463
3464 if (self.Clazz && Clazz.isClassDefined) {
3465         isClassDefined = Clazz.isClassDefined;
3466 } else {
3467         definedClasses = {};
3468         isClassDefined = function (clazzName) {
3469                 return definedClasses[clazzName] == true;
3470         };
3471 }
3472
3473 /**
3474  * Expand the shortened list of class names.
3475  * For example:
3476  * JU.Log, $.Display, $.Decorations
3477  * will be expanded to 
3478  * JU.Log, JU.Display, JU.Decorations
3479  * where "$." stands for the previous class name's package.
3480  *
3481  * This method will be used to unwrap the required/optional classes list and 
3482  * the ignored classes list.
3483  */
3484 /* private */
3485 var unwrapArray = function (arr) {
3486         if (!arr || arr.length == 0)
3487                 return [];
3488         var last = null;
3489         for (var i = 0; i < arr.length; i++) {
3490                 if (!arr[i])
3491                         continue;
3492                 if (arr[i].charAt (0) == '$') {
3493                         if (arr[i].charAt (1) == '.') {
3494                                 if (!last)
3495                                         continue;
3496                                 var idx = last.lastIndexOf (".");
3497                                 if (idx != -1) {
3498                                         var prefix = last.substring (0, idx);
3499                                         arr[i] = prefix + arr[i].substring (1);
3500                                 }
3501                         } else {
3502                                 arr[i] = "org.eclipse.s" + arr[i].substring (1);
3503                         }
3504                 }
3505                 last = arr[i];
3506         }
3507         return arr;
3508 };
3509
3510 /**
3511  * Used to keep to-be-loaded classes.
3512  */
3513 /* private */
3514 var classQueue = [];
3515
3516 /* private */
3517 var classpathMap = {};
3518
3519 /* private */
3520 var pkgRefCount = 0;
3521
3522 /* public */
3523 _Loader.loadPackageClasspath = function (pkg, base, isIndex, fSuccess, mode, pt) {
3524         var map = classpathMap;
3525         mode || (mode = 0);
3526         fSuccess || (fSuccess = null);
3527         pt || (pt = 0);
3528
3529         /*
3530          * In some situation, maybe,
3531          * _Loader.packageClasspath ("java", ..., true);
3532          * is called after other _Loader#packageClasspath, e.g.
3533          * <code>
3534          * _Loader.packageClasspath ("org.eclipse.swt", "...", true);
3535          * _Loader.packageClasspath ("java", "...", true);
3536          * </code>
3537          * which is not recommended. But _Loader should try to adjust orders
3538          * which requires "java" to be declared before normal _Loader
3539          * #packageClasspath call before that line! And later that line
3540          * should never initialize "java/package.js" again!
3541          */
3542         var isPkgDeclared = (isIndex && map["@" + pkg]);
3543         if (mode == 0 && isIndex && !map["@java"] && pkg.indexOf ("java") != 0 && needPackage("java")) {
3544                 _Loader.loadPackage("java", fSuccess ? function(_package){_Loader.loadPackageClasspath(pkg, base, isIndex, fSuccess, 1)} : null);
3545                 if (fSuccess)
3546                         return;
3547         }
3548         if (pkg instanceof Array) {
3549                 unwrapArray(pkg);
3550                 if (fSuccess) {
3551                         if (pt < pkg.length)
3552                                 _Loader.loadPackageClasspath(pkg[pt], base, isIndex, function(_loadPackageClassPath){_Loader.loadPackageClasspath(pkg, base, isIndex, fSuccess, 1, pt + 1)}, 1);
3553                         else
3554                                 fSuccess();
3555                 } else {
3556                         for (var i = 0; i < pkg.length; i++)
3557                                 _Loader.loadPackageClasspath(pkg[i], base, isIndex, null);
3558                 }
3559                 return;
3560         }
3561         switch (pkg) {
3562         case "java.*":
3563                 pkg = "java";
3564                 // fall through
3565         case "java":
3566                 if (base) {
3567                         // support ajax for default
3568                         var key = "@net.sf.j2s.ajax";
3569                         if (!map[key])
3570                                 map[key] = base;
3571                         key = "@net.sf.j2s";
3572                         if (!map[key])
3573                                 map[key] = base;
3574                 }               
3575                 break;
3576         case "swt":
3577                 pkg = "org.eclipse.swt";
3578                 break;
3579         case "ajax":
3580                 pkg = "net.sf.j2s.ajax";
3581                 break;
3582         case "j2s":
3583                 pkg = "net.sf.j2s";
3584                 break;
3585         default:
3586                 if (pkg.lastIndexOf(".*") == pkg.length - 2)
3587                         pkg = pkg.substring(0, pkg.length - 2);
3588                 break;
3589         }
3590         if (base) // critical for multiple applets
3591                 map["@" + pkg] = base;
3592         if (isIndex && !isPkgDeclared && !window[pkg + ".registered"]) {
3593                 pkgRefCount++;
3594                 if (pkg == "java")
3595                         pkg = "core" // JSmol -- moves java/package.js to core/package.js
3596                 _Loader.loadClass(pkg + ".package", function () {
3597                                         if (--pkgRefCount == 0)
3598                                                 runtimeLoaded();
3599                                         //fSuccess && fSuccess();
3600                                 }, true, true, 1);
3601                 return;
3602         }
3603         fSuccess && fSuccess();
3604 };
3605
3606 /**
3607  * BH: allows user/developer to load classes even though wrapping and Google
3608  * Closure Compiler has not been run on the class.
3609  *   
3610  */
3611 Clazz.loadClass = function (name, onLoaded, async) {
3612   if (!self.Class) {
3613     Class = Clazz;
3614     Class.forName = Clazz._4Name;
3615     JavaObject = Clazz._O;
3616     // maybe more here
3617   }
3618   return (name && _Loader.loadClass(name, onLoaded, true, async, 1));
3619 }
3620
3621 /**
3622  * Load the given class ant its related classes.
3623  */
3624 /* public */
3625 _Loader.loadClass = function (name, onLoaded, forced, async, mode) {
3626
3627   mode || (mode = 0); // BH: not implemented
3628   (async == null) && (async = false);
3629   
3630         if (typeof onLoaded == "boolean")
3631                 return Clazz.evalType(name);
3632
3633   System.out.println("loadClass " + name)
3634
3635         // Make sure that packageClasspath ("java", base, true); 
3636         // is called before any _Loader#loadClass is called.
3637
3638         if (needPackage("java"))
3639                 _Loader.loadPackage("java");
3640         if (needPackage("core"))
3641                 _Loader.loadPackage("core");    
3642
3643 //      var swtPkg = "org.eclipse.swt";
3644 //      if (name.indexOf (swtPkg) == 0 || name.indexOf ("$wt") == 0) {
3645 //              _Loader.assurePackageClasspath (swtPkg);
3646 //      }
3647 //      if (name.indexOf ("junit") == 0) {
3648 //              _Loader.assurePackageClasspath ("junit");
3649 //      }
3650
3651         // Any _Loader#loadClass calls will be queued until java.* core classes are loaded.
3652
3653         _Loader.keepOnLoading = true;
3654         
3655         if (!forced && (pkgRefCount && name.lastIndexOf(".package") != name.length - 8
3656                         || name.indexOf("java.") != 0 && !isClassDefined(runtimeKeyClass)
3657                  )) {   
3658                 queueBe4KeyClazz.push([name, onLoaded]);
3659     
3660     
3661   System.out.println("loadclass-queuing" + name+ runtimeKeyClass + " "+ isClassDefined(runtimeKeyClass))
3662
3663                 return;    
3664         }
3665         var b;
3666         if ((b = isClassDefined(name)) || isClassExcluded(name)) {
3667                 if (b && onLoaded) {
3668                         var nn = findNode(name);
3669                         if (!nn || nn.status >= Node.STATUS_LOAD_COMPLETE) {
3670                                 if (async) {
3671                                         window.setTimeout(onLoaded, 25);
3672                                 } else {
3673                                         onLoaded();
3674                                 }
3675                         }
3676                 }
3677                 return;
3678         }
3679         var path = _Loader.getClasspathFor(name);
3680   var existed = loadedScripts[path];
3681         var qq = classQueue;
3682         if (!existed)
3683                 for (var i = qq.length; --i >= 0;)
3684                         if (qq[i].path == path || qq[i].name == name) {
3685                                 existed = true;
3686                                 break;
3687                         }
3688         if (existed) {
3689                 if (onLoaded) {
3690                         var n = findNode(name);
3691                         if (n) {
3692                                 if (!n.onLoaded) {
3693                                         n.onLoaded = onLoaded;
3694                                 } else if (onLoaded != n.onLoaded) {
3695                                         n.onLoaded = (function (nF, oF) { return function () { nF(); oF() };    }) (n.onLoaded, onLoaded);
3696                                 }
3697                         }
3698                 }
3699                 return;
3700         }
3701
3702         var n = (Clazz.unloadedClasses[name] && findNode(name) || new Node());
3703         n.name = name;
3704         n.path = path;
3705         n.isPackage = (path.lastIndexOf("package.js") == path.length - 10);
3706         mappingPathNameNode(path, name, n);
3707         n.onLoaded = onLoaded;
3708         n.status = Node.STATUS_KNOWN;
3709         var needBeingQueued = false;
3710         for (var i = qq.length; --i >= 0;) {
3711                 if (qq[i].status != Node.STATUS_LOAD_COMPLETE) {
3712                         needBeingQueued = true;
3713                         break;
3714                 }
3715         }
3716         
3717         if (n.isPackage) {//forced
3718                 // push class to queue
3719                 var pt = qq.length;
3720                 for (; --pt >= 0;) {
3721                         if (qq[pt].isPackage) 
3722                                 break;
3723                         qq[pt + 1] = qq[pt];
3724                 }
3725                 qq[++pt] = n;
3726         } else if (needBeingQueued) {
3727                 qq.push(n);
3728         }
3729         if (!needBeingQueued) { // can be loaded directly
3730                 var bSave = false;
3731                 if (onLoaded) { 
3732                         bSave = isLoadingEntryClass;
3733                         isLoadingEntryClass = true;
3734                 }
3735     if (forced)onLoaded = null;
3736                 addChildClassNode(clazzTreeRoot, n, true);
3737                 loadScript(n, n.path, n.requiredBy, false, onLoaded ? function(_loadClass){ isLoadingEntryClass = bSave; onLoaded()}: null);
3738         }
3739 };
3740
3741 /*
3742  * Check whether given package's classpath is setup or not.
3743  * Only "java" and "org.eclipse.swt" are accepted in argument.
3744  */
3745 /* private */
3746 var needPackage = function(pkg) {
3747   // note that false != null and true != null
3748         return (window[pkg + ".registered"] != null && !classpathMap["@" + pkg]);
3749 }
3750
3751 /* private */
3752 _Loader.loadPackage = function(pkg, fSuccess) {
3753         fSuccess || (fSuccess = null);
3754         window[pkg + ".registered"] = false;
3755         _Loader.loadPackageClasspath(pkg, 
3756                 (_Loader.J2SLibBase || (_Loader.J2SLibBase = (_Loader.getJ2SLibBase() || "j2s/"))), 
3757                 true, fSuccess);
3758 };
3759
3760 /**
3761  * Register classes to a given *.z.js path, so only a single *.z.js is loaded
3762  * for all those classes.
3763  */
3764 /* public */
3765 _Loader.jarClasspath = function (jar, clazzes) {
3766         if (!(clazzes instanceof Array))
3767                 clazzes = [classes];
3768         unwrapArray(clazzes);
3769         for (var i = clazzes.length; --i >= 0;)
3770                 classpathMap["#" + clazzes[i]] = jar;
3771         classpathMap["$" + jar] = clazzes;
3772 };
3773
3774 /**
3775  * Usually be used in .../package.js. All given packages will be registered
3776  * to the same classpath of given prefix package.
3777  */
3778 /* public */
3779 _Loader.registerPackages = function (prefix, pkgs) {
3780         //_Loader.checkInteractive ();
3781         var base = _Loader.getClasspathFor (prefix + ".*", true);
3782         for (var i = 0; i < pkgs.length; i++) {
3783                 if (window["Clazz"]) {
3784                         Clazz.declarePackage (prefix + "." + pkgs[i]);
3785                 }
3786                 _Loader.loadPackageClasspath (prefix + "." + pkgs[i], base);
3787         }
3788 };
3789
3790 /**
3791  * Using multiple sites to load *.js in multiple threads. Using multiple
3792  * sites may avoid 2 HTTP 1.1 connections recommendation limit.
3793  * Here is a default implementation for http://archive.java2script.org.
3794  * In site archive.java2script.org, there are 6 sites:
3795  * 1. http://archive.java2script.org or http://a.java2script.org
3796  * 2. http://erchive.java2script.org or http://e.java2script.org
3797  * 3. http://irchive.java2script.org or http://i.java2script.org
3798  * 4. http://orchive.java2script.org or http://o.java2script.org
3799  * 5. http://urchive.java2script.org or http://u.java2script.org
3800  * 6. http://yrchive.java2script.org or http://y.java2script.org
3801  */
3802 /* protected */
3803         /*
3804 _Loader.multipleSites = function (path) {
3805         var deltas = window["j2s.update.delta"];
3806         if (deltas && deltas instanceof Array && deltas.length >= 3) {
3807                 var lastOldVersion = null;
3808                 var lastNewVersion = null;
3809                 for (var i = 0; i < deltas.length / 3; i++) {
3810                         var oldVersion = deltas[i + i + i];
3811                         if (oldVersion != "$") {
3812                                 lastOldVersion = oldVersion;
3813                         }
3814                         var newVersion = deltas[i + i + i + 1];
3815                         if (newVersion != "$") {
3816                                 lastNewVersion = newVersion;
3817                         }
3818                         var relativePath = deltas[i + i + i + 2];
3819                         var key = lastOldVersion + "/" + relativePath;
3820                         var idx = path.indexOf (key);
3821                         if (idx != -1 && idx == path.length - key.length) {
3822                                 path = path.substring (0, idx) + lastNewVersion + "/" + relativePath;
3823                                 break;
3824                         }
3825                 }
3826         }
3827         var length = path.length;
3828         if (maxLoadingThreads > 1 
3829                         && ((length > 15 && path.substring (0, 15) == "http://archive.")
3830                         || (length > 9 && path.substring (0, 9) == "http://a."))) {
3831                 var index = path.lastIndexOf("/");
3832                 if (index < length - 3) {
3833                         var arr = ['a', 'e', 'i', 'o', 'u', 'y'];
3834                         var c1 = path.charCodeAt (index + 1);
3835                         var c2 = path.charCodeAt (index + 2);
3836                         var idx = (length - index) * 3 + c1 * 5 + c2 * 7; // Hash
3837                         return path.substring (0, 7) + arr[idx % 6] + path.substring (8);
3838                 }
3839         }
3840         return path;
3841 };
3842         */
3843
3844 /**
3845  * Return the *.js path of the given class. Maybe the class is contained
3846  * in a *.z.js jar file.
3847  * @param clazz Given class that the path is to be calculated for. May
3848  * be java.package, or java.lang.String
3849  * @param forRoot Optional argument, if true, the return path will be root
3850  * of the given classs' package root path.
3851  * @param ext Optional argument, if given, it will replace the default ".js"
3852  * extension.
3853  */
3854 /* public */
3855 _Loader.getClasspathFor = function (clazz, forRoot, ext) {
3856         var path = classpathMap["#" + clazz];
3857         if (!path || forRoot || ext) {
3858                 var base;
3859                 var idx;
3860                 if (path) {
3861                         clazz = clazz.replace(/\./g, "/");      
3862                         if ((idx = path.lastIndexOf(clazz)) >= 0 
3863                                 || (idx = clazz.lastIndexOf("/")) >= 0 
3864                                         && (idx = path.lastIndexOf(clazz.substring(0, idx))) >= 0)
3865                                 base = path.substring(0, idx);
3866                 } else {
3867                         idx = clazz.length + 2;
3868                         while ((idx = clazz.lastIndexOf(".", idx - 2)) >= 0)
3869                                 if ((base = classpathMap["@" + clazz.substring(0, idx)]))
3870                                         break;
3871                         if (!forRoot)
3872                                 clazz = clazz.replace (/\./g, "/");     
3873                 }
3874                 if (base == null) {
3875                         var bins = "binaryFolders";
3876                         base = (window["Clazz"] && Clazz[bins] && Clazz[bins].length ? Clazz[bins][0] 
3877                                 : _Loader[bins] && _Loader[bins].length ? _Loader[bins][0]
3878                                 : "j2s");
3879                 }
3880                 path = (base.lastIndexOf("/") == base.length - 1 ? base : base + "/") + (forRoot ? ""
3881                         : clazz.lastIndexOf("/*") == clazz.length - 2 ? clazz.substring(0, idx + 1)
3882                         : clazz + (!ext ? ".js" : ext.charAt(0) != '.' ? "." + ext : ext));
3883         }               
3884         return path;//_Loader.multipleSites(path);
3885 };
3886
3887 /**
3888  * To ignore some classes.
3889  */
3890 /* public */
3891 _Loader.ignore = function () {
3892         var clazzes = (arguments.length == 1 && arguments[0] instanceof Array ?
3893                         clazzes = arguments[0] : null);
3894         var n = (clazzes ? clazzes.length : arguments.length);
3895         if (!clazzes) {
3896                 clazzes = new Array(n);
3897                 for (var i = 0; i < n; i++)
3898                         clazzes[i] = arguments[i];
3899         }
3900         unwrapArray(clazzes);
3901         for (var i = 0; i < n; i++)
3902                 excludeClassMap["@" + clazzes[i]] = 1;
3903 };
3904
3905 /**
3906  * The following *.script* can be overriden to indicate the 
3907  * status of classes loading.
3908  *
3909  * TODO: There should be a Java interface with name like INativeLoaderStatus
3910  */
3911 /* public */
3912 _Loader.onScriptLoading = function (file){};
3913
3914 /* public */
3915 _Loader.onScriptLoaded = function (file, isError){};
3916
3917 /* public */
3918 _Loader.onScriptInitialized = function (file){};
3919
3920 /* public */
3921 _Loader.onScriptCompleted = function (file){};
3922
3923 /* public */
3924 _Loader.onClassUnloaded = function (clazz){};
3925
3926 /**
3927  * After all the classes are loaded, this method will be called.
3928  * Should be overriden to run *.main([]).
3929  */
3930 /* public */
3931 _Loader.onGlobalLoaded = function () {};
3932
3933 /* public */
3934 _Loader.keepOnLoading = true; // never set false in this code
3935
3936
3937 /* private */
3938 var mapPath2ClassNode = {};
3939
3940 /* private */
3941 var isClassExcluded = function (clazz) {
3942         return excludeClassMap["@" + clazz];
3943 };
3944
3945 /* Used to keep ignored classes */
3946 /* private */
3947 var excludeClassMap = {};
3948
3949 /* private */
3950 var evaluate = function(file, js) {
3951                 try {
3952                         eval(js);
3953                 } catch (e) {      
3954       if (Clazz._isQuiet) 
3955         return;
3956                         var s = "[Java2Script] The required class file \n\n" + file + (js.indexOf("[Exception") == 0 && js.indexOf("data: no") ? 
3957          "\nwas not found.\n"
3958         : "\ncould not be loaded. Script error: " + e.message + " \n\ndata:\n\n" + js) + "\n\n" + Clazz.getStackTrace();
3959                 alert(s)
3960                         Clazz.alert(s);
3961                         throw e;
3962                 }
3963                 _Loader.onScriptLoaded(file, false);
3964                 tryToLoadNext(file);
3965 }
3966
3967 /* private */
3968 var failedHandles = {};
3969
3970 /* private */
3971 var generateRemovingFunction = function (node) {
3972         return function () {
3973                 if (node.readyState != "interactive") {
3974                         try {
3975                                 if (node.parentNode)
3976                                         node.parentNode.removeChild (node);
3977                         } catch (e) { }
3978                         node = null;
3979                 }
3980         };
3981 };
3982
3983 /* private */
3984 var removeScriptNode = function (n) {
3985         if (window["j2s.script.debugging"]) {
3986                 return;
3987         }
3988         // lazily remove script nodes.
3989         window.setTimeout (generateRemovingFunction (n), 1);
3990 };
3991
3992 /* public */
3993 Clazz._4Name = function(clazzName, applet, state) {
3994         if (Clazz.isClassDefined(clazzName))
3995                 return Clazz.evalType(clazzName);
3996         var f = (Jmol._isAsync && applet ? applet._restoreState(clazzName, state) : null);
3997         if (f == 1)
3998                 return null; // must be already being created
3999         if (_Loader.setLoadingMode(f ? _Loader.MODE_SCRIPT : "xhr.sync")) {
4000                 _Loader.loadClass(clazzName, f, false, true, 1);
4001                 return null; // this will surely throw an error, but that is OK
4002         }
4003         //alert ("Using Java reflection: " + clazzName + " for " + applet._id + " \n"+ Clazz.getStackTrace());
4004         _Loader.loadClass(clazzName);
4005         return Clazz.evalType(clazzName);
4006 };
4007
4008 /**
4009  * BH: possibly useful for debugging
4010  */ 
4011 Clazz.currentPath= "";
4012
4013 /**
4014  * Load *.js by adding script elements into head. Hook the onload event to
4015  * load the next class in dependency tree.
4016  */
4017 /* private */
4018 var loadScript = function (node, file, why, ignoreOnload, fSuccess, _loadScript) {
4019                 Clazz.currentPath = file;
4020         if (ignoreOnload)alert("WHY>>")
4021 //BH removed    // maybe some scripts are to be loaded without needs to know onload event.
4022 //      if (!ignoreOnload && loadedScripts[file]) {
4023 //              _Loader.tryToLoadNext(file);
4024 //              return;
4025 //      }
4026         loadedScripts[file] = true;
4027         // also remove from queue
4028         removeArrayItem(classQueue, file);
4029
4030     // forces not-found message
4031     isUsingXMLHttpRequest = true;
4032     isAsynchronousLoading = false;
4033   if (_Loader._checkLoad) {
4034     System.out.println("\t" + file + (why ? "\n -- required by " + why : "") + "  ajax=" + isUsingXMLHttpRequest + " async=" + isAsynchronousLoading)
4035   }
4036
4037         _Loader.onScriptLoading(file);
4038         if (isUsingXMLHttpRequest && !isAsynchronousLoading) {
4039                 // alert("\t" + file + (why ? "\n -- required by " + why : "") + "  ajax=" + isUsingXMLHttpRequest + " async=" + isAsynchronousLoading + " " + Clazz.getStackTrace())
4040                 // synchronous loading
4041                 // works in MSIE locally unless a binary file :)
4042                 // from Jmol.api.Interface only
4043                 var data = Jmol._getFileData(file);
4044     try{
4045                   evaluate(file, data);
4046     }catch(e) {
4047       alert(e + " loading file " + file + " " + node.name + " " + Clazz.getStackTrace());
4048     }
4049     if (fSuccess) {
4050 //      System.out.println("firing in loadScript " + file + " " + (fSuccess && fSuccess.toString()))
4051       fSuccess(); 
4052     }
4053                 return;
4054         }
4055   
4056   
4057 System.out.println("for file " + file +" fSuccess = " + (fSuccess ? fSuccess.toString() : ""))
4058         var info = {
4059                 dataType:"script",
4060                 async:true, 
4061                 type:"GET", 
4062                 url:file,
4063                 success:W3CScriptOnCallback(file, false, fSuccess),
4064                 error:W3CScriptOnCallback(file, true, fSuccess)
4065         };
4066         inLoadingThreads++;
4067         Jmol.$ajax(info);
4068 };
4069
4070 /* private */
4071 var W3CScriptOnCallback = function (path, forError, fSuccess) {
4072   var s = Clazz.getStackTrace();
4073   // if (!fSuccess)alert("why no fSuccess?" + s)
4074         return function () {
4075   //System.out.println("returning " + (fSuccess ? fSuccess.toString() : "no function ") + s) 
4076                 if (forError && __debuggingBH)Clazz.alert ("############ forError=" + forError + " path=" + path + " ####" + (forError ? "NOT" : "") + "LOADED###");
4077                 if (isGecko && this.timeoutHandle)
4078                         window.clearTimeout(this.timeoutHandle), this.timeoutHandle = null;
4079                 if (inLoadingThreads > 0)
4080                         inLoadingThreads--;
4081                 //System.out.println("w3ccalback for " + path + " " + inLoadingThreads + " threads")
4082                 this.onload = null;
4083                 this.onerror = null;
4084                 if (forError) 
4085                         alert ("There was a problem loading " + path);
4086                 _Loader.onScriptLoaded(path, true);
4087                 var node = this;                        
4088                 var f;
4089     if (fSuccess)
4090       f = function(_W3scriptFS){removeScriptNode(node);tryToLoadNext(path, fSuccess); };
4091     else
4092       f = function(_W3script){removeScriptNode(node);tryToLoadNext(path)};
4093                 if (loadingTimeLag >= 0)
4094                         window.setTimeout(function() { tryToLoadNext(path, f); }, loadingTimeLag);
4095                 else
4096                         tryToLoadNext(path, f);
4097         };
4098 };
4099
4100 /* private */
4101 var isLoadingEntryClass = true;
4102
4103 /* private */
4104 var besidesJavaPackage = false;
4105
4106 /**
4107  * After class is loaded, this method will be executed to check whether there
4108  * are classes in the dependency tree that need to be loaded.
4109  */
4110 /* private */
4111 var tryToLoadNext = function (file, fSuccess) {
4112         var node = mapPath2ClassNode["@" + file];
4113         if (!node) // maybe class tree root
4114                 return;
4115         var n;
4116   // check for content loaded
4117         var clazzes = classpathMap["$" + file];
4118         if (clazzes) {
4119                 for (var i = 0; i < clazzes.length; i++) {
4120                         var name = clazzes[i];
4121                         if (name != node.name && (n = findNode(name))) {
4122                                 if (n.status < Node.STATUS_CONTENT_LOADED) {
4123                                         n.status = Node.STATUS_CONTENT_LOADED;
4124                                         updateNode(n);
4125                                 }
4126                         } else {
4127                                 n = new Node();
4128                                 n.name = name;
4129                                 var pp = classpathMap["#" + name];
4130                                 if (!pp) {
4131                                         alert (name + " J2S error in tryToLoadNext");
4132                                         error("Java2Script implementation error! Please report this bug!");
4133                                 }
4134                                 n.path = pp;
4135                                 mappingPathNameNode (n.path, name, n);
4136                                 n.status = Node.STATUS_CONTENT_LOADED;
4137                                 addChildClassNode(clazzTreeRoot, n, false);
4138                                 updateNode(n);
4139                         }
4140                 }
4141         }
4142         if (node instanceof Array) {
4143                 for (var i = 0; i < node.length; i++) {
4144                         if (node[i].status < Node.STATUS_CONTENT_LOADED) {
4145                                 node[i].status = Node.STATUS_CONTENT_LOADED;
4146                                 updateNode(node[i]);
4147                         }
4148                 }
4149         } else if (node.status < Node.STATUS_CONTENT_LOADED) {
4150                 var stillLoading = false;
4151                 var ss = document.getElementsByTagName ("SCRIPT");
4152                 for (var i = 0; i < ss.length; i++) {
4153                         if (isIE) {
4154                                 if (ss[i].onreadystatechange && ss[i].onreadystatechange.path == node.path
4155                                                 && ss[i].readyState == "interactive") {
4156                                         stillLoading = true;
4157                                         break;
4158                                 }
4159                         } else if (ss[i].onload && ss[i].onload.path == node.path) {
4160                                 stillLoading = true;
4161                                 break;
4162                         }
4163                 }
4164                 if (!stillLoading) {
4165                         node.status = Node.STATUS_CONTENT_LOADED;
4166                         updateNode(node);
4167                 }
4168         }
4169         /*
4170          * Maybe in #optinalLoaded inside above _Loader#updateNode calls, 
4171          * _Loader.keepOnLoading is set false (Already loaded the wanted
4172          * classes), so here check to stop.
4173          */
4174          
4175         if (!_Loader.keepOnLoading) // set externally
4176                 return;
4177
4178  // check for a "must" class that has content and load it
4179         var cq;
4180         var working = true;
4181         if ((n = findNextMustClass(Node.STATUS_KNOWN))) {
4182                 loadClassNode(n);
4183                 while (inLoadingThreads < maxLoadingThreads) {
4184                         if (!(n = findNextMustClass(Node.STATUS_KNOWN)))
4185                                 break;
4186                         loadClassNode(n); // will increase inLoadingThreads!
4187                 }
4188         } else if ((cq = classQueue).length != 0) { 
4189                 /* queue must be loaded in order! */
4190                 n = cq.shift();
4191                 if (!loadedScripts[n.path] 
4192                                 || cq.length != 0 
4193                                 || !isLoadingEntryClass
4194                                 || n.musts.length
4195                                 || n.optionals.length) {
4196                         addChildClassNode(clazzTreeRoot, n, true);
4197                         loadScript(n, n.path, n.requiredBy, false);
4198                 } else if (isLoadingEntryClass) {
4199                         /*
4200                          * The first time reaching here is the time when ClassLoader
4201                          * is trying to load entry class. Class with #main method and
4202                          * is to be executed is called Entry Class.
4203                          *
4204                          * Here when loading entry class, ClassLoader should not call
4205                          * the next following loading script. This is because, those
4206                          * scripts will try to mark the class as loaded directly and
4207                          * then continue to call #onLoaded callback method,
4208                          * which results in an script error!
4209                          */
4210                         isLoadingEntryClass = false;
4211                 }
4212         } else if ((n = findNextRequiredClass(Node.STATUS_KNOWN))) {
4213                 loadClassNode(n);
4214                 while (inLoadingThreads < maxLoadingThreads) {
4215                         if (!(n = findNextRequiredClass(Node.STATUS_KNOWN)))
4216                                 break;
4217                         loadClassNode(n); // will increase inLoadingThreads!
4218                 }
4219         } else {
4220                 working = false;
4221         }
4222         if (working || inLoadingThreads > 0)
4223                 return;
4224   // 
4225   // now check all classes that MUST be loaded prior to initialization 
4226   // of some other class (static calls, extends, implements)
4227   // and all classes REQUIRED somewhere in that class, possibly by the constructor
4228   // (that is, "new xxxx()" called somewhere in code) and update them
4229   // that have content but are not declared already 
4230         var f = [findNextMustClass,findNextRequiredClass];
4231         var lastNode = null;
4232         for (var i = 0; i < 2; i++)
4233                 while ((n = f[i](Node.STATUS_CONTENT_LOADED))) {
4234                         if (i == 1 && lastNode === n) // Already existed cycle ?
4235                                 n.status = Node.STATUS_LOAD_COMPLETE;
4236                         updateNode(n);
4237                         lastNode = n;
4238                 }
4239     
4240   // check for load cycles
4241   
4242         while (true) {
4243                 tracks = [];
4244                 if (!checkCycle(clazzTreeRoot, file))
4245                         break;
4246         }
4247   
4248   // and update all MUST and REQUIRED classes that are declared already 
4249   
4250         for (var i = 0; i < 2; i++) {
4251                 lastNode = null;
4252                 while ((n = f[i](Node.STATUS_DECLARED))) {
4253                         if (lastNode === n) 
4254                                 break;
4255                         updateNode(lastNode = n);
4256                 }
4257         }
4258         var done = [];
4259         for (var i = 0; i < 2; i++) 
4260                 while ((n = f[i](Node.STATUS_DECLARED)))
4261                         done.push(n), n.status = Node.STATUS_LOAD_COMPLETE;
4262         if (done.length) {
4263                 for (var i = 0; i < done.length; i++)
4264                         destroyClassNode(done[i]);
4265                 for (var i = 0; i < done.length; i++)
4266                         if ((f = done[i].onLoaded))
4267                                 done[i].onLoaded = null, f();
4268         }
4269   
4270   
4271   
4272   
4273   
4274   
4275   
4276         //System.out.println(node.name + " loaded completely" + _Loader.onGlobalLoaded + "\n\n")
4277   if (fSuccess) {
4278     //System.out.println("tryToLoadNext firing " + _Loader._classCountOK + "/" + _Loader._classCountPending + " "   + fSuccess.toString() + " " + Clazz.getStackTrace())
4279           fSuccess();
4280   } else if (_Loader._classCountPending) {
4281     for (var name in _Loader._classPending) {
4282       var n = findNode(name);
4283       System.out.println("class left pending " + name + " " + n);
4284       if (n) {
4285         updateNode(n);
4286         break;
4287       }
4288     }
4289   } else {
4290     
4291  // System.out.println("I think I'm done " 
4292   // + _Loader._classCountOK + "/" + _Loader._classCountPending + " " 
4293    //+ _Loader.onGlobalLoaded.toString() + " " + Clazz.getStackTrace()
4294  //  )
4295     if (_Loader._checkLoad) {
4296       System.out.println("I think I'm done: SAEM call count: " + SAEMid);
4297       Clazz.showDuplicates(true);
4298     }
4299   }
4300         _Loader.onGlobalLoaded();
4301 };
4302
4303
4304 var tracks = [];
4305
4306 /*
4307  * There are classes reference cycles. Try to detect and break those cycles.
4308  */
4309 /* private */
4310 var checkCycle = function (node, file) {
4311         var ts = tracks;
4312         var len = ts.length;
4313   // add this node to tracks
4314         ts.push(node);
4315         var i = len;
4316         for (; --i >= 0;)
4317                 if (ts[i] === node && ts[i].status >= Node.STATUS_DECLARED) 
4318                         break;
4319         if (i >= 0) {
4320     // this node is already in tracks, and it has been declared already
4321     // for each node in tracks, set its status to "LOAD_COMPLETE"
4322     // update all parents, remove all parents, and fire its onLoaded function
4323     // then clear tracks and return true (keep checking)  
4324     if (_Loader._checkLoad) {
4325       var msg = "cycle found loading " + file + " for " + node;
4326       System.out.println(msg)
4327     } 
4328                 for (; i < len; i++) {
4329       var n = ts[i];
4330                         n.status = Node.STATUS_LOAD_COMPLETE;
4331                         destroyClassNode(n); // Same as above
4332                         for (var k = 0; k < n.parents.length; k++)
4333                                 updateNode(n.parents[k]);
4334                         n.parents = [];
4335       var f = n.onLoaded;
4336       if (_Loader._checkLoad) {
4337         var msg = "cycle setting status to LOAD_COMPLETE for " + n.name + (f ? " firing " + f.toString() : "");
4338         System.out.println(msg)
4339       } 
4340                         if (f)
4341                                 n.onLoaded = null, f();
4342                 }
4343                 ts.length = 0;
4344                 return true;
4345         }
4346         var a = [node.musts, node.optionals];
4347         for (var j = 0; j < 2; j++)
4348                 for (var r = a[j], i = r.length; --i >= 0;)
4349                         if (r[i].status == Node.STATUS_DECLARED && checkCycle(r[i], file)) 
4350                                 return true;
4351   // reset _tracks to its original length      
4352         ts.length = len;
4353         return false; // done 
4354 };
4355
4356
4357 _Loader._classCountPending = 0;
4358 _Loader._classCountOK = 0;
4359 _Loader._classPending = {};
4360
4361 _Loader.showPending = function() {
4362   var a = [];
4363   for (var name in _Loader._classPending) {
4364     var n = findNode(name);
4365     if (!n) {
4366       alert("No node for " + name);
4367       continue;
4368     }
4369     a.push(n);
4370     System.out.println(showNode("", "", n, "", 0));     
4371   }  
4372   return a;
4373 }
4374
4375 var showNode = function(s, names, node, inset, level) {
4376   names += "--" + node.name;
4377   s += names + "\n";
4378   if (level > 5) {
4379     s += inset + " ...\n";
4380     return s;
4381   }
4382   inset += "\t";
4383   s += inset + "status: " + node.status + "\n";
4384   if (node.parents && node.parents.length && node.parents[0] && node.parents[0].name) {
4385     s += inset + "parents: " + node.parents.length + "\n";
4386     for (var i = 0; i < node.parents.length; i++) {
4387       s = showNode(s, names, node.parents[i], inset + "\t", level+1);
4388     }
4389     s += "\n";
4390   }
4391 //  if (node.requiredBy) {
4392 //    s += inset + "requiredBy:\n";
4393 //    s = showNode(s, names, node.requiredBy, inset + "\t", level+1);
4394 //    s += "\n";
4395 //  }
4396   return s;    
4397 }     
4398
4399 /**
4400  * Update the dependency tree nodes recursively.
4401  */
4402 /* private */
4403 updateNode = function(node, _updateNode) {
4404         if (!node.name || node.status >= Node.STATUS_LOAD_COMPLETE) {
4405                 destroyClassNode(node);
4406                 return;
4407         }
4408         var ready = true;
4409   // check for declared and also having MUSTS
4410         if (node.musts.length && node.declaration) {
4411                 for (var mustLength = node.musts.length, i = mustLength; --i >= 0;) {
4412                         var n = node.musts[i];
4413                         n.requiredBy = node;
4414                         if (n.status < Node.STATUS_DECLARED && isClassDefined (n.name)) {
4415                                 var nns = []; // a stack for onLoaded events
4416                                 n.status = Node.STATUS_LOAD_COMPLETE;
4417                                 destroyClassNode(n); // Same as above
4418                                 if (n.declaration       && n.declaration.clazzList) {
4419                                         // For those classes within one *.js file, update them synchronously.
4420                                         for (var j = 0, list = n.declaration.clazzList, l = list.length; j < l; j++) {
4421                                                 var nn = findNode (list[j]);
4422                                                 if (nn && nn.status != Node.STATUS_LOAD_COMPLETE
4423                                                                 && nn !== n) {
4424                                                         nn.status = n.status;
4425                                                         nn.declaration = null;
4426                                                         destroyClassNode(nn);
4427                                                         nn.onLoaded && nns.push(nn);
4428                                                 }
4429                                         }
4430                                         n.declaration = null;
4431                                 }
4432         // fire all onLoaded events
4433                                 if (n.onLoaded)
4434                                         nns.push(n);
4435                                 for (var j = 0; j < nns.length; j++) {
4436                                         var onLoaded = nns[j].onLoaded;
4437                                         if (onLoaded) {
4438                                                 nns[j].onLoaded = null;
4439                                                 onLoaded();
4440                                         }
4441                                 }
4442                         } else {
4443                                 (n.status == Node.STATUS_CONTENT_LOADED) && updateNode(n); // musts may be changed
4444                                 if (n.status < Node.STATUS_DECLARED)
4445                                         ready = false;
4446                         }
4447                         if (node.musts.length != mustLength) {
4448                                 // length changed -- restart!
4449                                 i = mustLength = node.musts.length;
4450                                 ready = true;
4451                         }
4452                 }
4453         }
4454         if (!ready)
4455                 return;
4456         if (node.status < Node.STATUS_DECLARED) {
4457                 var decl = node.declaration;
4458                 if (decl)
4459                         decl(), decl.executed = true;
4460     if(_Loader._checkLoad) {
4461             if (_Loader._classPending[node.name]) {
4462               delete _Loader._classPending[node.name];
4463               _Loader._classCountOK;
4464               _Loader._classCountPending--;
4465 //              System.out.println("OK " + (_Loader._classCountOK) + " FOR " + node.name)
4466             }
4467     }
4468                 node.status = Node.STATUS_DECLARED;
4469                 if (definedClasses)
4470                         definedClasses[node.name] = true;
4471                 _Loader.onScriptInitialized(node.path);
4472                 if (node.declaration && node.declaration.clazzList) {
4473                         // For those classes within one *.js file, update them synchronously.
4474                         for (var j = 0, list = node.declaration.clazzList, l = list.length; j < l; j++) {
4475                                 var nn = findNode(list[j]);
4476                                 if (nn && nn.status != Node.STATUS_DECLARED
4477                                                 && nn !== node) {
4478                                         nn.status = Node.STATUS_DECLARED;
4479                                         if (definedClasses)
4480                                                 definedClasses[nn.name] = true;
4481                                         _Loader.onScriptInitialized(nn.path);
4482                                 }
4483                         }
4484                 }
4485         }
4486         var level = Node.STATUS_DECLARED;
4487         if (node.optionals.length == 0 && node.musts.length == 0
4488                         || node.status > Node.STATUS_KNOWN && !node.declaration
4489                         || checkStatusIs(node.musts, Node.STATUS_LOAD_COMPLETE)
4490                                         && checkStatusIs(node.optionals, Node.STATUS_LOAD_COMPLETE)) { 
4491                 level = Node.STATUS_LOAD_COMPLETE;
4492                 if (!doneLoading(node, level))
4493                         return false;
4494                         // For those classes within one *.js file, update them synchronously.
4495                 if (node.declaration && node.declaration.clazzList) {
4496                         for (var j = 0, list = node.declaration.clazzList, l = list.length; j < l; j++) {
4497                                 var nn = findNode(list[j]);
4498                                 if (nn && nn.status != level && nn !== node) {
4499                                         nn.declaration = null;
4500                                         if (!doneLoading(nn, level))
4501                                                 return false;
4502                                 }
4503                         }
4504                 }
4505         }
4506   // _Loader.updateParents = function (node, level, _updateParents)
4507         if (node.parents && node.parents.length) {
4508         for (var i = 0; i < node.parents.length; i++) {
4509                 var p = node.parents[i];
4510                 if (p.status < level) 
4511                         updateNode(p, p.name);
4512         }
4513         if (level == Node.STATUS_LOAD_COMPLETE)
4514                 node.parents = [];
4515   }
4516 };
4517
4518 /* private */
4519 var checkStatusIs = function(arr, status){
4520         for (var i = arr.length; --i >= 0;)
4521                 if (arr[i].status < status)
4522                         return false;
4523         return true;
4524 }
4525 /* private */
4526 var doneLoading = function(node, level, _doneLoading) {
4527         node.status = level;
4528         _Loader.onScriptCompleted(node.path);
4529   
4530         var onLoaded = node.onLoaded;
4531         if (onLoaded) {
4532                 node.onLoaded = null;
4533                 onLoaded();
4534                 if (!_Loader.keepOnLoading)
4535                         return false;
4536         }
4537   
4538         destroyClassNode(node);
4539         return true;
4540 }
4541
4542 /*
4543  * Be used to record already used random numbers. And next new random
4544  * number should not be in the property set.
4545  */
4546 /* private */
4547 var usedRandoms = {
4548   "r0.13412" : 1
4549 };
4550
4551 /* private */
4552 var getRnd = function() {
4553         while (true) { // get a unique random number
4554                 var rnd = Math.random();
4555                 var s = "r" + rnd;
4556                 if (!usedRandoms[s])
4557                         return (usedRandoms[s] = 1, clazzTreeRoot.random = rnd);
4558         }
4559 }
4560
4561 /* protected */
4562 var findNode = function(clazzName) {
4563         getRnd();
4564         return findNodeUnderNode(clazzName, clazzTreeRoot);
4565 };
4566
4567 /* private */
4568 var findNextRequiredClass = function(status) {
4569         getRnd();
4570         return findNextRequiredNode(clazzTreeRoot, status);
4571 };
4572
4573 /* private */
4574 var findNextMustClass = function(status) {
4575         return findNextMustNode(clazzTreeRoot, status);
4576 };
4577
4578 /* private */
4579 var findNodeUnderNode = function(clazzName, node) {
4580         var n;
4581         // node, then musts then optionals
4582         return (node.name == clazzName ? node 
4583                 : (n = findNodeWithin(clazzName, node.musts))
4584                 || (n = findNodeWithin(clazzName, node.optionals)) 
4585                 ? n : null);
4586 };
4587
4588 /* private */
4589 var findNodeWithin = function(name, arr) {
4590         var rnd = clazzTreeRoot.random;
4591         for (var i = arr.length; --i >= 0;) {
4592                 var n = arr[i];
4593                 if (n.name == name)
4594                         return n;
4595                 if (n.random != rnd) {
4596                         n.random = rnd;
4597                         if ((n = findNodeUnderNode(name, n)))
4598                                 return n;
4599                 }
4600         }
4601         return null;
4602 }
4603
4604 /* private */
4605 var checkStatus = function(n, status) {
4606         return (n.status == status 
4607                         && (status != Node.STATUS_KNOWN || !loadedScripts[n.path])
4608                         && (status == Node.STATUS_DECLARED      || !isClassDefined (n.name)));
4609 }
4610
4611 /* private */
4612 var findNextMustNode = function(node, status) {
4613         for (var i = node.musts.length; --i >= 0;) {
4614                 var n = node.musts[i];
4615                 if (checkStatus(n, status) || (n = findNextMustNode(n, status)))
4616                         return n;       
4617         }
4618         return (checkStatus(node, status) ? node : null); 
4619 };
4620
4621 /* private */
4622 var findNextRequiredNode = function (node, status) {
4623         // search musts first
4624         // search optionals second
4625         // search itself last
4626         var n;
4627         return ((n = searchClassArray(node.musts, status))
4628                 || (n = searchClassArray(node.optionals, status))
4629                 || checkStatus(n = node, status) ? n : null);
4630 };
4631
4632 /* private */
4633 var searchClassArray = function (arr, status) {
4634         if (arr) {
4635                 var rnd = clazzTreeRoot.random;
4636                 for (var i = 0; i < arr.length; i++) {
4637                         var n = arr[i];
4638                         if (checkStatus(n, status))
4639                                 return n;
4640                         if (n.random != rnd) {
4641                                 n.random = rnd; // mark as visited!
4642                                 if ((n = findNextRequiredNode(n, status)))
4643                                         return n;
4644                         }
4645                 }
4646         }
4647         return null;
4648 };
4649
4650 /**
4651  * This map variable is used to mark that *.js is correctly loaded.
4652  * In IE, _Loader has defects to detect whether a *.js is correctly
4653  * loaded or not, so inner loading mark is used for detecting.
4654  */
4655 /* private */
4656 var innerLoadedScripts = {};
4657
4658 /**
4659  * This method will be called in almost every *.js generated by Java2Script
4660  * compiler.
4661  */
4662 /* public */
4663 var load = function (musts, name, optionals, declaration) {
4664   // called as name.load in Jmol
4665         if (name instanceof Array) {
4666                 unwrapArray(name);
4667                 for (var i = 0; i < name.length; i++)
4668                         load(musts, name[i], optionals, declaration, name);
4669                 return;
4670         }       
4671
4672   if (_Loader._checkLoad) {
4673     if (_Loader._classPending[name]) {
4674       //alert("duplicate load for " + name)
4675     } else {
4676       _Loader._classPending[name] = 1;
4677       if (_Loader._classCountPending++ == 0)
4678         _Loader._classCountOK = 0;
4679       System.out.println("Loading class " + name);
4680     }
4681   }
4682
4683 //      if (clazz.charAt (0) == '$')
4684 //              clazz = "org.eclipse.s" + clazz.substring (1);
4685         var node = mapPath2ClassNode["#" + name];
4686         if (!node) { // load called inside *.z.js?
4687                 var n = findNode(name);
4688                 node = (n ? n : new Node());
4689                 node.name = name;
4690                 node.path = classpathMap["#" + name] || "unknown";
4691                 mappingPathNameNode(node.path, name, node);
4692                 node.status = Node.STATUS_KNOWN;
4693                 addChildClassNode(clazzTreeRoot, node, false);
4694         }
4695         processRequired(node, musts, true);
4696         if (arguments.length == 5 && declaration) {
4697                 declaration.status = node.status;
4698                 declaration.clazzList = arguments[4];
4699         }
4700         node.declaration = declaration;
4701         if (declaration) 
4702                 node.status = Node.STATUS_CONTENT_LOADED;
4703         processRequired(node, optionals, false);
4704 };
4705
4706 /* private */
4707 var processRequired = function(node, arr, isMust) {
4708         if (arr && arr.length) {
4709                 unwrapArray(arr);
4710                 for (var i = 0; i < arr.length; i++) {
4711                         var name = arr[i];
4712                         if (!name)
4713                                 continue;
4714                         if (isClassDefined(name)
4715                                         || isClassExcluded(name))
4716                                 continue;
4717                         var n = findNode(name);
4718                         if (!n) {
4719                                 n = new Node();
4720                                 n.name = name;
4721                                 n.status = Node.STATUS_KNOWN;
4722                         }
4723                         n.requiredBy = node;
4724                         addChildClassNode(node, n, isMust);
4725                 }
4726         }
4727 }
4728
4729 /*
4730  * Try to be compatiable of Clazz
4731  */
4732 if (window["Clazz"]) {
4733         Clazz.load = load;
4734 } else {
4735   _Loader.load = load;
4736 }  
4737 /**
4738  * Map different class to the same path! Many classes may be packed into
4739  * a *.z.js already.
4740  *
4741  * @path *.js path
4742  * @name class name
4743  * @node Node object
4744  */
4745 /* private */
4746 var mappingPathNameNode = function (path, name, node) {
4747         var map = mapPath2ClassNode;
4748         var keyPath = "@" + path;
4749         var v = map[keyPath];
4750         if (v) {
4751                 if (v instanceof Array) {
4752                         var existed = false;
4753                         for (var i = 0; i < v.length; i++) {
4754                                 if (v[i].name == name) {
4755                                         existed = true;
4756                                         break;
4757                                 }
4758                         }
4759                         if (!existed)
4760                                 v.push(node);
4761                 } else {
4762                         map[keyPath] = [v, node];
4763                 }
4764         } else {
4765                 map[keyPath] = node;
4766         }
4767         map["#" + name] = node;
4768 };
4769
4770 /* protected */
4771 var loadClassNode = function (node) {
4772         var name = node.name;
4773         if (!isClassDefined (name) 
4774                         && !isClassExcluded (name)) {
4775                 var path = _Loader.getClasspathFor (name/*, true*/);
4776                 node.path = path;
4777                 mappingPathNameNode (path, name, node);
4778                 if (!loadedScripts[path]) {
4779                         loadScript(node, path, node.requiredBy, false);
4780                         return true;
4781                 }
4782         }
4783         return false;
4784 };
4785
4786
4787 /**
4788  * Used in package
4789 /* public */
4790 var runtimeKeyClass = _Loader.runtimeKeyClass = "java.lang.String";
4791
4792 /**
4793  * Queue used to store classes before key class is loaded.
4794  */
4795 /* private */
4796 var queueBe4KeyClazz = [];
4797
4798 /* private */
4799 var J2sLibBase;
4800
4801 /**
4802  * Return J2SLib base path from existed SCRIPT src attribute.
4803  */
4804 /* public */
4805 _Loader.getJ2SLibBase = function () {
4806         var o = window["j2s.lib"];
4807         return (o ? o.base + (o.alias == "." ? "" : (o.alias ? o.alias : (o.version ? o.version : "1.0.0")) + "/") : null);
4808 };
4809
4810 /**
4811  * Indicate whether _Loader is loading script synchronously or 
4812  * asynchronously.
4813  */
4814 /* private */
4815 var isAsynchronousLoading = true;
4816
4817 /* private */
4818 var isUsingXMLHttpRequest = false;
4819
4820 /* private */
4821 var loadingTimeLag = -1;
4822
4823 _Loader.MODE_SCRIPT = 4;
4824 _Loader.MODE_XHR = 2;
4825 _Loader.MODE_SYNC = 1;
4826
4827 /**
4828  * String mode:
4829  * asynchronous modes:
4830  * async(...).script, async(...).xhr, async(...).xmlhttprequest,
4831  * script.async(...), xhr.async(...), xmlhttprequest.async(...),
4832  * script
4833  * 
4834  * synchronous modes:
4835  * sync(...).xhr, sync(...).xmlhttprequest,
4836  * xhr.sync(...), xmlhttprequest.sync(...),
4837  * xmlhttprequest, xhr
4838  *                                                    
4839  * Integer mode:
4840  * Script 4; XHR 2; SYNC bit 1; 
4841  */
4842 /* public */
4843 _Loader.setLoadingMode = function (mode, timeLag) {
4844         var async = true;
4845         var ajax = true;
4846         if (typeof mode == "string") {
4847                 mode = mode.toLowerCase();
4848                 if (mode.indexOf("script") >= 0)
4849                         ajax = false;
4850                 else
4851                         async = (mode.indexOf("async") >=0);
4852                 async = false; // BH
4853         } else {
4854                 if (mode & _Loader.MODE_SCRIPT)
4855                         ajax = false;
4856                 else
4857                         async = !(mode & _Loader.MODE_SYNC);
4858         }
4859         isUsingXMLHttpRequest = ajax;
4860         isAsynchronousLoading = async;
4861         loadingTimeLag = (async && timeLag >= 0 ? timeLag: -1);
4862         return async;
4863 };
4864
4865 /* private */
4866 var runtimeLoaded = function () {
4867         if (pkgRefCount || !isClassDefined(runtimeKeyClass))
4868                 return;
4869         var qbs = queueBe4KeyClazz;
4870         for (var i = 0; i < qbs.length; i++)
4871                 _Loader.loadClass(qbs[i][0], qbs[i][1]);
4872         queueBe4KeyClazz = [];
4873 };
4874
4875 /*
4876  * Load those key *.z.js. This *.z.js will be surely loaded before other 
4877  * queued *.js.
4878  */
4879 /* public */
4880 _Loader.loadZJar = function (zjarPath, keyClass) {
4881 // used only by package.js for core.z.js
4882         var f = null;
4883         var isArr = (keyClass instanceof Array);
4884         if (isArr)
4885                 keyClass = keyClass[keyClass.length - 1];
4886         else
4887                 f = (keyClass == runtimeKeyClass ? runtimeLoaded : null);                       
4888         _Loader.jarClasspath(zjarPath, isArr ? keyClass : [keyClass]);
4889         // BH note: runtimeKeyClass is java.lang.String 
4890         _Loader.loadClass(keyClass, f, true);
4891 };
4892
4893 var NodeMap = {};
4894 var _allNodes = [];
4895
4896 /**
4897  * The method help constructing the multiple-binary class dependency tree.
4898  */
4899 /* private */
4900 var addChildClassNode = function (parent, child, isMust) {
4901         var existed = false;
4902         var arr;
4903         if (isMust) {
4904                 arr = parent.musts;
4905                 if (!child.requiredBy)
4906                         child.requiredBy = parent;
4907 //              if (!parent.requiresMap){
4908 //                      parent.requires = [];
4909 //                      parent.requiresMap = {};
4910 //              }
4911 //              if (!parent.requiresMap[child.name]) {
4912 //                      parent.requiresMap[child.name] = 1;
4913 //                      parent.requires.push[child];
4914 //              }
4915         } else {
4916                 arr = parent.optionals;
4917         }
4918         if (!NodeMap[child.name]) {
4919                 _allNodes.push(child)
4920                 NodeMap[child.name]=child
4921         }
4922         for (var i = 0; i < arr.length; i++) {
4923                 if (arr[i].name == child.name) {
4924                         existed = true;
4925                         break;
4926                 }
4927         }
4928         if (!existed) {
4929                 arr.push(child);
4930                 if (isLoadingEntryClass 
4931                                 && child.name.indexOf("java") != 0 
4932                                 && child.name.indexOf("net.sf.j2s.ajax") != 0) {
4933                         if (besidesJavaPackage)
4934                                 isLoadingEntryClass = false;
4935                         besidesJavaPackage = true;
4936 //              } else if (child.name.indexOf("org.eclipse.swt") == 0 
4937 //                              || child.name.indexOf("$wt") == 0) {
4938 //                      window["swt.lazy.loading.callback"] = swtLazyLoading;
4939 //                      if (needPackage("org.eclipse.swt"))
4940 //                              return _Loader.loadPackage("org.eclipse.swt", function() {addParentClassNode(child, parent)});
4941                 }
4942         }
4943         addParentClassNode(child, parent);
4944 };
4945
4946 /* private */
4947 var addParentClassNode = function(child, parent) {
4948         if (parent.name && parent != clazzTreeRoot && parent != child)
4949                 for (var i = 0; i < child.parents.length; i++)
4950                         if (child.parents[i].name == parent.name)
4951                                 return;
4952         child.parents.push(parent);
4953 }
4954
4955 /* private */
4956 var destroyClassNode = function (node) {
4957         var parents = node.parents;
4958         if (parents)
4959                 for (var k = parents.length; --k >= 0;)
4960                         removeArrayItem(parents[k].musts, node) || removeArrayItem(parents[k].optionals, node);
4961 };
4962
4963 /* public */
4964 _Loader.unloadClassExt = function (qClazzName) {
4965         if (definedClasses)
4966                 definedClasses[qClazzName] = false;
4967         if (classpathMap["#" + qClazzName]) {
4968                 var pp = classpathMap["#" + qClazzName];
4969                 classpathMap["#" + qClazzName] = null;
4970                 var arr = classpathMap["$" + pp];
4971                 removeArrayItem(arr, qClazzName) && (classpathMap["$" + pp] = arr);
4972         }
4973         var n = findNode(qClazzName);
4974         if (n) {
4975                 n.status = Node.STATUS_KNOWN;
4976                 loadedScripts[n.path] = false;
4977         }
4978         var path = _Loader.getClasspathFor (qClazzName);
4979         loadedScripts[path] = false;
4980         innerLoadedScripts[path] && (innerLoadedScripts[path] = false);
4981         _Loader.onClassUnloaded(qClazzName);
4982 };
4983
4984 /* private */
4985 var assureInnerClass = function (clzz, fun) {
4986         clzz = clzz.__CLASS_NAME__;
4987         if (Clazz.unloadedClasses[clzz]) {
4988                 if (clzz.indexOf("$") >= 0)
4989                         return;
4990                 var list = [];
4991                 var key = clzz + "$";
4992                 for (var s in Clazz.unloadedClasses)
4993                         if (Clazz.unloadedClasses[s] && s.indexOf(key) == 0)
4994                                 list.push(s);
4995                 if (!list.length) 
4996                         return;
4997                 fun = "" + fun;
4998                 var idx1, idx2;
4999                 if ((idx1 = fun.indexOf(key)) < 0 || (idx2 = fun.indexOf("\"", idx1 + key.length)) < 0) 
5000                         return;
5001                 clzz = fun.substring(idx1, idx2);
5002                 if (!Clazz.unloadedClasses[clzz] || (idx1 = fun.indexOf("{", idx2) + 1) == 0)
5003                         return;
5004                 if ((idx2 = fun.indexOf("(" + clzz + ",", idx1 + 3)) < 0
5005                         || (idx2 = fun.lastIndexOf("}", idx2 - 1)) < 0)
5006                                 return;
5007                 eval(fun.substring(idx1, idx2));
5008                 Clazz.unloadedClasses[clzz] = null;
5009         }
5010 };
5011
5012 Clazz.binaryFolders =  _Loader.binaryFolders = [ _Loader.getJ2SLibBase() ];
5013
5014 })(Clazz, Clazz._Loader);
5015
5016 //}
5017 /******************************************************************************
5018  * Copyright (c) 2007 java2script.org and others.
5019  * All rights reserved. This program and the accompanying materials
5020  * are made available under the terms of the Eclipse Public License v1.0
5021  * which accompanies this distribution, and is available at
5022  * http://www.eclipse.org/legal/epl-v10.html
5023  *
5024  * Contributors:
5025  *     Zhou Renjian - initial API and implementation
5026  *****************************************************************************/
5027 /*******
5028  * @author zhou renjian
5029  * @create Jan 11, 2007
5030  *******/
5031
5032 Clazz._LoaderProgressMonitor = {};
5033
5034 ;(function(CLPM, Jmol) {
5035
5036 var fadeOutTimer = null;
5037 var fadeAlpha = 0;
5038 var monitorEl = null;
5039 var lastScrollTop = 0;
5040 var bindingParent = null;
5041
5042 CLPM.DEFAULT_OPACITY = (Jmol && Jmol._j2sLoadMonitorOpacity ? Jmol._j2sLoadMonitorOpacity : 55);
5043
5044 /* public */
5045 /*CLPM.initialize = function (parent) {
5046         bindingParent = parent;
5047         if (parent && !attached) {
5048                 attached = true;
5049                 //Clazz.addEvent (window, "unload", cleanup);
5050                 // window.attachEvent ("onunload", cleanup);
5051         }
5052 };
5053 */
5054
5055 /* public */
5056 CLPM.hideMonitor = function () {
5057         monitorEl.style.display = "none";
5058 }
5059
5060 /* public */
5061 CLPM.showStatus = function (msg, fading) {
5062         if (!monitorEl) {
5063                 createHandle ();
5064                 if (!attached) {
5065                         attached = true;
5066                         //Clazz.addEvent (window, "unload", cleanup);
5067                         // window.attachEvent ("onunload", cleanup);
5068                 }
5069         }
5070         clearChildren(monitorEl);
5071   if (msg == null) {
5072     if (fading) {
5073       fadeOut();
5074     } else {
5075         CLPM.hideMonitor();
5076     }
5077     return;
5078   }
5079   
5080         monitorEl.appendChild(document.createTextNode ("" + msg));
5081         if (monitorEl.style.display == "none") {
5082                 monitorEl.style.display = "";
5083         }
5084         setAlpha(CLPM.DEFAULT_OPACITY);
5085         var offTop = getFixedOffsetTop();
5086         if (lastScrollTop != offTop) {
5087                 lastScrollTop = offTop;
5088                 monitorEl.style.bottom = (lastScrollTop + 4) + "px";
5089         }
5090         if (fading) {
5091                 fadeOut();
5092         }
5093 };
5094
5095 /* private static */ 
5096 var clearChildren = function (el) {
5097         if (!el)
5098                 return;
5099         for (var i = el.childNodes.length; --i >= 0;) {
5100                 var child = el.childNodes[i];
5101                 if (!child)
5102                         continue;
5103                 if (child.childNodes && child.childNodes.length)
5104                         clearChildren (child);
5105                 try {
5106                         el.removeChild (child);
5107                 } catch (e) {};
5108         }
5109 };
5110 /* private */ 
5111 var setAlpha = function (alpha) {
5112         if (fadeOutTimer && alpha == CLPM.DEFAULT_OPACITY) {
5113                 window.clearTimeout (fadeOutTimer);
5114                 fadeOutTimer = null;
5115         }
5116         fadeAlpha = alpha;
5117         var ua = navigator.userAgent.toLowerCase();
5118         monitorEl.style.filter = "Alpha(Opacity=" + alpha + ")";
5119         monitorEl.style.opacity = alpha / 100.0;
5120 };
5121 /* private */ 
5122 var hidingOnMouseOver = function () {
5123   CLPM.hideMonitor();
5124 };
5125
5126 /* private */ 
5127 var attached = false;
5128 /* private */ 
5129 var cleanup = function () {
5130         //if (monitorEl) {
5131         //      monitorEl.onmouseover = null;
5132         //}
5133         monitorEl = null;
5134         bindingParent = null;
5135         //Clazz.removeEvent (window, "unload", cleanup);
5136         //window.detachEvent ("onunload", cleanup);
5137         attached = false;
5138 };
5139 /* private */ 
5140 var createHandle = function () {
5141         var div = document.createElement ("DIV");
5142         div.id = "_Loader-status";
5143         div.style.cssText = "position:absolute;bottom:4px;left:4px;padding:2px 8px;"
5144                         + "z-index:" + (window["j2s.lib"].monitorZIndex || 10000) + ";background-color:#8e0000;color:yellow;" 
5145                         + "font-family:Arial, sans-serif;font-size:10pt;white-space:nowrap;";
5146         div.onmouseover = hidingOnMouseOver;
5147         monitorEl = div;
5148         if (bindingParent) {
5149                 bindingParent.appendChild(div);
5150         } else {
5151                 document.body.appendChild(div);
5152         }
5153         return div;
5154 };
5155 /* private */ 
5156
5157 var fadeOut = function () {
5158         if (monitorEl.style.display == "none") return;
5159         if (fadeAlpha == CLPM.DEFAULT_OPACITY) {
5160                 fadeOutTimer = window.setTimeout(function () {
5161                                         fadeOut();
5162                                 }, 750);
5163                 fadeAlpha -= 5;
5164         } else if (fadeAlpha - 10 >= 0) {
5165                 setAlpha(fadeAlpha - 10);
5166                 fadeOutTimer = window.setTimeout(function () {
5167                                         fadeOut();
5168                                 }, 40);
5169         } else {
5170                 monitorEl.style.display = "none";
5171         }
5172 };
5173 /* private */
5174 var getFixedOffsetTop = function (){
5175         if (bindingParent) {
5176                 var b = bindingParent;
5177                 return b.scrollTop;
5178         }
5179         var dua = navigator.userAgent;
5180         var b = document.body;
5181         var p = b.parentNode;
5182         var pcHeight = p.clientHeight;
5183         var bcScrollTop = b.scrollTop + b.offsetTop;
5184         var pcScrollTop = p.scrollTop + p.offsetTop;
5185         return (dua.indexOf("Opera") < 0 && document.all ? (pcHeight == 0 ? bcScrollTop : pcScrollTop)
5186                 : dua.indexOf("Gecko") < 0 ? (pcHeight == p.offsetHeight 
5187                                 && pcHeight == p.scrollHeight ? bcScrollTop : pcScrollTop) : bcScrollTop);
5188 };
5189
5190 /* not used in Jmol
5191 if (window["ClazzLoader"]) {
5192         _Loader.onScriptLoading = function(file) {
5193                 CLPM.showStatus("Loading " + file + "...");
5194         };
5195         _Loader.onScriptLoaded = function(file, isError) {
5196                 CLPM.showStatus(file + (isError ? " loading failed." : " loaded."), true);
5197         };
5198         _Loader.onGlobalLoaded = function(file) {
5199                 CLPM.showStatus("Application loaded.", true);
5200         };
5201         _Loader.onClassUnloaded = function(clazz) {
5202                 CLPM.showStatus("Class " + clazz + " is unloaded.", true);
5203   };
5204 }
5205 */
5206
5207 })(Clazz._LoaderProgressMonitor, Jmol);
5208
5209 //}
5210 /******************************************************************************
5211  * Copyright (c) 2007 java2script.org and others.
5212  * All rights reserved. This program and the accompanying materials
5213  * are made available under the terms of the Eclipse Public License v1.0
5214  * which accompanies this distribution, and is available at
5215  * http://www.eclipse.org/legal/epl-v10.html
5216  *
5217  * Contributors:
5218  *     Zhou Renjian - initial API and implementation
5219  *****************************************************************************/
5220 /*******
5221  * @author zhou renjian
5222  * @create Nov 5, 2005
5223  *******/
5224
5225 ;(function(Con, Sys) {
5226 /**
5227  * Setting maxTotalLines to -1 will not limit the console result
5228  */
5229 /* protected */
5230 Con.maxTotalLines =     10000;
5231
5232 /* protected */
5233 Con.setMaxTotalLines = function (lines) {
5234         Con.maxTotalLines = (lines > 0 ? lines : 999999);
5235 }
5236
5237 /* protected */
5238 Con.maxLatency = 40;
5239
5240 /* protected */
5241 Con.setMaxLatency = function (latency) {
5242         Con.maxLatency = (latency > 0 ? latency : 40);
5243 };
5244
5245 /* protected */
5246 Con.pinning  = false;
5247
5248 /* protected */
5249 Con.enablePinning = function (enabled) {
5250         Con.pinning = enabled;
5251 };
5252
5253 /* private */
5254 Con.linesCount = 0;
5255
5256 /* private */
5257 Con.metLineBreak = false;
5258
5259
5260 /*
5261  * Give an extension point so external script can create and bind the console
5262  * themself.
5263  *
5264  * TODO: provide more template of binding console window to browser.
5265  */
5266 /* protected */
5267 Con.createConsoleWindow = function (parentEl) {
5268         var console = document.createElement ("DIV");
5269         console.style.cssText = "font-family:monospace, Arial, sans-serif;";
5270         document.body.appendChild (console);
5271         return console;
5272 };
5273
5274 var c160 = String.fromCharCode(160); //nbsp;
5275 c160 += c160+c160+c160;
5276
5277 /* protected */
5278 Con.consoleOutput = function (s, color) {
5279         var o = window["j2s.lib"];
5280         var console = (o && o.console);
5281         if (console && typeof console == "string")
5282                 console = document.getElementById(console)
5283         if (!console)
5284                 return false; // BH this just means we have turned off all console action
5285         if (Con.linesCount > Con.maxTotalLines) {
5286                 for (var i = 0; i < Con.linesCount - Con.maxTotalLines; i++) {
5287                         if (console && console.childNodes.length > 0) {
5288                                 console.removeChild (console.childNodes[0]);
5289                         }
5290                 }
5291                 Con.linesCount = Con.maxTotalLines;
5292         }
5293
5294         var willMeetLineBreak = false;
5295         s = (typeof s == "undefined" ? "" : s == null ? "null" : "" + s);
5296         s = s.replace (/\t/g, c160);
5297         if (s.length > 0)
5298                 switch (s.charAt(s.length - 1)) {
5299                 case '\n':
5300                 case '\r':
5301                         s = (s.length > 1 ? s.substring (0, s.length - (s.charAt (s.length - 2) == '\r' ? 2 : 1)) : "");
5302                         willMeetLineBreak = true;
5303                         break;
5304                 }
5305
5306         var lines = null;
5307         s = s.replace (/\t/g, c160);
5308         lines = s.split(/\r\n|\r|\n/g);
5309         for (var i = 0, last = lines.length - 1; i <= last; i++) {
5310                 var lastLineEl = null;
5311                 if (Con.metLineBreak || Con.linesCount == 0 
5312                                 || console.childNodes.length < 1) {
5313                         lastLineEl = document.createElement ("DIV");
5314                         console.appendChild (lastLineEl);
5315                         lastLineEl.style.whiteSpace = "nowrap";
5316                         Con.linesCount++;
5317                 } else {
5318                         try {
5319                                 lastLineEl = console.childNodes[console.childNodes.length - 1];
5320                         } catch (e) {
5321                                 lastLineEl = document.createElement ("DIV");
5322                                 console.appendChild (lastLineEl);
5323                                 lastLineEl.style.whiteSpace = "nowrap";
5324                                 Con.linesCount++;
5325                         }
5326                 }
5327                 var el = document.createElement ("SPAN");
5328                 lastLineEl.appendChild (el);
5329                 el.style.whiteSpace = "nowrap";
5330                 if (color)
5331                         el.style.color = color;
5332                 var l = lines[i]
5333                 if (l.length == 0)
5334                         l = c160;
5335                 el.appendChild(document.createTextNode(l));
5336                 if (!Con.pinning)
5337                         console.scrollTop += 100;
5338                 Con.metLineBreak = (i != last || willMeetLineBreak);
5339         }
5340
5341         var cssClazzName = console.parentNode.className;
5342         if (!Con.pinning && cssClazzName
5343                         && cssClazzName.indexOf ("composite") != -1) {
5344                 console.parentNode.scrollTop = console.parentNode.scrollHeight;
5345         }
5346         Con.lastOutputTime = new Date ().getTime ();
5347 };
5348
5349 /*
5350  * Clear all contents inside the console.
5351  */
5352 /* public */
5353 Con.clear = function () {
5354         try {
5355                 Con.metLineBreak = true;
5356                 var o = window["j2s.lib"];
5357                 var console = o && o.console;
5358                 if (!console || !(console = document.getElementById (console)))
5359                         return;
5360                 var childNodes = console.childNodes;
5361                 for (var i = childNodes.length; --i >= 0;)
5362                         console.removeChild (childNodes[i]);
5363                 Con.linesCount = 0;
5364         } catch(e){};
5365 };
5366
5367 /* public */
5368 Clazz.alert = function (s) {
5369         Con.consoleOutput (s + "\r\n");
5370 };
5371
5372
5373 /* public */
5374 Sys.out.print = function (s) { 
5375         Con.consoleOutput (s);
5376 };
5377 /* public */
5378 Sys.out.println = function(s) { 
5379         Con.consoleOutput(typeof s == "undefined" ? "\r\n" : s == null ?  s = "null\r\n" : s + "\r\n");
5380 };
5381
5382 Sys.out.write = function (buf, offset, len) {
5383         Sys.out.print(String.instantialize(buf).substring(offset, offset+len));
5384 };
5385
5386 /* public */
5387 Sys.err.__CLASS_NAME__ = "java.io.PrintStream";
5388
5389 /* public */
5390 Sys.err.print = function (s) { 
5391         Con.consoleOutput (s, "red");
5392 };
5393
5394 /* public */
5395 Sys.err.println = function (s) {
5396         Con.consoleOutput (typeof s == "undefined" ? "\r\n" : s == null ?  s = "null\r\n" : s + "\r\n", "red");
5397 };
5398
5399 Sys.err.write = function (buf, offset, len) {
5400         Sys.err.print(String.instantialize(buf).substring(offset, offset+len));
5401 };
5402
5403 })(Clazz.Console, System);
5404
5405 })(Clazz, Jmol); // requires JSmolCore.js
5406
5407 }; // called by external application