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