package java.lang {
import java.io.PrintStream;
import flash.system.Capabilities;
import java.lang.Arguments;
dynamic public class System {
  public static var err: PrintStream;
  public static var out: PrintStream;
  public static var nextHashCode: int;
  public static var dummy1: Arguments = null;
  public static var dummy2: JavaArray = null;
  public static var dummy3: Cloneable = null;

  __clinit();

  static private function __clinit(): void {
    {
      nextHashCode++;
      initSystem__();
      err = new TracePrintStream(new TraceOutputStream());
      out = new TracePrintStream(new TraceOutputStream());
    }
  }
  private static function initSystem__(): void {
    // Initialize Object prototype
    var obj:Object = Object.prototype;
    obj.clone__ = function():Object {
    import mx.utils.ObjectUtil;
    if (!(this is Cloneable)) throw new CloneNotSupportedException();
    var cls:Object = this.constructor;
    var result:Object = new cls();
    for each (var prop:String in ObjectUtil.getClassInfo(this)["properties"]) {
    result[prop] = this[prop];
    }
    return result;
    };
    obj.setPropertyIsEnumerable("clone__", false);
    obj.hashCode__ = function():int {
    return java.lang.System.identityHashCode__Ljava_lang_Object_2(this);
    };
    obj.setPropertyIsEnumerable("hashCode__", false);
    obj.equals__Ljava_lang_Object_2 = function (other:Object):Boolean {
    return this === other;
    }
    obj.setPropertyIsEnumerable("equals__Ljava_lang_Object_2", false);
    obj.getClass__ = function ():java.lang.Class__ {
    return java.lang.Class__.getClass__Ljava_lang_Object_2(this);
    }
    obj.setPropertyIsEnumerable("getClass__", false);
    obj.toString__ = function ():String {
    return this.getClass__().getName__() + "@" + this.hashCode__();
    }
    obj.setPropertyIsEnumerable("toString__", false);
    obj.finalize__ = function ():void {
    }
    obj.setPropertyIsEnumerable("finalize__", false);
    obj.notify__ = function ():void {
    }
    obj.setPropertyIsEnumerable("notify__", false);
    obj.notifyAll__ = function ():void {
    }
    obj.setPropertyIsEnumerable("notifyAll__", false);
    obj.wait__ = function ():void {
    }
    obj.setPropertyIsEnumerable("wait__", false);
    obj.wait__J = function (timeout:Number):void {
    }
    obj.setPropertyIsEnumerable("wait__J", false);
    obj.wait__JI = function (timeout:Number, nanos:int):void {
    }
    obj.setPropertyIsEnumerable("wait__JI", false);
    
    // Initialize Object class to implement super (i.e super.clone());
    obj = Object;
    obj.clone__ = function(o:Object):Object {
    import mx.utils.ObjectUtil;
    if (!(o is Cloneable)) throw new CloneNotSupportedException();
    var cls:Object = o.constructor;
    var result:Object = new cls();
    for each (var prop:String in ObjectUtil.getClassInfo(o)["properties"]) {
    result[prop] = o[prop];
    }
    return result;
    };
    obj.setPropertyIsEnumerable("clone__", false);
    obj.hashCode__ = function(o:Object):int {
    return java.lang.System.identityHashCode__Ljava_lang_Object_2(o);
    };
    obj.setPropertyIsEnumerable("hashCode__", false);
    obj.equals__Ljava_lang_Object_2 = function (o:Object, other:Object):Boolean {
    return o === other;
    }
    obj.setPropertyIsEnumerable("equals__Ljava_lang_Object_2", false);
    obj.getClass__ = function (o:Object):java.lang.Class__ {
    return java.lang.Class__.getClass__Ljava_lang_Object_2(o);
    }
    obj.setPropertyIsEnumerable("getClass__", false);
    obj.toString__ = function (o:Object):String {
    return o.getClass__().getName__() + "@" + o.hashCode__();
    }
    obj.setPropertyIsEnumerable("toString__", false);
    obj.finalize__ = function (o:Object):void {
    }
    obj.setPropertyIsEnumerable("finalize__", false);
    obj.notify__ = function (o:Object):void {
    }
    obj.setPropertyIsEnumerable("notify__", false);
    obj.notifyAll__ = function (o:Object):void {
    }
    obj.setPropertyIsEnumerable("notifyAll__", false);
    obj.wait__ = function (o:Object):void {
    }
    obj.setPropertyIsEnumerable("wait__", false);
    obj.wait__J = function (o:Object, timeout:Number):void {
    }
    obj.setPropertyIsEnumerable("wait__J", false);
    obj.wait__JI = function (o:Object, timeout:Number, nanos:int):void {
    }
    obj.setPropertyIsEnumerable("wait__JI", false);
    
    // Initialize String class
    obj = String;
    obj.__init__Ljava_lang_String_2 = function(str:String):String {
    return str;
    }
    obj.__init___3C = function(data:JavaArray):String {
    return Object(String).valueOf___3C(data);
    }
    obj.__init___3CII = function(data:JavaArray, offset:int, count:int):String {
    return Object(String).valueOf___3CII(data, offset, count);
    }
    obj.valueOf__Z = function(b:Boolean):String {
    return b ? "true" : "false";
    }
    obj.valueOf__C = function(c:Number):String {
    return String.fromCharCode(c);
    }
    obj.valueOf___3C = function(data:JavaArray):String {
    return Object(String).valueOf___3CII(data, 0, data.length);
    }
    obj.valueOf___3CII = function(data:JavaArray, offset:int, count:int):String {
    var str:String = "";
    var end:int = offset + count;
    for (var i:int=offset; i<end; i++) {
    str += String.fromCharCode(Number(data[i]));
    }
    return str;
    }
    obj.valueOf__D = function(d:Number):String {
    return "" + d;
    }
    obj.valueOf__F = function(f:Number):String {
    return "" + f;
    }
    obj.valueOf__I = function(i:Number):String {
    return "" + i;
    }
    obj.valueOf__J = function(j:Number):String {
    return "" + j;
    }
    obj.valueOf__Ljava_lang_Object_2 = function(o:Object):String {
    if (o == null) return "null";
    return o.toString__();
    }
    obj.copyValueOf___3C = function(data:JavaArray):String {
    return Object(String).valueOf___3C(data);
    }
    obj.copyValueOf___3CII = function(data:JavaArray, offset:int, count:int):String {
    return Object(String).valueOf___3CII(data, offset, count);
    }
    
    // Initialize String prototype
    obj = String.prototype;
    obj.hashCode__ = function():int {
    var hash:int = 0;
    for (var i:int = 0; i<this.length; i++) {
    hash = hash * 31 + this.charCodeAt(i);
    }
    return hash;
    };
    obj.toString__ = function():String {
    return this;
    };
    obj.charAt__I = function(index:int):int {
    return this.charCodeAt(index);
    };
    obj.compareTo__Ljava_lang_Object_2 = function(obj:Object):int {
    if (!(obj is String)) throw new java.lang.ClassCastException();
    return this.compareTo__Ljava_lang_String_2(String(obj));
    };
    obj.compareTo__Ljava_lang_String_2 = function(str:String):int {
    var str1:String = this;
    var str2:String = String(obj);
    var end:int = Math.min(str1.length, str2.length);
    for (var i:int = 0; i < end; i++) {
    var c1:Number = str1.charCodeAt(i);
    var c2:Number = str2.charCodeAt(i);
    if (c1 != c2) {
    return c1 - c2;
    }
    }
    return str1.length - str2.length;
    };
    obj.compareToIgnoreCase__Ljava_lang_String_2 = function(str:String):int {
    return this.toUpperCase()._compareTo__Ljava_lang_String_2(str.toUpperCase());
    };
    obj.concat__Ljava_lang_String_2 = function(str:String):String {
    if (str.length == 0) return this;
    return this.concat(str);
    };
    obj.contentEquals__Ljava_lang_StringBuffer_2 = function(str:java.lang.StringBuffer):Boolean {
    return this == str.buffer;
    };
    obj.endsWith__Ljava_lang_String_2 = function(str:String):Boolean {
    return this.indexOf(str) == this.length - str.length;
    };
    obj.equalsIgnoreCase__Ljava_lang_String_2 = function(str:String):Boolean {
    return this.toUpperCase() == str.toUpperCase();
    };
    obj.getChars__II_3CI = function(srcBegin:int, srcEnd:int, dst:JavaArray, dstBegin:int):void {
    //TODO - check range
    for(var i:int=srcBegin; i<srcEnd; i++) {
    dst[dstBegin+i] = this.charCodeAt(i);
    }
    }
    obj.indexOf__I = function(ch:int):int {
    return this.indexOf(String.fromCharCode(ch));
    }
    obj.indexOf__II = function(ch:int, fromIndex:int):int {
    return this.indexOf(String.fromCharCode(ch), fromIndex);
    }
    obj.indexOf__Ljava_lang_String_2 = function(str:String):int {
    return this.indexOf(str);
    }
    obj.indexOf__Ljava_lang_String_2I = function(str:String, fromIndex:int):int {
    return this.indexOf(str, fromIndex);
    }
    obj.lastIndexOf__I = function(ch:int):int {
    return this.lastIndexOf(String.fromCharCode(ch));
    }
    obj.lastIndexOf__II = function(ch:int, fromIndex:int):int {
    return this.lastIndexOf(String.fromCharCode(ch), fromIndex);
    }
    obj.lastIndexOf__Ljava_lang_String_2 = function(str:String):int {
    return this.lastIndexOf(str);
    }
    obj.lastIndexOf__Ljava_lang_String_2I = function(str:String, fromIndex:int):int {
    return this.lastIndexOf(str, fromIndex);
    }
    obj.length__ = function():int {
    return this.length;
    };
    obj.matches__Ljava_lang_String_2 = function(regex:String):Boolean {
    var matchObj:RegExp = new RegExp(regex).exec(this);
    return (matchObj == null) ? false : (this == matchObj[0]);
    };
    obj.replace__CC = function(oldChar:int, newChar:int):String {
    var code:String = java.lang.Integer.toHexString__I(oldChar);
    var regx:RegExp = new RegExp("\\x" + code, "g");
    return this.replace(regx, String.fromCharCode(newChar));
    };
    //TODO replaceFirst, replaceAll, split
    obj.startsWith__Ljava_lang_String_2 = function(str:String):Boolean {
    return this.indexOf(str) == 0;
    };
    obj.startsWith__Ljava_lang_String_2I = function(str:String, toffset:int):Boolean {
    return this.indexOf(str, toffset) == toffset;
    };
    obj.subSequence__II = function(startIndex:int, endIndex:int):String {
    return this.substring(startIndex, endIndex);
    };
    obj.substring__I = function(startIndex:int):String {
    return this.substring(startIndex);
    };
    obj.substring__II = function(startIndex:int, endIndex:int):String {
    return this.substring(startIndex, endIndex);
    };
    obj.toCharArray__ = function():JavaArray {
    var result:JavaArray = new JavaArray("[C");
    var chars:Array = new Array(this.length);
    result.array = chars;
    for (var i:int = 0; i<this.length; i++) {
    chars[i] = this.charCodeAt(i);
    }
    return result;
    };
    obj.toUpperCase__ = function():String {
    return this.toUpperCase();
    };
    obj.toLowerCase__ = function():String {
    return this.toLowerCase();
    };
    obj.trim__ = function():String {
    return this.replace(/^(\s*)/, '').replace(/\s*$/, '');
    };
    }
    public static function stringValueOf(o: Object): String {
    return o == null ? "null" : o.toString__();
  }
  public static function arraycopy__Ljava_lang_Object_2ILjava_lang_Object_2II(src: Object, srcPos: int, dest: Object, destPos: int, length: int): void {
    //TODO check range
    var end:int, i:int, j:int;
    if (srcPos < destPos) {
    end = srcPos;
    j = destPos + length - 1;
    i = srcPos + length - 1;
    while (i>=end) {
    dest[j--] = src[i--];
    }
    } else {
    end = srcPos + length;
    j = destPos;
    i = srcPos;
    while (i<end) {
    dest[j++] = src[i++];
    }
    }
  }
  public static function currentTimeMillis__(): Number {
    return new Date().getTime();
  }
  public static function exit__I(status: int): void {
  }
  public static function gc__(): void {
  }
  public static function getProperty__Ljava_lang_String_2(key: String): String {
    return getProperty__Ljava_lang_String_2Ljava_lang_String_2(key, null);
  }
  public static function getProperty__Ljava_lang_String_2Ljava_lang_String_2(key: String, dfts: String): String {
    if (key === null)
      throw new NullPointerException(new Arguments(java.lang.NullPointerException.NullPointerException__, []));
    if (Object(key).length__() == 0)
      throw new IllegalArgumentException(new Arguments(java.lang.IllegalArgumentException.IllegalArgumentException__, []));
    if (Object(key).equals__Ljava_lang_Object_2("line.separator"))
      return "\n";
    if (Object(key).equals__Ljava_lang_Object_2("file.encoding"))
      return "utf-8";
    if (Object(key).equals__Ljava_lang_Object_2("os.name"))
      return flash.system.Capabilities.os;
    var serverString: String = flash.system.Capabilities.serverString;
    if (Object(key).equals__Ljava_lang_Object_2("os.version"))
      return Object(serverString).substring__I(Object(serverString).indexOf__Ljava_lang_String_2("ML") + 3);
    ;
    return dfts;
  }
  public static function identityHashCode__Ljava_lang_Object_2(obj: Object): int {
    if (obj == null) return 0;
    if (obj.__hashCode__ == undefined) {
    obj.__hashCode__  = java.lang.System.nextHashCode++;
    }
    return obj.__hashCode__;
  }
  public static function setErr__Ljava_io_PrintStream_2(err: PrintStream): void {
    java.lang.System.err = err;
  }
  public static function setOut__Ljava_io_PrintStream_2(out: PrintStream): void {
    java.lang.System.out = out;
  }
}
}
