diff options
author | chiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3> | 2011-08-31 10:29:34 +0000 |
---|---|---|
committer | chiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3> | 2011-08-31 10:29:34 +0000 |
commit | d72870bfb6b09927e10944bdd129ce18dfcf7366 (patch) | |
tree | 27f56e4d1523a8cecc8976df60155e6b8429e504 | |
parent | 76a1cba9c433e8242bb6648e72b3ed43c7a4995a (diff) | |
download | javassist-d72870bfb6b09927e10944bdd129ce18dfcf7366.tar.gz javassist-d72870bfb6b09927e10944bdd129ce18dfcf7366.zip |
JvstTest test case.
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@589 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
260 files changed, 40406 insertions, 0 deletions
diff --git a/src/test/Readme.txt b/src/test/Readme.txt new file mode 100644 index 00000000..712b8536 --- /dev/null +++ b/src/test/Readme.txt @@ -0,0 +1,2 @@ +check javassist.JvstTestRoot.PATH and .JAR_PATH and then +run javassist.JvstTest diff --git a/src/test/VisibleTop.java b/src/test/VisibleTop.java new file mode 100644 index 00000000..6430bd70 --- /dev/null +++ b/src/test/VisibleTop.java @@ -0,0 +1,6 @@ +public class VisibleTop { + public int pub; + protected int pro; + private int pri; + int pack; +} diff --git a/src/test/VisibleTop2.java b/src/test/VisibleTop2.java new file mode 100644 index 00000000..93fed9da --- /dev/null +++ b/src/test/VisibleTop2.java @@ -0,0 +1,6 @@ +public class VisibleTop2 { + public int pub; + protected int pro; + private int pri; + int pack; +} diff --git a/src/test/annotation/Test.java b/src/test/annotation/Test.java new file mode 100644 index 00000000..2c9da5e1 --- /dev/null +++ b/src/test/annotation/Test.java @@ -0,0 +1,35 @@ +package annotation; + +@interface Id { + int id(); +} + +enum EnumTest { + A, B, C +} + +@interface Tag { + boolean z(); + byte b(); + char c(); + short s(); + int i(); + long j(); + float f(); + double d(); + String string(); + Class<? extends Object> integer(); + EnumTest enumtest(); + String[] array(); + Id annotation(); +} + +@Tag(z = true, b = 1, c = 'a', s = 2, i = 3, j = 4L, f = 5.0F, d = 5.0, + string = "abc", + enumtest = EnumTest.A, + integer = Integer.class, + array = { "p", "q", "r" }, + annotation = @Id(id = 20)) +public class Test { + public int test() { return 0; } +} diff --git a/src/test/javassist/Bench.java b/src/test/javassist/Bench.java new file mode 100644 index 00000000..723fa198 --- /dev/null +++ b/src/test/javassist/Bench.java @@ -0,0 +1,167 @@ +package javassist; + +import junit.framework.*; +import javassist.expr.*; +import javassist.compiler.*; + +public class Bench extends JvstTestRoot { + public Bench(String name) { + super(name); + } + + public void testProceed() throws Exception { + CtClass cc = sloader.get("test.BenchProceed"); + CtMethod m1 = cc.getDeclaredMethod("p"); + m1.instrument(new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + if (m.getMethodName().equals("calc")) + m.replace("{ before($args); $_ = $proceed($$); }"); + } + }); + + CtMethod m2 = cc.getDeclaredMethod("q"); + m2.instrument(new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + if (m.getMethodName().equals("calc")) + m.replace("{ $_ = ($r)replace($args); }"); + } + }); + + CtMethod m3 = cc.getDeclaredMethod("s"); + m3.instrument(new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + if (m.getMethodName().equals("calc2")) + m.replace( + "{ long start = System.currentTimeMillis();" + + "$_ = $proceed($$);" + + "long elapsed = System.currentTimeMillis() - start;" + + "System.out.println(elapsed); }"); + } + }); + + CtMethod m4 = cc.getDeclaredMethod("t"); + m4.instrument(new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + if (m.getMethodName().equals("calc2")) + m.replace( + "{ long start = System.currentTimeMillis();" + + "$_ = $proceed($$);" + + "System.out.println(System.currentTimeMillis() - start);" + + "}"); + } + }); + + cc.writeFile(); + Object obj = make(cc.getName()); + int ptime = invoke(obj, "p"); + int qtime = invoke(obj, "q"); + System.out.println("time: (p) " + ptime + ", (q) " + qtime); + System.out.println("s:"); + invoke(obj, "s"); + System.out.println("t:"); + invoke(obj, "t"); + assertTrue(ptime < qtime); + } + + public void testProceedNew() throws Exception { + CtClass cc = sloader.get("test.BenchProceedNew"); + CtMethod m1 = cc.getDeclaredMethod("jvst0"); + m1.instrument(new ExprEditor() { + public void edit(NewExpr m) throws CannotCompileException { + m.replace("{ $_ = $proceed($$); }"); + } + }); + + CtMethod m2 = cc.getDeclaredMethod("jvst2"); + m2.instrument(new ExprEditor() { + public void edit(NewExpr m) throws CannotCompileException { + m.replace("{ $_ = $proceed($$); }"); + } + }); + + cc.writeFile(); + Object obj = make(cc.getName()); + int qtime = invoke(obj, "jvst0"); + int ptime = invoke(obj, "org0"); + System.out.println("time: (org0) " + ptime + ", (jvst0) " + qtime); + qtime = invoke(obj, "jvst2"); + ptime = invoke(obj, "org2"); + System.out.println("time: (org2) " + ptime + ", (jvst2) " + qtime); + } + + public void testStaticMethod() throws Exception { + CtClass cc = sloader.get("test.BenchStaticMethod"); + CtMethod m1 = cc.getDeclaredMethod("test"); + m1.instrument(new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + if (m.getMethodName().equals("foo")) + m.replace("{ num += $1; $_ = $proceed($$); }"); + } + }); + + cc.writeFile(); + Object obj = make(cc.getName()); + int qtime = invoke(obj, "test"); + int ptime = invoke(obj, "orgTest"); + System.out.println( + "BenchStaticMethod time: (org) " + ptime + ", (jvst) " + qtime); + } + + public void testStaticField() throws Exception { + System.out.println(sloader); + Javac jc = new Javac(sloader.get("test.StaticField")); + long t0 = System.currentTimeMillis(); + for (int i = 0; i < 100; i++) + jc.compileStmnt("{ int counter = 0; counter++; }"); + + t0 = System.currentTimeMillis() - t0; + System.out.println("local variable: " + (t0 * 10) + " usec"); + + long t = System.currentTimeMillis(); + for (int i = 0; i < 100; i++) + jc.compileStmnt("{ test.StaticField.counter++; }"); + + t = System.currentTimeMillis() - t; + System.out.println("StaticField: " + (t * 10) + " usec"); + + long t2 = System.currentTimeMillis(); + for (int i = 0; i < 100; i++) + jc.compileStmnt("{ test.StaticField#counter++; }"); + + t2 = System.currentTimeMillis() - t2; + System.out.println("StaticField with #: " + (t2 * 10) + " usec"); + + long t3 = System.currentTimeMillis(); + for (int i = 0; i < 100; i++) + jc.compileStmnt("{ StaticField.counter2++; }"); + + t3 = System.currentTimeMillis() - t3; + System.out.println("StaticField without package: " + (t3 * 10) + " usec"); + + long t4 = System.currentTimeMillis(); + for (int i = 0; i < 100; i++) + jc.compileStmnt("{ test.StaticField.counter++; }"); + + t4 = System.currentTimeMillis() - t4; + System.out.println("StaticField: " + (t4 * 10) + " usec"); + + long t5 = System.currentTimeMillis(); + for (int i = 0; i < 100; i++) + jc.compileStmnt("{ System.out.println(); }"); + + t5 = System.currentTimeMillis() - t5; + System.out.println("println: " + (t5 * 10) + " usec"); + } + + public static void main(String[] args) { + // junit.textui.TestRunner.run(suite()); + junit.swingui.TestRunner.main(new String[] { "javassist.Bench" }); + } + + public static Test suite() { + TestSuite suite = new TestSuite("Benchmark Tests"); + suite.addTestSuite(Bench.class); + suite.addTestSuite(testproxy.ProxyFactoryPerformanceTest.class); + return suite; + } +} diff --git a/src/test/javassist/ClassPoolBench.java b/src/test/javassist/ClassPoolBench.java new file mode 100644 index 00000000..d3cb6b2d --- /dev/null +++ b/src/test/javassist/ClassPoolBench.java @@ -0,0 +1,57 @@ +package javassist;
+
+import java.util.Enumeration;
+import java.util.zip.*;
+
+public class ClassPoolBench {
+ static ClassPool cp;
+ static boolean mod = false, detach = false, readonly = false;
+
+ public static void accessClass(String name) throws Exception {
+ CtClass cc = cp.get(name);
+ System.out.println(cc.getName());
+ cc.getSuperclass();
+ if (mod)
+ cc.getClassFile();
+
+ if (detach)
+ cc.stopPruning(true);
+
+ if (!readonly)
+ cc.toBytecode();
+
+ if (detach)
+ cc.detach();
+ }
+
+ public static void accessAll(String filename) throws Exception {
+ ZipFile zip = new ZipFile(filename);
+ Enumeration files = zip.entries();
+ while (files.hasMoreElements()) {
+ ZipEntry z = (ZipEntry)files.nextElement();
+ String name = z.getName();
+ if (name.endsWith(".class")) {
+ name = name.substring(0, name.length() - 6)
+ .replace('/', '.');
+ accessClass(name);
+ }
+ }
+
+ zip.close();
+ }
+
+ public static void main(String[] args) throws Exception {
+ cp = ClassPool.getDefault();
+ cp.appendClassPath(args[0]);
+ if (args[1].equals("true"))
+ mod = true;
+ else if (args[1].equals("detach"))
+ mod = detach = true;
+ else if (args[1].equals("read"))
+ readonly = true;
+
+ System.err.println("mod: " + mod + " detach: " + detach
+ + " readonly: " + readonly);
+ accessAll(args[0]);
+ }
+}
diff --git a/src/test/javassist/JvstTest.java b/src/test/javassist/JvstTest.java new file mode 100644 index 00000000..92154b38 --- /dev/null +++ b/src/test/javassist/JvstTest.java @@ -0,0 +1,1123 @@ +package javassist; + +import junit.framework.*; +import java.io.FileInputStream; +import java.lang.reflect.Method; +import javassist.bytecode.*; +import javassist.expr.*; +import javassist.runtime.*; + +public class JvstTest extends JvstTestRoot { + static { + //javassist.bytecode.MethodInfo.doPreverify = true; + } + public JvstTest(String name) { + super(name); + } + + public void testConfig() { + // is the value of PATH correct? + assertTrue("not found " + PATH, new java.io.File(PATH).exists()); + } + + public void testLoader() throws Exception { + Loader loader = new Loader(sloader); + loader.delegateLoadingOf("test1."); + assertEquals(loader.loadClass("test1.Cflow").getClassLoader(), + loader.getParent()); + assertEquals(loader.loadClass("javassist.Loader").getClassLoader(), + loader.getParent()); + assertEquals(loader.loadClass("javassist.CtClass").getClassLoader(), + loader); + } + + public void testDefreeze() throws Exception { + CtClass cc = sloader.get("test1.Freeze"); + cc.stopPruning(true); + cc.addInterface(sloader.get("java.io.Serializable")); + assertTrue(!cc.isFrozen()); + cc.writeFile(); + assertTrue(cc.isFrozen()); + cc.defrost(); + assertTrue(!cc.isFrozen()); + } + + public void testClassPath() throws Exception { + ClassPool pool = new ClassPool(null); + ClassPath cp1 = pool.appendClassPath("d1"); + ClassPath cp2 = pool.appendClassPath("d2"); + ClassPath cp3 = pool.appendClassPath("d3"); + ClassPath cp4 = pool.appendClassPath("d4"); + print(pool.toString()); + pool.removeClassPath(cp3); + print(pool.toString()); + pool.removeClassPath(cp4); + print(pool.toString()); + pool.removeClassPath(cp2); + print(pool.toString()); + pool.removeClassPath(cp1); + assertTrue("[class path: ]".equals(pool.toString())); + } + + public void testSubtype() throws Exception { + CtClass cc = sloader.get("test1.Subtype"); + assertTrue(cc.subtypeOf(cc)); + assertTrue(cc.subtypeOf(sloader.get("test1.SubtypeA"))); + assertTrue(cc.subtypeOf(sloader.get("test1.SubtypeB"))); + assertTrue(cc.subtypeOf(sloader.get("test1.SubtypeC"))); + assertTrue(cc.subtypeOf(sloader.get("java.lang.Object"))); + assertTrue(!cc.subtypeOf(sloader.get("java.lang.String"))); + } + + public void testClassPoolGet() throws Exception { + ClassPool pool = ClassPool.getDefault(); + CtClass cc = pool.makeClass("test1.Point"); + CtClass cc1 = pool.get("test1.Point"); // cc1 is identical to cc. + cc.setName("test1.Pair"); + CtClass cc2 = pool.get("test1.Pair"); // cc2 is identical to cc. + CtClass cc3 = pool.get("test1.Point"); // cc3 is not identical to cc. + + assertTrue(cc == cc1); + assertTrue(cc == cc2); + assertTrue(cc != cc3); + + assertEquals("test1.Pair", cc.getName()); + assertEquals("test1.Point", cc3.getName()); + } + + public static long testFieldInitHash; + + /* test CodeIterator.insertExGap(). + * The result of this test is checked again by JvstTest3#testFieldInitAgain(). + */ + public void testFieldInit() throws Exception { + CtClass cc = sloader.get("test1.FieldInit"); + CtField f1 = new CtField(CtClass.intType, "f1", cc); + cc.addField(f1, CtField.Initializer.byCall(cc, "get")); + CtField f2 = CtField.make("public int f2 = 3;", cc); + cc.addField(f2); + CtField f3 = CtField.make("public int f3;", cc); + cc.addField(f3); + testFieldInitHash = f1.hashCode(); + cc.writeFile(); + Object obj = make(cc.getName()); + int value = obj.getClass().getField("counter").getInt(obj); + assertEquals(1, value); + int value2 = obj.getClass().getField("f2").getInt(obj); + assertEquals(3, value2); + int value3 = obj.getClass().getField("f3").getInt(obj); + assertEquals(0, value3); + } + + /* test CodeIterator.insertExGap(). + */ + public void testFieldInit2() throws Exception { + CtClass cc = sloader.get("test1.FieldInit2"); + CtField f = new CtField(CtClass.intType, "f1", cc); + cc.addField(f, CtField.Initializer.byCall(cc, "get")); + cc.writeFile(); + try { + Object obj = make(cc.getName()); + fail(); + } + catch (Exception e) { + print("testFieldInit2: catch"); + } + } + + public static CtMethod testCalleeBeforeMethod; + public static long testCalleeBeforeMethod2; + + /* The test result is checked again by JvstTest3#testCalleeBeforeAgain(). + */ + public void testCalleeBefore() throws Exception { + CtClass cc = sloader.get("test1.CalleeBefore"); + + CtMethod m1 = cc.getDeclaredMethod("m1"); + m1.insertBefore("{ int k = 1; p = k; }"); + CtMethod m2 = cc.getDeclaredMethod("m2"); + testCalleeBeforeMethod = m1; + testCalleeBeforeMethod2 = m2.getMethodInfo2().hashCode(); + m2.insertBefore("{ int k = 3; q = k; }"); + CtConstructor[] cons = cc.getDeclaredConstructors(); + + for (int i = 0; i < cons.length; ++i) { + MethodInfo minfo = cons[i].getMethodInfo(); + CodeAttribute ca = minfo.getCodeAttribute(); + CodeIterator iterator = ca.iterator(); + if (cons[i].getParameterTypes().length == 0) { + assertTrue(iterator.skipThisConstructor() >= 0); + assertTrue(iterator.skipSuperConstructor() < 0); + assertTrue(iterator.skipConstructor() >= 0); + } + else { + assertTrue(iterator.skipThisConstructor() < 0); + assertTrue(iterator.skipSuperConstructor() >= 0); + assertTrue(iterator.skipConstructor() >= 0); + } + + cons[i].insertBeforeBody("{ int k = 1; counter += k; }"); + } + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(0, invoke(obj, "getr")); + assertEquals(17, invoke(obj, "test")); + } + + public void testCalleeAfter() throws Exception { + CtClass cc = sloader.get("test1.CalleeAfter"); + + CtMethod m1 = cc.getDeclaredMethod("m1"); + m1.insertAfter("{ int k = 1; $_ = $_ + k; }", false); + + CtMethod m2 = cc.getDeclaredMethod("m2"); + m2.insertAfter("{ char k = 1; $_ = $_ + k; }", false); + + CtConstructor[] cons = cc.getDeclaredConstructors(); + cons[0].insertAfter("{ ++p; $_ = ($r)null; }", false); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(15, invoke(obj, "test")); + } + + public void testCalleeAfter2() throws Exception { + CtClass cc = sloader.get("test1.CalleeAfter2"); + + CtMethod m1 = cc.getDeclaredMethod("m1"); + m1.insertAfter("$_ = 7; $_ = ($r)k1(0);", false); + + CtMethod m2 = cc.getDeclaredMethod("m2"); + m2.insertAfter("$_ = ($r)k2(0);", false); + + CtMethod m3 = cc.getDeclaredMethod("m3"); + m3.insertAfter("$_ = ($r)k3(0);", false); + + CtMethod m4 = cc.getDeclaredMethod("m4"); + try { + m4.insertAfter("$_ = ($r)1;", false); + assertTrue(false); + } + catch (CannotCompileException e) { + } + + CtMethod m5 = cc.getDeclaredMethod("m5"); + m5.insertAfter("$_ = ($r)k5(0);", false); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(17, invoke(obj, "test")); + } + + public void testCalleeAfter3() throws Exception { + CtClass cc = sloader.get("test1.CalleeAfter3"); + CtMethod m1 = cc.getDeclaredMethod("m1"); + m1.insertAfter("value++;", true); + CtMethod m2 = cc.getDeclaredMethod("m2"); + m2.insertAfter("value++;", true); + CtMethod m3 = cc.getDeclaredMethod("m3"); + m3.insertAfter("value++;", true); + CtMethod m4 = cc.getDeclaredMethod("m4"); + m4.insertAfter("value++;", true); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(22, invoke(obj, "test")); + } + + public void testCalleeCatch() throws Exception { + CtClass cc = sloader.get("test1.CalleeCatch"); + + CtMethod m1 = cc.getDeclaredMethod("m1"); + m1.addCatch("{ System.out.println($e); return p; }", + sloader.get("java.lang.Exception")); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(3, invoke(obj, "test")); + } + + public void testSuperclass() throws Exception { + CtClass cc = sloader.get("java.lang.Object"); + assertEquals(null, cc.getSuperclass()); + } + + public void testProceed() throws Exception { + CtClass cc = sloader.get("test1.Proceed"); + + CtMethod m1 = CtNewMethod.make( + "public int m1() { return $proceed(3); }", + cc, "this", "k1"); + CtMethod m2 = CtNewMethod.make( + "public int m2() { return $proceed(3); }", + cc, "another", "k2"); + CtMethod m3 = CtNewMethod.make( + "public int q(int i) { return p($1 + 1, $$); }", cc); + cc.addMethod(m1); + cc.addMethod(m2); + cc.addMethod(m3); + CtMethod m4 = CtNewMethod.make( + "public int q2() { return q(4); }", cc); + cc.addMethod(m4); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(3, invoke(obj, "m1")); + assertEquals(4, invoke(obj, "m2")); + assertEquals(9, invoke(obj, "q2")); + } + + public void testProceed2() throws Exception { + CtClass cc = sloader.get("test1.Proceed2"); + CtMethod m1 = cc.getDeclaredMethod("k1"); + m1.instrument(new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + m.replace("{ $_ = $proceed($$); }"); + } + public void edit(NewExpr m) throws CannotCompileException { + m.replace("{ $_ = $proceed($$); }"); + } + public void edit(FieldAccess m) throws CannotCompileException { + m.replace("{ $_ = $proceed($$); }"); + } + public void edit(Instanceof i) throws CannotCompileException { + i.replace("{ $_ = $proceed($$); }"); + } + public void edit(Cast c) throws CannotCompileException { + c.replace("{ $_ = $proceed($$); }"); + } + }); + + CtMethod m2 = cc.getDeclaredMethod("k2"); + m2.instrument(new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + m.replace("{ $proceed(); }"); + } + public void edit(NewExpr m) throws CannotCompileException { + m.replace("{ $_ = $proceed(); }"); + } + public void edit(FieldAccess m) throws CannotCompileException { + if (m.isReader()) + m.replace("{ $_ = $proceed(); }"); + else + m.replace("{ $proceed($$); }"); + } + }); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(2, invoke(obj, "k1")); + } + + public void testProceed3() throws Exception { + CtClass cc = sloader.get("test1.Proceed3"); + CtMethod m1 = cc.getDeclaredMethod("p"); + CtMethod m2 = CtNewMethod.copy(m1, cc, null); + m1.setName(m1.getName() + "_orig"); + m2.setBody("{ return $proceed($1 + 1); }", "this", m1.getName()); + cc.addMethod(m2); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(4, invoke(obj, "k1")); + } + + public void testSetBody() throws Exception { + CtClass cc = sloader.get("test1.SetBody"); + CtMethod m1 = cc.getDeclaredMethod("m1"); + m1.setBody("{ int i = $1 * $2; return i; }"); + CtMethod m2 = cc.getDeclaredMethod("m2"); + m2.setBody("System.out.println(\"setbody: \" + $1);"); + + CtMethod m3 = cc.getDeclaredMethod("m3"); + try { + m3.setBody("value = 1; System.out.println(\"setbody: \" + $1);"); + fail(); + } + catch (CannotCompileException e) { + // System.err.println(e); + } + + CtConstructor cons + = new CtConstructor(new CtClass[] { CtClass.intType }, cc); + cons.setBody(null); + cc.addConstructor(cons); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(12, invoke(obj, "run")); + } + + public void testSetStaticConsBody() throws Exception { + CtClass cc = sloader.get("test1.StaticConsBody"); + CtConstructor cons = cc.getClassInitializer(); + cons.setBody(null); + + cons = cc.getConstructors()[0]; + cons.setBody(null); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(0, invoke(obj, "run")); + } + + public void testSetConsBody() throws Exception { + CtClass superClazz = sloader.get("java.io.File"); + CtClass cc = sloader.makeClass("test1.SetConsBody"); + cc.setSuperclass(superClazz); + CtConstructor constructor = new CtConstructor(new CtClass[0], cc); + constructor.setBody("super(\"MyFile\");"); + cc.addConstructor(constructor); + + constructor = new CtConstructor(new CtClass[] { CtClass.intType }, + cc); + constructor.setBody("{ super(\"MyFile\"); }"); + cc.addConstructor(constructor); + + cc.addMethod(CtNewMethod.make(CtClass.voidType, "m1", + null, null, null, cc)); + cc.addMethod(CtNewMethod.make(CtClass.intType, "m2", + null, null, null, cc)); + cc.addMethod(CtNewMethod.make(CtClass.byteType, "m3", + null, null, null, cc)); + cc.addMethod(CtNewMethod.make(CtClass.longType, "m4", + null, null, null, cc)); + cc.addMethod(CtNewMethod.make(CtClass.floatType, "m5", + null, null, null, cc)); + cc.addMethod(CtNewMethod.make(CtClass.doubleType, "m6", + null, null, null, cc)); + cc.addMethod(CtNewMethod.make(sloader.get("int[]"), "m7", + null, null, null, cc)); + + cc.addMethod(CtNewMethod.make( + "public int run() {" + + " return (int)(m2() + m3() + m4() + m5() + m6() + 3); }", cc)); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(3, invoke(obj, "run")); + } + + public void testEmptyBody() throws Exception { + String[] methods = { "m1", "m2", "m3", "m4" }; + boolean[] results = { true, false, false, false, true }; + boolean[] cResults = { true, true, false, false, false, true }; + + CtClass cc = sloader.get("test1.EmptyBody"); + for (int i = 0; i < methods.length; ++i) { + CtMethod m = cc.getDeclaredMethod(methods[i]); + assertEquals(results[i], m.isEmpty()); + } + + CtConstructor[] cons = cc.getDeclaredConstructors(); + for (int j = 0; j < cons.length; ++j) + assertEquals(cResults[j], cons[j].isEmpty()); + } + + public void testExprEditor() throws Exception { + CtClass cc = sloader.get("test1.ExprEdit"); + + CtMethod m1 = cc.getDeclaredMethod("k0"); + m1.instrument(new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + if (m.getClassName().equals("test1.ExprEdit")) { + String name = m.getMethodName(); + if (name.equals("k1") || name.equals("k2")) { + try { + CtMethod cm = m.getMethod(); + print(cm.getParameterTypes()[0].getName()); + print(cm.getReturnType().getName()); + } + catch (NotFoundException e) { + throw new CannotCompileException(e); + } + m.replace("{ ++$1; $_ = $proceed($$); }"); + } + else if (name.equals("k3")) + m.replace("{ ++$1; $proceed($$); }"); + } + } + }); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(12, invoke(obj, "k0")); + } + + public void testExprEditor2() throws Exception { + CtClass cc = sloader.get("test1.ExprEdit2"); + + CtMethod m1 = cc.getDeclaredMethod("k1"); + m1.instrument(new ExprEditor() { + public void edit(FieldAccess m) throws CannotCompileException { + if (m.getClassName().equals("test1.ExprEdit2")) { + String name = m.getFieldName(); + try { + CtField cf = m.getField(); + print(cf.getType().getName()); + print("file: " + m.getFileName()); + print("line: " + m.getLineNumber()); + } + catch (NotFoundException e) { + throw new CannotCompileException(e); + } + if (name.equals("df")) + if (m.isReader()) + m.replace("{ $_ = $proceed() + 1; }"); + else + m.replace("{ $proceed($1 + 1); }"); + else if (name.equals("sf")) + if (m.isReader()) + m.replace("{ $_ = $proceed() + 2; }"); + else + m.replace("{ $proceed($1 + 2); }"); + } + } + }); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(16, invoke(obj, "k1")); + } + + public void testExprEditor3() throws Exception { + CtClass cc = sloader.get("test1.ExprEdit3"); + + CtMethod m1 = cc.getDeclaredMethod("k1"); + m1.instrument(new ExprEditor() { + public void edit(NewExpr m) throws CannotCompileException { + System.out.println("new " + m.getClassName()); + try { + CtConstructor cc = m.getConstructor(); + print(cc.getParameterTypes()[0].getName()); + } + catch (NotFoundException e) { + throw new CannotCompileException(e); + } + if (m.getClassName().equals("test1.ExprEdit3")) { + m.replace("{ ++$2; $_ = $proceed($$); }"); + } + } + }); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(4, invoke(obj, "k1")); + } + + public void testExprEditor4() throws Exception { + CtClass cc = sloader.get("test1.ExprEdit4"); + + CtMethod m1 = cc.getDeclaredMethod("k1"); + m1.instrument(new ExprEditor() { + public void edit(NewExpr m) throws CannotCompileException { + System.out.println("new " + m.getClassName()); + if (m.getClassName().equals("test1.ExprEdit4")) + m.replace("$_ = null;"); + } + + public void edit(MethodCall m) throws CannotCompileException { + if (m.getClassName().equals("test1.ExprEdit4")) + m.replace("{}"); + } + }); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(1, invoke(obj, "k1")); + } + + public void testExprEditor5() throws Exception { + CtClass cc = sloader.get("test1.ExprEdit5"); + + CtMethod m1 = cc.getDeclaredMethod("k1"); + m1.instrument(new ExprEditor() { + public void edit(NewExpr m) throws CannotCompileException { + m.replace("{ $_ = $proceed($$, \"test\"); }"); + } + }); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(1, invoke(obj, "k1")); + } + + public void testExprEditor6() throws Exception { + CtClass cc = sloader.get("test1.ExprEdit6"); + cc.instrument(new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + assertTrue(m.where().getName().equals("k1")); + m.replace("$_ = 3;"); + } + }); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(3, invoke(obj, "k1")); + } + + public void testExprEditor7() throws Exception { + CtClass cc = sloader.get("test1.ExprEdit7"); + cc.instrument(new ExprEditor() { + public void edit(Instanceof i) throws CannotCompileException { + i.replace("{ this.c1 = $type; $_ = !$proceed($1); }"); + } + public void edit(Cast c) throws CannotCompileException { + c.replace("{ this.c2 = $type; $_ = ($r)$1; }"); + } + }); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(7, invoke(obj, "k1")); + } + + public void testExprEditor8() throws Exception { + CtClass cc = sloader.get("test1.ExprEdit8"); + cc.instrument(new ExprEditor() { + public void edit(ConstructorCall c) throws CannotCompileException { + assertTrue(c.isSuper()); + c.replace("{ $_ = $proceed($$); value = 7; }"); + } + }); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(7, invoke(obj, "k1")); + } + + public void testCflow() throws Exception { + CtClass cc = sloader.get("test1.Cflow"); + CtMethod m1 = cc.getDeclaredMethod("k1"); + m1.useCflow("cflow1"); + m1.insertBefore("System.out.println(\"$cflow1: \" + $cflow(cflow1));"); + m1.insertAfter("System.out.println(\"*$cflow1: \" + $cflow(cflow1));", + true); + CtMethod m2 = cc.getDeclaredMethod("k2"); + m2.useCflow("test1.t.cflow2"); + m2.insertBefore( + "System.out.println(\"$cflow2: \" + $cflow(test1.t.cflow2));"); + CtMethod m3 = cc.getDeclaredMethod("fact"); + m3.useCflow("fact"); + m3.insertBefore("if ($cflow(fact) == 0)" + + " System.out.println(\"fact \" + $1);"); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(1, invoke(obj, "run")); + assertEquals(120, invoke(obj, "run2")); + } + + public void testSigType() throws Exception { + CtClass cc = sloader.get("test1.SigType"); + + CtMethod m1 = cc.getDeclaredMethod("k1"); + m1.insertBefore("{ Class[] p = $sig; $1 += p.length; }"); + m1.insertAfter("System.out.println(\"testSigType: \"" + + " + $type.getName());", false); + + CtMethod m2 = cc.getDeclaredMethod("k2"); + m2.instrument(new ExprEditor() { + public void edit(FieldAccess m) throws CannotCompileException { + m.replace("{ $_ = $proceed($$) + $type.getName().length(); }"); + } + + public void edit(MethodCall m) throws CannotCompileException { + m.replace("{ $_ = $proceed($$) + $sig.length; }"); + } + }); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(19, invoke(obj, "run")); + } + + public void testDollarClass() throws Exception { + CtClass cc = sloader.get("test1.DollarClass"); + + CtMethod m1 = cc.getDeclaredMethod("k1"); + m1.insertBefore("{ $1 += $class.getName().length(); }"); + + CtMethod m2 = cc.getDeclaredMethod("k2"); + m2.instrument(new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + m.replace("{ $_ = $class.getName().length(); }"); + } + }); + m2.insertBefore("{ $1 += $class.getName().length(); }"); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(58, invoke(obj, "run")); + } + + public void testHandler() throws Exception { + CtClass cc = sloader.get("test1.Handler"); + + CtMethod m1 = cc.getDeclaredMethod("m1"); + m1.instrument(new ExprEditor() { + public void edit(Handler h) throws CannotCompileException { + try { + print(h.getType().getName()); + h.insertBefore( + "{ p = (($r)$1).getClass().getName().length()" + + "+ $type.getName().length(); }"); + } + catch (NotFoundException e) { + throw new CannotCompileException(e); + } + } + }); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(("java.lang.IndexOutOfBoundsException".length() + + "java.lang.ClassNotFoundException".length()) + * 2 + 1, + invoke(obj, "test")); + } + + public void testInterface() throws Exception { + String className = "test1.NewInterface"; + ClassPool pool = ClassPool.getDefault(); + CtClass targetCtClass = pool.get(className); + CtClass ctInterface + = pool.makeInterface(className + "2"); + CtMethod[] ctMethods = targetCtClass.getDeclaredMethods(); + for (int i = 0;i < ctMethods.length; i++) { + String code = Modifier.toString(ctMethods[i].getModifiers()) + + " " + ctMethods[i].getReturnType().getName() + + " " + ctMethods[i].getName() + "();"; + + System.out.println(code); + CtMethod m = CtNewMethod.make(code, ctInterface); + ctInterface.addMethod(m); + } + + targetCtClass.addInterface(ctInterface); + targetCtClass.stopPruning(true); + targetCtClass.writeFile(); + + ctInterface.stopPruning(true); + ctInterface.writeFile(); + ctInterface.toClass(); + targetCtClass.toClass(); + } + + public void testDispatch() throws Exception { + CtClass cc = sloader.get("test1.Dispatch"); + + CtMethod m1 = cc.getDeclaredMethod("run"); + m1.insertAfter("$_ += f(new Object[1]);"); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(7, invoke(obj, "run")); + } + + public void testMakeClass()throws Exception { + CtClass cc = sloader.makeClass( + new FileInputStream(PATH + "test1/MakeClass.class")); + assertEquals("test1.MakeClass", cc.getName()); + assertEquals(cc, sloader.get(cc.getName())); + cc.toBytecode(); + assertTrue(cc.isFrozen()); + try { + cc = sloader.makeClass( + new FileInputStream(PATH + "test1/MakeClass.class")); + assertTrue(false); + } + catch (RuntimeException e) { + print(e.getMessage()); + } + } + + public void testMakeMethod() throws Exception { + CtClass cc = sloader.makeClass("test1.MakeMethod"); + cc.addField(new CtField(CtClass.intType, "i", cc)); + String cons_body = "{ i = 3; }"; + CtConstructor cons = CtNewConstructor.make(null, null, + cons_body, cc); + cc.addConstructor(cons); + CtMethod m = CtNewMethod.make(CtClass.intType, "run", null, null, + "{ return i; }", cc); + cc.addMethod(m); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(3, invoke(obj, "run")); + } + + public void testDesc() throws Exception { + Class[] sig; + + assertEquals(int.class, Desc.getType("I")); + assertEquals(String.class, Desc.getType("Ljava/lang/String;")); + assertEquals(String[].class, Desc.getType("[Ljava/lang/String;")); + assertEquals(int[].class, Desc.getType("[I")); + + sig = Desc.getParams("()V"); + assertEquals(0, sig.length); + + sig = Desc.getParams("(I)V"); + assertEquals(int.class, sig[0]); + assertEquals(1, sig.length); + + sig = Desc.getParams("(IJ)V"); + assertEquals(long.class, sig[1]); + assertEquals(2, sig.length); + + sig = Desc.getParams("(Ljava/lang/String;)V"); + assertEquals(String.class, sig[0]); + assertEquals(1, sig.length); + + sig = Desc.getParams("([Ljava/lang/String;I)V"); + assertEquals(String[].class, sig[0]); + assertEquals(2, sig.length); + + sig = Desc.getParams("(Ljava/lang/String;[Ljava/lang/String;)V"); + assertEquals(String[].class, sig[1]); + assertEquals(2, sig.length); + } + + public void testCast() throws Exception { + CtClass cc = sloader.makeClass("test1.CastTest"); + + StringBuffer src = new StringBuffer(); + src.append("public void test(java.lang.String[] strValues)\n"); + src.append("{\n"); + src.append("\tObject[] values = new Object[2];"); + src.append("\tvalues[0] = strValues;"); + src.append("\tvalues[1] = strValues;"); + src.append("\tstrValues = (String[])values[0];"); + src.append("}\n"); + + CtMethod m = CtNewMethod.make(src.toString(), cc); + } + + static final long svUID = 6006955401253799668L; + + public void testSerialVUID() throws Exception { + CtClass cc = sloader.get("test1.MySerializableClass"); + assertEquals(svUID, SerialVersionUID.calculateDefault(cc)); + SerialVersionUID.setSerialVersionUID(cc); + cc.writeFile(); + } + + public void testInvokeInt() throws Exception { + CtClass cc = sloader.get("test1.InvokeInt"); + CtMethod m1 = cc.getDeclaredMethod("check"); + + m1.instrument(new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + m.replace("$_ = $proceed($$) + k(1);"); + } + }); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(6, invoke(obj, "run")); + } + + public void testSubtypeOf() throws Exception { + testSubtypeOf2("java.lang.Object", "int", false); + testSubtypeOf2("int[]", "java.lang.Object", true); + testSubtypeOf2("int[]", "java.lang.Cloneable", true); + testSubtypeOf2("java.lang.Object", "int[]", false); + testSubtypeOf2("java.lang.Integer", "java.lang.Number", true); + testSubtypeOf2("java.lang.Number", "java.lang.Integer", false); + testSubtypeOf2("java.lang.Integer[]", "java.lang.Number[]", true); + testSubtypeOf2("java.lang.Number[]", "java.lang.Integer[]", false); + testSubtypeOf2("java.lang.Integer", "java.io.Serializable", true); + testSubtypeOf2("java.lang.Integer", "java.lang.Object", true); + } + + private void testSubtypeOf2(String s, String t, boolean b) + throws Exception + { + assertTrue(sloader.get(s).subtypeOf(sloader.get(t)) == b); + } + + public void testMakeInterface() throws Exception { + CtClass cc = sloader.makeInterface("test1.MkInterface"); + CtMethod m = CtNewMethod.make("public abstract void ready();", cc); + cc.addMethod(m); + cc.writeFile(); + // cloader.loadClass(cc.getName()); + java.io.File genDir = new java.io.File("."); + java.net.URLClassLoader ucl = new java.net.URLClassLoader( + new java.net.URL[] { genDir.toURL() }, null); + Class intf = ucl.loadClass("test1.MkInterface"); + } + + public void testCodeConv() throws Exception { + CtClass cc = sloader.get("test1.CodeConv"); + CtClass pc = sloader.get("test1.CodeConvP"); + + CodeConverter conv = new CodeConverter(); + conv.replaceFieldRead(pc.getDeclaredField("a1"), cc, "getA1"); + conv.replaceFieldRead(pc.getDeclaredField("a2"), cc, "getA2"); + conv.redirectFieldAccess(pc.getDeclaredField("a3"), cc, "a4"); + conv.replaceFieldWrite(pc.getDeclaredField("b1"), cc, "putB1"); + + cc.instrument(conv); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(51, invoke(obj, "run")); + } + + public void testTryCatch() throws Exception { + CtClass cc = sloader.get("test1.TryCatch"); + CtMethod m1 = cc.getDeclaredMethod("m1"); + + m1.instrument(new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + m.replace( + "try { doit(); }" + + "catch(NullPointerException e){ init(); doit(); }"); + } + }); + + final String src = + "try { doit(); }" + + "catch(NullPointerException e){ init(); doit(); return a; }"; + + CtMethod p1 = cc.getDeclaredMethod("p1"); + p1.insertAfter(src, true); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(4, invoke(obj, "run")); + Object obj2 = make(cc.getName()); + assertEquals(4, invoke(obj2, "p1")); + } + + private CtClass[] throwablesList = null; + + public void testGetThrowables() throws Exception { + CtClass cc = sloader.get("test1.GetThrowables"); + CtMethod m1 = cc.getDeclaredMethod("run"); + m1.instrument(new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + throwablesList = m.mayThrow(); + } + }); + + System.out.println(throwablesList[0].getName()); + System.out.println(throwablesList[1].getName()); + assertEquals(2, throwablesList.length); + } + + public void testArrayAccess() throws Exception { + CtClass cc = sloader.get("test1.ArrayAccess"); + CtMethod m1 = cc.getDeclaredMethod("test"); + m1.insertBefore("{ ia[0] += 1; iaa[1] = iaa[0]; }"); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(8, invoke(obj, "test")); + } + + public void testClinit() throws Exception { + CtClass cc = sloader.get("test1.Clinit"); + CtConstructor clinit = cc.getClassInitializer(); + assertTrue(clinit != null); + try { + clinit.insertBeforeBody(";"); + assertTrue(false); + } + catch (CannotCompileException e) { + print(e.toString()); + assertEquals("class initializer", e.getReason()); + } + + CtConstructor[] init = cc.getConstructors(); + assertEquals(1, init.length); + clinit.insertAfter("j += 1;"); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(457, invoke(obj, "run")); + } + + public void testClinit2() throws Exception { + CtClass cc = sloader.get("test1.Clinit2"); + CtConstructor clinit = cc.makeClassInitializer(); + clinit.insertAfter("j = 7;"); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(7, invoke(obj, "run")); + } + + // by yamazaki + public void testCondExpr() throws Exception { + CtClass cc = sloader.makeClass("test1.CondExpr"); + CtMethod methodM = new CtMethod(CtClass.intType, "m", + new CtClass[]{ CtClass.intType }, cc); + methodM.setModifiers(methodM.getModifiers() | Modifier.STATIC); + methodM.setBody("{if($1 <= 0) return 1; else return 0;}"); + cc.addMethod(methodM); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(0, invoke(obj, "m", 3)); + } + + // by yamazaki + public void testCondExpr2() throws Exception { + CtClass cc = sloader.makeClass("test1.CondExpr2"); + CtMethod methodM = new CtMethod(CtClass.intType, "m", + new CtClass[]{ CtClass.intType }, cc); + methodM.setModifiers(methodM.getModifiers() | Modifier.STATIC); + methodM.setBody("{return ($1 <= 0) ? 1 : (m($1 - 1) * $1);}"); + cc.addMethod(methodM); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(6, invoke(obj, "m", 3)); + } + + // by yamazaki + public void testCondExpr3() throws Exception { + CtClass cc = sloader.makeClass("test1.CondExpr3"); + + CtMethod methodM = CtNewMethod.make( + "public abstract int m(int i);", cc); + CtMethod methodN = CtNewMethod.make( + "public abstract int n(int i);", cc); + cc.addMethod(methodM); + cc.addMethod(methodN); + + methodM.setBody("{return ($1 <= 0) ? 1 : (n($1 - 1) * $1);}"); + methodN.setBody("{return m($1);}"); + + cc.setModifiers(cc.getModifiers() & ~Modifier.ABSTRACT); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(6, invoke(obj, "m", 3)); + } + + public void testDelegator() throws Exception { + CtClass cc = sloader.get("test1.Delegator"); + + assertEquals("test1.SuperDelegator", cc.getSuperclass().getName()); + + CtMethod f = sloader.getMethod("test1.SuperDelegator", "f"); + CtMethod g = sloader.getMethod("test1.SuperDelegator", "g"); + + cc.addMethod(CtNewMethod.delegator(f, cc)); + cc.addMethod(CtNewMethod.delegator(g, cc)); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(15, invoke(obj, "run")); + } + + public void testSetName() throws Exception { + CtClass cc = sloader.get("test1.SetName"); + CtMethod m0 = cc.getDeclaredMethod("foo"); + cc.setName("test1.SetName2"); + assertEquals(cc, sloader.get("test1.SetName2")); + assertEquals("foo(Ltest1/SetName2;)", m0.getStringRep()); + CtClass cc2 = sloader.makeClass("test1.SetName3"); + CtMethod m = CtNewMethod.make( + "public int m(test1.SetName2 obj) { return ((test1.SetName2)obj).i; }", + cc2); + cc2.addMethod(m); + cc.writeFile(); + cc2.writeFile(); + } + + public void testFieldModifier() throws Exception { + CtClass cc = sloader.get("test1.FieldMod"); + CtField f = cc.getField("text"); + f.setModifiers(Modifier.PUBLIC); + f = cc.getField("i"); + f.setName("j"); + cc.writeFile(); + + Object obj = make(cc.getName()); + assertEquals(java.lang.reflect.Modifier.PUBLIC, + obj.getClass().getField("text").getModifiers()); + assertTrue(obj.getClass().getField("j") != null); + } + + public void testToString() throws Exception { + System.out.println(sloader.get("test1.FieldMod")); + System.out.println(sloader.get("java.lang.Object")); + } + + public void testPackage() throws Exception { + Object obj = new Loader().loadClass("test1.Pac").newInstance(); + assertEquals(1, invoke(obj, "run")); + } + + public void testHoward() throws Exception { + String head = + "public Object lookup() throws java.rmi.RemoteException "; + String src = + "{ if (_remote != null) return _remote;" + + " test1.HowardHome h = (test1.HowardHome)lookup(\"Howard\");" + + " try { _remote = h.create(); }" + + " catch (java.io.IOException e) { throw new java.rmi.RemoteException(e.getMessage(), e); }" + + " return _remote; }"; + + String src2 = + "public void lookup2() {" + + " try {}" + + " catch (java.io.IOException e) { throw new Exception(e); }" + + "}"; + + CtClass cc = sloader.get("test1.Howard"); + CtMethod m = CtNewMethod.make(head + src, cc); + cc.addMethod(m); + try { + CtMethod m2 = CtNewMethod.make(src2, cc); + cc.addMethod(m2); + assertTrue(false); + } + catch (CannotCompileException e) {} + + m = new CtMethod(sloader.get("java.lang.Object"), + "lookup3", null, cc); + m.setBody(src); + m.setModifiers(Modifier.PUBLIC); + m.setExceptionTypes(new CtClass[] { + sloader.get("java.rmi.RemoteException") }); + cc.addMethod(m); + + cc.writeFile(); + Object target = make(cc.getName()); + Method mth = target.getClass().getMethod("lookup", new Class[0]); + Object res = mth.invoke(target, new Object[0]); + assertEquals("howard4", res); + + mth = target.getClass().getMethod("lookup3", new Class[0]); + res = mth.invoke(target, new Object[0]); + assertEquals("howard4", res); + } + + public void testLoop() throws Exception { + CtClass cc = sloader.makeClass("test1.Loop"); + CtMethod m = CtNewMethod.make( + "public int run(int i) { int k = 0;" + + "while (true) { if (k++ > 10) return i; } }", + cc); + cc.addMethod(m); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(3, invoke(obj, "run", 3)); + } + + public static Test suite() { + TestSuite suite = new TestSuite("Javassist Tests"); + suite.addTestSuite(JvstTest.class); + suite.addTestSuite(JvstTest2.class); + suite.addTestSuite(JvstTest3.class); + suite.addTestSuite(JvstTest4.class); + suite.addTestSuite(LoaderTestByRandall.class); + suite.addTestSuite(javassist.bytecode.BytecodeTest.class); + // suite.addTestSuite(javassist.bytecode.StackMapTest.class); + suite.addTestSuite(javassist.compiler.CompTest.class); + suite.addTestSuite(javassist.SetterTest.class); + suite.addTestSuite(javassist.bytecode.InsertGap0.class); + suite.addTestSuite(javassist.tools.reflect.LoaderTest.class); + suite.addTestSuite(testproxy.ProxyTester.class); + // suite.addTestSuite(testproxy.ProxyFactoryPerformanceTest.class); + suite.addTestSuite(javassist.proxyfactory.ProxyFactoryTest.class); + return suite; + } +} diff --git a/src/test/javassist/JvstTest2.java b/src/test/javassist/JvstTest2.java new file mode 100644 index 00000000..7a9d398a --- /dev/null +++ b/src/test/javassist/JvstTest2.java @@ -0,0 +1,1502 @@ +package javassist; + +import java.io.*; +import java.net.URL; +import java.lang.reflect.Method; +import javassist.expr.*; + +public class JvstTest2 extends JvstTestRoot { + public JvstTest2(String name) { + super(name); + } + + public void testInsertAt() throws Exception { + CtClass cc = sloader.get("test2.InsertAt"); + CtMethod m1 = cc.getDeclaredMethod("foo"); + int line = 6; + int ln = m1.insertAt(line, false, null); + int ln2 = m1.insertAt(line, "counter++;"); + assertEquals(ln, ln2); + assertEquals(7, ln2); + + line = 8; + ln = m1.insertAt(line, false, null); + ln2 = m1.insertAt(line, "counter++;"); + assertEquals(ln, ln2); + assertEquals(8, ln2); + + CtMethod m2 = cc.getDeclaredMethod("bar2"); + int ln3 = m2.insertAt(20, "{ int m = 13; j += m; }"); + assertEquals(20, ln3); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(7, invoke(obj, "foo")); + assertEquals(25, invoke(obj, "bar")); + } + + public void testInsertLocal() throws Exception { + CtClass cc = sloader.get("test2.InsertLocal"); + CtMethod m1 = cc.getDeclaredMethod("foo"); + m1.insertBefore("{ i = s.length(); d = 0.14; }"); + m1.insertAfter("{ field = i; }"); + + CtMethod m2 = cc.getDeclaredMethod("run2"); + m2.insertAt(22, "{ s = \"12\"; k = 5; }"); + + CtMethod m3 = cc.getDeclaredMethod("run3"); + m3.instrument(new ExprEditor() { + public void edit(NewExpr n) throws CannotCompileException { + n.replace("{ i++; $_ = $proceed($$); }"); + } + public void edit(FieldAccess f) throws CannotCompileException { + f.replace("{ i++; $_ = $proceed($$); }"); + } + public void edit(MethodCall m) throws CannotCompileException { + m.replace("{ i++; $_ = $proceed($$); }"); + } + }); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(317, invoke(obj, "run")); + assertEquals(7, invoke(obj, "run2")); + assertEquals(3, invoke(obj, "run3")); + } + + public void testStaticMember() throws Exception { + CtClass cc = sloader.get("test2.StaticMember"); + CtMethod m = CtNewMethod.make( + "public int run() {" + + "return test2.StaticMember#k + test2.StaticMember#foo(); }", cc); + cc.addMethod(m); + + m = CtNewMethod.make( + "public int run2() {" + + "return k + foo(); }", cc); + cc.addMethod(m); + + m = CtNewMethod.make( + "public int run3() {" + + " test2.StaticMember sm = this;" + + " return sm.k + sm.foo(); }", cc); + cc.addMethod(m); + + m = CtNewMethod.make( + "public int run4() {" + + " return this.k + this.foo(); }", cc); + cc.addMethod(m); + + m = CtNewMethod.make( + "public static int run5() {" + + " return k + foo(); }", cc); + cc.addMethod(m); + + m = CtNewMethod.make( + "public int run6() {" + + " test2.IStaticMember i = this; return i.bar(); }", cc); + cc.addMethod(m); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(10, invoke(obj, "run")); + assertEquals(10, invoke(obj, "run2")); + assertEquals(10, invoke(obj, "run3")); + assertEquals(10, invoke(obj, "run4")); + assertEquals(10, invoke(obj, "run5")); + assertEquals(3, invoke(obj, "run6")); + } + + public void testStaticMember2() throws Exception { + CtClass cc = sloader.get("test2.StaticMember2"); + + cc.addMethod(CtNewMethod.make( + "public int run() {" + + " return test2.StaticMember2.k + test2.StaticMember2.seven()" + + " + (test2.StaticMember2.f + f)" + + " + test2.StaticMember2.f + f; }", + cc)); + + cc.addMethod(CtNewMethod.make( + "public int run1() {" + + " long j = 1L;" + + " return (int)(j + (test2.StaticMember2.fj + fj)" + + " + test2.StaticMember2.fj + fj); }", + cc)); + + cc.addMethod(CtNewMethod.make( + "public int run2() {" + + " double x = 1.0;" + + " double d = x + test2.StaticMember2.fd + fd" + + " + (test2.StaticMember2.fd + fd);" + + " return (int)(d * 10); }", + cc)); + + cc.addMethod(CtNewMethod.make( + "public int run3() {" + + " return (test2.StaticMember2.fb & fb) ? 1 : 0; }", + cc)); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(54, invoke(obj, "run")); + assertEquals(53, invoke(obj, "run1")); + assertEquals(958, invoke(obj, "run2")); + assertEquals(0, invoke(obj, "run3")); + } + + public void testSuperCall() throws Exception { + CtClass cc = sloader.get("test2.SuperCall"); + CtMethod m1 = cc.getDeclaredMethod("foo"); + m1.instrument(new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + m.replace("{ $_ = $proceed($$); }"); + } + }); + cc.writeFile(); + Object obj = make(cc.getName()); + invoke(obj, "bar"); + } + + public void testSetSuper() throws Exception { + CtClass cc = sloader.makeClass("test2.SetSuper"); + CtClass cc2 = sloader.makeClass("test2.SetSuperParent"); + CtClass intf = sloader.makeInterface("test2.SetSuperIntf"); + CtClass remote = sloader.get("java.rmi.Remote"); + + cc.setSuperclass(cc2); + cc.setInterfaces(new CtClass[] { intf }); + intf.setSuperclass(remote); + intf.writeFile(); + cc2.writeFile(); + cc.writeFile(); + + assertEquals(cc2, cc.getSuperclass()); + assertEquals(intf, cc.getInterfaces()[0]); + assertEquals(sloader.get("java.lang.Object"), intf.getSuperclass()); + assertEquals(remote, intf.getInterfaces()[0]); + + make(cc.getName()); + } + + public void testReplaceClassName() throws Exception { + String oldName = "test2.ReplaceClassName2"; + String newName = "test2.ReplaceClassName3"; + CtClass cc = sloader.get("test2.ReplaceClassName"); + cc.replaceClassName(oldName, newName); + cc.writeFile(); + CtClass cc2 = dloader.get(cc.getName()); + CtMethod m = cc2.getDeclaredMethod("foo"); + assertEquals(newName, m.getParameterTypes()[0].getName()); + } + + public void testCodeGen() throws Exception { + CtClass cc = sloader.get("test2.CodeGen"); + CtMethod m1 = cc.getDeclaredMethod("run"); + m1.insertBefore( + "{ double d = true ? 1 : 0.1; " + + " d = d > 0.5 ? 0.0 : - 1.0; " + + " System.out.println(d); " + + " String s = \"foo\"; " + + " s = 1 + 2 + s + \"bar\"; " + + " s += \"poi\" + 3 + seven() + seven(\":\" + ' '); " + + " s += .14; " + + " msg = s; " + + " System.out.println(s); }"); + + // recursive type check is done if $proceed is used. + CtMethod m2 = CtNewMethod.make( + "public int test() {" + + " String s = $proceed(\"int\" + (3 + 0.14)) + '.'; " + + " System.out.println(s); return s.length(); }", + cc, "this", "seven"); + cc.addMethod(m2); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(19, invoke(obj, "run")); + assertEquals(9, invoke(obj, "test")); + } + + public void testCodeGen2() throws Exception { + CtClass cc = sloader.makeClass("test2.CodeGen2"); + + CtMethod m1 = CtNewMethod.make( + "public int test() {" + + " int len;" + + " String s = \"foo\" + \"bar\" + 3;" + + " System.out.println(s); len = s.length();" + + " len = -3 + len; len = len - (7 - 2 + -1);" + + " int k = 3; len += ~k - ~3;" + + " return len; }", + cc); + cc.addMethod(m1); + + CtMethod m2 = CtNewMethod.make( + "public int test2() {" + + " double d = 0.2 - -0.1;" + + " d += (0.2 + 0.3) * 1.0;" + + " return (int)(d * 10); }", + cc); + cc.addMethod(m2); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(0, invoke(obj, "test")); + assertEquals(8, invoke(obj, "test2")); + } + + // not used anymore. + private void notTestGetInner() throws Exception { + ClassPool pool = ClassPool.getDefault(); + CtClass c = pool.get("javassist.CtMethod.ConstParameter"); + CtClass d = pool.get("javassist.CtMethod.ConstParameter"); + CtClass e = pool.get("javassist.CtMethod$ConstParameter"); + assertSame(c, d); + assertSame(c, e); + try { + c = pool.get("test2.Inner.Fake"); + fail("found not-existing class"); + } + catch (NotFoundException ex) {} + } + + public void testInner() throws Exception { + ClassPool pool = ClassPool.getDefault(); + String classname = "test2.Inner"; + CtClass target = pool.get(classname); + String src = + "public void sampleMethod() throws Exception {" + + "java.util.Properties props = new java.util.Properties();" + + "java.rmi.activation.ActivationGroupDesc.CommandEnvironment ace " + + " = null;" + + "java.rmi.activation.ActivationGroupDesc agd " + + " = new java.rmi.activation.ActivationGroupDesc(props,ace);}"; + CtMethod newmethod = CtNewMethod.make(src, target); + target.addMethod(newmethod); + + String src2 = + "public java.lang.Character.Subset sampleMethod2() {" + + " java.lang.Character.Subset s " + + " = Character.UnicodeBlock.HIRAGANA; " + + " return s; }"; + CtMethod newmethod2 = CtNewMethod.make(src2, target); + target.addMethod(newmethod2); + + target.writeFile(); + } + + public void testURL() throws Exception { + String url; + + ClassPool cp = new ClassPool(null); + cp.appendSystemPath(); + + url = cp.find("java.lang.Object").toString(); + System.out.println(url); + assertTrue(url.startsWith("jar:file:")); + assertTrue(url.endsWith(".jar!/java/lang/Object.class")); + + assertNull(cp.find("class.not.Exist")); + + cp = new ClassPool(null); + cp.insertClassPath("."); + + url = cp.find("test2.Inner").toString(); + System.out.println(url); + assertTrue(url.startsWith("file:/")); + assertTrue(url.endsWith("/test2/Inner.class")); + + assertNull(cp.find("test2.TestURL")); + + cp = new ClassPool(null); + cp.insertClassPath(JAR_PATH + "javassist.jar"); + + url = cp.find("javassist.CtClass").toString(); + System.out.println(url); + assertTrue(url.startsWith("jar:file:")); + assertTrue(url.endsWith("javassist.jar!/javassist/CtClass.class")); + + assertNull(cp.find("javassist.TestURL")); + + cp = new ClassPool(null); + cp.insertClassPath(new LoaderClassPath(cloader)); + + url = cp.find("javassist.CtMethod").toString(); + System.out.println(url); + // assertTrue(url.startsWith("jar:file:")); + // assertTrue(url.endsWith("javassist.jar!/javassist/CtMethod.class")); + + assertNull(cp.find("javassist.TestURL")); + + cp = new ClassPool(null); + cp.insertClassPath(new ByteArrayClassPath("test2.ByteArray", null)); + + url = cp.find("test2.ByteArray").toString(); + System.out.println(url); + assertTrue( + url.equals("file:/ByteArrayClassPath/test2/ByteArray.class")); + + assertNull(cp.find("test2.TestURL")); + } + + public void not_testURLClassPath() throws Exception { + String host = "www.csg.is.titech.ac.jp"; + String path = "/~chiba/tmp/"; + String url; + + ClassPool cp = new ClassPool(null); + cp.insertClassPath(new URLClassPath(host, 80, path, "test")); + + url = cp.find("test.TestClassPath").toString(); + System.out.println(url); + assertEquals("http://" + host + ":80" + path + + "test/TestClassPath.class", url); + + assertNull(cp.find("test.No")); + } + + public void testGetURL() throws Exception { + CtClass cc = sloader.get("java.lang.String"); + String url = cc.getURL().toString(); + System.out.println(url); + assertTrue(url.startsWith("jar:file:")); + assertTrue(url.endsWith(".jar!/java/lang/String.class")); + + cc = sloader.get("int"); + try { + URL u = cc.getURL(); + fail(); + } + catch (NotFoundException e) { + assertEquals("int", e.getMessage()); + } + } + + public void testInheritance() throws Exception { + ClassPool pool = ClassPool.getDefault(); + String classname = "test2.Inherit"; + CtClass target = pool.get(classname); + String src = + "public void sampleMethod() {" + + " test2.Inherit i = new test2.Inherit();" + + " test2.Inherit2 i2 = i;" + + " test2.Inherit3 i3 = i;" + + " i3.foo2(); i3.foo2(); i2.foo1(); }"; + + CtMethod newmethod = CtNewMethod.make(src, target); + target.addMethod(newmethod); + target.writeFile(); + } + + public void testIncOp() throws Exception { + CtClass target = sloader.makeClass("test2.IncOp"); + String src = + "public int sample() {" + + " int ia[] = new int[50];" + + " ia[0] = 1;" + + " int v = ++(ia[0]);" + + " return v; }"; + + CtMethod newmethod = CtNewMethod.make(src, target); + target.addMethod(newmethod); + target.writeFile(); + Object obj = make(target.getName()); + assertEquals(2, invoke(obj, "sample")); + } + + public void testSetExceptions() throws Exception { + CtClass cc = sloader.get("test2.SetExceptions"); + CtMethod m = cc.getDeclaredMethod("f"); + CtClass ex = m.getExceptionTypes()[0]; + assertEquals("java.lang.Exception", ex.getName()); + m.setExceptionTypes(null); + assertEquals(0, m.getExceptionTypes().length); + m.setExceptionTypes(new CtClass[0]); + assertEquals(0, m.getExceptionTypes().length); + m.setExceptionTypes(new CtClass[] { ex }); + assertEquals(ex, m.getExceptionTypes()[0]); + } + + public void testNullArg() throws Exception { + CtClass cc = sloader.makeClass("test2.NullArgTest"); + CtMethod m1 = CtNewMethod.make( + "public Object foo(Object[] obj, int idx) throws Throwable {" + + " return null; }", cc); + cc.addMethod(m1); + CtMethod m2 = CtNewMethod.make( + "public void bar() { this.foo(null, 0); }", cc); + cc.addMethod(m2); + CtMethod m3 = CtNewMethod.make( + "public void bar2() { this.foo((Object[])null, 0); }", cc); + cc.addMethod(m3); + cc.writeFile(); + } + + public void testAddMethod() throws Exception { + CtClass cc = sloader.get("test2.AddMethod"); + CtMethod m = CtNewMethod.make( + "public void f() { return 1; }", cc); + try { + cc.addMethod(m); + fail(); + } + catch (CannotCompileException e) {} + CtMethod m2 = CtNewMethod.make( + "public void f(int i, int j) { return 1; }", cc); + cc.addMethod(m2); + try { + cc.addField(new CtField(CtClass.longType, "f", cc)); + fail(); + } + catch (CannotCompileException e) {} + } + + public void testCopyStream() throws Exception { + int[] size = { 100, 4096, 8000, 1023, 1024, 1025, 2047, + 4096*3, 4096*6, 4096*6-1, 4096*256*3, 4096*256*6 }; + for (int i = 0; i < size.length; i++) { + byte[] data = new byte[size[i]]; + for (int j = 0; j < data.length; j++) + data[j] = (byte)j; + + InputStream ins = new ByteArrayInputStream(data); + ByteArrayOutputStream outs = new ByteArrayOutputStream(); + ClassPoolTail.copyStream(ins, outs); + byte[] data2 = outs.toByteArray(); + if (data2.length != data.length) + throw new Exception("bad size"); + + for (int k = 0; k < data.length; k++) + if (data[k] != data2[k]) + throw new Exception("bad element"); + } + } + + public void testDeclaringClass() throws Exception { + try { + CtClass cc = sloader.get("test2.NotExistingClass"); + } + catch (NotFoundException e) { System.out.println(e); } + CtClass inner = sloader.get("test2.Nested$Inner"); + CtClass outer = sloader.get("test2.Nested"); + assertEquals(outer, inner.getDeclaringClass()); + assertEquals(null, outer.getDeclaringClass()); + assertEquals(null, CtClass.intType.getDeclaringClass()); + + CtClass inner3 = sloader.get("test2.Nested$Inner3"); + outer.writeFile(); + try { + CtMethod m = CtNewMethod.make( + "public void f(test2.Nested n) { return n.geti(); }", + inner3); + fail(); + } + catch (RuntimeException e) {} + outer.defrost(); + CtMethod m = CtNewMethod.make( + "public int f(test2.Nested n) { " + + "return n.geti() + test2.Nested.getj(1) + f() + g(); } ", + inner3); + inner3.addMethod(m); + inner3.writeFile(); + outer.writeFile(); + + Object nobj = make(outer.getName()); + Object iobj = make(inner3.getName()); + Method mth = iobj.getClass().getMethod("f", + new Class[] { nobj.getClass() }); + Object resobj = mth.invoke(iobj, new Object[] { nobj }); + int res = ((Integer) resobj).intValue(); + assertEquals(6, res); + } + + public void testDeclaringClass2() throws Exception { + CtClass out = sloader.get("test2.Anon"); + CtClass inner = sloader.get("test2.Anon$1"); + if (System.getProperty("java.vm.version").startsWith("1.4")) + assertTrue(inner.getEnclosingMethod() == null); + else { + assertEquals("make", inner.getEnclosingMethod().getName()); + assertEquals(out, inner.getDeclaringClass()); + assertEquals(out, + inner.getEnclosingMethod().getDeclaringClass()); + } + } + + public void testMethodInInner() throws Exception { + CtClass inner = sloader.get("test2.Nested2$Inner"); + CtClass outer = sloader.get("test2.Nested2"); + String src = + "public int f(test2.Nested2 n) {" + + " n.i = 1; n.i++; n.i += 2; return n.i; }"; + + outer.writeFile(); + try { + CtMethod m = CtNewMethod.make(src, inner); + fail(); + } + catch (RuntimeException e) {} + outer.defrost(); + + CtMethod m = CtNewMethod.make(src, inner); + inner.addMethod(m); + + src = "public int g(test2.Nested2 n) {" + + " n.d = 1.0; n.d++; n.d += 2.0;" + + " return n.d == 4.0 ? 7 : 8; }"; + m = CtNewMethod.make(src, inner); + inner.addMethod(m); + + src = "public int h(test2.Nested2 n) {" + + " n.s = \"poi\";" + + "return n.s.length() + f(n) + g(n); }"; + m = CtNewMethod.make(src, inner); + inner.addMethod(m); + + inner.writeFile(); + outer.writeFile(); + + Object nobj = make(outer.getName()); + Object iobj = make(inner.getName()); + Method mth = iobj.getClass().getMethod("h", + new Class[] { nobj.getClass() }); + Object resobj = mth.invoke(iobj, new Object[] { nobj }); + int res = ((Integer) resobj).intValue(); + assertEquals(14, res); + } + + public void testMethodInInner2() throws Exception { + CtClass inner = sloader.get("test2.Nested3$Inner"); + CtClass outer = sloader.get("test2.Nested3"); + String src = + "public int f() {" + + " int k = 0;" + + " test2.Nested3 n = new test2.Nested3(3);" + + " k += n.geti();" + + " n = new test2.Nested3();" + + " k += n.geti();" + + " n = new test2.Nested3(\"foo\");" + + " k += n.geti();" + + " return k; }"; + + outer.stopPruning(true); + outer.writeFile(); + try { + CtMethod m = CtNewMethod.make(src, inner); + fail(); + } + catch (RuntimeException e) {} + outer.defrost(); + + CtMethod m = CtNewMethod.make(src, inner); + inner.addMethod(m); + + inner.writeFile(); + outer.writeFile(); + + Object iobj = make(inner.getName()); + assertEquals(6, invoke(iobj, "f")); + } + + public void testMakeNestedClass() throws Exception { + CtClass outer = sloader.get("test2.Nested4"); + try { + CtClass inner = outer.makeNestedClass("Inner", false); + fail(); + } + catch (RuntimeException e) { + print(e.getMessage()); + } + + CtClass nested = outer.makeNestedClass("Inner", true); + outer.stopPruning(true); + outer.writeFile(); + outer.defrost(); + String src = + "public int f() { return test2.Nested4.value; }"; + + CtMethod m = CtNewMethod.make(src, nested); + nested.addMethod(m); + nested.writeFile(); + outer.writeFile(); + + Object iobj = make(nested.getName()); + assertEquals(6, invoke(iobj, "f")); + } + + public void testPrivateMethod() throws Exception { + CtClass cc = sloader.get("test2.PrivateMethod"); + try { + CtMethod m = CtNewMethod.make( + "public int f(test2.PrivateMethod2 p) { return p.f(); }", + cc); + fail(); + } + catch (CannotCompileException e) {} + } + + public void testArrayLength() throws Exception { + CtClass cc = sloader.makeClass("test2.ArrayLength"); + CtMethod m2 = CtNewMethod.make( + "public int f() { String[] s = new String[3]; " + + "return s.length; }", cc); + cc.addMethod(m2); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(3, invoke(obj, "f")); + } + + public void testMakeStaticMethod() throws Exception { + CtClass cc = sloader.makeClass("test2.MakeStaticMethod"); + CtMethod m = CtNewMethod.make(Modifier.PUBLIC | Modifier.STATIC, + CtClass.intType, "create", + new CtClass[] { CtClass.intType }, null, + "{ return $1; }", cc); + cc.addMethod(m); + cc.addMethod(CtNewMethod.make( + "public int test() { return create(13); }", cc)); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(13, invoke(obj, "test")); + } + + public void testNewExprTry() throws Exception { + ExprEditor ed = new ExprEditor() { + public void edit(NewExpr expr) throws CannotCompileException { + StringBuffer code = new StringBuffer(300); + code.append("{ try "); + code.append("{ $_ = $proceed($$); }"); + code.append("catch (OutOfMemoryError e) {}}"); + expr.replace(code.toString()); + } + }; + + CtClass cc = sloader.get("test2.NewExprTry"); + CtMethod m1 = cc.getDeclaredMethod("foo"); + m1.instrument(ed); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(16, invoke(obj, "run")); + } + + public void testToClass() throws Exception { + ClassPool cp = ClassPool.getDefault(); + CtClass cc = cp.makeClass("test2.ToClassTest"); + Class c = cc.toClass(); + assertEquals(getClass().getClassLoader(), c.getClassLoader()); + } + + public void testAddCatchForConstructor() throws Exception { + CtClass cc = sloader.get("test2.AddCatchForConstructor"); + CtConstructor m1 = cc.getDeclaredConstructors()[0]; + m1.addCatch("return;", sloader.get("java.lang.Exception")); + cc.writeFile(); + Object obj = make(cc.getName()); + } + + public void testAddLocalVar() throws Exception { + CtClass cc = sloader.get("test2.AddLocalVar"); + CtMethod m1 = cc.getDeclaredMethod("foo"); + m1.addLocalVariable("i", CtClass.intType); + m1.insertBefore("i = 3;"); + m1.insertAfter("$_ = i + 1;"); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(4, invoke(obj, "foo")); + } + + public void testNewArray() throws Exception { + ExprEditor ed = new ExprEditor() { + int dim[] = { 1, 2, 2, 1, 2, 2, 3 }; + int cdim[] = { 1, 1, 2, 1, 1, 2, 2 }; + int counter = 0; + public void edit(NewArray expr) throws CannotCompileException { + try { + CtClass str = sloader.get("java.lang.String"); + if (counter < 3) + assertEquals(str, expr.getComponentType()); + else + assertEquals(CtClass.intType, expr.getComponentType()); + + assertEquals(dim[counter], expr.getDimension()); + assertEquals(cdim[counter], expr.getCreatedDimensions()); + expr.replace("{ i += $1; $_ = $proceed($$); }"); + ++counter; + } + catch (NotFoundException e) { + throw new CannotCompileException(e); + } + } + }; + + CtClass cc = sloader.get("test2.NewArray"); + CtMethod m1 = cc.getDeclaredMethod("foo"); + m1.instrument(ed); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(48, invoke(obj, "run")); + } + + public void testToString() throws Exception { + System.out.println(sloader.get("int")); + System.out.println(sloader.get("int[]")); + System.out.println(sloader.get("java.lang.Object")); + System.out.println(sloader.get("java.lang.String")); + System.out.println(sloader.get("javassist.CtNewClass")); + } + + public void testDotClass() throws Exception { + testDotClass("test2.DotClass", false); + testDotClass("test2.DotClass_", true); + } + + private void testDotClass(String cname, boolean java5) throws Exception { + CtClass cc = sloader.makeClass(cname); + if (java5) + cc.getClassFile2().setVersionToJava5(); + + CtMethod m = CtNewMethod.make( + "public String getclass() {" + + " return int.class.getName() + int[].class.getName()" + + " + String.class.getName() + String[].class.getName()" + + " + java.lang.Object.class.getName()" + + " + java.util.Vector.class.getName(); }", cc); + cc.addMethod(m); + CtMethod m2 = CtNewMethod.make( + "public int test() {" + + " String s = getclass(); System.out.println(s);" + + " return s.length(); }", cc); + cc.addMethod(m2); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(72, invoke(obj, "test")); + } + + public void testDotClass2() throws Exception { + testDotClass2("test2.DotClass2", false); + testDotClass2("test2.DotClass2_", true); + } + + private void testDotClass2(String cname, boolean java5) throws Exception { + CtClass cc = sloader.makeClass(cname); + CtClass cc3 = sloader.makeClass("test2.DotClass3"); + if (java5) + cc.getClassFile2().setVersionToJava5(); + + CtMethod m = CtNewMethod.make( + "public int test() {" + + " return test2.DotClass3.class.getName().length(); }", cc); + cc.addMethod(m); + cc.writeFile(); + // don't execute cc3.writeFile(); + Object obj = make(cc.getName()); + try { + assertEquals(15, invoke(obj, "test")); + } + catch (java.lang.reflect.InvocationTargetException e) { + Throwable t = e.getCause(); + assertTrue(t instanceof java.lang.NoClassDefFoundError); + } + } + + public void testDotClass4() throws Exception { + testDotClass4("test2.DotClass4", false); + testDotClass4("test2.DotClass4_", true); + } + + private void testDotClass4(String cname, boolean java5) throws Exception { + CtClass cc = sloader.makeClass(cname); + if (java5) + cc.getClassFile2().setVersionToJava5(); + + CtMethod m = CtNewMethod.make( + "public int test() {" + + " String s = Object.class.getName()" + + " + Object[].class.getName();" + + " return s.length(); }", cc); + cc.addMethod(m); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(35, invoke(obj, "test")); + } + + public void testSuperInterface() throws Exception { + CtClass cc = sloader.makeClass("test2.SuperInterface3"); + CtClass cc2 = sloader.get("test2.SuperInterface2"); + cc.addInterface(cc2); + cc.addField(new CtField(cc2, "inner", cc)); + CtMethod m = CtNewMethod.make( + "public int getAge() { return inner.getAge(); }", cc); + cc.addMethod(m); + cc.writeFile(); + } + + public void testPrune() throws Exception { + CtClass cc = sloader.get("test2.Prune"); + cc.stopPruning(false); + System.out.println(cc); + cc.addField(new CtField(CtClass.intType, "f", cc)); + cc.toBytecode(); + try { + cc.defrost(); + fail("can call defrost()"); + } + catch (RuntimeException e) { + assertTrue(e.getMessage().indexOf("prune") >= 0); + } + + System.out.println(cc); + } + + public void testNewExprInTry() throws Exception { + ExprEditor ed = new ExprEditor() { + public void edit(NewExpr expr) throws CannotCompileException { + expr.replace("$_ = new test2.HashMapWrapper($1, 1);"); + } + }; + + CtClass cc = sloader.get("test2.NewExprInTry"); + CtMethod m1 = cc.getDeclaredMethod("foo"); + m1.instrument(ed); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(1, invoke(obj, "run")); + } + + public void testConstField() throws Exception { + CtClass cc = sloader.get("test2.ConstField"); + CtField f; + f = cc.getField("b"); + assertEquals(true, ((Boolean)f.getConstantValue()).booleanValue()); + f = cc.getField("i"); + assertEquals(3, ((Integer)f.getConstantValue()).intValue()); + f = cc.getField("j"); + assertEquals(7L, ((Long)f.getConstantValue()).longValue()); + f = cc.getField("f"); + assertEquals(8.0F, ((Float)f.getConstantValue()).floatValue(), 0.0); + f = cc.getField("d"); + assertEquals(9.0, ((Double)f.getConstantValue()).doubleValue(), 0.0); + f = cc.getField("s"); + assertEquals("const", f.getConstantValue()); + f = cc.getField("obj"); + assertEquals(null, f.getConstantValue()); + f = cc.getField("integer"); + assertEquals(null, f.getConstantValue()); + f = cc.getField("k"); + assertEquals(null, f.getConstantValue()); + + cc.getClassFile().prune(); + + f = cc.getField("i"); + assertEquals(3, ((Integer)f.getConstantValue()).intValue()); + f = cc.getField("k"); + assertEquals(null, f.getConstantValue()); + } + + public void testWhere() throws Exception { + CtClass cc = sloader.get("test2.Where"); + CtConstructor cons = cc.getClassInitializer(); + cons.instrument(new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + System.out.println(m.where().getName()); + } + }); + + } + + public void testNewOp() throws Exception { + CtClass cc = sloader.get("test2.NewOp"); + + CtMethod add = CtNewMethod.make( +"public test2.NewOp2 " + +" addMonitoringRemoteEventListener(" + +" test2.NewOp2 listener)" + +" throws java.rmi.RemoteException {" + +" $0.listenerList.addElement(listener);" + +" return new test2.NewOp2(0L, this, null, 0L);" + +"}", cc); + + add.setModifiers(Modifier.PUBLIC); + cc.addMethod(add); + /* + CtMethod type= CtNewMethod.make( + "public test2.Where getNewType() { return new test2.Where(); }", + cc); + cc.addMethod(type); + */ + cc.writeFile(); + } + + public void testSwitch() throws Exception { + CtClass cc = sloader.makeClass("test2.Switch"); + + cc.addMethod(CtNewMethod.make( + "public int test1() {" + + " int i = 1;" + + " int j;" + + " switch (i) {" + + " case 0: j = i; break;" + + " case 1: j = -i; break;" + + " default: j = 0; break;" + + " }" + + " return j; }", cc)); + + cc.addMethod(CtNewMethod.make( + "public int test2() {" + + " int i = 2;" + + " int j = 7;" + + " switch (i) {" + + " case 0: j = i; break;" + + " case 1: j = -i; break;" + + " }" + + " return j; }", cc)); + + cc.addMethod(CtNewMethod.make( + "public int test3() {" + + " int i = Byte.MAX_VALUE;" + + " int j;" + + " switch (i) {" + + " case Byte.MAX_VALUE: j = i; break;" + + " case Byte.MIN_VALUE: j = -i; break;" + + " default: j = 0; break;" + + " }" + + " return j; }", cc)); + + try { + cc.addMethod(CtNewMethod.make( + "public int test4() {" + + " int i = Byte.MAX_VALUE;" + + " int j;" + + " switch (i) {" + + " case Byte.MAX_VALUE: j = i; return j;" + + " case Byte.MIN_VALUE: j = -i; return j;" + + " default: j = 0;" + + " }" + + "}", cc)); + fail("does not report an error (no return)"); + } + catch (CannotCompileException e) { System.out.println(e); } + + try { + cc.addMethod(CtNewMethod.make( + "public int test5() {" + + " int i = Byte.MAX_VALUE;" + + " int j;" + + " switch (i) {" + + " case Byte.MAX_VALUE: j = i; return j;" + + " case Byte.MIN_VALUE: j = -i; return j;" + + " }" + + "}", cc)); + fail("does not report an error (not default)"); + } + catch (CannotCompileException e) { System.out.println(e); } + + try { + cc.addMethod(CtNewMethod.make( + "public int test6() {" + + " int i = Byte.MAX_VALUE;" + + " int j;" + + " switch (i) {" + + " case Byte.MAX_VALUE: j = i; break;" + + " default: j = -i; return j;" + + " }" + + " }", cc)); + fail("does not report an error (break)"); + } + catch (CannotCompileException e) { System.out.println(e); } + + cc.addField(CtField.make("public static int k;", cc)); + + cc.addMethod(CtNewMethod.make( + "public void foo() {" + + " int i = 0;" + + " k = 3;" + + " switch (i) {" + + " case Byte.MAX_VALUE: k = 1;" + + " case Byte.MIN_VALUE: k = 2;" + + " }" + + "}", cc)); + + cc.addMethod(CtNewMethod.make( + "public int test7() {" + + " int i = Byte.MAX_VALUE;" + + " int j = 3; foo();" + + " System.out.println(k);" + + " switch (i) {" + + " case Byte.MAX_VALUE: return k;" + + " case Byte.MIN_VALUE: return j;" + + " default: return 0;" + + " }" + + "}", cc)); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(-1, invoke(obj, "test1")); + assertEquals(7, invoke(obj, "test2")); + assertEquals(Byte.MAX_VALUE, invoke(obj, "test3")); + assertEquals(3, invoke(obj, "test7")); + } + + public void testGet() throws Exception { + CtClass cc = sloader.get("char[]"); + CtClass cc2 = cc.getComponentType(); + System.out.println(cc2); + } + + public void testSynchronized() throws Exception { + CtClass cc = sloader.makeClass("test2.Synch"); + + cc.addMethod(CtNewMethod.make( + "public synchronized int test1() {" + + " int i = 0;" + + " synchronized (this) {" + + " i = 3;" + + " }" + + " return i; }", cc)); + + cc.addMethod(CtNewMethod.make( + "public synchronized int test2() {" + + " int i = 0;" + + " synchronized (this) {" + + " i = 3;" + + " return i;" + + " }" + + "}", cc)); + + cc.addMethod(CtNewMethod.make( + "public synchronized int test3() {" + + " int i = 0;" + + " synchronized (this) {" + + " if (this instanceof String)" + + " return i;" + + " else" + + " i = 3;" + + " }" + + " return i;" + + "}", cc)); + + cc.addMethod(CtNewMethod.make( + "public synchronized int test4() {" + + " int i = 0;" + + " synchronized (this) {" + + " }" + + " return i; }", cc)); + + try { + cc.addMethod(CtNewMethod.make( + "public synchronized int test5() {" + + " while (true)" + + " synchronized (this) {" + + " break;" + + " }" + + " return i; }", cc)); + fail("does not report an error"); + } + catch (CannotCompileException e) { System.out.println(e); } + + cc.addMethod(CtNewMethod.make( + "public synchronized int test6() {" + + " int i = 0;" + + " while (true) {" + + " synchronized (this) {" + + " i = 3;" + + " }" + + " break; }" + + " return i; }", cc)); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(3, invoke(obj, "test1")); + assertEquals(3, invoke(obj, "test2")); + assertEquals(3, invoke(obj, "test3")); + assertEquals(0, invoke(obj, "test4")); + } + + public void testTryFinally() throws Exception { + CtClass cc = sloader.get("test2.Finally"); + + cc.addMethod(CtNewMethod.make( + "public int test1() {" + + " a = 0;" + + " try {" + + " update();" + + " } catch (NullPointerException e) {" + + " a = 1;" + + " } finally {" + + " a = 2;" + + " }" + + " return a; }", cc)); + + cc.addMethod(CtNewMethod.make( + "public int test2() {" + + " a = 0;" + + " try {" + + " update(); return a;" + + " } catch (NullPointerException e) {" + + " a = 1; throw e;" + + " } finally {" + + " a = 2; return a;" + + " }" + + "}", cc)); + + cc.addMethod(CtNewMethod.make( + "public int test3() {" + + " a = 0;" + + " try {" + + " update(); return a;" + + " } catch (NullPointerException e) {" + + " a = 1;" + + " } finally {" + + " a = 2;" + + " }" + + " return a;" + + "}", cc)); + + cc.addMethod(CtNewMethod.make( + "public int test4() {" + + " a = 0;" + + " try {" + + " update(); return a;" + + " } catch (NullPointerException e) {" + + " a = 1; return a;" + + " } finally {" + + " a = 2;" + + " }" + + "}", cc)); + + cc.addMethod(CtNewMethod.make( + "public double test5() {" + + " b = 1.0;" + + " try {" + + " return b;" + + // " } catch (NullPointerException e) {" + + // " b = 2.0; return b;" + + " } finally {" + + " b += 3.0;" + + " }" + + "}", cc)); + + cc.addMethod(CtNewMethod.make( + "public int test5a() {" + + " return (int)test5();" + + "}", cc)); + + cc.addMethod(CtNewMethod.make( + "public int test6() {" + + " a = 0;" + + " try {" + + " if (a > 0)" + + " return a;" + + " update(); a = 1;" + + " }" + + " catch (RuntimeException e) {" + + " if (a > 0) a = 2; else a = 3;" + + " }" + + " catch (Throwable e) {" + + " a = 4;" + + " } finally {" + + " try { if (a < 0) update(); return a; }" + + " finally { if (a > 0) return a; a = 5; }" + + " " + + " }" + + "}", cc)); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(2, invoke(obj, "test1")); + assertEquals(2, invoke(obj, "test2")); + assertEquals(2, invoke(obj, "test3")); + assertEquals(1, invoke(obj, "test4")); + assertEquals(1, invoke(obj, "test5a")); + assertEquals(3, invoke(obj, "test6")); + } + + public void testConstructorName() throws Exception { + CtClass cc = sloader.get("test2.Construct"); + CtConstructor[] cons = cc.getDeclaredConstructors(); + assertEquals("Construct", cons[0].getName()); + assertEquals("Construct", cons[1].getName()); + assertEquals("<clinit>", cc.getClassInitializer().getName()); + } + + public void testRemoveCall() throws Exception { + CtClass cc = sloader.get("test2.RemoveCall"); + CtMethod m1 = cc.getDeclaredMethod("bar"); + m1.instrument(new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + m.replace("{ $_ = ($r)null; }"); + } + }); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(0, invoke(obj, "bar")); + } + + public void testRemove() throws Exception { + CtClass cc = sloader.get("test2.Remove"); + testRemove2(cc, "f1"); + testRemove2(cc, "f6"); + testRemove2(cc, "f3"); + CtField p = cc.getField("p"); + try { + cc.removeField(p); + fail("non-existing field has been removed"); + } + catch (NotFoundException e) {} + + testRemove3(cc, "bar"); + testRemove3(cc, "bar2"); + testRemove4(cc, "(I)V"); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(7, invoke(obj, "foo")); + } + + private void testRemove2(CtClass cc, String fieldName) throws Exception { + CtField f = cc.getField(fieldName); + cc.removeField(f); + try { + CtField f2 = cc.getField(fieldName); + fail("the removed field still exists"); + } + catch (NotFoundException e) {} + } + + private void testRemove3(CtClass cc, String methodName) throws Exception { + CtMethod m = cc.getDeclaredMethod(methodName); + cc.removeMethod(m); + try { + CtMethod m2 = cc.getDeclaredMethod(methodName); + fail("the removed method still exists"); + } + catch (NotFoundException e) {} + } + + private void testRemove4(CtClass cc, String desc) throws Exception { + CtConstructor c = cc.getConstructor(desc); + cc.removeConstructor(c); + try { + CtConstructor c2 = cc.getConstructor(desc); + fail("the removed method still exists"); + } + catch (NotFoundException e) {} + } + + public void testGetAndRename() throws Exception { + try { + CtClass cc = sloader.getAndRename("NotExisting", "Existing"); + } + catch (NotFoundException e) { + System.out.println(e); + } + } + + public void testConstBody() throws Exception { + CtClass cc = sloader.get("test2.ConstBody"); + CtConstructor cons = new CtConstructor(new CtClass[] { + sloader.get("java.lang.String"), + sloader.get("java.lang.Integer") }, cc); + cons.setBody("super((String)$1, (Integer)$2);"); + cc.addConstructor(cons); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(1, invoke(obj, "bar")); + } + + private String methodCallData = null; + + public void testMethodCall() throws Exception { + CtClass cc = sloader.get("test2.MethodCall"); + + CtMethod m1 = cc.getDeclaredMethod("bar"); + m1.instrument(new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + if ("clone".equals(m.getMethodName())) + methodCallData = m.getClassName(); + } + }); + + cc.writeFile(); + assertEquals("java.lang.String[]", methodCallData); + + assertEquals("java.lang.String[]", + sloader.get("[Ljava/lang/String;").getName()); + assertEquals("int[][]", + sloader.get("[[I").getName()); + } + + public void testKmatcha() throws Exception { + CtClass cc = sloader.makeClass("test2.Kmatcha"); + cc.addMethod(CtNewMethod.make( +"public void display(String [] params){" + +" if(params == null){" + +" System.out.println(\"Nothing to display\");" + +" }else{" + +" int k = params.length - 1;" + +" if(k >= 0)" + +" do " + +" System.out.println(params[k]);" + +" while(--k >= 0);" + +" }}", cc)); + } + + public void testStrict() throws Exception { + CtClass cc = sloader.makeClass("test2.StrictTest"); + cc.addMethod(CtNewMethod.make( +"public strictfp int foo(){ " + +" int strict = 1; return strict + 1; }", cc)); + } + + public void testArrayLen() throws Exception { + CtClass cc = sloader.get("test2.ArrayLenTest"); + cc.addMethod(CtNewMethod.make( +"public int foo(){ return this.length; }", cc)); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(1, invoke(obj, "foo")); + } + + public void testUnicodeIdentifier() throws Exception { + CtClass cc = sloader.makeClass("test2.UnicodeIdentifier"); + String src = "public int foo(){ int \u5206 = 0; return \u5206; }"; + cc.addMethod(CtNewMethod.make(src, cc)); + } + + public void testBrennan() throws Exception { + CtClass cc = sloader.get("test2.Brennan"); + cc.addMethod(CtNewMethod.make( +"public int foo(){" + +" java.text.SimpleDateFormat df;" + +" if((df = (java.text.SimpleDateFormat)format) == null)" + +" df = new java.text.SimpleDateFormat(\"yyyyMMdd\");" + +" return 1;}", cc)); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(1, invoke(obj, "foo")); + } + + public void testArrayAndNull() throws Exception { + CtClass cc = sloader.get("test2.ArrayAndNull"); + CtMethod m = cc.getDeclaredMethod("test"); + m.insertAfter("if ($_ == null) $_ = new int[0];"); + } + + public void testStaticArrays() throws Exception { + CtClass cc = sloader.makeClass("StaticArrays"); + CtField f = new CtField(sloader.get("test2.StaticArraysMem[]"), + "myStaticField", cc); + + f.setModifiers(Modifier.STATIC); + cc.addField(f); + CtConstructor init = cc.makeClassInitializer(); + String body = "{\n"; + body += ("myStaticField = new test2.StaticArraysMem[2];\n"); + body += ("\n}"); + init.setBody(body); + } + + public void testObjectSuper() throws Exception { + CtClass cc = sloader.get("java.lang.Object"); + try { + cc.addMethod(CtNewMethod.make( + "public int foo(){ return super.hashCode(); }", cc)); + fail("could access the super of java.lang.Object"); + } + catch (CannotCompileException e) {} + } + + public void testStaticFinal() throws Exception { + CtClass cc = sloader.makeClass("test2.StaticFinal"); + CtField f = new CtField(CtClass.intType, "sff1", cc); + f.setModifiers(Modifier.STATIC | Modifier.FINAL); + cc.addField(f, "5"); + assertEquals(new Integer(5), f.getConstantValue()); + + f = new CtField(CtClass.longType, "sff2", cc); + f.setModifiers(Modifier.STATIC | Modifier.FINAL); + cc.addField(f, "6"); + assertEquals(new Long(6), f.getConstantValue()); + + f = new CtField(CtClass.floatType, "sff3", cc); + f.setModifiers(Modifier.STATIC | Modifier.FINAL); + cc.addField(f, "7"); + assertEquals(new Float(7.0F), f.getConstantValue()); + + f = new CtField(CtClass.floatType, "sff4", cc); + f.setModifiers(Modifier.STATIC | Modifier.FINAL); + cc.addField(f, "8.0"); + assertEquals(new Float(8.0F), f.getConstantValue()); + + f = new CtField(CtClass.doubleType, "sff5", cc); + f.setModifiers(Modifier.STATIC | Modifier.FINAL); + cc.addField(f, "9"); + assertEquals(new Double(9.0), f.getConstantValue()); + + f = new CtField(CtClass.doubleType, "sff6", cc); + f.setModifiers(Modifier.STATIC | Modifier.FINAL); + cc.addField(f, "10.0"); + assertEquals(new Double(10.0), f.getConstantValue()); + + f = new CtField(sloader.get("java.lang.String"), "sff7", cc); + f.setModifiers(Modifier.STATIC | Modifier.FINAL); + cc.addField(f, "\"test\""); + assertEquals("test", f.getConstantValue()); + + f = new CtField(sloader.get("java.lang.String"), "sff8", cc); + f.setModifiers(Modifier.STATIC); + cc.addField(f, "\"static\""); + assertEquals(null, f.getConstantValue()); + + cc.addMethod(CtNewMethod.make( + "public int foo(){ return sff1 + sff7.length(); }", cc)); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(9, invoke(obj, "foo")); + } + + public void testLocalVar() throws Exception { + CtClass cc = sloader.get("test2.LocalVar"); + CtMethod m = cc.getDeclaredMethod("toString"); + m.addLocalVariable("var", CtClass.booleanType); + m.insertBefore("{var = true; }"); + m.insertAfter("{if (var) hashCode(); }", false); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(3, invoke(obj, "foo")); + } + + public void testImportPackage() throws Exception { + CtClass cc2 = sloader.makeClass("test2.Imported"); + cc2.writeFile(); + CtClass cc = sloader.makeClass("test2.Importer"); + sloader.importPackage("test2"); + cc.addMethod(CtNewMethod.make( + "public int foo(){ " + + " Imported obj = new Imported();" + + " return obj.getClass().getName().length(); }", cc)); + sloader.clearImportedPackages(); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(14, invoke(obj, "foo")); + } + + public void testArrayInit() throws Exception { + CtClass cc = sloader.makeClass("test2.ArrayInit"); + cc.addMethod(CtNewMethod.make( + "public int foo(){ " + + " int[] i = new int[] { 1, 2 };" + + " double[] d = new double[] { 3.0, 4.0 };" + + " String[] s = new String[] { \"foo\", \"12345\" };" + + " return i[0] + (int)d[0] + s[1].length(); }", cc)); + cc.addMethod(CtNewMethod.make( + "public int bar(){ " + + " int[] i = { 1, 2.0 };" + + " double[] d = { 3.0, 4 };" + + " String[] s = { \"foo\", \"12345\" };" + + " return i[0] + (int)d[0] + s[1].length(); }", cc)); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(9, invoke(obj, "foo")); + assertEquals(9, invoke(obj, "bar")); + } +} diff --git a/src/test/javassist/JvstTest3.java b/src/test/javassist/JvstTest3.java new file mode 100644 index 00000000..d99fde1f --- /dev/null +++ b/src/test/javassist/JvstTest3.java @@ -0,0 +1,1125 @@ +package javassist; + +import javassist.bytecode.*; +import javassist.bytecode.annotation.*; +import javassist.expr.*; +import test3.*; + +public class JvstTest3 extends JvstTestRoot { + public JvstTest3(String name) { + super(name); + } + + public void testAnnotation() throws Exception { + CtClass cc = sloader.get("test3.AnnoTest"); + Object[] all = cc.getAnnotations(); + Anno a = (Anno)all[0]; + assertEquals('0', a.c()); + assertEquals(true, a.bool()); + assertEquals(1, a.b()); + assertEquals(2, a.s()); + assertEquals(3, a.i()); + assertEquals(4L, a.j()); + assertEquals(5.0F, a.f()); + assertEquals(6.0, a.d()); + assertEquals("7", a.str()); + assertEquals(AnnoTest.class, a.clazz()); + assertEquals(3, a.anno2().str().length); + } + + public void testAnnotation2() throws Exception { + CtClass cc = sloader.get("test3.AnnoTest2"); + Object[] all = cc.getAnnotations(); + Anno a = (Anno)all[0]; + assertEquals('a', a.c()); + assertEquals(false, a.bool()); + assertEquals(11, a.b()); + assertEquals(12, a.s()); + assertEquals(13, a.i()); + assertEquals(14L, a.j()); + assertEquals(15.0F, a.f()); + assertEquals(16.0, a.d()); + assertEquals("17", a.str()); + assertEquals(String.class, a.clazz()); + assertEquals(11, a.anno2().i()[0]); + } + + public void testAnnotation3() throws Exception { + CtClass cc = sloader.get("test3.AnnoTest3"); + Object[] all = cc.getAnnotations(); + assertEquals(2, all.length); + int i; + if (all[0] instanceof Anno2) + i = 0; + else + i = 1; + + Anno2 a = (Anno2)all[i]; + assertEquals(1, a.i()[0]); + assertEquals(test3.ColorName.RED, a.color()); + assertEquals(test3.ColorName.BLUE, a.color2()[0]); + } + + public void testAnnotation4() throws Exception { + CtClass cc = sloader.get("test3.AnnoTest4"); + Object[] all = cc.getAnnotations(); + Anno3 a = null; + for (int i = 0; i < all.length; i++) + if (all[i] instanceof Anno3) + a = (Anno3)all[i]; + + assertTrue(a != null); + assertEquals('0', a.c()[0]); + assertEquals(true, a.bool()[0]); + assertEquals(1, a.b()[0]); + assertEquals(2, a.s()[0]); + assertEquals(3, a.i()[0]); + assertEquals(4L, a.j()[0]); + assertEquals(5.0F, a.f()[0]); + assertEquals(6.0, a.d()[0]); + assertEquals("7", a.str()[0]); + assertEquals(AnnoTest.class, a.clazz()[0]); + assertEquals(11, a.anno2()[0].i()[0]); + } + + public void testAnnotation5() throws Exception { + CtClass cc = sloader.get("test3.AnnoTest5"); + Object[] all = cc.getField("bar").getAnnotations(); + Anno2 a2 = (Anno2)all[0]; + assertEquals(test3.ColorName.RED, a2.color()); + + all = cc.getDeclaredMethod("foo").getAnnotations(); + Anno a = (Anno)all[0]; + assertEquals("7", a.str()); + } + + public void testAnnotation6() throws Exception { + CtClass cc = sloader.get("test3.AnnoTest6"); + Object[] all = cc.getAnnotations(); + Anno6 a = (Anno6)all[0]; + assertEquals(0, a.str1().length); + assertEquals(0, a.str2().length); + } + + public void testChainedException() throws Exception { + try { + throwChainedException(); + } + catch (CannotCompileException e) { + e.printStackTrace(System.out); + } + + try { + throwChainedException2(); + } + catch (CannotCompileException e) { + e.printStackTrace(System.out); + } + + try { + throwChainedException3(); + } + catch (Exception e) { + e.printStackTrace(System.out); + } + + } + + public void throwChainedException() throws Exception { + throw new CannotCompileException("test"); + } + + public void throwChainedException2() throws Exception { + Throwable e = new CannotCompileException("test"); + throw new CannotCompileException("test2", e); + } + + public void throwChainedException3() throws Exception { + Throwable e = new CannotCompileException("testA"); + Throwable e2 = new CannotCompileException("testB", e); + throw new Exception(e2); + } + + // JIRA Javassist-12 + public void testInnerClassMethod() throws Exception { + CtClass cc = sloader.get("test3.InnerMethod"); + CtMethod m1 = cc.getDeclaredMethod("test"); + m1.setBody("{inner.test();}"); + + CtMethod m2 = CtNewMethod.make( + "public int bar() {" + + " if (counter-- <= 0) return 3;" + + " else return bar();" + + "}", + cc); + cc.addMethod(m2); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(1, invoke(obj, "foo")); + assertEquals(3, invoke(obj, "bar")); + } + + public void testCheckModifyAndPruned() throws Exception { + CtClass cc = sloader.get("test3.CheckModify"); + cc.addField(new CtField(CtClass.intType, "j", cc)); + cc.stopPruning(false); + cc.toBytecode(); + try { + cc.getClassFile(); + fail(); + } + catch (RuntimeException e) { + // System.err.println(e.getMessage()); + assertTrue(e.getMessage().indexOf("prune") >= 0); + } + } + + public void testReplaceNew() throws Exception { + CtClass cc = sloader.get("test3.ReplaceNew"); + CtMethod m1 = cc.getDeclaredMethod("run"); + m1.instrument(new ExprEditor() { + public void edit(NewExpr n) throws CannotCompileException { + n.replace("{ i++; $_ = null; }"); + } + }); + + CtMethod m2 = cc.getDeclaredMethod("run2"); + m2.instrument(new ExprEditor() { + public void edit(NewExpr n) throws CannotCompileException { + n.replace("{ j++; $_ = null; }"); + } + }); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(5, invoke(obj, "run")); + assertEquals(2, invoke(obj, "run2")); + } + + public void testPublicInner() throws Exception { + CtClass cc0 = sloader.get("test3.PublicInner2"); + int mod = cc0.getClassFile2().getAccessFlags(); + System.out.println("testPublicInner: " + mod); + + CtClass cc = sloader.get("test3.PublicInner"); + CtClass jp = cc.makeNestedClass("Inner", true); + assertEquals(Modifier.PUBLIC | Modifier.STATIC, jp.getModifiers()); + assertEquals(Modifier.PUBLIC | Modifier.STATIC, + getPublicInner(jp, "Inner")); + assertEquals(Modifier.PUBLIC | Modifier.STATIC, + getPublicInner(cc, "Inner")); + + jp.setModifiers(Modifier.STATIC); + assertEquals(Modifier.STATIC, jp.getModifiers()); + assertEquals(Modifier.STATIC, getPublicInner(jp, "Inner")); + assertEquals(Modifier.STATIC, getPublicInner(cc, "Inner")); + + jp.setModifiers(Modifier.PUBLIC | Modifier.ABSTRACT); + assertEquals(Modifier.PUBLIC | Modifier.ABSTRACT | Modifier.STATIC, jp.getModifiers()); + assertEquals(Modifier.PUBLIC | Modifier.ABSTRACT | Modifier.STATIC, + getPublicInner(jp, "Inner")); + assertEquals(Modifier.PUBLIC | Modifier.ABSTRACT | Modifier.STATIC, + getPublicInner(cc, "Inner")); + + cc.writeFile(); + jp.writeFile(); + } + + private int getPublicInner(CtClass cc, String name) throws Exception { + ClassFile cf = cc.getClassFile(); + InnerClassesAttribute ica + = (InnerClassesAttribute)cf.getAttribute( + InnerClassesAttribute.tag); + assertEquals(name, ica.innerName(0)); + return ica.accessFlags(0); + } + + public void testConstructorToMethod() throws Exception { + CtClass cc = sloader.get("test3.Constructor"); + CtConstructor[] cons = cc.getConstructors(); + CtConstructor sinit = cc.getClassInitializer(); + + for (int i = 0; i < cons.length; i++) { + CtConstructor ccons = cons[i]; + String desc = ccons.getSignature(); + boolean result = false; + if (desc.equals("()V")) + result = false; + else if (desc.equals("(I)V")) + result = true; + else if (desc.equals("(Ljava/lang/String;)V")) + result = false; + else if (desc.equals("(D)V")) + result = true; + else + fail("unknonw constructor"); + + assertEquals(result, ccons.callsSuper()); + } + + CtClass cc2 = sloader.get("test3.Constructor2"); + for (int i = 0; i < cons.length; i++) + cc2.addMethod(cons[i].toMethod("m", cc2)); + + cc2.addMethod(sinit.toMethod("sinit", cc2)); + cc2.addMethod(CtMethod.make( + "public int run() { m(); m(5); m(\"s\"); m(0.0);" + + " sinit(); return i + str.length(); }", + cc2)); + cc2.writeFile(); + + Object obj = make(cc2.getName()); + assertEquals(119, invoke(obj, "run")); + } + + public void testUnique() throws Exception { + CtClass cc = sloader.get("test3.Unique"); + CtClass cc2 = sloader.get("test3.Unique3"); + assertEquals("poi", cc.makeUniqueName("poi")); + assertEquals("foo102", cc.makeUniqueName("foo")); + assertEquals("bar102", cc2.makeUniqueName("bar")); + assertEquals("foo100", cc2.makeUniqueName("foo")); + } + + public void testGetMethods() throws Exception { + CtClass cc = sloader.get("test3.GetMethods"); + assertEquals(3, cc.getConstructors().length); + assertEquals(6, cc.getFields().length); + assertEquals(6 + Object.class.getMethods().length + 2, + cc.getMethods().length); + } + + public void testVisiblity() throws Exception { + CtClass cc = sloader.get("test3.Visible"); + CtClass cc2 = sloader.get("test3.Visible2"); + CtClass subcc = sloader.get("test3.sub.Visible"); + CtClass subcc2 = sloader.get("test3.sub.Visible2"); + CtClass top = sloader.get("VisibleTop"); + CtClass top2 = sloader.get("VisibleTop2"); + + assertEquals(true, cc.getField("pub").visibleFrom(cc2)); + assertEquals(true, cc.getField("pub").visibleFrom(subcc)); + + assertEquals(true, cc.getField("pri").visibleFrom(cc)); + assertEquals(false, cc.getField("pri").visibleFrom(cc2)); + + assertEquals(true, cc.getField("pack").visibleFrom(cc)); + assertEquals(true, cc.getField("pack").visibleFrom(cc2)); + assertEquals(false, cc.getField("pack").visibleFrom(subcc)); + assertEquals(false, cc.getField("pack").visibleFrom(top)); + + assertEquals(true, cc.getField("pro").visibleFrom(cc)); + assertEquals(true, cc.getField("pro").visibleFrom(cc2)); + assertEquals(true, cc.getField("pro").visibleFrom(subcc2)); + assertEquals(false, cc.getField("pro").visibleFrom(subcc)); + assertEquals(false, cc.getField("pro").visibleFrom(top)); + + assertEquals(true, top.getField("pack").visibleFrom(top2)); + assertEquals(false, top.getField("pack").visibleFrom(cc)); + } + + public void testNewAnnotation() throws Exception { + CtClass c = sloader.makeClass("test3.NewClass"); + ClassFile cf = c.getClassFile(); + ConstPool cp = cf.getConstPool(); + AnnotationsAttribute attr + = new AnnotationsAttribute(cp, AnnotationsAttribute.visibleTag); + javassist.bytecode.annotation.Annotation a + = new Annotation("test3.ChibaAnnotation", cp); + a.addMemberValue("name", new StringMemberValue("Chiba", cp)); + a.addMemberValue("version", new StringMemberValue("Chiba", cp)); + a.addMemberValue("description", new StringMemberValue("Chiba", cp)); + a.addMemberValue("interfaceName", new StringMemberValue("Chiba", cp)); + attr.setAnnotation(a); + System.out.println(attr); + cf.addAttribute(attr); + cf.setVersionToJava5(); + Object [] ans = c.getAnnotations() ; + System.out.println("Num Annotation : " +ans.length); + + // c.debugWriteFile(); + Class newclass = c.toClass(); + java.lang.annotation.Annotation[] anns = newclass.getAnnotations(); + System.out.println("Num NewClass Annotation : " +anns.length); + assertEquals(ans.length, anns.length); + } + + public void testRecursiveReplace() throws Exception { + CtClass cc = sloader.get("test3.RecReplace"); + CtMethod m1 = cc.getDeclaredMethod("run"); + final ExprEditor e2 = new ExprEditor() { + public void edit(MethodCall mc) throws CannotCompileException { + if (mc.getMethodName().equals("bar")) { + mc.replace("{ double k = 10.0; $_ = $proceed($1 + k); }"); + } + } + }; + m1.instrument(new ExprEditor() { + public void edit(MethodCall mc) throws CannotCompileException { + if (mc.getMethodName().equals("foo")) { + mc.replace("{ int k = bar($$); $_ = k + $proceed(7.0); }", + e2); + } + } + }); + + CtMethod m2 = cc.getDeclaredMethod("run2"); + m2.instrument(new ExprEditor() { + public void edit(MethodCall mc) throws CannotCompileException { + if (mc.getMethodName().equals("foo")) { + mc.replace("{ int k = bar($$); $_ = k + $proceed(7.0); }"); + } + } + }); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(26, invoke(obj, "run")); + assertEquals(16, invoke(obj, "run2")); + } + + public void testRecursiveReplace2() throws Exception { + final ExprEditor[] ref = new ExprEditor[1]; + ExprEditor e2 = new ExprEditor() { + public void edit(FieldAccess fa) throws CannotCompileException { + if (fa.getFieldName().equals("value2") + && fa.isWriter()) { + fa.replace("{ $_ = $proceed($1 + 2); }"); + } + } + }; + ExprEditor e1 = new ExprEditor() { + public void edit(FieldAccess fa) throws CannotCompileException { + if (fa.getFieldName().equals("value") + && fa.isWriter()) { + fa.replace("{ value2 = $1; value = value2; }", + ref[0]); + } + } + }; + + CtClass cc = sloader.get("test3.RecReplace2"); + CtMethod m1 = cc.getDeclaredMethod("run"); + ref[0] = e2; + m1.instrument(e1); + CtMethod m2 = cc.getDeclaredMethod("run2"); + ref[0] = null; + m2.instrument(e1); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(28, invoke(obj, "run")); + assertEquals(24, invoke(obj, "run2")); + } + + public void testInnerModifier() throws Exception { + CtClass cc = sloader.get("test3.InnerClass$Inner"); + assertEquals(Modifier.PUBLIC | Modifier.STATIC, cc.getModifiers()); + CtClass cc2 = sloader.get("test3.InnerClass$Inner2"); + assertEquals(Modifier.PUBLIC, cc2.getModifiers()); + } + + public void testMethodLookup() throws Exception { + CtClass cc = sloader.get("test3.SubValue"); + CtMethod m1 = CtNewMethod.make( + "public int run() {" + + " test3.SuperValue sup = new test3.SuperValue();" + + " test3.SubValue sub = new test3.SubValue();" + + " return this.after(sup, sub, sub) == null ? 0 : 1;" + + "}", + cc); + cc.addMethod(m1); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(1, invoke(obj, "run")); + } + + public void testFieldAccessType() throws Exception { + CtClass cc = sloader.get("test3.FieldAccessType"); + CtMethod m1 = cc.getDeclaredMethod("access"); + final boolean[] result = new boolean[1]; + result[0] = true; + ExprEditor e = new ExprEditor() { + public void edit(FieldAccess fa) throws CannotCompileException { + if (!fa.getSignature().equals("[I")) + result[0] = false; + } + }; + m1.instrument(e); + assertTrue(result[0]); + } + + public void testGetNestedClasses() throws Exception { + CtClass cc = sloader.get("test3.NestedClass"); + CtClass[] nested = cc.getNestedClasses(); + assertEquals(4, nested.length); + testGetNestedClasses("test3.NestedClass$Inner", nested); + testGetNestedClasses("test3.NestedClass$StaticNested", nested); + testGetNestedClasses("test3.NestedClass$1Local", nested); + testGetNestedClasses("test3.NestedClass$1", nested); + } + + private void testGetNestedClasses(String name, CtClass[] classes) { + for (int i = 0; i < classes.length; i++) + if (classes[i].getName().equals(name)) + return; + + fail("no class: " + name); + } + + public void testGetParmeterAnnotations() throws Exception { + CtClass cc = sloader.get("test3.ParamAnno"); + Object[][] anno = cc.getDeclaredMethod("foo").getParameterAnnotations(); + assertEquals(4, anno.length); + assertEquals(0, anno[0].length); + assertEquals(0, anno[1].length); + assertEquals(0, anno[2].length); + assertEquals(0, anno[3].length); + + Object[][] anno2 = cc.getDeclaredMethod("bar").getParameterAnnotations(); + assertEquals(0, anno2.length); + + Class rc = Class.forName("test3.ParamAnno"); + java.lang.reflect.Method[] ms = rc.getDeclaredMethods(); + java.lang.reflect.Method m1, m2; + if (ms[0].getName().equals("foo")) { + m1 = ms[0]; + m2 = ms[1]; + } + else { + m1 = ms[1]; + m2 = ms[0]; + } + + java.lang.annotation.Annotation[][] ja; + ja = m1.getParameterAnnotations(); + assertEquals(4, ja.length); + assertEquals(0, ja[0].length); + assertEquals(0, ja[1].length); + assertEquals(0, ja[2].length); + assertEquals(0, ja[3].length); + + assertEquals(0, m2.getParameterAnnotations().length); + } + + public void testSetModifiers() throws Exception { + CtClass cc = sloader.get("test3.SetModifiers"); + try { + cc.setModifiers(Modifier.STATIC | Modifier.PUBLIC); + fail("static public class SetModifiers"); + } + catch (RuntimeException e) { + assertEquals("cannot change test3.SetModifiers into a static class", e.getMessage()); + } + + cc = sloader.get("test3.SetModifiers$A"); + cc.setModifiers(Modifier.STATIC | Modifier.PUBLIC); + assertTrue(Modifier.isStatic(cc.getModifiers())); + assertTrue((cc.getClassFile2().getAccessFlags() & AccessFlag.STATIC) == 0); + } + + public void testFieldCopy() throws Exception { + CtClass cc = sloader.get("test3.FieldCopy"); + CtClass cc2 = sloader.get("test3.FieldCopy2"); + CtField f = cc.getDeclaredField("foo"); + cc2.addField(new CtField(f, cc2)); + CtField f2 = cc2.getDeclaredField("foo"); + Object[] anno = f2.getAnnotations(); + assertTrue(anno[0] instanceof test3.FieldCopy.Test); + assertEquals(Modifier.PRIVATE | Modifier.STATIC, + f2.getModifiers()); + } + + public void testMethodRedirect() throws Exception { + CtClass cc = sloader.get("test3.MethodRedirect"); + CtClass cc2 = sloader.get("test3.MethodRedirectIntf"); + CtMethod foo = cc.getDeclaredMethod("foo"); + CtMethod poi = cc.getDeclaredMethod("poi"); + CtMethod bar = cc.getDeclaredMethod("bar"); + CtMethod afo = cc2.getDeclaredMethod("afo"); + CodeConverter conv = new CodeConverter(); + + try { + conv.redirectMethodCall(foo, bar); + fail("foo"); + } + catch (CannotCompileException e) {} + + try { + conv.redirectMethodCall(poi, bar); + fail("bar"); + } + catch (CannotCompileException e) {} + + try { + conv.redirectMethodCall(bar, afo); + fail("afo"); + } + catch (CannotCompileException e) {} + bar.setName("bar2"); + conv.redirectMethodCall("bar", bar); + cc.instrument(conv); + // cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(2, invoke(obj, "test")); + } + + public void testMethodRedirect2() throws Exception { + CtClass cc = sloader.get("test3.MethodRedirect2"); + CtClass sup = sloader.get("test3.MethodRedirect2Sup"); + CtClass supsup = sloader.get("test3.MethodRedirect2SupSup"); + CtClass intf = sloader.get("test3.MethodRedirect2SupIntf"); + CtMethod bfo2 = supsup.getDeclaredMethod("bfo2"); + CtMethod afo2 = sup.getDeclaredMethod("afo2"); + CtMethod foo = intf.getDeclaredMethod("foo"); + CodeConverter conv = new CodeConverter(); + + conv.redirectMethodCall("bfo", bfo2); + conv.redirectMethodCall("afo", afo2); + conv.redirectMethodCall("bar", foo); + conv.redirectMethodCall("bar2", foo); + cc.instrument(conv); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(524, invoke(obj, "test")); + } + + public void testClassMap() throws Exception { + ClassMap map = new ClassMap(); + map.put("aa", "AA"); + map.put("xx", "XX"); + assertEquals("AA", map.get("aa")); + assertEquals(null, map.get("bb")); + ClassMap map2 = new ClassMap(map); + map2.put("aa", "A1"); + map2.put("cc", "CC"); + assertEquals("A1", map2.get("aa")); + assertEquals("CC", map2.get("cc")); + assertEquals("XX", map2.get("xx")); + assertEquals(null, map2.get("bb")); + } + + public void testEmptyConstructor() throws Exception { + CtClass cc = sloader.get("test3.EmptyConstructor"); + CtConstructor[] cons = cc.getDeclaredConstructors(); + for (int i = 0; i < cons.length; i++) + assertTrue("index: " + i, cons[i].isEmpty()); + + cc = sloader.get("test3.EmptyConstructor2"); + cons = cc.getDeclaredConstructors(); + for (int i = 0; i < cons.length; i++) + assertTrue("index: " + i, cons[i].isEmpty()); + + cc = sloader.get("test3.EmptyConstructor3"); + cons = cc.getDeclaredConstructors(); + for (int i = 0; i < cons.length; i++) + assertTrue("index: " + i, cons[i].isEmpty()); + + cc = sloader.get("test3.EmptyConstructor4"); + cons = cc.getDeclaredConstructors(); + for (int i = 0; i < cons.length; i++) + assertFalse("index: " + i, cons[i].isEmpty()); + } + + public void testTransformRead() throws Exception { + CtClass cc = sloader.get("test3.TransformRead"); + CtClass parent = cc.getSuperclass(); + CtMethod m = cc.getDeclaredMethod("foo"); + CodeConverter conv = new CodeConverter(); + conv.replaceFieldRead(parent.getField("value"), cc, "getValue"); + conv.replaceFieldRead(parent.getField("value2"), cc, "getValue2"); + m.instrument(conv); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(11100, invoke(obj, "foo")); + } + + public void testDescriptor() throws Exception { + assertEquals("int", Descriptor.toString("I")); + assertEquals("long[][]", Descriptor.toString("[[J")); + assertEquals("java.lang.Object", Descriptor.toString("Ljava/lang/Object;")); + assertEquals("()", Descriptor.toString("()V")); + assertEquals("(int)", Descriptor.toString("(I)V")); + assertEquals("(int,int[])", Descriptor.toString("(I[I)V")); + assertEquals("(java.lang.String,Foo[][])", Descriptor.toString("(Ljava/lang/String;[[LFoo;)V")); + } + + public void testLongName() throws Exception { + CtClass cc = sloader.get("test3.Name"); + assertEquals("test3.Name.<clinit>()", cc.getClassInitializer().getLongName()); + assertEquals("test3.Name()", cc.getConstructor("()V").getLongName()); + assertEquals("test3.Name(int)", cc.getConstructor("(I)V").getLongName()); + assertEquals("test3.Name(test3.Name)", cc.getConstructor("(Ltest3/Name;)V").getLongName()); + assertEquals("test3.Name(test3.Name,java.lang.String)", + cc.getConstructor("(Ltest3/Name;Ljava/lang/String;)V").getLongName()); + + assertEquals("test3.Name.foo()", cc.getDeclaredMethod("foo").getLongName()); + assertEquals("test3.Name.foo2(int)", cc.getDeclaredMethod("foo2").getLongName()); + assertEquals("test3.Name.foo3(java.lang.String)", cc.getDeclaredMethod("foo3").getLongName()); + assertEquals("test3.Name.foo4(java.lang.String[])", cc.getDeclaredMethod("foo4").getLongName()); + assertEquals("test3.Name.foo5(int,java.lang.String)", cc.getDeclaredMethod("foo5").getLongName()); + } + + public void testPackageName() throws Exception { + CtClass cc = sloader.get("test3.PackName"); + CtMethod m1 = CtNewMethod.make( + "public int run() {" + + " return test3.PackName.get() + test3.sub.SubPackName.get(); }", + cc); + cc.addMethod(m1); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(8, invoke(obj, "run")); + } + + public void testErasure() throws Exception { + CtClass cc = sloader.get("test3.Erasure"); + cc.addInterface(sloader.get("test3.ErasureGet")); + CtMethod m1 = CtNewMethod.make( + "public Object get() { return value; }", + cc); + cc.addMethod(m1); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(4, invoke(obj, "run")); + } + + /* Check the result of JvstTest#testFieldInit() + * This tests CtClassType#saveClassFile(). + */ + public void testFieldInitAgain() throws Exception { + System.gc(); + CtClass cc = sloader.get("test1.FieldInit"); + CtField f = cc.getDeclaredField("f1"); + assertEquals(CtClass.intType, f.getType()); + assertTrue("f.hashCode() doesn't change!", f.hashCode() != JvstTest.testFieldInitHash); + } + + /* This tests CtClassType#saveClassFile(). + * A CtMethod is not garbage collected, its CtClass is never + * compressed. + */ + public void testCalleeBeforeAgain() throws Exception { + CtClass cc = sloader.get("test1.CalleeBefore"); + assertEquals(JvstTest.testCalleeBeforeMethod, + cc.getDeclaredMethod("m1")); + assertEquals(JvstTest.testCalleeBeforeMethod2, + cc.getDeclaredMethod("m2").getMethodInfo2().hashCode()); + } + + public void testSetSuper() throws Exception { + CtClass cc = sloader.get("test3.Superclass"); + CtClass cc3 = sloader.get("test3.Superclass3"); + cc3.setModifiers(Modifier.setPublic(cc3.getModifiers())); + cc.setSuperclass(sloader.get("test3.Superclass3")); + cc.writeFile(); + cc3.writeFile(); + Object obj = make(cc.getName()); + assertEquals(21, invoke(obj, "test")); + } + + public void testFrozen2() throws Exception { + CtClass cc = sloader.get("test3.Frozen"); + cc.addField(new CtField(CtClass.intType, "k", cc)); + cc.toBytecode(); + cc.toBytecode(); + cc = sloader.makeClass("test3.Frozen2"); + cc.toBytecode(); + cc.toBytecode(); + } + + public void testCopyAnnotation() throws Exception { + CtClass cc1 = sloader.get("test3.CopyAnnoBase"); + CtMethod m1 = cc1.getDeclaredMethod("getX"); + CtClass cc2 = sloader.get("test3.CopyAnno"); + CtMethod m2 = cc2.getDeclaredMethod("getX"); + copyAnnotations(m1, m2); + cc2.getClassFile(); + Class clazz = cc2.toClass(); + java.lang.reflect.Method m = clazz.getDeclaredMethod("getX", new Class[0]); + assertEquals(1, m.getAnnotations().length); + test3.VisibleAnno a = m.getAnnotation(test3.VisibleAnno.class); + assertNotNull(a); + } + + private void copyAnnotations(CtMethod src, CtMethod dest) + throws NotFoundException + { + MethodInfo srcInfo = src.getMethodInfo2(); + MethodInfo destInfo = dest.getMethodInfo2(); + copyAnnotations(srcInfo, destInfo, AnnotationsAttribute.invisibleTag); + copyAnnotations(srcInfo, destInfo, AnnotationsAttribute.visibleTag); + } + + private void copyAnnotations(MethodInfo src, MethodInfo dest, String annotationTag) { + AnnotationsAttribute attribute = (AnnotationsAttribute)src.getAttribute(annotationTag); + if (attribute != null) + dest.addAttribute(attribute.copy(dest.getConstPool(), new java.util.HashMap())); + } + + public void testStaticFinalField() throws Exception { + CtClass cc = sloader.makeClass("test3.StaticFinalField"); + CtField fj = new CtField(CtClass.longType, "j", cc); + fj.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL); + cc.addField(fj, CtField.Initializer.constant(2L)); + CtField fi = new CtField(CtClass.intType, "i", cc); + fi.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL); + cc.addField(fi, CtField.Initializer.constant(3)); + CtField fs = new CtField(CtClass.shortType, "s", cc); + fs.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL); + cc.addField(fs, CtField.Initializer.constant(4)); + CtField fc = new CtField(CtClass.charType, "c", cc); + fc.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL); + cc.addField(fc, CtField.Initializer.constant('5')); + CtField fby = new CtField(CtClass.byteType, "by", cc); + fby.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL); + cc.addField(fby, CtField.Initializer.constant(6)); + CtField fb = new CtField(CtClass.booleanType, "b", cc); + fb.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL); + cc.addField(fb, CtField.Initializer.constant(true)); + CtField ff = new CtField(CtClass.floatType, "f", cc); + ff.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL); + cc.addField(ff, CtField.Initializer.constant(7.0F)); + CtField fstr = new CtField(sloader.get("java.lang.String"), "str", cc); + fstr.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL); + cc.addField(fstr, CtField.Initializer.constant("foo")); + CtField fobj = new CtField(sloader.get("java.lang.Object"), "obj", cc); + fobj.setModifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL); + cc.addField(fobj, CtField.Initializer.constant("bar")); + + cc.writeFile(); + Class clazz = cc.toClass(); + assertEquals(2L, clazz.getField("j").getLong(null)); + assertEquals(3, clazz.getField("i").getInt(null)); + assertEquals(4, clazz.getField("s").getShort(null)); + assertEquals('5', clazz.getField("c").getChar(null)); + assertEquals(6, clazz.getField("by").getByte(null)); + assertEquals(true, clazz.getField("b").getBoolean(null)); + assertEquals(7.0F, clazz.getField("f").getFloat(null)); + assertEquals("foo", clazz.getField("str").get(null)); + assertEquals("bar", clazz.getField("obj").get(null)); + } + + /* + public void testClassPath() throws Exception { + ClassPool cp = new ClassPool(null); + cp.appendClassPath("./test-classpath.JaR"); + assertNotNull(cp.get("test.Point")); + cp = new ClassPool(null); + cp.appendClassPath("./*"); + assertNotNull(cp.get("javassist.bytecode.Gap0Example")); + }*/ + + public void testVoidReturn() throws Exception { + CtClass cc = sloader.get("test3.VoidReturn"); + CtMethod m1 = cc.getDeclaredMethod("foo"); + m1.insertAfter("System.out.println(\"return value: \" + $_);", true); + cc.writeFile(); + make(cc.getName()); + } + + public void testInsertParam0() throws Exception { + assertEquals("(I)V", Descriptor.insertParameter(CtClass.intType, "()V")); + assertEquals("(ILjava/lang/Object;)V", Descriptor.insertParameter(CtClass.intType, "(Ljava/lang/Object;)V")); + assertEquals("(IJ)V", Descriptor.appendParameter(CtClass.longType, "(I)V")); + assertEquals("(Ljava/lang/String;I)V", Descriptor.insertParameter(sloader.get("java.lang.String"), "(I)V")); + } + + public void testInsertParam() throws Exception { + CtClass cc = sloader.get("test3.InsParam"); + CtMethod m1 = cc.getDeclaredMethod("foo"); + m1.insertParameter(CtClass.longType); + m1.insertBefore("$2 += (int)$1;"); + + CtMethod m2 = cc.getDeclaredMethod("bar"); + m2.addParameter(CtClass.doubleType); + m2.insertBefore("$1 += (int)$2;"); + + CtMethod m3 = cc.getDeclaredMethod("poi"); + m3.addParameter(sloader.get("java.lang.Object")); + m3.insertBefore("$2 = (String)$3;"); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(11, invoke(obj, "foo", 10L, 1)); + assertEquals(11, invoke(obj, "bar", 1, 10.0)); + assertEquals(3, invoke(obj, "poi", 1, "x", "xx")); + } + + private int invoke(Object target, String method, long arg1, int arg2) + throws Exception + { + java.lang.reflect.Method m = + target.getClass().getMethod(method, new Class[] { long.class, int.class }); + Object res = m.invoke(target, new Object[] { new Long(arg1), new Integer(arg2)}); + return ((Integer)res).intValue(); + } + + private int invoke(Object target, String method, int arg1, double arg2) + throws Exception + { + java.lang.reflect.Method m = + target.getClass().getMethod(method, new Class[] { int.class, double.class }); + Object res = m.invoke(target, new Object[] { new Integer(arg1), new Double(arg2)}); + return ((Integer)res).intValue(); + } + + private int invoke(Object target, String method, int arg1, String arg2, Object arg3) + throws Exception + { + java.lang.reflect.Method m = + target.getClass().getMethod(method, new Class[] { int.class, String.class, Object.class }); + Object res = m.invoke(target, new Object[] { new Integer(arg1), arg2, arg3}); + return ((Integer)res).intValue(); + } + + public void testInvokeinterface() throws Exception { + // JIRA JASSIST-60 + CtClass cc = sloader.get("test3.InvokeIntf"); + CtMethod mth = cc.getDeclaredMethod("doit"); + ExprEditor e = new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + String block = "{$_=$proceed($$);}"; + m.replace(block); + } + }; + mth.instrument(e); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(7, invoke(obj, "test")); + } + + public void testInvokeArrayObj() throws Exception { + // JIRA JASSIST-61 + CtClass cc = sloader.get("test3.InvokeArray"); + CtMethod mth = cc.getDeclaredMethod("doit"); + ExprEditor e = new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + String block = "{$_=$proceed($$);}"; + m.replace(block); + } + }; + mth.instrument(e); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(3, invoke(obj, "test")); + } + + public void testNewExprTry() throws Exception { + CtClass cc = sloader.get("test3.NewExprTryCatch"); + CtMethod mth = cc.getDeclaredMethod("instrumentMe"); + ExprEditor e = new ExprEditor() { + public void edit(NewExpr m) throws CannotCompileException { + String block = "{$_=$proceed($$);}"; + m.replace(block); + } + }; + mth.instrument(e); + + // JIRA JASSIST-52 + CtMethod mth2 = cc.getDeclaredMethod("me2"); + ExprEditor e2 = new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + String block = "{try{$_=$proceed($$);} catch(Throwable t) {}}"; + m.replace(block); + } + }; + //mth2.instrument(e2); + + /* + // JIRA JASSIST-53 + CtClass cc2 = sloader.get("test3.NewExprTryCatch2"); + CtBehavior mth3 = cc2.getDeclaredConstructors()[0]; + ExprEditor e3 = new ExprEditor() { + public void edit(ConstructorCall m) throws CannotCompileException { + String block = "{try {$_=$proceed($$);} catch (Throwable t) {}}"; + m.replace(block); + } + }; + mth3.instrument(e3); + */ + + cc.writeFile(); + // cc2.writeFile(); + Object obj = make(cc.getName()); + assertEquals(0, invoke(obj, "test")); + // Object obj2 = make(cc2.getName()); + } + + public void testJIRA63() throws Exception { + frameTypeTest(2); + frameTypeTest(7); + } + + private void frameTypeTest(final int initializerRepeatCount) throws Exception { + // Get a class + final CtClass cTst = sloader.get("test3.JIRA63"); + cTst.getClassFile().setMajorVersion(ClassFile.JAVA_6); + try { + // Create an initializer for the fields + String initializer = "test3.JIRA63Helper"; + for(int i=0; i < initializerRepeatCount; i++) + initializer += ".getAnObject(new Integer(1))"; + + initializer += ";"; + + // Add some fields + final CtClass cObj = sloader.get("java.lang.Object"); + for(int i = 0; i < 7; i++) + cTst.addField(new CtField(cObj, "a" + i, cTst), initializer); + + // Modify the constructors + for(final CtConstructor m : cTst.getConstructors()) { + m.insertAfter(initializer, true); + m.insertBefore(initializer); + } + + // Get the byte code. + // cTst.toBytecode(); + cTst.writeFile(); + //make(cTst.getName()); + } + finally { + cTst.detach(); + } + } + + public void testInsertBeforeType() throws Exception { + CtClass cc = sloader.get("test3.InsertBeforeType"); + CtMethod m1 = cc.getDeclaredMethod("foo"); + m1.insertBefore("value = $type.getName();"); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(5, invoke(obj, "test")); + } + + public void testTransformNewClass() throws Exception { + CodeConverter conv = new CodeConverter(); + conv.replaceNew(sloader.get("test3.TransNewClassOld"), + sloader.get("test3.TransNewClassNew")); + CtClass cc = sloader.get("test3.TransNewClass"); + cc.instrument(conv); + cc.writeFile(); + + CtClass cc2 = sloader.get("test3.TransNewClass$TransNewClass2"); + cc2.instrument(conv); + cc2.writeFile(); + + Object obj = make(cc.getName()); + assertEquals(170, invoke(obj, "test")); + Object obj2 = make(cc2.getName()); + assertEquals(50, invoke(obj2, "test")); + } + + public void testInsertAfter() throws Exception { + CtClass cc = sloader.get("test3.InsertAfter"); + CtMethod m1 = cc.getDeclaredMethod("foo"); + m1.insertAfter("k++;", true); + CtConstructor cons = cc.getConstructor("()V"); + cons.insertAfter("k++;", true); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(6, invoke(obj, "test")); + } + + public void testInsertSwitch() throws Exception { + CtClass cc = sloader.get("test3.Switch"); + CtMethod m1 = cc.getDeclaredMethod("foo"); + String sourceCode = "{" + + "System.out.println(\"Bla!\");" + + "}"; + String toInsert = + " try " + + " { " + + sourceCode + + " } " + + " catch(Throwable e) " + + " { " + + " e.printStackTrace(); " + + " } "; + + m1.insertBefore(toInsert); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(0, invoke(obj, "test")); + } + + public void testStringBuilder() throws Exception { + CtClass cc = sloader.get("test3.StrBuild"); + CtMethod mth = cc.getDeclaredMethod("test"); + ExprEditor ed = new ExprEditor() { + public void edit(MethodCall m) throws CannotCompileException { + String block = "$_=$proceed($$);"; + m.replace(block); + } + }; + mth.instrument(ed); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals('t', invoke(obj, "test")); + } + + public void testInheritCons() throws Exception { + CtClass s = sloader.get("test3.InheritCons"); + CtClass cc = sloader.makeClass("test3.InheritCons2", s); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals("test3.InheritCons2", obj.getClass().getName()); + assertEquals(3, obj.getClass().getDeclaredConstructors().length); + + cc = sloader.makeClass("InheritCons3", s); + cc.writeFile(); + obj = make(cc.getName()); + assertEquals("InheritCons3", obj.getClass().getName()); + assertEquals(2, obj.getClass().getDeclaredConstructors().length); + } + + public void testAddInterfaceMethod() throws Exception { + CtClass cc = sloader.makeInterface("test3.AddIntfMth"); + CtMethod m = CtMethod.make("void foo();", cc); + cc.addMethod(m); + assertTrue(Modifier.isPublic(m.getModifiers())); + CtMethod m2 = CtMethod.make("public void foo2();", cc); + cc.addMethod(m2); + assertTrue(Modifier.isPublic(m2.getModifiers())); + CtMethod m3 = CtMethod.make("public void foo3() {}", cc); + try { + cc.addMethod(m3); + fail(); + } + catch (CannotCompileException e) { + // System.out.println(e); + } + } + + // JIRA-67 + public void test67() throws Exception { + ClassPool pool = new ClassPool(true); + CtClass ctc = pool.makeClass("test3.Clazz67"); + StringBuilder sb = new StringBuilder("public void test() {"); + for (int i = 0; i < 1000; i++) { + sb.append("for(int i=0; i<10; i++) {}"); // line 1 + // sb.append("for(int i=0; i<10; i++) {int j=i;}"); // line 2 + } + + sb.append("}"); + ctc.addMethod(CtNewMethod.make(sb.toString(), ctc)); + ctc.debugWriteFile(); + ctc.toClass().newInstance(); + } + + // JIRA-83 + public void testEmptyCatch() throws Exception { + CtClass cc = sloader.get("test3.EmptyCatch"); + CtMethod mth = cc.getDeclaredMethod("test"); + mth.instrument(new ExprEditor() { + public void edit(Handler h) throws CannotCompileException { + try { + assertEquals(null, h.getType()); + assertTrue(h.isFinally()); + } catch (NotFoundException e) {} + } + }); + } +} diff --git a/src/test/javassist/JvstTest4.java b/src/test/javassist/JvstTest4.java new file mode 100644 index 00000000..016420d9 --- /dev/null +++ b/src/test/javassist/JvstTest4.java @@ -0,0 +1,569 @@ +package javassist; + +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.util.Collection; +import java.util.HashSet; +import javassist.bytecode.*; +import javassist.bytecode.annotation.*; +import javassist.expr.*; + +public class JvstTest4 extends JvstTestRoot { + public JvstTest4(String name) { + super(name); + } + + public void testInsertLocalVars() throws Exception { + CtClass cc = sloader.get("test4.LocalVars"); + + CtMethod m1 = cc.getDeclaredMethod("run"); + m1.getMethodInfo().getCodeAttribute().insertLocalVar(2, 20); + CtMethod m2 = cc.getDeclaredMethod("run2"); + m2.getMethodInfo().getCodeAttribute().insertLocalVar(2, 0x101); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(10, invoke(obj, "run")); + assertEquals(10, invoke(obj, "run2")); + } + + public void testCodeConv() throws Exception { + CtClass cc = sloader.get("test4.CodeConv"); + CtMethod m1 = cc.getDeclaredMethod("m1"); + CtMethod m2 = cc.getDeclaredMethod("m2"); + CtMethod m3 = cc.getDeclaredMethod("m3"); + CodeConverter conv = new CodeConverter(); + conv.insertAfterMethod(m1, m3); + conv.insertBeforeMethod(m2, m3); + cc.instrument(conv); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(111033, invoke(obj, "run")); + } + + public void testCodeConv2() throws Exception { + CtClass cc = sloader.get("test4.CodeConv2"); + CtField f = cc.getDeclaredField("field"); + CtField f2 = cc.getDeclaredField("sf"); + CtMethod run = cc.getDeclaredMethod("run"); + CodeConverter conv = new CodeConverter(); + conv.replaceFieldRead(f, cc, "read"); + conv.replaceFieldWrite(f, cc, "write"); + conv.replaceFieldRead(f2, cc, "read"); + conv.replaceFieldWrite(f2, cc, "write"); + run.instrument(conv); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(14001600, invoke(obj, "run")); + } + + public void testInsGap() throws Exception { + CtClass cc = sloader.get("test4.GapSwitch"); + ExprEditor ed = new ExprEditor() { + public void edit(MethodCall c) throws CannotCompileException { + c.replace("{ value++; $_ = $proceed($$); }"); + } + }; + + CtMethod m1 = cc.getDeclaredMethod("run"); + m1.instrument(ed); + CtMethod m2 = cc.getDeclaredMethod("run2"); + m2.instrument(ed); + + final CtMethod m3 = cc.getDeclaredMethod("run3"); + m3.instrument(new ExprEditor() { + public void edit(MethodCall c) throws CannotCompileException { + CodeIterator it = m3.getMethodInfo().getCodeAttribute().iterator(); + try { + it.insertGap(c.indexOfBytecode(), 5000); + } catch (BadBytecode e) { + throw new CannotCompileException(e); + } + } + }); + + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(1010, invoke(obj, "run")); + assertEquals(1100, invoke(obj, "run2")); + assertEquals(12222, invoke(obj, "run3")); + } + + public void testAnnotationCheck() throws Exception { + CtClass cc = sloader.get("test4.Anno"); + CtMethod m1 = cc.getDeclaredMethod("foo"); + CtField f = cc.getDeclaredField("value"); + + assertTrue(cc.hasAnnotation(test4.Anno1.class)); + assertFalse(cc.hasAnnotation(java.lang.annotation.Documented.class)); + assertEquals("empty", ((test4.Anno1)cc.getAnnotation(test4.Anno1.class)).value()); + assertNull(cc.getAnnotation(Deprecated.class)); + + assertTrue(m1.hasAnnotation(test4.Anno1.class)); + assertFalse(m1.hasAnnotation(java.lang.annotation.Documented.class)); + assertTrue(m1.getAnnotation(test4.Anno1.class) != null); + assertNull(m1.getAnnotation(Deprecated.class)); + + assertTrue(f.hasAnnotation(test4.Anno1.class)); + assertFalse(f.hasAnnotation(java.lang.annotation.Documented.class)); + assertTrue(f.getAnnotation(test4.Anno1.class) != null); + assertNull(f.getAnnotation(Deprecated.class)); + } + + public void testRename() throws Exception { + CtClass cc = sloader.get("test4.Rename"); + cc.setName("test4.Rename2"); + cc.rebuildClassFile(); + cc.writeFile(); + CtClass cc2 = sloader.get("test4.IRename"); + cc2.replaceClassName("test4.Rename", "test4.Rename2"); + cc2.rebuildClassFile(); + cc2.writeFile(); + Object obj = make(cc.getName()); + assertEquals(4, invoke(obj, "run")); + } + + public void testRename2() throws Exception { + CtClass cc = sloader.get("test4.Signature"); + cc.setName("test4.Sig"); + cc.rebuildClassFile(); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(3, invoke(obj, "run")); + } + + public void testJIRA93() throws Exception { + ClassPool cp = ClassPool.getDefault(); + CtClass cc = sloader.getCtClass("test4.JIRA93"); + CtMethod m = cc.getDeclaredMethod("foo"); + + m.addLocalVariable("bar", CtClass.longType); + // The original bug report includes the next line. + // But this is not a bug. + //m.insertAfter("bar;", true); + // Instead, the following code is OK. + m.insertBefore("bar = 0;"); + m.insertAfter("bar;", false); + + cc.writeFile(); + Object obj = make(cc.getName()); + } + + public void testNewRemover() throws Exception { + CtClass cc = sloader.get("test4.NewRemover"); + CtMethod mth = cc.getDeclaredMethod("make"); + mth.getMethodInfo().rebuildStackMap(cc.getClassPool()); + mth.getMethodInfo().rebuildStackMapForME(cc.getClassPool()); + //cc.debugWriteFile("debug"); + CodeConverter conv = new CodeConverter(); + conv.replaceNew(cc, cc, "make2"); + mth.instrument(conv); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(10, invoke(obj, "run")); + } + + public void testClassFileWriter() throws Exception { + ClassFileWriter cfw = new ClassFileWriter(ClassFile.JAVA_4, 0); + ClassFileWriter.ConstPoolWriter cpw = cfw.getConstPool(); + + ClassFileWriter.FieldWriter fw = cfw.getFieldWriter(); + fw.add(AccessFlag.PUBLIC, "value", "J", null); + fw.add(AccessFlag.PROTECTED | AccessFlag.STATIC, "value2", "Ljava/lang/String;", null); + + ClassFileWriter.MethodWriter mw = cfw.getMethodWriter(); + + mw.begin(AccessFlag.PUBLIC, MethodInfo.nameInit, "()V", null, null); + mw.add(Opcode.ALOAD_0); + mw.addInvoke(Opcode.INVOKESPECIAL, "java/lang/Object", MethodInfo.nameInit, "()V"); + mw.add(Opcode.RETURN); + mw.codeEnd(1, 1); + mw.end(null, null); + + mw.begin(AccessFlag.PUBLIC, "move", "(II)V", null, null); + mw.add(Opcode.ALOAD_0); + mw.addInvoke(Opcode.INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;"); + mw.add(Opcode.POP); + mw.add(Opcode.RETURN); + mw.add(Opcode.POP); + mw.add(Opcode.RETURN); + mw.codeEnd(1, 3); + mw.addCatch(0, 4, 6, cpw.addClassInfo("java/lang/Exception")); + mw.addCatch(0, 4, 6, cpw.addClassInfo("java/lang/Throwable")); + mw.end(null, null); + + String[] exceptions = { "java/lang/Exception", "java/lang/NullPointerException" }; + mw.begin(AccessFlag.PUBLIC, "move2", "()V", exceptions, null); + mw.add(Opcode.RETURN); + mw.codeEnd(0, 1); + StackMapTable.Writer stack = new StackMapTable.Writer(32); + stack.sameFrame(1); + mw.end(stack, null); + + mw.begin(AccessFlag.PUBLIC, "foo", "()I", null, null); + mw.add(Opcode.ICONST_2); + mw.add(Opcode.IRETURN); + mw.codeEnd(1, 1); + mw.end(null, null); + + byte[] out = cfw.end(AccessFlag.PUBLIC, cpw.addClassInfo("test4/WrittenFile"), + cpw.addClassInfo("java/lang/Object"), + null, null); + FileOutputStream fos = new FileOutputStream("test4/WrittenFile.class"); + fos.write(out); + fos.close(); + Object obj = make("test4.WrittenFile"); + assertNotNull(obj); + assertEquals(2, invoke(obj, "foo")); + } + + public void testClassFileWriter2() throws Exception { + ClassFileWriter cfw = new ClassFileWriter(ClassFile.JAVA_4, 0); + ClassFileWriter.ConstPoolWriter cpw = cfw.getConstPool(); + + ClassFileWriter.FieldWriter fw = cfw.getFieldWriter(); + fw.add(AccessFlag.PUBLIC | AccessFlag.STATIC, "value", "I", null); + + ClassFileWriter.MethodWriter mw = cfw.getMethodWriter(); + + mw.begin(AccessFlag.PUBLIC, MethodInfo.nameInit, "()V", null, null); + mw.add(Opcode.ALOAD_0); + mw.addInvoke(Opcode.INVOKESPECIAL, "java/lang/Object", MethodInfo.nameInit, "()V"); + mw.add(Opcode.RETURN); + mw.codeEnd(1, 1); + mw.end(null, null); + + String[] exceptions = { "java/lang/Exception" }; + mw.begin(AccessFlag.PUBLIC | AccessFlag.ABSTRACT, "move", "(II)V", exceptions, null); + mw.end(null, null); + + int thisClass = cpw.addClassInfo("test4/WrittenFile2"); + int superClass = cpw.addClassInfo("java/lang/Object"); + + cfw.end(new DataOutputStream(new FileOutputStream("test4/WrittenFile2.class")), + AccessFlag.PUBLIC | AccessFlag.ABSTRACT, thisClass, superClass, + null, null); + + File f = new File("test4/WrittenFile2.class"); + byte[] file = new byte[(int)f.length()]; + FileInputStream fis = new FileInputStream(f); + fis.read(file); + fis.close(); + + byte[] out = cfw.end(AccessFlag.PUBLIC | AccessFlag.ABSTRACT, thisClass, + superClass, null, null); + + assertEquals(out.length, file.length); + for (int i = 0; i < out.length; i++) + assertEquals(out[i], file[i]); + + CtClass sub = dloader.makeClass("test4.WrittenFile2sub", dloader.get("test4.WrittenFile2")); + sub.addMethod(CtMethod.make("public void move(int i, int j) {}", sub)); + sub.addMethod(CtMethod.make("public int foo() { move(0, 1); return 1; }", sub)); + sub.writeFile(); + Object obj = make("test4.WrittenFile2sub"); + assertEquals(1, invoke(obj, "foo")); + } + + public void testClassFileWriter3() throws Exception { + ClassFileWriter cfw = new ClassFileWriter(ClassFile.JAVA_4, 0); + ClassFileWriter.ConstPoolWriter cpw = cfw.getConstPool(); + int superClass = cpw.addClassInfo("java/lang/Object"); + + final int syntheticTag = cpw.addUtf8Info("Synthetic"); + ClassFileWriter.AttributeWriter attribute = new ClassFileWriter.AttributeWriter() { + public void write(DataOutputStream out) throws java.io.IOException { + out.writeShort(syntheticTag); + out.writeInt(0); + } + + public int size() { + return 1; + } + }; + + ClassFileWriter.FieldWriter fw = cfw.getFieldWriter(); + fw.add(AccessFlag.PUBLIC, "value", "J", null); + fw.add(AccessFlag.PROTECTED | AccessFlag.STATIC, "value2", "Ljava/lang/String;", attribute); + + ClassFileWriter.MethodWriter mw = cfw.getMethodWriter(); + + mw.begin(AccessFlag.PUBLIC, MethodInfo.nameInit, "()V", null, attribute); + mw.add(Opcode.ALOAD_0); + mw.add(Opcode.INVOKESPECIAL); + mw.add16(cpw.addMethodrefInfo(superClass, cpw.addNameAndTypeInfo(MethodInfo.nameInit, "()V"))); + // mw.addInvoke(Opcode.INVOKESPECIAL, "java/lang/Object", MethodInfo.nameInit, "()V"); + mw.add(Opcode.RETURN); + mw.codeEnd(1, 1); + mw.end(null, null); + + mw.begin(AccessFlag.PUBLIC, "foo", "()I", null, attribute); + mw.add(Opcode.ICONST_2); + mw.add(Opcode.IRETURN); + mw.codeEnd(1, 1); + mw.end(null, null); + + int thisClass = cpw.addClassInfo("test4/WrittenFile3"); + cfw.end(new DataOutputStream(new FileOutputStream("test4/WrittenFile3.class")), + AccessFlag.PUBLIC, thisClass, superClass, + null, attribute); + + File f = new File("test4/WrittenFile3.class"); + byte[] file = new byte[(int)f.length()]; + FileInputStream fis = new FileInputStream(f); + fis.read(file); + fis.close(); + + byte[] out = cfw.end(AccessFlag.PUBLIC, thisClass, superClass, + null, attribute); + + assertEquals(out.length, file.length); + for (int i = 0; i < out.length; i++) + assertEquals(out[i], file[i]); + + Object obj = make("test4.WrittenFile3"); + assertNotNull(obj); + assertEquals(2, invoke(obj, "foo")); + } + + public void testCtArray() throws Exception { + CtClass cc = sloader.get("int"); + assertEquals(Modifier.FINAL | Modifier.PUBLIC, cc.getModifiers()); + cc = sloader.get("int[]"); + assertEquals(Modifier.FINAL | Modifier.PUBLIC, cc.getModifiers()); + cc = sloader.get("java.lang.String[]"); + assertEquals(Modifier.FINAL | Modifier.PUBLIC, cc.getModifiers()); + CtClass[] intfs = cc.getInterfaces(); + assertEquals(Cloneable.class.getName(), intfs[0].getName()); + assertEquals(java.io.Serializable.class.getName(), intfs[1].getName()); + cc = sloader.get("test4.CtArrayTest[]"); + assertEquals(Modifier.FINAL | Modifier.PUBLIC, cc.getModifiers()); + } + + public void testAnalysisType() throws Exception { + testAnalysisType2(sloader.get("int[]"), 1); + testAnalysisType2(sloader.get("java.lang.String[][]"), 2); + sloader.makeClass("A"); + testAnalysisType2(sloader.getCtClass("A"), 0); + testAnalysisType2(sloader.getCtClass("A[]"), 1); + testAnalysisType2(sloader.getCtClass("A[][]"), 2); + } + + private void testAnalysisType2(CtClass cc, int size) throws Exception { + javassist.bytecode.analysis.Type t = javassist.bytecode.analysis.Type.get(cc); + assertEquals(cc.getName(), size, t.getDimensions()); + } + + public void testArrayType() throws Exception { + CtClass at = sloader.get("java.lang.Object[]"); + CtClass[] intfs = at.getInterfaces(); + assertEquals(intfs.length, 2); + assertEquals(intfs[0].getName(), java.lang.Cloneable.class.getName()); + assertEquals(intfs[1].getName(), java.io.Serializable.class.getName()); + + assertTrue(at.subtypeOf(sloader.get(java.lang.Object.class.getName()))); + assertTrue(at.subtypeOf(intfs[0])); + assertTrue(at.subtypeOf(intfs[1])); + assertTrue(at.subtypeOf(intfs[1])); + CtClass subt = sloader.get(java.text.CharacterIterator.class.getName()); + assertFalse(at.subtypeOf(subt)); + } + + public void testGetFieldDesc() throws Exception { + CtClass cc = sloader.get("test4.GetFieldDesc"); + cc.getDeclaredField("f", "I"); + cc.getField("s", "Ljava/lang/String;"); + CtClass cc2 = sloader.get("test4.GetFieldDescSub"); + assertEquals(cc2.getField("s", "Ljava/lang/String;").getDeclaringClass().getName(), + "test4.GetFieldDesc"); + assertEquals(cc2.getField("s", "I").getDeclaringClass().getName(), + "test4.GetFieldDescSub"); + } + + public void testMakeMethod() throws CannotCompileException { + CtClass ctClass = sloader.makeClass("test4.MakeMethod2"); + CtNewMethod.make("public String foox(){return test4.MakeMethod.foo();}", ctClass); + CtNewMethod.make("public String foo(){return test4.MakeMethod.foo();}", ctClass); + } + + public void testVarArgs() throws Exception { + CtClass cc = sloader.get("test4.VarArgs"); + CtMethod m = CtMethod.make("public int foo(int i, String[] args) { return args.length; }", cc); + m.setModifiers(m.getModifiers() | Modifier.VARARGS); + cc.addMethod(m); + m = CtMethod.make("public int run() { return goo(7, new int[] { 1, 2, 3 }); }", cc); + cc.addMethod(m); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(3, invoke(obj, "run")); + } + + public void testGetAllRef() throws Exception { + CtClass cc = sloader.get("test4.GetAllRef"); + ClassFile cf = cc.getClassFile(); + AttributeInfo ainfo + = cf.getAttribute(AnnotationsAttribute.visibleTag); + ClassMap map = new ClassMap(); + map.put("test4.GetAllRefAnno", "test4.GetAllRefAnno2"); + map.put("test4.GetAllRefEnum", "test4.GetAllRefEnum2"); + map.put("java.lang.String", "java.lang.StringBuilder"); + cf.addAttribute(ainfo.copy(cf.getConstPool(), map)); + cc.writeFile(); + cc.detach(); + + cc = dloader.get(cc.getName()); + test4.GetAllRefAnno2 anno + = (test4.GetAllRefAnno2)cc.getAnnotation(test4.GetAllRefAnno2.class); + assertEquals(test4.GetAllRefEnum2.A, anno.getA()); + assertEquals(StringBuilder.class, anno.getC()); + } + + public void testGetAllRefB() throws Exception { + CtClass cc = sloader.get("test4.GetAllRefB"); + ClassMap map = new ClassMap(); + map.put("test4.GetAllRefAnno", "test4.GetAllRefAnno2"); + map.put("test4.GetAllRefEnum", "test4.GetAllRefEnum2"); + map.put("java.lang.String", "java.lang.StringBuilder"); + cc.replaceClassName(map); + //cc.replaceClassName("test4.GetAllRefAnno", "test4.GetAllRefAnno2"); + cc.writeFile(); + + cc = dloader.get(cc.getName()); + test4.GetAllRefAnno2 anno + = (test4.GetAllRefAnno2)cc.getAnnotation(test4.GetAllRefAnno2.class); + assertEquals(test4.GetAllRefEnum2.A, anno.getA()); + assertEquals(StringBuilder.class, anno.getC()); + /* + AnnotationsAttribute aainfo = (AnnotationsAttribute) + cc.getClassFile().getAttribute(AnnotationsAttribute.visibleTag); + Annotation[] a = aainfo.getAnnotations(); + System.err.println(a[0].getTypeName()); + System.err.println(a[0]); + */ + } + + public void testGetAllRefC() throws Exception { + CtClass cc = sloader.get("test4.GetAllRefC"); + HashSet set = new HashSet(); + set.add("java.lang.Object"); + set.add("java.lang.String"); + set.add("test4.GetAllRefC"); + set.add("test4.GetAllRefAnno"); + set.add("test4.GetAllRefEnum"); + set.add("test4.GetAllRefAnnoC"); + set.add("test4.GetAllRefAnnoC2"); + set.add("test4.GetAllRefAnnoC3"); + set.add("test4.GetAllRefAnnoC4"); + java.util.Collection<String> refs + = (java.util.Collection<String>)cc.getRefClasses(); + assertEquals(set.size(), refs.size()); + for (String s: refs) { + assertTrue(set.contains(s)); + } + } + + public void testGetAllRefInner() throws Exception { + HashSet set = new HashSet(); + set.add("java.lang.Object"); + set.add("test4.GetAllRefInnerTest"); + set.add("test4.GetAllRefInnerTest$1"); + set.add("test4.GetAllRefInnerTest$2"); + CtClass cc = sloader.get("test4.GetAllRefInnerTest"); + int size = 0; + for (Object s: cc.getRefClasses()) { + assertTrue((String)s, set.contains(s)); + ++size; + } + + assertEquals(set.size(), size); + } + + public void testNestedClass() throws Exception { + CtClass cc = sloader.get("test4.NestedClass$1"); + CtClass[] tab = cc.getNestedClasses(); + assertEquals(1, tab.length); + assertEquals("test4.NestedClass$1$1", tab[0].getName()); + + cc = sloader.get("test4.NestedClass$1$1"); + tab = cc.getNestedClasses(); + assertEquals(0, tab.length); + + cc = sloader.get("test4.NestedClass"); + tab = cc.getNestedClasses(); + assertEquals(4, tab.length); + for (CtClass c: tab) { + String name = c.getName(); + assertTrue(name.equals("test4.NestedClass$N") + || name.equals("test4.NestedClass$S") + || name.equals("test4.NestedClass$1") + || name.equals("test4.NestedClass$1In")); + } + + cc = sloader.get("test4.NestedClass$1In"); + tab = cc.getNestedClasses(); + assertEquals(0, tab.length); + } + + public void testGetClasses() throws Exception { + CtClass cc = sloader.get("test4.NestedClass"); + CtClass[] tab = cc.getDeclaredClasses(); + assertEquals(4, tab.length); + for (CtClass c: tab) { + String name = c.getName(); + assertTrue(name.equals("test4.NestedClass$N") + || name.equals("test4.NestedClass$S") + || name.equals("test4.NestedClass$1") + || name.equals("test4.NestedClass$1In")); + } + + cc = sloader.get("test4.NestedClass$1In"); + tab = cc.getDeclaredClasses(); + assertEquals(0, tab.length); + } + + public void testImportPac() throws Exception { + CtClass cc = sloader.makeClass("test4.TestImpP"); + sloader.importPackage("test4.NewImportPac"); + try { + cc.addMethod(CtNewMethod.make( + "public int foo(){ " + + " ImportPac obj = new ImportPac();" + + " return obj.getClass().getName().length(); }", cc)); + fail("ImportPac was found"); + } + catch (CannotCompileException e) {} + + cc.addMethod(CtNewMethod.make( + "public int bar(){ " + + " NewImportPac obj = new NewImportPac();" + + " return obj.getClass().getName().length(); }", cc)); + sloader.clearImportedPackages(); + } + + public void testLength() throws Exception { + CtClass cc = sloader.makeClass("test4.LengthTest"); + cc.addMethod(CtNewMethod.make( + "public int len(String s){ " + + " return s.length(); }", cc)); + cc.addField(CtField.make("int length = 100;", cc)); + cc.addConstructor(CtNewConstructor.defaultConstructor(cc)); + cc.addMethod(CtNewMethod.make( + "public int run(){ " + + " test4.LengthTest t = new test4.LengthTest();" + + " return len(\"foo\") + t.length + test4.length.m(); }", cc)); + try { + cc.addMethod(CtNewMethod.make( + "public int run(){ " + + " return test4no.length.m(); }", cc)); + fail("test4no was found!"); + } + catch (CannotCompileException e) { + System.err.println(e); + } + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(110, invoke(obj, "run")); + } +} diff --git a/src/test/javassist/JvstTestRoot.java b/src/test/javassist/JvstTestRoot.java new file mode 100644 index 00000000..86d6c1ca --- /dev/null +++ b/src/test/javassist/JvstTestRoot.java @@ -0,0 +1,53 @@ +package javassist; + +import junit.framework.*; +import java.lang.reflect.Method; + +public class JvstTestRoot extends TestCase { + // the directory where all compiled class files are found. + public static final String PATH = "../eclipse-output/classes/"; + + // the directory where javassist.jar is found. + public static final String JAR_PATH = "../"; + + ClassPool sloader, dloader; + Loader cloader; + + public JvstTestRoot(String name) { + super(name); + } + + protected void print(String msg) { + System.out.println(msg); + } + + protected void print(Exception e) { + e.printStackTrace(); + } + + protected void setUp() throws Exception { + sloader = ClassPool.getDefault(); + dloader = new ClassPool(null); + dloader.appendSystemPath(); + dloader.insertClassPath("."); + cloader = new Loader(dloader); + } + + protected Object make(String name) throws Exception { + return cloader.loadClass(name).newInstance(); + } + + protected int invoke(Object target, String method) throws Exception { + Method m = target.getClass().getMethod(method, new Class[0]); + Object res = m.invoke(target, new Object[0]); + return ((Integer)res).intValue(); + } + + protected int invoke(Object target, String method, int arg) + throws Exception { + Method m = + target.getClass().getMethod(method, new Class[] { int.class }); + Object res = m.invoke(target, new Object[] { new Integer(arg)}); + return ((Integer) res).intValue(); + } +} diff --git a/src/test/javassist/LoaderTestByRandall.java b/src/test/javassist/LoaderTestByRandall.java new file mode 100644 index 00000000..1b8825f6 --- /dev/null +++ b/src/test/javassist/LoaderTestByRandall.java @@ -0,0 +1,98 @@ +/*
+ * Copyright (c) Brett Randall 2004. All rights reserved.
+ *
+ * Created on Jul 20, 2004
+ */
+
+package javassist;
+
+import junit.framework.TestCase;
+
+/**
+ * @author brandall
+ */
+public class LoaderTestByRandall extends TestCase {
+
+ ClassPool cp;
+ Loader loader;
+
+ public LoaderTestByRandall(String name) {
+ super(name);
+ }
+
+ public void setUp() {
+ cp = new ClassPool();
+ cp.appendSystemPath();
+ loader = new Loader(cp);
+ }
+
+ public void testLoadGoodClass() throws Exception {
+ String name = "javassist.LoaderTestByRandall";
+ cp.get(name);
+ Class clazz = loader.loadClass(name);
+ assertEquals("Class not loaded by loader",
+ loader, clazz.getClassLoader());
+ }
+
+ public void testLoadGoodClassByDelegation() throws Exception {
+ Class clazz = loader.loadClass("java.lang.String");
+ }
+
+ public void testLoadBadClass() {
+ try {
+ Class clazz = loader.loadClass("never.going.to.find.Class");
+ fail("Expected ClassNotFoundException to be thrown");
+ } catch (ClassNotFoundException e) {
+ // expected
+ }
+ }
+
+ public void testLoadBadClassByDelegation() {
+ try {
+ Class clazz = loader.loadClass("java.never.going.to.find.Class");
+ fail("Expected ClassNotFoundException to be thrown");
+ } catch (ClassNotFoundException e) {
+ // expected
+ }
+ }
+
+ public void testLoadBadCodeModification() throws Exception {
+ String classname = "javassist.LoaderTestByRandall";
+
+ Translator trans = new Translator() {
+ public void start(ClassPool pool)
+ throws NotFoundException, CannotCompileException
+ {
+ }
+
+ public void onLoad(ClassPool pool, String classname)
+ throws NotFoundException, CannotCompileException
+ {
+ String body = new String("this will never compile");
+ CtClass clazz = pool.get(classname);
+ CtMethod newMethod = CtNewMethod.make(CtClassType.voidType,
+ "wontCompileMethod",
+ new CtClass[] {},
+ new CtClass[] {},
+ body,
+ clazz);
+ clazz.addMethod(newMethod);
+ }
+ };
+
+ loader.addTranslator(cp, trans);
+
+ try {
+ Class clazz = loader.loadClass(classname);
+ fail("Expected loader to throw ClassNotFoundException " +
+ "caused by CannotCompileException");
+ } catch (ClassNotFoundException e) {
+ // expected
+ System.out.println(e);
+ assertEquals("ClassNotFoundException was not caused "
+ + "by CannotCompileException",
+ CannotCompileException.class,
+ e.getCause().getClass());
+ }
+ }
+}
diff --git a/src/test/javassist/SetterTest.java b/src/test/javassist/SetterTest.java new file mode 100644 index 00000000..f11429ad --- /dev/null +++ b/src/test/javassist/SetterTest.java @@ -0,0 +1,111 @@ +package javassist;
+import java.lang.reflect.Method;
+
+import junit.framework.TestCase;
+
+public class SetterTest extends TestCase {
+
+ ClassPool pool;
+
+ public SetterTest(String name) {
+ super(name);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ pool = ClassPool.getDefault();
+ }
+
+ /**
+ * Tests a getter only on a field without a Modifier.
+ *
+ * @throws Exception
+ */
+ public void testFieldGetter() throws Exception {
+ CtClass clazz = pool.makeClass("HasFieldGetter");
+ clazz.setSuperclass(pool.get("java.lang.Object"));
+ CtField field = new CtField(CtClass.booleanType, "broken", clazz);
+ clazz.addField(field, "true");
+ clazz.addMethod(CtNewMethod.getter("isBroken", field));
+ Class _class = clazz.toClass();
+
+ Object object = _class.newInstance();
+ check(_class, object, true);
+ }
+
+ /**
+ * Tests a getter and a setter on a field without a Modifier.
+ *
+ * @throws Exception
+ */
+ public void testFieldGetterSetter() throws Exception {
+ CtClass clazz = pool.makeClass("HasFieldGetterSetter");
+ clazz.setSuperclass(pool.get("java.lang.Object"));
+ CtField field = new CtField(CtClass.booleanType, "broken", clazz);
+ clazz.addField(field, "true");
+ clazz.addMethod(CtNewMethod.getter("isBroken", field));
+ clazz.addMethod(CtNewMethod.setter("setBroken", field));
+ Class _class = clazz.toClass();
+
+ Object object = _class.newInstance();
+
+ set(_class, object, false);
+ check(_class, object, false);
+ }
+
+ /**
+ * Tests a getter only on a field with Modifier.STATIC.
+ *
+ * @throws Exception
+ */
+ public void testStaticFieldGetter() throws Exception {
+ CtClass clazz = pool.makeClass("HasStaticFieldGetter");
+ clazz.setSuperclass(pool.get("java.lang.Object"));
+ CtField field = new CtField(CtClass.booleanType, "broken", clazz);
+ field.setModifiers(Modifier.STATIC);
+ clazz.addField(field, "true");
+ clazz.addMethod(CtNewMethod.getter("isBroken", field));
+ Class _class = clazz.toClass();
+
+ Object object = _class.newInstance();
+ check(_class, object, true);
+ }
+
+ /**
+ * Tests a getter and setter on a field with Modifier.STATIC.
+ *
+ * @throws Exception
+ */
+ public void testStaticFieldGetterSetter() throws Exception {
+ CtClass clazz = pool.makeClass("HasStaticFieldGetterSetter");
+ clazz.setSuperclass(pool.get("java.lang.Object"));
+ CtField field = new CtField(CtClass.booleanType, "broken", clazz);
+ field.setModifiers(Modifier.STATIC);
+ clazz.addField(field, "true");
+ clazz.addMethod(CtNewMethod.getter("isBroken", field));
+ clazz.addMethod(CtNewMethod.setter("setBroken", field));
+ Class _class = clazz.toClass();
+
+ Object object = _class.newInstance();
+
+ set(_class, object, false);
+ check(_class, object, false);
+ }
+
+ private void check(Class _class, Object object, boolean shouldBe)
+ throws Exception
+ {
+ Method method = _class.getMethod("isBroken", new Class[] {});
+ Boolean result = (Boolean) method.invoke(object, new Object[] {});
+ assertEquals("boolean is wrong value",
+ shouldBe, result.booleanValue());
+ }
+
+ private void set(Class _class, Object object, boolean willBe)
+ throws Exception
+ {
+ Method method = _class.getMethod("setBroken",
+ new Class[] {Boolean.TYPE});
+ method.invoke(object, new Object[] {new Boolean(willBe)});
+ }
+}
diff --git a/src/test/javassist/bytecode/BytecodeTest.java b/src/test/javassist/bytecode/BytecodeTest.java new file mode 100644 index 00000000..27fa0b5a --- /dev/null +++ b/src/test/javassist/bytecode/BytecodeTest.java @@ -0,0 +1,572 @@ +package javassist.bytecode; + +import java.io.*; +import java.lang.reflect.Method; +import junit.framework.*; +import javassist.*; +import javassist.bytecode.annotation.*; + +public class BytecodeTest extends TestCase { + public static final String PATH = JvstTest.PATH; + private ClassPool loader, dloader; + private Loader cloader; + + public BytecodeTest(String name) { + super(name); + } + + protected void print(String msg) { + System.out.println(msg); + } + + protected void setUp() throws Exception { + loader = ClassPool.getDefault(); + dloader = new ClassPool(null); + dloader.appendSystemPath(); + dloader.insertClassPath("."); + cloader = new Loader(dloader); + } + + protected Object make(String name) throws Exception { + return cloader.loadClass(name).newInstance(); + } + + protected int invoke(Object target, String method) throws Exception { + Method m = target.getClass().getMethod(method, new Class[0]); + Object res = m.invoke(target, new Object[0]); + return ((Integer)res).intValue(); + } + + public void testByteVector() throws Exception { + final int N = 257; + Bytecode code = new Bytecode(null); + for (int i = 0; i < N; i++) { + code.add(i); + assertEquals(i + 1, code.length()); + assertEquals((int)(byte)i, code.read(i)); + code.write(i, i + 1); + assertEquals((int)(byte)(i + 1), code.read(i)); + } + + byte[] b = code.copy(); + assertEquals(N, b.length); + for (int i = 0; i < N; i++) + assertEquals((int)(byte)(i + 1), b[i]); + + + code = new Bytecode(null); + code.add(1); + code.addGap(100); + code.add(2); + assertEquals(2, code.read(101)); + } + + public void testLongVector() throws Exception { + LongVector vec = new LongVector(); + assertEquals(LongVector.ASIZE * LongVector.VSIZE, vec.capacity()); + int size = LongVector.ASIZE * LongVector.VSIZE * 3; + for (int i = 0; i < size; i++) { + vec.addElement(new IntegerInfo(i)); + assertEquals(i, ((IntegerInfo)vec.elementAt(i)).value); + assertEquals(i + 1, vec.size()); + } + + size = LongVector.ASIZE * LongVector.VSIZE * 3; + vec = new LongVector(size - 5); + assertEquals(size, vec.capacity()); + for (int i = 0; i < size; i++) { + vec.addElement(new IntegerInfo(i)); + assertEquals(i, ((IntegerInfo)vec.elementAt(i)).value); + assertEquals(i + 1, vec.size()); + } + } + + public void testClone() throws Exception { + ConstPool cp = new ConstPool("test.CloneTest"); + Bytecode bc = new Bytecode(cp); + bc.add(7); + bc.add(11); + Bytecode bc2 = (Bytecode)bc.clone(); + bc2.add(13); + bc2.write(0, 17); + assertEquals(7, bc.read(0)); + assertEquals(2, bc.length()); + assertEquals(3, bc2.length()); + assertEquals(cp, bc2.getConstPool()); + assertTrue(bc.getExceptionTable() != bc2.getExceptionTable()); + } + + public void test2byteLocalVar() throws Exception { + CtClass cc = loader.makeClass("test.LocalVar2"); + CtMethod m = CtNewMethod.abstractMethod(CtClass.intType, "test", + null, null, cc); + Bytecode code = new Bytecode(cc.getClassFile().getConstPool(), 2, 300); + code.addIconst(1); + code.addIstore(255); + code.addIload(255); + code.addIstore(256); + code.addIload(256); + + code.addLconst(1); + code.addLstore(255); + code.addLload(255); + code.addLstore(256); + code.addLload(256); + + code.addFconst(1.0f); + code.addFstore(255); + code.addFload(255); + code.addFstore(256); + code.addFload(256); + + code.addDconst(1.0); + code.addDstore(255); + code.addDload(255); + code.addDstore(256); + code.addDload(256); + + code.addOpcode(Opcode.ACONST_NULL); + code.addAstore(255); + code.addAload(255); + code.addAstore(256); + code.addAload(256); + + code.addIconst(1); + code.addOpcode(Opcode.IRETURN); + + m.getMethodInfo().setCodeAttribute(code.toCodeAttribute()); + m.setModifiers(Modifier.PUBLIC); + cc.addMethod(m); + cc.writeFile(); + + Object obj = make(cc.getName()); + assertEquals(1, invoke(obj, "test")); + } + + public void testBytecode() throws Exception { + final int N = 64; + Bytecode b = new Bytecode(null, 0, 0); + try { + b.write(3, 3); + throw new Exception("out of range"); + } + catch (ArrayIndexOutOfBoundsException e) {} + + try { + b.read(3); + throw new Exception("out of range"); + } + catch (ArrayIndexOutOfBoundsException e) {} + + for (int i = 0; i < N * 3; ++i) { + b.add(i % 100); + assertEquals(i % 100, b.read(i)); + } + + for (int i = 0; i < N * 3; ++i) + assertEquals(i % 100, b.read(i)); + + for (int i = 0; i < N * 3; ++i) { + b.write(i, i % 100); + assertEquals(i % 100, b.read(i)); + } + + for (int i = 0; i < N * 3; ++i) + assertEquals(i % 100, b.read(i)); + } + + public void testBytecode2() throws Exception { + final int N = 64; + Bytecode b = new Bytecode(null, 0, 0); + + for (int i = 0; i < N * 3 / 16; ++i) { + b.addGap(16); + assertEquals(16 * (i + 1), b.length()); + } + + b = new Bytecode(null, 0, 0); + + for (int i = 0; i < N * 3 / 10; ++i) { + b.addGap(10); + assertEquals(10 * (i + 1), b.length()); + } + } + + public void testDescriptor() throws Exception { + assertEquals("(II)", Descriptor.getParamDescriptor("(II)V")); + assertEquals("()", Descriptor.getParamDescriptor("()I")); + + assertEquals(1, Descriptor.dataSize("I")); + assertEquals(2, Descriptor.dataSize("D")); + assertEquals(2, Descriptor.dataSize("J")); + assertEquals(1, Descriptor.dataSize("[J")); + assertEquals(1, Descriptor.dataSize("[[D")); + assertEquals(1, Descriptor.dataSize("LD;")); + + assertEquals(-1, Descriptor.dataSize("(I)V")); + assertEquals(0, Descriptor.dataSize("(D)J")); + assertEquals(0, Descriptor.dataSize("()V")); + assertEquals(1, Descriptor.dataSize("()I")); + assertEquals(-1, Descriptor.dataSize("([DLA;)I")); + assertEquals(-3, Descriptor.dataSize("(BIJ)LA;")); + assertEquals(-3, Descriptor.dataSize("(BIJ)[D")); + + boolean ok = false; + try { + Descriptor.dataSize("(Ljava/lang/String)I"); + } + catch (IndexOutOfBoundsException e) { + print("testDescriptor(): dataSize() " + e); + ok = true; + } + assertTrue(ok); + + ok = false; + try { + Descriptor.numOfParameters("([DLjava/lang/String)I"); + } + catch (IndexOutOfBoundsException e) { + print("testDescriptor(): numOfParameters() " + e); + ok = true; + } + assertTrue(ok); + } + + public void testDescriptor2() throws Exception { + assertEquals("int", Descriptor.toClassName("I")); + assertEquals("double[]", Descriptor.toClassName("[D")); + assertEquals("boolean[][]", Descriptor.toClassName("[[Z")); + assertEquals("java.lang.String", + Descriptor.toClassName("Ljava/lang/String;")); + assertEquals("java.lang.String[]", + Descriptor.toClassName("[Ljava/lang/String;")); + try { + assertEquals("Foo", Descriptor.toClassName("LFoo;;")); + fail("LFoo;;"); + } + catch (RuntimeException e) {} + try { + assertEquals("int", Descriptor.toClassName("II")); + fail("II"); + } + catch (RuntimeException e) {} + } + + public void testLineNumberAttribute() throws Exception { + CtClass cc = loader.get("test1.LineNumber"); + CtMethod m = cc.getDeclaredMethod("sort"); + MethodInfo minfo = m.getMethodInfo(); + CodeAttribute ca = minfo.getCodeAttribute(); + LineNumberAttribute ainfo + = (LineNumberAttribute)ca.getAttribute(LineNumberAttribute.tag); + + int n = ainfo.tableLength(); + for (int i = 0; i < n; ++i) + print("Line " + ainfo.lineNumber(i) + " at " + ainfo.startPc(i)); + + print("find Line 10: " + ainfo.toStartPc(10)); + print("find PC 30: " + ainfo.toLineNumber(30)); + + LineNumberAttribute.Pc pc = ainfo.toNearPc(6); + print("line 6: " + pc.index); + assertEquals(8, pc.line); + + pc = ainfo.toNearPc(7); + print("line 7: " + pc.index); + assertEquals(8, pc.line); + + pc = ainfo.toNearPc(8); + print("line 8: " + pc.index); + assertEquals(8, pc.line); + + pc = ainfo.toNearPc(9); + print("line 9: " + pc.index); + assertEquals(9, pc.line); + + pc = ainfo.toNearPc(15); + print("line 15: " + pc.index); + assertEquals(17, pc.line); + + pc = ainfo.toNearPc(19); + print("line 19: " + pc.index); + assertEquals(20, pc.line); + + pc = ainfo.toNearPc(21); + print("line 20: " + pc.index); + assertEquals(20, pc.line); + + pc = ainfo.toNearPc(22); + print("line 21: " + pc.index); + assertEquals(20, pc.line); + } + + public void testRenameClass() throws Exception { + CtClass cc = loader.get("test1.RenameClass"); + cc.replaceClassName("test1.RenameClass2", "java.lang.String"); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(0, invoke(obj, "test")); + } + + public void testDeprecatedAttribute() throws Exception { + CtClass cc = loader.get("java.lang.Thread"); + CtMethod m = cc.getDeclaredMethod("suspend"); + MethodInfo minfo = m.getMethodInfo(); + DeprecatedAttribute ainfo + = (DeprecatedAttribute)minfo.getAttribute(DeprecatedAttribute.tag); + assertTrue(ainfo != null); + m = cc.getDeclaredMethod("toString"); + minfo = m.getMethodInfo(); + ainfo + = (DeprecatedAttribute)minfo.getAttribute(DeprecatedAttribute.tag); + assertTrue(ainfo == null); + } + + public void testLocalVarAttribute() throws Exception { + CtClass cc = loader.get("test1.LocalVars"); + CtMethod m = cc.getDeclaredMethod("foo"); + MethodInfo minfo = m.getMethodInfo(); + CodeAttribute ca = minfo.getCodeAttribute(); + LocalVariableAttribute ainfo + = (LocalVariableAttribute)ca.getAttribute( + LocalVariableAttribute.tag); + assertTrue(ainfo != null); + + CtClass cc2 = loader.makeClass("test1.LocalVars2"); + CtMethod m2 = new CtMethod(m, cc2, null); + CodeAttribute ca2 = m2.getMethodInfo().getCodeAttribute(); + ConstPool cp2 = ca2.getConstPool(); + LocalVariableAttribute ainfo2 + = (LocalVariableAttribute)ainfo.copy(cp2, null); + ca2.getAttributes().add(ainfo2); + cc2.addMethod(m2); + cc2.writeFile(); + print("**** local variable table ***"); + for (int i = 0; i < ainfo2.tableLength(); i++) { + String msg = ainfo2.startPc(i) + " " + ainfo2.codeLength(i) + + " " + ainfo2.variableName(i) + " " + + ainfo2.descriptor(i) + + " " + ainfo2.index(i); + print(msg); + if (ainfo2.variableName(i).equals("j")) + assertEquals("I", ainfo2.descriptor(i)); + } + print("**** end ***"); + } + + public void testAnnotations() throws Exception { + String fname = PATH + "annotation/Test.class"; + BufferedInputStream fin + = new BufferedInputStream(new FileInputStream(fname)); + ClassFile cf = new ClassFile(new DataInputStream(fin)); + AnnotationsAttribute attr = (AnnotationsAttribute) + cf.getAttribute(AnnotationsAttribute.invisibleTag); + String sig = attr.toString(); + System.out.println(sig); + + ClassFile cf2 = new ClassFile(false, "test1.AnnoTest", + "java.lang.Object"); + cf2.addAttribute(attr.copy(cf2.getConstPool(), null)); + AnnotationsAttribute attr2 = (AnnotationsAttribute) + cf2.getAttribute(AnnotationsAttribute.invisibleTag); + + DataOutputStream out + = new DataOutputStream(new FileOutputStream("test1/AnnoTest.class")); + cf2.write(out); + + assertEquals(sig, attr2.toString()); + } + + public void testAnnotations2() throws Exception { + ClassFile cf = new ClassFile(false, "test1.AnnoTest2", + "java.lang.Object"); + AnnotationsAttribute anno + = new AnnotationsAttribute(cf.getConstPool(), + AnnotationsAttribute.invisibleTag); + ConstPool cp = cf.getConstPool(); + Annotation a = new Annotation("Anno", cp); + StringMemberValue smv = new StringMemberValue("foo", cp); + a.addMemberValue("name", smv); + anno.setAnnotation(a); + cf.addAttribute(anno); + + String fname = "test1/AnnoTest2.class"; + DataOutputStream out + = new DataOutputStream(new FileOutputStream(fname)); + cf.write(out); + + BufferedInputStream fin + = new BufferedInputStream(new FileInputStream(fname)); + cf = new ClassFile(new DataInputStream(fin)); + AnnotationsAttribute attr = (AnnotationsAttribute) + cf.getAttribute(AnnotationsAttribute.invisibleTag); + + String sig = attr.toString(); + System.out.println(sig); + assertEquals("@Anno(name=\"foo\")", sig); + } + + public void testAddClassInfo() throws Exception { + CtClass cc = loader.get("test1.AddClassInfo"); + ClassFile cf = cc.getClassFile(); + ConstPool cp = cf.getConstPool(); + int i = cp.addClassInfo("test1.AddClassInfo"); + assertEquals(i, cp.getThisClassInfo()); + + cc.addMethod(CtNewMethod.make("public int bar() { return foo(); }", cc)); + cc.writeFile(); + Object obj = make(cc.getName()); + assertEquals(1, invoke(obj, "bar")); + } + + public void testRename() throws Exception { + ConstPool cp = new ConstPool("test1.Foo"); + int i = cp.addClassInfo("test1.Bar"); + assertEquals(i, cp.addClassInfo("test1.Bar")); + cp.renameClass("test1/Bar", "test1/Bar2"); + assertEquals("test1.Bar2", cp.getClassInfo(i)); + assertEquals(i, cp.addClassInfo("test1.Bar2")); + int j = cp.addClassInfo("test1.Bar"); + assertTrue(i != j); + assertEquals(j, cp.addClassInfo("test1.Bar")); + } + + public void testSignature() throws Exception { + parseMsig("(TT;)TT;", "<> (T) T"); + parseMsig("<S:Ljava/lang/Object;>(TS;[TS;)TT;", + "<S extends java.lang.Object> (S, S[]) T"); + parseMsig("()TT;^TT;", "<> () T throws T"); + String sig = "<T:Ljava/lang/Exception;>LPoi$Foo<Ljava/lang/String;>;LBar;LBar2;"; + String rep = "<T extends java.lang.Exception> extends Poi.Foo<java.lang.String> implements Bar, Bar2"; + SignatureAttribute.ClassSignature cs = SignatureAttribute.toClassSignature(sig); + assertEquals(rep, cs.toString()); + CtClass c = loader.get("test3.SigAttribute"); + CtField f = c.getDeclaredField("value"); + SignatureAttribute a = (SignatureAttribute)f.getFieldInfo2().getAttribute(SignatureAttribute.tag); + assertNotNull(a); + f.getFieldInfo().prune(new ConstPool("test3.SigAttribute")); + a = (SignatureAttribute)f.getFieldInfo2().getAttribute(SignatureAttribute.tag); + assertNotNull(a); + } + + private void parseMsig(String sig, String rep) throws Exception { + SignatureAttribute.MethodSignature ms = SignatureAttribute.toMethodSignature(sig); + assertEquals(rep, ms.toString()); + } + + public void testSignatureChange() throws Exception { + changeMsig("<S:Ljava/lang/Object;>(TS;[TS;)Ljava/lang/Object", "java/lang/Object", + "<S:Ljava/lang/Objec;>(TS;[TS;)Ljava/lang/Object", "java/lang/Objec"); + changeMsig("<S:Ljava/lang/Object;>(TS;[TS;)TT;", "java/lang/Object", + "<S:Ljava/lang/Objec;>(TS;[TS;)TT;", "java/lang/Objec"); + changeMsig("<S:Ljava/lang/Object;>(TS;[TS;)Ljava/lang/Object2;", "java/lang/Object", + "<S:Ljava/lang/Objec;>(TS;[TS;)Ljava/lang/Object2;", "java/lang/Objec"); + changeMsig("<S:Ljava/lang/Object;>(TS;[TS;)Ljava/lang/Objec;", "java/lang/Object", + "<S:Ljava/lang/Object2;>(TS;[TS;)Ljava/lang/Objec;", "java/lang/Object2"); + changeMsig2("<S:Ljava/lang/Object;>(TS;[TS;)TT;", "java/lang/Object", + "<S:Ljava/lang/Objec;>(TS;[TS;)TT;", "java/lang/Objec"); + changeMsig2("<S:Ljava/lang/Object;>(TS;[TS;)Ljava/lang/Object2;", "java/lang/Object", + "<S:Ljava/lang/Objec;>(TS;[TS;)Ljava/lang/Object2;", "java/lang/Objec"); + changeMsig2("<S:Ljava/lang/Object;>(TS;[TS;)Ljava/lang/Objec;", "java/lang/Object", + "<S:Ljava/lang/Object2;>(TS;[TS;)Ljava/lang/Objec;", "java/lang/Object2"); + String sig = "<T:Ljava/lang/Exception;>LPoi$Foo<Ljava/lang/String;>;LBar;LBar2;"; + //String res = "<T:Ljava/lang/Exception;>LPoi$Foo<Ljava/lang/String2;>;LBar;LBar2;"; + changeMsig(sig, "java/lang/String", sig, "java/lang/String2"); + changeMsig2(sig, "java/lang/String", sig, "java/lang/String2"); + changeMsig("Ltest<TE;>.List;", "ist", "Ltest<TE;>.List;", "IST"); + } + + private void changeMsig(String old, String oldname, String result, String newname) { + String r = SignatureAttribute.renameClass(old, oldname, newname); + assertEquals(result, r); + } + + private void changeMsig2(String old, String oldname, String result, String newname) { + ClassMap map = new ClassMap(); + map.put(oldname, newname); + String r = SignatureAttribute.renameClass(old, map); + assertEquals(result, r); + } + + public void testModifiers() throws Exception { + CtClass c = loader.get("test3.Mods"); + c.setModifiers(Modifier.PROTECTED); + assertEquals(AccessFlag.PROTECTED | AccessFlag.SUPER, c.getClassFile2().getAccessFlags()); + CtClass c2 = loader.get("test3.Mods2"); + c2.setModifiers(Modifier.PUBLIC | c2.getModifiers()); + assertEquals(AccessFlag.PUBLIC | AccessFlag.INTERFACE | AccessFlag.ABSTRACT, + c2.getClassFile2().getAccessFlags()); + + ClassFile cf = new ClassFile(false, "Test", null); + assertEquals(AccessFlag.SUPER, cf.getAccessFlags()); + ClassFile cf2 = new ClassFile(true, "Test2", null); + assertEquals(AccessFlag.INTERFACE | AccessFlag.ABSTRACT, cf2.getAccessFlags()); + } + + public void testByteStream() throws Exception { + ByteStream bs = new ByteStream(16); + ByteArrayOutputStream ba = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(ba); + for (int i = 0; i < 100; i++) { + bs.write(i); + dos.write(i); + bs.writeShort(i + 1); + dos.writeShort(i + 1); + bs.writeInt(i + 2); + dos.writeInt(i + 2); + bs.writeLong(i + 3); + dos.writeLong(i + 3); + } + + bs.writeLong(Long.MAX_VALUE); + dos.writeLong(Long.MAX_VALUE); + bs.writeFloat(Float.MAX_VALUE); + dos.writeFloat(Float.MAX_VALUE); + bs.writeDouble(Double.MAX_VALUE); + dos.writeDouble(Double.MAX_VALUE); + compare(bs, ba); + } + + public void testByteStreamUtf() throws Exception { + ByteStream bs = new ByteStream(4); + ByteArrayOutputStream ba = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(ba); + char c2 = '\u00b4'; + char c3 = '\u3007'; + bs.writeUTF("abc"); + dos.writeUTF("abc"); + String s = "" + c2 + c2; + bs.writeUTF(s); + dos.writeUTF(s); + + s = "" + c3 + c3; + bs.writeUTF(s); + dos.writeUTF(s); + + s = "abcdefgh" + c2 + "123" + c3 + "456"; + bs.writeUTF(s); + dos.writeUTF(s); + + compare(bs, ba); + } + + private void compare(ByteStream bs, ByteArrayOutputStream bos) { + byte[] bs2 = bs.toByteArray(); + byte[] bos2 = bos.toByteArray(); + assertEquals(bs2.length, bos2.length); + for (int i = 0; i < bs2.length; i++) + assertEquals(bs2[i], bos2[i]); + } + + public static void main(String[] args) { + // junit.textui.TestRunner.run(suite()); + junit.awtui.TestRunner.main(new String[] { + "javassist.bytecode.BytecodeTest" }); + } + + public static Test suite() { + TestSuite suite = new TestSuite("Bytecode Tests"); + suite.addTestSuite(BytecodeTest.class); + return suite; + } +} diff --git a/src/test/javassist/bytecode/CodeAnalyzerTest.java b/src/test/javassist/bytecode/CodeAnalyzerTest.java new file mode 100644 index 00000000..4f115687 --- /dev/null +++ b/src/test/javassist/bytecode/CodeAnalyzerTest.java @@ -0,0 +1,47 @@ +package javassist.bytecode;
+
+import java.util.zip.*;
+import java.util.Enumeration;
+import java.util.List;
+import java.io.*;
+
+public class CodeAnalyzerTest {
+ public static void main(String[] args) throws Exception {
+ ZipFile zfile = new ZipFile(args[0]);
+ Enumeration e = zfile.entries();
+ while (e.hasMoreElements()) {
+ ZipEntry zip = (ZipEntry)e.nextElement();
+ if (zip.getName().endsWith(".class"))
+ test(zfile.getInputStream(zip));
+ }
+ }
+
+ static void test(InputStream is) throws Exception {
+ is = new BufferedInputStream(is);
+ ClassFile cf = new ClassFile(new DataInputStream(is));
+ is.close();
+ List list = cf.getMethods();
+ int n = list.size();
+ for (int i = 0; i < n; ++i) {
+ MethodInfo minfo = (MethodInfo)list.get(i);
+ CodeAttribute ca = minfo.getCodeAttribute();
+ if (ca != null) {
+ try {
+ int max = ca.getMaxStack();
+ int newMax = ca.computeMaxStack();
+ if (max != newMax)
+ System.out.println(max + " -> " + newMax +
+ " for " + minfo.getName() + " (" +
+ minfo.getDescriptor() + ") in " +
+ cf.getName());
+ }
+ catch (BadBytecode e) {
+ System.out.println(e.getMessage() +
+ " for " + minfo.getName() + " (" +
+ minfo.getDescriptor() + ") in " +
+ cf.getName());
+ }
+ }
+ }
+ }
+}
diff --git a/src/test/javassist/bytecode/Gap0Example.class b/src/test/javassist/bytecode/Gap0Example.class Binary files differnew file mode 100644 index 00000000..f705a904 --- /dev/null +++ b/src/test/javassist/bytecode/Gap0Example.class diff --git a/src/test/javassist/bytecode/InsertGap0.java b/src/test/javassist/bytecode/InsertGap0.java new file mode 100644 index 00000000..31fec3aa --- /dev/null +++ b/src/test/javassist/bytecode/InsertGap0.java @@ -0,0 +1,228 @@ +package javassist.bytecode; + +import javassist.*; + +final class Gap0Example { + public static int counter = 1; + + public Gap0Example() {} + + public int run(int x) { return counter; } + + private static final int INTVALUE = 100000; + private int i1, i2, i3, i4, i5, i6, i7, i8, i9, i10; + private int i11, i12, i13, i14, i15, i16, i17, i18, i19, i20; + private int i21, i22, i23, i24, i25, i26, i27, i28, i29, i30; + private int i31, i32, i33, i34, i35, i36, i37, i38, i39, i40; + + public void doit() { + + i1 = INTVALUE; + i2 = INTVALUE; + i3 = INTVALUE; + i4 = INTVALUE; + i5 = INTVALUE; + i6 = INTVALUE; + i7 = INTVALUE; + i8 = INTVALUE; + i9 = INTVALUE; + i10 = INTVALUE; + i11 = INTVALUE; + i12 = INTVALUE; + i13 = INTVALUE; + i14 = INTVALUE; + i15 = INTVALUE; + i16 = INTVALUE; + i17 = INTVALUE; + i18 = INTVALUE; + i19 = INTVALUE; + i20 = INTVALUE; + i21 = INTVALUE; + i22 = INTVALUE; + i23 = INTVALUE; + i24 = INTVALUE; + i25 = INTVALUE; + i26 = INTVALUE; + i27 = INTVALUE; + i28 = INTVALUE; + i29 = INTVALUE; + i20 = INTVALUE; + i21 = INTVALUE; + i22 = INTVALUE; + i23 = INTVALUE; + i24 = INTVALUE; + i25 = INTVALUE; + i26 = INTVALUE; + i27 = INTVALUE; + i28 = INTVALUE; + i29 = INTVALUE; + i30 = INTVALUE; + i31 = INTVALUE; + i32 = INTVALUE; + i33 = INTVALUE; + i34 = INTVALUE; + i35 = INTVALUE; + i36 = INTVALUE; + i37 = INTVALUE; + i38 = INTVALUE; + i39 = INTVALUE; + i40 = INTVALUE; + } +} + +final class Gap0Example2 { + public static int counter = 1; + + public Gap0Example2() {} + + public int run(int x) { return counter; } + + private static final int INTVALUE = 100000; + private int i1, i2, i3, i4, i5, i6, i7, i8, i9, i10; + private int i11, i12, i13, i14, i15, i16, i17, i18, i19, i20; + private int i21, i22, i23, i24, i25, i26, i27, i28, i29, i30; + private int i31, i32, i33, i34, i35, i36, i37, i38, i39, i40; + + public int run2(int x) { + switch (x) { + case 0: + i1 = INTVALUE; + i2 = INTVALUE; + i3 = INTVALUE; + i4 = INTVALUE; + i5 = INTVALUE; + i6 = INTVALUE; + i7 = INTVALUE; + break; + case 100: + i8 = INTVALUE; + i9 = INTVALUE; + i10 = INTVALUE; + i11 = INTVALUE; + i12 = INTVALUE; + i13 = INTVALUE; + i14 = INTVALUE; + break; + default: + i15 = INTVALUE; + i16 = INTVALUE; + i17 = INTVALUE; + if (x > 0) { + i18 = INTVALUE; + i19 = INTVALUE; + i20 = INTVALUE; + i21 = INTVALUE; + i22 = INTVALUE; + i23 = INTVALUE; + i24 = INTVALUE; + } + i25 = INTVALUE; + i26 = INTVALUE; + i27 = INTVALUE; + i28 = INTVALUE; + i29 = INTVALUE; + i20 = INTVALUE; + i21 = INTVALUE; + i22 = INTVALUE; + i23 = INTVALUE; + i24 = INTVALUE; + i25 = INTVALUE; + i26 = INTVALUE; + i27 = INTVALUE; + i28 = INTVALUE; + i29 = INTVALUE; + i30 = INTVALUE; + i31 = INTVALUE; + i32 = INTVALUE; + i33 = INTVALUE; + i34 = INTVALUE; + i35 = INTVALUE; + i36 = INTVALUE; + i37 = INTVALUE; + i38 = INTVALUE; + i39 = INTVALUE; + i40 = INTVALUE; + break; + } + switch (x) { + case 0: + break; + default: + return x + 1; + } + + return x; + } +} + +public final class InsertGap0 extends JvstTestRoot { + public InsertGap0(String name) { + super(name); + } + + public void testExample() throws Throwable { + ClassPool pool = ClassPool.getDefault(); + CtClass cc = pool.get("javassist.bytecode.Gap0Example"); + CtMethod[] ms = cc.getDeclaredMethods(); + for (int i = 0; i < ms.length; i++) { + addMethod(ms[i], cc); + } + + cc.setModifiers(Modifier.PUBLIC | Modifier.FINAL); + cc.addField(new CtField(CtClass.intType, "i", cc), "++counter"); + boolean p = cc.stopPruning(true); + cc.writeFile(); + Class c = cc.toClass(); + cc.stopPruning(p); + + Object obj = c.newInstance(); + assertEquals(2, invoke(obj, "run", 0)); + } + + public void testExample2() throws Throwable { + ClassPool pool = ClassPool.getDefault(); + CtClass cc = pool.get("javassist.bytecode.Gap0Example2"); + CtMethod[] ms = cc.getDeclaredMethods(); + for (int i = 0; i < ms.length; i++) { + addMethod(ms[i], cc); + } + + cc.setModifiers(Modifier.PUBLIC | Modifier.FINAL); + cc.addField(new CtField(CtClass.intType, "i", cc), "++counter"); + boolean p = cc.stopPruning(true); + cc.writeFile(); + Class c = cc.toClass(); + cc.stopPruning(p); + + Object obj = c.newInstance(); + assertEquals(0, invoke(obj, "run2", 0)); + } + + private void addMethod(CtMethod method, CtClass target) + throws CannotCompileException, NotFoundException { + + CtClass[] ts = method.getParameterTypes(); + CtClass[] newts = new CtClass[ts.length + 1]; + for (int i = 0; i < ts.length; i++) { + newts[i] = ts[i]; + } + ClassPool p = method.getDeclaringClass().getClassPool(); + newts[ts.length] = target; + + CtMethod m = + CtNewMethod.make( + method.getModifiers(), + method.getReturnType(), + method.getName(), + newts, + method.getExceptionTypes(), + null, + method.getDeclaringClass()); + + m.setBody(method, null); + + CodeAttribute ca = m.getMethodInfo().getCodeAttribute(); + ca.setMaxLocals(ca.getMaxLocals() + 1); + target.addMethod(m); + } +} diff --git a/src/test/javassist/compiler/CodeTest.java b/src/test/javassist/compiler/CodeTest.java new file mode 100644 index 00000000..0cff5538 --- /dev/null +++ b/src/test/javassist/compiler/CodeTest.java @@ -0,0 +1,26 @@ +package javassist.compiler; + +import java.io.*; +import javassist.*; +import javassist.bytecode.*; + +public class CodeTest implements TokenId { + public static void main(String[] args) throws Exception { + ClassPool loader = ClassPool.getDefault(); + + CtClass c = loader.get(args[0]); + + String line + = new BufferedReader(new InputStreamReader(System.in)).readLine(); + Bytecode b = new Bytecode(c.getClassFile().getConstPool(), 0, 0); + + Javac jc = new Javac(b, c); + CtMember obj = jc.compile(line); + if (obj instanceof CtMethod) + c.addMethod((CtMethod)obj); + else + c.addConstructor((CtConstructor)obj); + + c.writeFile(); + } +} diff --git a/src/test/javassist/compiler/CompTest.java b/src/test/javassist/compiler/CompTest.java new file mode 100644 index 00000000..6a1d5424 --- /dev/null +++ b/src/test/javassist/compiler/CompTest.java @@ -0,0 +1,155 @@ +package javassist.compiler; + +import junit.framework.*; +import javassist.*; +import java.util.*; +import javassist.compiler.ast.*; + +/* +public class Test{ + + public static void main(String[] args) throws Exception { + ClassPool pool = ClassPool.getDefault(); + CtClass cc = pool.get("Print"); + CtMethod cm = cc.getDeclaredMethod("print"); + cm.insertBefore("{((Advice)(new + HelloAspect().getAdvice().get(0))).print();}"); + //cm.insertBefore("{new Advice(\"advice\").print();}"); + pool.write(cc.getName()); + new Print().print(); + } +} +*/ + +public class CompTest extends TestCase { + ClassPool sloader; + + public CompTest(String name) { + super(name); + } + + protected void print(String msg) { + System.out.println(msg); + } + + protected void setUp() throws Exception { + sloader = ClassPool.getDefault(); + } + + public void testCast() throws Exception { + Javac jc = new Javac(sloader.get("javassist.compiler.Print")); + jc.compileStmnt( + "{((javassist.compiler.Advice)" + + " (new javassist.compiler.HelloAspect().getAdvice().get(0)))" + + " .print();}"); + } + + public void testStaticMember() throws Exception { + String src = "javassist.compiler.Print#k = 3;"; + Parser p = new Parser(new Lex(src)); + SymbolTable stb = new SymbolTable(); + Stmnt s = p.parseStatement(stb); + Expr expr = (Expr)s.getLeft().getLeft(); + assertEquals('#', expr.getOperator()); + assertEquals("javassist.compiler.Print", + ((Symbol)expr.oprand1()).get()); + } + + public void testStaticMember2() throws Exception { + String src = "String#k = 3;"; + Parser p = new Parser(new Lex(src)); + SymbolTable stb = new SymbolTable(); + Stmnt s = p.parseStatement(stb); + Expr expr = (Expr)s.getLeft().getLeft(); + assertEquals('#', expr.getOperator()); + assertEquals("String", ((Symbol)expr.oprand1()).get()); + } + + public void testDoubleConst() { + Lex lex = new Lex("7d 0.3d 5e-2d .3d 3e2; .4D 2e-1D;"); + assertEquals(TokenId.DoubleConstant, lex.get()); + assertEquals(TokenId.DoubleConstant, lex.get()); + assertEquals(TokenId.DoubleConstant, lex.get()); + assertEquals(TokenId.DoubleConstant, lex.get()); + assertEquals(TokenId.DoubleConstant, lex.get()); + assertEquals(';', lex.get()); + assertEquals(TokenId.DoubleConstant, lex.get()); + assertEquals(TokenId.DoubleConstant, lex.get()); + assertEquals(';', lex.get()); + } + + public void testRecordLocalVar() throws Exception { + Javac jv = new Javac(sloader.get("javassist.compiler.Print")); + jv.gen.recordVariable("I", "i0", 0, jv.stable); + isRightDecl((Declarator)jv.stable.get("i0"), TokenId.INT, 0, null); + jv.gen.recordVariable("[I", "i1", 1, jv.stable); + isRightDecl((Declarator)jv.stable.get("i1"), TokenId.INT, 1, null); + jv.gen.recordVariable("[[D", "i2", 2, jv.stable); + isRightDecl((Declarator)jv.stable.get("i2"), TokenId.DOUBLE, 2, null); + jv.gen.recordVariable("Ljava/lang/String;", "i3", 4, jv.stable); + isRightDecl((Declarator)jv.stable.get("i3"), TokenId.CLASS, 0, + "java/lang/String"); + jv.gen.recordVariable("[LTest;", "i4", 5, jv.stable); + isRightDecl((Declarator)jv.stable.get("i4"), TokenId.CLASS, 1, + "Test"); + jv.gen.recordVariable("[[LTest;", "i5", 6, jv.stable); + isRightDecl((Declarator)jv.stable.get("i5"), TokenId.CLASS, 2, + "Test"); + } + + private void isRightDecl(Declarator d, int type, int dim, String cname) { + assertEquals(type, d.getType()); + assertEquals(dim, d.getArrayDim()); + assertEquals(cname, d.getClassName()); + } + + public void testArgTypesToString() { + String s; + s = TypeChecker.argTypesToString(new int[0], new int[0], new String[0]); + assertEquals("()", s); + s = TypeChecker.argTypesToString(new int[] { TokenId.INT, TokenId.CHAR, TokenId.CLASS }, + new int[] { 0, 1, 0 }, + new String[] { null, null, "String" }); + assertEquals("(int,char[],String)", s); + } + + public static void main(String[] args) { + // junit.textui.TestRunner.run(suite()); + junit.awtui.TestRunner.main(new String[] { + "javassist.compiler.CompTest" }); + } + + public static Test suite() { + TestSuite suite = new TestSuite("Compiler Tests"); + suite.addTestSuite(CompTest.class); + return suite; + } +} + +class Print{ + public void print(){ System.out.println("@@@"); } + public static int k; +} + +class HelloAspect{ + List list; + + HelloAspect() { + list = new LinkedList(); + list.add(new Advice("advice")); + } + + List getAdvice() { + return list; + } +} + +class Advice{ + String str = ""; + Advice(String str) { + this.str = str; + } + void print(){ + System.out.println(str); + } +} diff --git a/src/test/javassist/compiler/LexTest.java b/src/test/javassist/compiler/LexTest.java new file mode 100644 index 00000000..a02cd5f3 --- /dev/null +++ b/src/test/javassist/compiler/LexTest.java @@ -0,0 +1,21 @@ +package javassist.compiler;
+
+public class LexTest implements TokenId {
+ public static void main(String[] args) {
+ Lex lex = new Lex(args[0]);
+ int t;
+ while ((t = lex.get()) > 0) {
+ System.out.print(t);
+ if (t == Identifier || t == StringL)
+ System.out.print("(" + lex.getString() + ") ");
+ else if (t == CharConstant || t == IntConstant)
+ System.out.print("(" + lex.getLong() + ") ");
+ else if (t == DoubleConstant)
+ System.out.print("(" + lex.getDouble() + ") ");
+ else
+ System.out.print(" ");
+ }
+
+ System.out.println(" ");
+ }
+}
diff --git a/src/test/javassist/compiler/ParseTest.java b/src/test/javassist/compiler/ParseTest.java new file mode 100644 index 00000000..ad51155c --- /dev/null +++ b/src/test/javassist/compiler/ParseTest.java @@ -0,0 +1,13 @@ +package javassist.compiler;
+
+import javassist.compiler.ast.*;
+
+public class ParseTest implements TokenId {
+ public static void main(String[] args) throws CompileError {
+ Parser p = new Parser(new Lex(args[0]));
+ SymbolTable stb = new SymbolTable();
+ // MethodDecl s = (MethodDecl)p.parseMember(stb);
+ Stmnt s = p.parseStatement(stb);
+ System.out.println(s == null ? "null" : s.toString());
+ }
+}
diff --git a/src/test/javassist/proxyfactory/MyCls.java b/src/test/javassist/proxyfactory/MyCls.java new file mode 100644 index 00000000..43fcb8dd --- /dev/null +++ b/src/test/javassist/proxyfactory/MyCls.java @@ -0,0 +1,27 @@ +package javassist.proxyfactory; + +import java.io.Serializable; + +/** + * <a href="mailto:struberg@yahoo.de">Mark Struberg</a> + */ +public class MyCls implements Serializable { + + private int i,j; + + public int getI() { + return i; + } + + public void setI(int i) { + this.i = i; + } + + public int getJ() { + return j; + } + + public void setJ(int j) { + this.j = j; + } +} diff --git a/src/test/javassist/proxyfactory/ProxyFactoryTest.java b/src/test/javassist/proxyfactory/ProxyFactoryTest.java new file mode 100644 index 00000000..7224eb50 --- /dev/null +++ b/src/test/javassist/proxyfactory/ProxyFactoryTest.java @@ -0,0 +1,93 @@ +package javassist.proxyfactory; + +import javassist.util.proxy.MethodHandler; +import javassist.util.proxy.ProxyFactory; +import javassist.util.proxy.ProxyObject; +import junit.framework.TestCase; + +import java.io.*; +import java.lang.reflect.Method; + +/** + * <a href="mailto:struberg@yahoo.de">Mark Struberg</a> + */ +public class ProxyFactoryTest extends TestCase { + + + public void testMethodHandlers() throws Exception { + ProxyFactory fact = new ProxyFactory(); + fact.setSuperclass(MyCls.class); + + Class proxyClass = fact.createClass(); + + MyMethodHandler myHandler = new MyMethodHandler(); + myHandler.setX(4711); + + MyCls myCls = (MyCls) proxyClass.newInstance(); + ((ProxyObject) myCls).setHandler(myHandler); + + MethodHandler h2 = ((ProxyObject) myCls).getHandler(); + assertNotNull(h2); + assertTrue(h2 instanceof MyMethodHandler); + } + + public void testSerialize() throws Exception { + ProxyFactory fact = new ProxyFactory(); + fact.setSuperclass(MyCls.class); + + Class proxyClass = fact.createClass(); + + MyMethodHandler myHandler = new MyMethodHandler(); + myHandler.setX(4711); + + MyCls myCls = (MyCls) proxyClass.newInstance(); + ((ProxyObject) myCls).setHandler(myHandler); + + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(myCls); + byte[] ba = baos.toByteArray(); + + ByteArrayInputStream bais = new ByteArrayInputStream(ba); + ObjectInputStream ois = new ObjectInputStream(bais); + MyCls myCls2 = (MyCls) ois.readObject(); + + MethodHandler h2 = ((ProxyObject) myCls2).getHandler(); + assertNotNull(h2); + assertTrue(h2 instanceof MyMethodHandler); + } + + + public static class MyMethodHandler implements MethodHandler, Serializable { + + private int x; + + public int getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } + + public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable { + // actually do nothing! + return null; + } + } + + public void testJira127() throws Exception { + ProxyFactory proxyFactory = new ProxyFactory(); + proxyFactory.setInterfaces(new Class[]{ JIRA127Sub.class }); + proxyFactory.createClass(); + } + + public interface JIRA127 { + JIRA127 get(); + } + public interface JIRA127Sub extends JIRA127 { + JIRA127Sub get(); + } + +} diff --git a/src/test/javassist/tools/reflect/ClassMetaobjectTest.java b/src/test/javassist/tools/reflect/ClassMetaobjectTest.java new file mode 100644 index 00000000..904fbaf7 --- /dev/null +++ b/src/test/javassist/tools/reflect/ClassMetaobjectTest.java @@ -0,0 +1,14 @@ +package javassist.tools.reflect;
+
+/**
+ * @author Brett Randall
+ */
+public class ClassMetaobjectTest {
+ public static void main(String[] args) throws Throwable {
+ Loader loader = new Loader();
+ loader.makeReflective("javassist.tools.reflect.Person",
+ "javassist.tools.reflect.Metaobject",
+ "javassist.tools.reflect.ClassMetaobject");
+ loader.run("javassist.tools.reflect.Person", new String[] {});
+ }
+}
diff --git a/src/test/javassist/tools/reflect/LoaderTest.java b/src/test/javassist/tools/reflect/LoaderTest.java new file mode 100644 index 00000000..d11a38a8 --- /dev/null +++ b/src/test/javassist/tools/reflect/LoaderTest.java @@ -0,0 +1,69 @@ +package javassist.tools.reflect; + +import javassist.*; +import junit.framework.*; + +public class LoaderTest extends TestCase { + private Loader loader; + + public LoaderTest(String name) { + super(name); + } + + public void setUp() throws Exception { + loader = new Loader(); + } + + public void testAttemptReflectInterface() throws Exception { + try { + loader.makeReflective("javassist.ClassPath", + "javassist.tools.reflect.Metaobject", + "javassist.tools.reflect.ClassMetaobject"); + fail("Attempting to reflect an interface should throw a CannotReflectException"); + } catch (CannotReflectException e) { + // expected + } + } + + public void testAttemptReflectClassMetaobject() throws Exception { + try { + loader.makeReflective("javassist.tools.reflect.ClassMetaobject", + "javassist.tools.reflect.Metaobject", + "javassist.tools.reflect.ClassMetaobject"); + fail("Attempting to reflect a ClassMetaobject should throw a CannotReflectException"); + } catch (CannotReflectException e) { + // expected + } + } + + public void testAttemptReflectMetaobject() throws Exception { + try { + loader.makeReflective("javassist.tools.reflect.Metaobject", + "javassist.tools.reflect.Metaobject", + "javassist.tools.reflect.ClassMetaobject"); + fail("Attempting to reflect a Metaobject should throw a CannotReflectException"); + } catch (CannotReflectException e) { + // expected + } + } + + public void testFinalMethod() throws Throwable { + loader.makeReflective("javassist.tools.reflect.SuperClass", + "javassist.tools.reflect.Metaobject", + "javassist.tools.reflect.ClassMetaobject"); + + ClassPool cp = ClassPool.getDefault(); + CtClass cc = cp.get("javassist.tools.reflect.SubClass"); + + CtMethod[] ms = cc.getMethods(); + for (int i = 0; i < ms.length; ++i) + System.out.println(ms[i] + " in " + + ms[i].getDeclaringClass().getName()); + + loader.makeReflective("javassist.tools.reflect.SubClass", + "javassist.tools.reflect.Metaobject", + "javassist.tools.reflect.ClassMetaobject"); + + loader.run("javassist.tools.reflect.SubClass", new String[] {}); + } +} diff --git a/src/test/javassist/tools/reflect/Person.java b/src/test/javassist/tools/reflect/Person.java new file mode 100644 index 00000000..739d5948 --- /dev/null +++ b/src/test/javassist/tools/reflect/Person.java @@ -0,0 +1,64 @@ +package javassist.tools.reflect;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+import junit.framework.Assert;
+
+/**
+ * Work with ClassMetaobjectTest.java
+ *
+ * @author Brett Randall
+ */
+public class Person {
+ public String name;
+ public static int birth = 3;
+ public static final String defaultName = "John";
+
+ public Person(String name, int birthYear) {
+ if (name == null)
+ this.name = defaultName;
+ else
+ this.name = name;
+
+ Person.birth = birthYear;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public int getAge(int year) {
+ return year - birth;
+ }
+
+ public static void main(String[] args) throws Exception {
+ Person person = new Person("Bob", 10);
+
+ Metalevel metalevel = (Metalevel) person;
+ ClassMetaobject cmo = metalevel._getClass();
+
+ // this should return the index of the original getAge method
+ int methodIndex = cmo.getMethodIndex("getAge",
+ new Class[] {Integer.TYPE});
+
+ System.out.println(methodIndex);
+
+ // and the name verified by getMethodName
+ String methodName = cmo.getMethodName(methodIndex);
+ System.out.println(methodName);
+
+ // check the name
+ Assert.assertEquals("Incorrect method was found",
+ "getAge", methodName);
+
+ // check the arguments
+ Method method = cmo.getReflectiveMethods()[methodIndex];
+ Assert.assertTrue("Method signature did not match",
+ Arrays.equals(method.getParameterTypes(),
+ new Class[] {Integer.TYPE}));
+ System.out.println(method);
+ System.out.println("OK");
+ }
+}
+
diff --git a/src/test/javassist/tools/reflect/SubClass.java b/src/test/javassist/tools/reflect/SubClass.java new file mode 100644 index 00000000..dd818316 --- /dev/null +++ b/src/test/javassist/tools/reflect/SubClass.java @@ -0,0 +1,20 @@ +package javassist.tools.reflect;
+
+import junit.framework.*;
+
+public class SubClass extends SuperClass {
+ public String f() { return "f2"; } // override
+ public String i() { return "i"; }
+ public final String j() { return "j"; }
+
+ public static void main(String[] args) {
+ SuperClass sup = new SuperClass();
+ SubClass sub = new SubClass();
+ String s = sup.f() + sup.g() + sup.h();
+ String t = sub.f() + sub.g() + sub.h() + sub.i() + sub.j();
+ System.out.println(s);
+ System.out.println(t);
+ Assert.assertEquals("fgh", s);
+ Assert.assertEquals("f2ghij", t);
+ }
+}
diff --git a/src/test/javassist/tools/reflect/SuperClass.java b/src/test/javassist/tools/reflect/SuperClass.java new file mode 100644 index 00000000..5547c0df --- /dev/null +++ b/src/test/javassist/tools/reflect/SuperClass.java @@ -0,0 +1,7 @@ +package javassist.tools.reflect;
+
+public class SuperClass {
+ public String f() { return "f"; }
+ public String g() { return "g"; }
+ public final String h() { return "h"; }
+}
diff --git a/src/test/test1/AddClassInfo.java b/src/test/test1/AddClassInfo.java new file mode 100644 index 00000000..da1b0cf3 --- /dev/null +++ b/src/test/test1/AddClassInfo.java @@ -0,0 +1,7 @@ +package test1; + +public class AddClassInfo { + public int value; + public int foo() { return 1; } + public AddClassInfo() { System.out.println("ok"); } +} diff --git a/src/test/test1/ArrayAccess.java b/src/test/test1/ArrayAccess.java new file mode 100644 index 00000000..98cbf4ba --- /dev/null +++ b/src/test/test1/ArrayAccess.java @@ -0,0 +1,17 @@ +package test1; + +public class ArrayAccess { + int[] ia; + int[][] iaa; + + public ArrayAccess() { + ia = new int[3]; + iaa = new int[2][]; + ia[0] = 3; + iaa[0] = ia; + } + + public int test() { + return ia[0] + iaa[1][0]; + } +} diff --git a/src/test/test1/BenchProceed.java b/src/test/test1/BenchProceed.java new file mode 100644 index 00000000..c7561811 --- /dev/null +++ b/src/test/test1/BenchProceed.java @@ -0,0 +1,83 @@ +package test1; + +class BenchProceed2 { + public void calc2() { + for (long i = 0; i < 10000000; ++i) + Math.sqrt(i); + } +} + +public class BenchProceed { + public double d; + public java.lang.reflect.Method calcM; + + public static final int N = 1000000; + + public BenchProceed() throws Exception { + calcM = this.getClass().getDeclaredMethod("calc", new Class[0]); + } + + public void calc() { + d = Math.sqrt(3.0); + } + + public int p() { + long time = System.currentTimeMillis(); + for (int i = N; i > 0; --i) + calc(); + + long time2 = System.currentTimeMillis(); + return (int)(time2 - time); + } + + public int q() { + long time = System.currentTimeMillis(); + for (int i = N; i > 0; --i) + calc(); + + long time2 = System.currentTimeMillis(); + return (int)(time2 - time); + } + + public int s() { + BenchProceed2 bp = new BenchProceed2(); + for (int i = 0; i < 5; ++i) + bp.calc2(); + + return 0; + } + + public int t() { + BenchProceed2 bp = new BenchProceed2(); + for (int i = 0; i < 5; ++i) + bp.calc2(); + + return 0; + } + + public void before(Object[] args) { + } + + public Object replace(Object[] args) { + try { + return calcM.invoke(this, args); + } + catch (Exception e) { + System.out.println(e); + } + + return null; + } + + public static void main(String[] args) throws Exception { + BenchProceed bp = new BenchProceed(); + System.out.println("iteration " + N); + System.out.println("p (msec) " + bp.p()); + System.out.println("q (msec) " + bp.q()); + System.out.println("p (msec) " + bp.p()); + System.out.println("q (msec) " + bp.q()); + + bp.s(); + bp.t(); + } +} diff --git a/src/test/test1/BenchProceedNew.java b/src/test/test1/BenchProceedNew.java new file mode 100644 index 00000000..4b56be73 --- /dev/null +++ b/src/test/test1/BenchProceedNew.java @@ -0,0 +1,74 @@ +package test1; + +class BenchProceedNew2 { +} + +class BenchProceedNew3 { + int p, q; + BenchProceedNew3(int i, int j) { + p = i; q = j; + } +} + +public class BenchProceedNew { + public static final int N = 10000000; + Object result0; + + public int org0() { + long time = System.currentTimeMillis(); + Object obj = null; + for (int i = N; i > 0; --i) + obj = new BenchProceedNew2(); + + long time2 = System.currentTimeMillis(); + result0 = obj; + return (int)(time2 - time); + } + + public int jvst0() { + long time = System.currentTimeMillis(); + Object obj = null; + for (int i = N; i > 0; --i) + obj = new BenchProceedNew2(); + + long time2 = System.currentTimeMillis(); + result0 = obj; + return (int)(time2 - time); + } + + public int org2() { + long time = System.currentTimeMillis(); + Object obj = null; + for (int i = N; i > 0; --i) + obj = new BenchProceedNew3(i, i); + + long time2 = System.currentTimeMillis(); + result0 = obj; + return (int)(time2 - time); + } + + public int jvst2() { + long time = System.currentTimeMillis(); + Object obj = null; + for (int i = N; i > 0; --i) + obj = new BenchProceedNew3(i, i); + + long time2 = System.currentTimeMillis(); + result0 = obj; + return (int)(time2 - time); + } + + public static void main(String[] args) throws Exception { + BenchProceedNew bp = new BenchProceedNew(); + System.out.println("iteration " + N); + System.out.println("org0 (msec) " + bp.org0()); + System.out.println("jvst0 (msec) " + bp.jvst0()); + System.out.println("org2 (msec) " + bp.org2()); + System.out.println("jvst2 (msec) " + bp.jvst2()); + + System.out.println("org0 (msec) " + bp.org0()); + System.out.println("jvst0 (msec) " + bp.jvst0()); + System.out.println("org2 (msec) " + bp.org2()); + System.out.println("jvst2 (msec) " + bp.jvst2()); + } +} diff --git a/src/test/test1/BenchStaticMethod.java b/src/test/test1/BenchStaticMethod.java new file mode 100644 index 00000000..69abc306 --- /dev/null +++ b/src/test/test1/BenchStaticMethod.java @@ -0,0 +1,53 @@ +package test1; + +public class BenchStaticMethod { + public static final int N = 10000000; + + public static int foo(int i) { + i /= 100000; + int f = 1; + while (i > 1) + f *= i--; + + return f; + } + + public static void foo2(int i) {} + + public static int num = 0; + + public static int test() { + long time = System.currentTimeMillis(); + for (int i = N; i > 0; --i) + foo(i); + + long time2 = System.currentTimeMillis(); + return (int)(time2 - time); + } + + public static int orgTest() { + long time = System.currentTimeMillis(); + for (int i = N; i > 0; --i) + foo(i); + + long time2 = System.currentTimeMillis(); + return (int)(time2 - time); + } + + public static int handTest() { + long time = System.currentTimeMillis(); + for (int i = N; i > 0; --i) { + num += i; + foo(i); + } + + long time2 = System.currentTimeMillis(); + return (int)(time2 - time); + } + + public static void main(String[] args) throws Exception { + System.out.println("orgTest (msec) " + orgTest()); + System.out.println("handTest (msec) " + handTest()); + System.out.println("test (msec) " + test()); + } +} diff --git a/src/test/test1/CalleeAfter.java b/src/test/test1/CalleeAfter.java new file mode 100644 index 00000000..7d31d1bf --- /dev/null +++ b/src/test/test1/CalleeAfter.java @@ -0,0 +1,24 @@ +package test1; + +public class CalleeAfter { + public int p; + + public CalleeAfter() { + p = 3; + } + + public int m1(int i) { + return p + i; + } + + public char m2(char c) { + return c; + } + + public int test() { + if (m2('a') == 'b') + return m1(10); + else + return -1; + } +} diff --git a/src/test/test1/CalleeAfter2.java b/src/test/test1/CalleeAfter2.java new file mode 100644 index 00000000..8a60c4dd --- /dev/null +++ b/src/test/test1/CalleeAfter2.java @@ -0,0 +1,50 @@ +package test1; + +public class CalleeAfter2 { + public int p; + + public CalleeAfter2() { + p = 0; + } + + public int m1(int i) { + return 0; + } + + public void m2(int i) { + } + + public String m3(int i) { + return null; + } + + public String m4(int i) { + return null; + } + + public int[] m5(int i) { + return null; + } + + public int k1(int i) { + return 1; + } + + public void k2(int i) { + p = 4; + } + + public String k3(int i) { + return "ok"; + } + + public int[] k5(int i) { + return new int[2]; + } + + public int test() { + m2(0); + int q = m3(0).equals("ok") ? 10 : 20; + return m1(0) + p + q + m5(0).length; + } +} diff --git a/src/test/test1/CalleeAfter3.java b/src/test/test1/CalleeAfter3.java new file mode 100644 index 00000000..068816c6 --- /dev/null +++ b/src/test/test1/CalleeAfter3.java @@ -0,0 +1,39 @@ +package test1; + +public class CalleeAfter3 { + int value = 1; + public int m1(int k) { + if (k > 3) + return k; + else + return k + 1; + } + + public String m2(int k) { + if (k > 3) + return "value" + k; + else + return "value" + value; + } + + public void m3(int k) { + if (k > 3) + value += k; + else + value -= k; + } + + public int m4(String obj) { + try { + return obj.length(); + } + catch (NullPointerException e) { + return 0; + } + } + + public int test() { + m3(5); + return m1(1) + m2(5).length() + value + m4("12345"); + } +} diff --git a/src/test/test1/CalleeBefore.java b/src/test/test1/CalleeBefore.java new file mode 100644 index 00000000..2e30b31c --- /dev/null +++ b/src/test/test1/CalleeBefore.java @@ -0,0 +1,39 @@ +package test1; + +class CalleeBeforeParent { + static int counter = 0; + int r; + + CalleeBeforeParent(int k) { + System.out.println("CalleeBeforeParent:" + k); + r = counter; + } +} + +public class CalleeBefore extends CalleeBeforeParent { + public int p; + public static int q; + + public CalleeBefore() { + this(3); + } + + public CalleeBefore(int k) { + super(k); + p = q = 0; + } + + public int m1(int i) { + return p + i; + } + + public static int m2(int i) { + return q + i; + } + + public int getr() { return r; } + + public int test() { + return m1(3) + m2(10); + } +} diff --git a/src/test/test1/CalleeCatch.java b/src/test/test1/CalleeCatch.java new file mode 100644 index 00000000..f399aedc --- /dev/null +++ b/src/test/test1/CalleeCatch.java @@ -0,0 +1,17 @@ +package test1; + +public class CalleeCatch { + public int p; + + public CalleeCatch() { + p = 3; + } + + public int m1(int i) throws Exception { + throw new Exception(); + } + + public int test() throws Exception { + return m1(p); + } +} diff --git a/src/test/test1/Cflow.java b/src/test/test1/Cflow.java new file mode 100644 index 00000000..a5c73f30 --- /dev/null +++ b/src/test/test1/Cflow.java @@ -0,0 +1,40 @@ +package test1; + +public class Cflow { + public int run() { + return k1(4); + } + + public int run2() { + return fact(5); + } + + public int fact(int n) { + if (n <= 1) + return n; + else + return n * fact(n - 1); + } + + public int k1(int i) { + if (i > 1) + return k2(i - 1); + else if (i == 1) + return i; + else if (i == 0) + throw new RuntimeException(); + else + return -i; + } + + public int k2(int i) { + if (i > 1) + return k1(i - 1); + else if (i == 1) + return i; + else if (i == 0) + throw new RuntimeException(); + else + return -i; + } +} diff --git a/src/test/test1/Clinit.java b/src/test/test1/Clinit.java new file mode 100644 index 00000000..076983bd --- /dev/null +++ b/src/test/test1/Clinit.java @@ -0,0 +1,8 @@ +package test1; + +public class Clinit { + public int i = 123; + public static int j = 456; + + public int run() { return j; } +} diff --git a/src/test/test1/Clinit2.java b/src/test/test1/Clinit2.java new file mode 100644 index 00000000..0f19a8fe --- /dev/null +++ b/src/test/test1/Clinit2.java @@ -0,0 +1,8 @@ +package test1; + +public class Clinit2 { + public int i = 123; + public static int j; + + public int run() { return j; } +} diff --git a/src/test/test1/CodeConv.java b/src/test/test1/CodeConv.java new file mode 100644 index 00000000..76cc010b --- /dev/null +++ b/src/test/test1/CodeConv.java @@ -0,0 +1,25 @@ +package test1; + +class CodeConvP { + private int a1 = 7; + protected int a2 = 11; + protected int a3 = 13; + protected int a4 = 17; + + protected int b1 = 3; + + public static int getA1(Object t) { return 23; } + + public static int getA2(Object t) { return 27; } + + public static void putB1(Object t, int v) { ((CodeConvP)t).b1 = 5; } +} + +public class CodeConv extends CodeConvP { + private String a1 = "a1"; + + public int run() { + b1 = 0; + return b1 + a1.length() + a2 + a3; + } +} diff --git a/src/test/test1/Delegator.java b/src/test/test1/Delegator.java new file mode 100644 index 00000000..c3108b96 --- /dev/null +++ b/src/test/test1/Delegator.java @@ -0,0 +1,12 @@ +package test1; + +class SuperDelegator { + public int f(int p) { return p + 1; } + public static int g(int p) { return p + 1; } +} + +public class Delegator extends SuperDelegator { + public int run() { + return f(3) + g(10); + } +} diff --git a/src/test/test1/Dispatch.java b/src/test/test1/Dispatch.java new file mode 100644 index 00000000..0ee8b3f1 --- /dev/null +++ b/src/test/test1/Dispatch.java @@ -0,0 +1,15 @@ +package test1; + +public class Dispatch { + public int run() { + return 5; + } + + public int f(Object obj) { + return 1; + } + + public int f(Object[] obj) { + return 2; + } +} diff --git a/src/test/test1/DollarClass.java b/src/test/test1/DollarClass.java new file mode 100644 index 00000000..74e6c380 --- /dev/null +++ b/src/test/test1/DollarClass.java @@ -0,0 +1,21 @@ +package test1; + +public class DollarClass { + int f = 1; + + public int run() { + return k1(4) + k2(3); + } + + public int k1(int i) { + return i; + } + + public static int k2(int i) { + return i + k3(i); + } + + public static int k3(int i) { + return i; + } +} diff --git a/src/test/test1/EmptyBody.java b/src/test/test1/EmptyBody.java new file mode 100644 index 00000000..9a098538 --- /dev/null +++ b/src/test/test1/EmptyBody.java @@ -0,0 +1,20 @@ +package test1; + +public abstract class EmptyBody { + public EmptyBody() {} + public EmptyBody(int i) {} + public EmptyBody(String i) { System.out.println(i); } + public EmptyBody(double d) { this(3); } + + public void m1(int i, int j) {} + public void m2(int i, int j) { + try { return; } + catch (Exception e) {} + } + + public int m3(int k) { return 0; } + + public native int m4(); + + public abstract int m5(); +} diff --git a/src/test/test1/ExprEdit.java b/src/test/test1/ExprEdit.java new file mode 100644 index 00000000..761712f1 --- /dev/null +++ b/src/test/test1/ExprEdit.java @@ -0,0 +1,11 @@ +package test1; + +public class ExprEdit { + public int k1(int j) { return j; } + + public static int k2(int j) { return j; } + + public void k3(int j) { System.out.println("k3: " + j); } + + public int k0() { k3(1); return k1(3) + k2(7); } +} diff --git a/src/test/test1/ExprEdit2.java b/src/test/test1/ExprEdit2.java new file mode 100644 index 00000000..86b107b1 --- /dev/null +++ b/src/test/test1/ExprEdit2.java @@ -0,0 +1,8 @@ +package test1; + +public class ExprEdit2 { + int df; + static int sf; + + public int k1() { df = 3; sf = 7; return df + sf; } +} diff --git a/src/test/test1/ExprEdit3.java b/src/test/test1/ExprEdit3.java new file mode 100644 index 00000000..ecfcc676 --- /dev/null +++ b/src/test/test1/ExprEdit3.java @@ -0,0 +1,13 @@ +package test1; + +public class ExprEdit3 { + int value; + + private int f() { return 3; } + + public ExprEdit3() { value = 0; } + + public ExprEdit3(ExprEdit3 e, int i) { value = i; } + + public int k1() { return new ExprEdit3(null, f()).value; } +} diff --git a/src/test/test1/ExprEdit4.java b/src/test/test1/ExprEdit4.java new file mode 100644 index 00000000..6f764471 --- /dev/null +++ b/src/test/test1/ExprEdit4.java @@ -0,0 +1,16 @@ +package test1; + +public class ExprEdit4 { + int value; + + void f() { value = 3; } + + public ExprEdit4() { value = 0; } + + public int k1() { + ExprEdit4 e = null; + e.f(); + e = null; + return new ExprEdit4() == null ? 1 : 0; + } +} diff --git a/src/test/test1/ExprEdit5.java b/src/test/test1/ExprEdit5.java new file mode 100644 index 00000000..931f4c71 --- /dev/null +++ b/src/test/test1/ExprEdit5.java @@ -0,0 +1,14 @@ +package test1; + +public class ExprEdit5 { + int value; + + public ExprEdit5() { value = 0; } + + public ExprEdit5(String s) { value = 1; } + + public int k1() { + ExprEdit5 e = new ExprEdit5(); + return e.value; + } +} diff --git a/src/test/test1/ExprEdit6.java b/src/test/test1/ExprEdit6.java new file mode 100644 index 00000000..8db5f72e --- /dev/null +++ b/src/test/test1/ExprEdit6.java @@ -0,0 +1,15 @@ +package test1; + +public class ExprEdit6 { + int value; + + public ExprEdit6() { value = 0; } + + public int k2() { + return value; + } + + public int k1() { + return k2(); + } +} diff --git a/src/test/test1/ExprEdit7.java b/src/test/test1/ExprEdit7.java new file mode 100644 index 00000000..03be6d86 --- /dev/null +++ b/src/test/test1/ExprEdit7.java @@ -0,0 +1,30 @@ +package test1; + +public class ExprEdit7 { + int value; + Class c1, c2; + + public ExprEdit7() { value = 0; } + + public boolean k2(Object obj) { + return obj instanceof ExprEdit7; + } + + public ExprEdit7 k3(Object obj) { + return (ExprEdit7)obj; + } + + public int k1() { + ExprEdit7 e = new ExprEdit7(); + if (k2(e)) + k3(e).value = 3; + else + k3(e).value = 7; + + System.out.println("ExprEdit7: " + c1.getName()); + if (c1 == c2 && c1.getName().equals("test1.ExprEdit7")) + return e.value; + else + return e.value - 1; + } +} diff --git a/src/test/test1/ExprEdit8.java b/src/test/test1/ExprEdit8.java new file mode 100644 index 00000000..a38b744a --- /dev/null +++ b/src/test/test1/ExprEdit8.java @@ -0,0 +1,16 @@ +package test1; + +class ExprSuper8 { + int value; + ExprSuper8(int i) { + value = i; + } +} + +public class ExprEdit8 extends ExprSuper8 { + public ExprEdit8() { super(3); } + + public int k1() { + return value; + } +} diff --git a/src/test/test1/FieldInit.java b/src/test/test1/FieldInit.java new file mode 100644 index 00000000..87f5a3bc --- /dev/null +++ b/src/test/test1/FieldInit.java @@ -0,0 +1,17 @@ +package test1; + +public class FieldInit { + public static int counter = 0; + public static int loop = 3; + + public static int get(Object obj) { + System.out.println("FieldInit: get"); + return ++counter; + } + + public FieldInit() { + do { + --loop; + } while (loop > 0); + } +} diff --git a/src/test/test1/FieldInit2.java b/src/test/test1/FieldInit2.java new file mode 100644 index 00000000..3260b0fa --- /dev/null +++ b/src/test/test1/FieldInit2.java @@ -0,0 +1,21 @@ +package test1; + +public class FieldInit2 { + public static int counter = 0; + public static int loop = 3; + + public static int get(Object obj) throws Exception { + throw new Exception(); + } + + public FieldInit2() { + try { + do { + --loop; + } while (loop > 0); + } + catch (Exception e) { + System.out.println("FieldInit2: catch"); + } + } +} diff --git a/src/test/test1/FieldMod.java b/src/test/test1/FieldMod.java new file mode 100644 index 00000000..0023d2e3 --- /dev/null +++ b/src/test/test1/FieldMod.java @@ -0,0 +1,6 @@ +package test1;
+
+public class FieldMod {
+ private String text;
+ public int i;
+}
diff --git a/src/test/test1/Freeze.java b/src/test/test1/Freeze.java new file mode 100644 index 00000000..80676e7a --- /dev/null +++ b/src/test/test1/Freeze.java @@ -0,0 +1,4 @@ +package test1; + +public class Freeze { +} diff --git a/src/test/test1/GetThrowables.java b/src/test/test1/GetThrowables.java new file mode 100644 index 00000000..19e9a8a5 --- /dev/null +++ b/src/test/test1/GetThrowables.java @@ -0,0 +1,41 @@ +package test1; + +class GetThrow1 extends Exception { +} + +class GetThrow2 extends Exception { +} + +public class GetThrowables { + int k = 0; + + public void m1() throws GetThrow1, GetThrow2 { + if (k < 0) + throw new GetThrow1(); + else if (k == 1) + throw new GetThrow2(); + + k = 1; + } + + public int run() throws GetThrow2 { + int i = 0; + try { + try { + m1(); + } + catch (GetThrow1 e) { + i = 1; + throw e; + } + finally { + i += 3; + } + } + catch (GetThrow1 e2) { + ++i; + } + + return i; + } +} diff --git a/src/test/test1/Handler.java b/src/test/test1/Handler.java new file mode 100644 index 00000000..17855518 --- /dev/null +++ b/src/test/test1/Handler.java @@ -0,0 +1,29 @@ +package test1; + +public class Handler { + public int p; + + public Handler() { + p = 3; + } + + public int m1(int i) { + p = 1; + try { + try { + if (i < 0) + throw new IndexOutOfBoundsException(); + else if (i == 0) + throw new ClassNotFoundException(); + } + catch (IndexOutOfBoundsException e) {} + } + catch (ClassNotFoundException e) {} + + return p; + } + + public int test() { + return m1(1) + m1(0) + m1(-1); + } +} diff --git a/src/test/test1/Howard.java b/src/test/test1/Howard.java new file mode 100644 index 00000000..53bbae8c --- /dev/null +++ b/src/test/test1/Howard.java @@ -0,0 +1,29 @@ +package test1;
+
+import java.io.IOException;
+
+class Howard4 implements HowardHome {
+ int n = 0;
+ public Object create() throws IOException {
+ if (n == 1)
+ throw new IOException();
+ else
+ return "howard4";
+ }
+}
+
+interface HowardHome {
+ Object create() throws IOException;
+}
+
+class Howard2 {
+ Object lookup(String n) { return new Howard4(); }
+}
+
+public class Howard extends Howard2 {
+ private Object _remote;
+
+ public int run() {
+ return 0;
+ }
+}
diff --git a/src/test/test1/InvokeInt.java b/src/test/test1/InvokeInt.java new file mode 100644 index 00000000..22eb5f11 --- /dev/null +++ b/src/test/test1/InvokeInt.java @@ -0,0 +1,19 @@ +package test1; + +interface InvokeInt2 { + int k(int i); +} + +public class InvokeInt implements InvokeInt2 { + public int run() { + return check(this); + } + + public int check(InvokeInt2 obj) { + return obj.k(3); + } + + public int k(int i) { + return i + 1; + } +} diff --git a/src/test/test1/LineNumber.java b/src/test/test1/LineNumber.java new file mode 100644 index 00000000..46d3d12d --- /dev/null +++ b/src/test/test1/LineNumber.java @@ -0,0 +1,46 @@ +package test1; + +import java.io.*; + +public class LineNumber { + public static void sort(int[] data) { + int i, j; + for (i = 0; i < data.length - 1; ++i) { + int k = i; + int p = data[k]; + for (j = i + 1; j < data.length; ++j) + if (p > data[j]) { + k = j; + p = data[k]; + } + + data[k] = data[i]; + data[i] = p; + } + } + + public int f(int i) { + i = i + 3; + return i; + } + + public static void main(String[] args) throws Exception { + int i; + int data[] = new int[Integer.parseInt(args[0])]; + + BufferedReader r = new BufferedReader(new FileReader(args[1])); + for (i = 0; i < data.length; ++i) { + String value = r.readLine(); + data[i] = Integer.parseInt(value); + } + + r.close(); + sort(data); + PrintWriter out = + new PrintWriter(new BufferedWriter(new FileWriter(args[2]))); + for (i = 0; i < data.length; ++i) + out.println(data[i]); + + out.close(); + } +} diff --git a/src/test/test1/LocalVars.java b/src/test/test1/LocalVars.java new file mode 100644 index 00000000..a3d14d7a --- /dev/null +++ b/src/test/test1/LocalVars.java @@ -0,0 +1,18 @@ +package test1;
+
+public class LocalVars {
+ public int poi(String str) {
+ Object obj = str;
+ int hash = obj.hashCode();
+ return hash;
+ }
+
+ public int foo(int i) {
+ int j = 3;
+ if (i == 0) {
+ String s = "zero";
+ j += s.length();
+ }
+ return j + 3;
+ }
+}
diff --git a/src/test/test1/MakeClass.java b/src/test/test1/MakeClass.java new file mode 100644 index 00000000..e6d6b50d --- /dev/null +++ b/src/test/test1/MakeClass.java @@ -0,0 +1,9 @@ +package test1;
+
+public class MakeClass {
+ public int p;
+
+ public MakeClass() {
+ p = 3;
+ }
+}
diff --git a/src/test/test1/MySerializableClass.java b/src/test/test1/MySerializableClass.java new file mode 100644 index 00000000..486d1b1b --- /dev/null +++ b/src/test/test1/MySerializableClass.java @@ -0,0 +1,34 @@ +package test1; + +import java.io.*; + +/** + * + * @author Bob Lee + */ +public class MySerializableClass implements Serializable, Cloneable { + String fieldA; + String fieldB; + + public MySerializableClass() { fieldA = null; } + + public MySerializableClass(String k) { fieldA = k; } + + public MySerializableClass(int k) { fieldA = null; } + + public String getFieldA() { + return fieldB; + } + + public String getFieldA(int i) { return fieldB; } + + public String getFieldA(int i, int j) { return fieldB; } + + public String getFieldB() { + return fieldB; + } + + public void doSomething(Object o) { + } + +} diff --git a/src/test/test1/NewInterface.java b/src/test/test1/NewInterface.java new file mode 100644 index 00000000..c604e481 --- /dev/null +++ b/src/test/test1/NewInterface.java @@ -0,0 +1,5 @@ +package test1; + +public class NewInterface { + public int foo() { return 3; } +} diff --git a/src/test/test1/Pac.java b/src/test/test1/Pac.java new file mode 100644 index 00000000..3e99596a --- /dev/null +++ b/src/test/test1/Pac.java @@ -0,0 +1,15 @@ +package test1; + +class Pac2 { + int p, q; +} + +public class Pac { + int x; + public int run() { + Class c = Pac2.class; + Package p = c.getPackage(); + System.out.println(p); + return p == null ? 0 : 1; + } +} diff --git a/src/test/test1/Point.java b/src/test/test1/Point.java new file mode 100644 index 00000000..1f88159c --- /dev/null +++ b/src/test/test1/Point.java @@ -0,0 +1,5 @@ +package test1; + +public class Point { + public int x, y; +} diff --git a/src/test/test1/Proceed.java b/src/test/test1/Proceed.java new file mode 100644 index 00000000..a37306ef --- /dev/null +++ b/src/test/test1/Proceed.java @@ -0,0 +1,11 @@ +package test1; + +public class Proceed { + public int p(int i, int j) { return i + j; } + + public int k1(int j) { return j; } + + private int k2(int j) { return j + 1; } + + private static Proceed another = new Proceed(); +} diff --git a/src/test/test1/Proceed2.java b/src/test/test1/Proceed2.java new file mode 100644 index 00000000..b66eb0ae --- /dev/null +++ b/src/test/test1/Proceed2.java @@ -0,0 +1,26 @@ +package test1; + +public class Proceed2 { + public Proceed2() { i = 3; } + + public int i; + + public void p() {} + + public int k1() { + Proceed2 p2 = new Proceed2(); + boolean b = p2 instanceof Proceed2; + Object obj = p2; + Proceed2 q2 = (Proceed2)obj; + p2.p(); + i = 2; + return i; + } + + public int k2() { + Proceed2 p2 = new Proceed2(); + p2.p(); + i = 2; + return i; + } +} diff --git a/src/test/test1/Proceed3.java b/src/test/test1/Proceed3.java new file mode 100644 index 00000000..7cee996d --- /dev/null +++ b/src/test/test1/Proceed3.java @@ -0,0 +1,9 @@ +package test1; + +public class Proceed3 { + public int p(int i) { return i; } + + public int k1() { + return p(3); + } +} diff --git a/src/test/test1/RenameClass.java b/src/test/test1/RenameClass.java new file mode 100644 index 00000000..99a92c62 --- /dev/null +++ b/src/test/test1/RenameClass.java @@ -0,0 +1,26 @@ +package test1; + +import java.util.Hashtable; + +class RenameClass2 { + String name; +} + +public class RenameClass { + private Hashtable table; + public RenameClass() { + table = new Hashtable(); + } + + public int test() { + say(); + return 0; + } + + public void say() { + RenameClass2[] pair = new RenameClass2[2]; + pair[0] = new RenameClass2(); + table.put("Muga", pair); + RenameClass2[] p = (RenameClass2[]) table.get("Muga"); + } +} diff --git a/src/test/test1/SetBody.java b/src/test/test1/SetBody.java new file mode 100644 index 00000000..7849b27a --- /dev/null +++ b/src/test/test1/SetBody.java @@ -0,0 +1,9 @@ +package test1; + +public class SetBody { + int value; + public int m1(int i, int j) { return i + j; } + public void m2(int k) {} + public void m3(int k) {} + public int run() { m2(3); return m1(3, 4); } +} diff --git a/src/test/test1/SetName.java b/src/test/test1/SetName.java new file mode 100644 index 00000000..95e283e5 --- /dev/null +++ b/src/test/test1/SetName.java @@ -0,0 +1,6 @@ +package test1; + +public class SetName { + public int i; + public int foo(SetName sn) { return 1; } +} diff --git a/src/test/test1/SigType.java b/src/test/test1/SigType.java new file mode 100644 index 00000000..6fa03f30 --- /dev/null +++ b/src/test/test1/SigType.java @@ -0,0 +1,21 @@ +package test1; + +public class SigType { + int f = 1; + + public int run() { + return k1(4, "test") + k2(3); + } + + public int k1(int i, String s) { + return i + s.length(); + } + + public int k2(int i) { + return f + k3(i); + } + + public int k3(int i) { + return i + 1; + } +} diff --git a/src/test/test1/StaticConsBody.java b/src/test/test1/StaticConsBody.java new file mode 100644 index 00000000..8060763d --- /dev/null +++ b/src/test/test1/StaticConsBody.java @@ -0,0 +1,18 @@ +package test1; + +public class StaticConsBody { + public static int i; + public int j; + + static { + i = 3; + } + + public StaticConsBody() { + j = 2; + } + + public int run() { + return i + j; + } +} diff --git a/src/test/test1/StaticField.java b/src/test/test1/StaticField.java new file mode 100644 index 00000000..e792402b --- /dev/null +++ b/src/test/test1/StaticField.java @@ -0,0 +1,5 @@ +package test1;
+
+public class StaticField {
+ public static int counter;
+}
diff --git a/src/test/test1/Subtype.java b/src/test/test1/Subtype.java new file mode 100644 index 00000000..dffd1eb6 --- /dev/null +++ b/src/test/test1/Subtype.java @@ -0,0 +1,17 @@ +package test1; + +public class Subtype extends SubtypeA implements SubtypeC { + int i; +} + +class SubtypeA { + int a; +} + +interface SubtypeB { + final int b = 3; +} + +interface SubtypeC extends SubtypeB { + final int c = 4; +} diff --git a/src/test/test1/TryCatch.java b/src/test/test1/TryCatch.java new file mode 100644 index 00000000..72f21073 --- /dev/null +++ b/src/test/test1/TryCatch.java @@ -0,0 +1,34 @@ +package test1; + +public class TryCatch { + int a = 0; + String s = null; + + public void init() { + s = "test"; + } + + public void doit() { + a = s.length(); + } + + public void m2() {} + + public int m1() { + m2(); + return a; + } + + public int p1() { + try { + return s.length(); + } + catch (NullPointerException e) { + throw e; + } + } + + public int run() { + return m1(); + } +} diff --git a/src/test/test2/AddCatchForConstructor.class b/src/test/test2/AddCatchForConstructor.class Binary files differnew file mode 100644 index 00000000..9b5e937f --- /dev/null +++ b/src/test/test2/AddCatchForConstructor.class diff --git a/src/test/test2/AddCatchForConstructor.java b/src/test/test2/AddCatchForConstructor.java new file mode 100644 index 00000000..f604f99f --- /dev/null +++ b/src/test/test2/AddCatchForConstructor.java @@ -0,0 +1,13 @@ +package test2;
+
+public class AddCatchForConstructor {
+ int i;
+ public AddCatchForConstructor() {
+ this(3);
+ i++;
+ }
+
+ public AddCatchForConstructor(int k) {
+ i = k;
+ }
+}
diff --git a/src/test/test2/AddLocalVar.class b/src/test/test2/AddLocalVar.class Binary files differnew file mode 100644 index 00000000..ad5f1d94 --- /dev/null +++ b/src/test/test2/AddLocalVar.class diff --git a/src/test/test2/AddLocalVar.java b/src/test/test2/AddLocalVar.java new file mode 100644 index 00000000..7885b65a --- /dev/null +++ b/src/test/test2/AddLocalVar.java @@ -0,0 +1,8 @@ +package test2;
+
+public class AddLocalVar {
+ public int foo() {
+ int j = 1;
+ return j;
+ }
+}
diff --git a/src/test/test2/AddMethod.java b/src/test/test2/AddMethod.java new file mode 100644 index 00000000..a7179e6e --- /dev/null +++ b/src/test/test2/AddMethod.java @@ -0,0 +1,9 @@ +package test2;
+
+public class AddMethod {
+ private int f;
+
+ public int f() { return 0; }
+ public AddMethod() {}
+ public int f(int i) { return i; }
+}
diff --git a/src/test/test2/Anon.java b/src/test/test2/Anon.java new file mode 100644 index 00000000..a6ccd8f0 --- /dev/null +++ b/src/test/test2/Anon.java @@ -0,0 +1,7 @@ +package test2;
+
+public class Anon {
+ public Object make() {
+ return new Object() { int k; };
+ }
+}
diff --git a/src/test/test2/ArrayAndNull.java b/src/test/test2/ArrayAndNull.java new file mode 100644 index 00000000..52b8b973 --- /dev/null +++ b/src/test/test2/ArrayAndNull.java @@ -0,0 +1,9 @@ +package test2; + +public class ArrayAndNull { + public int[] test() { + int[] arr = { 1, 2 }; + arr = null; + return arr; + } +} diff --git a/src/test/test2/ArrayInit.class b/src/test/test2/ArrayInit.class Binary files differnew file mode 100644 index 00000000..1786a0e6 --- /dev/null +++ b/src/test/test2/ArrayInit.class diff --git a/src/test/test2/ArrayLenTest.class b/src/test/test2/ArrayLenTest.class Binary files differnew file mode 100644 index 00000000..0987cc07 --- /dev/null +++ b/src/test/test2/ArrayLenTest.class diff --git a/src/test/test2/ArrayLenTest.java b/src/test/test2/ArrayLenTest.java new file mode 100644 index 00000000..52fe85f2 --- /dev/null +++ b/src/test/test2/ArrayLenTest.java @@ -0,0 +1,5 @@ +package test2;
+
+public class ArrayLenTest {
+ public int length = 1;
+}
diff --git a/src/test/test2/ArrayLength.class b/src/test/test2/ArrayLength.class Binary files differnew file mode 100644 index 00000000..9577874c --- /dev/null +++ b/src/test/test2/ArrayLength.class diff --git a/src/test/test2/Brennan.class b/src/test/test2/Brennan.class Binary files differnew file mode 100644 index 00000000..9c7f3954 --- /dev/null +++ b/src/test/test2/Brennan.class diff --git a/src/test/test2/Brennan.java b/src/test/test2/Brennan.java new file mode 100644 index 00000000..e93e00a9 --- /dev/null +++ b/src/test/test2/Brennan.java @@ -0,0 +1,5 @@ +package test2; + +public class Brennan { + private Object format = null; +} diff --git a/src/test/test2/CodeGen.class b/src/test/test2/CodeGen.class Binary files differnew file mode 100644 index 00000000..65c24e6c --- /dev/null +++ b/src/test/test2/CodeGen.class diff --git a/src/test/test2/CodeGen.java b/src/test/test2/CodeGen.java new file mode 100644 index 00000000..d3df0d8b --- /dev/null +++ b/src/test/test2/CodeGen.java @@ -0,0 +1,15 @@ +package test2;
+
+public class CodeGen {
+ public String msg = "";
+ public int seven() { return 7; }
+
+ public String seven(String s) { return s + 7; }
+
+ public String six(String s) { return s + 6; }
+
+ public int run() {
+ System.out.println("done.");
+ return msg.length();
+ }
+}
diff --git a/src/test/test2/CodeGen2.class b/src/test/test2/CodeGen2.class Binary files differnew file mode 100644 index 00000000..fea25cc5 --- /dev/null +++ b/src/test/test2/CodeGen2.class diff --git a/src/test/test2/ConstBody.class b/src/test/test2/ConstBody.class Binary files differnew file mode 100644 index 00000000..41175d14 --- /dev/null +++ b/src/test/test2/ConstBody.class diff --git a/src/test/test2/ConstBody.java b/src/test/test2/ConstBody.java new file mode 100644 index 00000000..3fad860c --- /dev/null +++ b/src/test/test2/ConstBody.java @@ -0,0 +1,22 @@ +package test2; + +class ConstBody2 { + int value; + ConstBody2() { + value = 1; + } + + ConstBody2(String s, Integer i) { + value = 2; + } +} + +public class ConstBody extends ConstBody2 { + public ConstBody() { + super(); + } + + public int bar() { + return value; + } +} diff --git a/src/test/test2/ConstField.class b/src/test/test2/ConstField.class Binary files differnew file mode 100644 index 00000000..5f7a4d8b --- /dev/null +++ b/src/test/test2/ConstField.class diff --git a/src/test/test2/ConstField.java b/src/test/test2/ConstField.java new file mode 100644 index 00000000..d733b4f6 --- /dev/null +++ b/src/test/test2/ConstField.java @@ -0,0 +1,13 @@ +package test2;
+
+public class ConstField {
+ public static final boolean b = true;
+ public static final int i = 3;
+ public static final long j = 7L;
+ public static final float f = 8.0F;
+ public static final double d = 9.0;
+ public static final String s = "const";
+ public static final Object obj = null;
+ public static final Integer integer = new Integer(4);
+ public static int k = 2;
+}
diff --git a/src/test/test2/Construct.java b/src/test/test2/Construct.java new file mode 100644 index 00000000..250a55c2 --- /dev/null +++ b/src/test/test2/Construct.java @@ -0,0 +1,7 @@ +package test2;
+
+public class Construct {
+ public Construct(int i) {}
+ public Construct() {}
+ static int i = 3;
+}
diff --git a/src/test/test2/DotClass.class b/src/test/test2/DotClass.class Binary files differnew file mode 100644 index 00000000..6cc7a6bd --- /dev/null +++ b/src/test/test2/DotClass.class diff --git a/src/test/test2/DotClass2.class b/src/test/test2/DotClass2.class Binary files differnew file mode 100644 index 00000000..aa67fb10 --- /dev/null +++ b/src/test/test2/DotClass2.class diff --git a/src/test/test2/DotClass4.class b/src/test/test2/DotClass4.class Binary files differnew file mode 100644 index 00000000..48e51b7e --- /dev/null +++ b/src/test/test2/DotClass4.class diff --git a/src/test/test2/Finally.class b/src/test/test2/Finally.class Binary files differnew file mode 100644 index 00000000..f680dbc3 --- /dev/null +++ b/src/test/test2/Finally.class diff --git a/src/test/test2/Finally.java b/src/test/test2/Finally.java new file mode 100644 index 00000000..1da85725 --- /dev/null +++ b/src/test/test2/Finally.java @@ -0,0 +1,12 @@ +package test2;
+
+public class Finally {
+ int a = 0;
+ String s = null;
+ double b = 1.0;
+
+ public void update() {
+ a = s.length();
+ b++;
+ }
+}
diff --git a/src/test/test2/Imported.class b/src/test/test2/Imported.class Binary files differnew file mode 100644 index 00000000..3ae65fdd --- /dev/null +++ b/src/test/test2/Imported.class diff --git a/src/test/test2/Importer.class b/src/test/test2/Importer.class Binary files differnew file mode 100644 index 00000000..24da5de9 --- /dev/null +++ b/src/test/test2/Importer.class diff --git a/src/test/test2/IncOp.class b/src/test/test2/IncOp.class Binary files differnew file mode 100644 index 00000000..f75a9eb1 --- /dev/null +++ b/src/test/test2/IncOp.class diff --git a/src/test/test2/Inherit.class b/src/test/test2/Inherit.class Binary files differnew file mode 100644 index 00000000..ef886ce1 --- /dev/null +++ b/src/test/test2/Inherit.class diff --git a/src/test/test2/Inherit.java b/src/test/test2/Inherit.java new file mode 100644 index 00000000..b310730b --- /dev/null +++ b/src/test/test2/Inherit.java @@ -0,0 +1,26 @@ +package test2; + +interface Inherit1 { + void foo1(); +} + +interface Inherit2 extends Inherit1 { + void foo2(); +} + +abstract class Inherit3 implements Inherit2 { + abstract void foo3(); +} + +public class Inherit extends Inherit3 { + public void foo1() { System.out.println("foo1"); } + public void foo2() { System.out.println("foo2"); } + public void foo3() { System.out.println("foo3"); } + + public static void main(String args[]) { + Inherit i = new Inherit(); + Inherit2 i2 = i; + i.foo2(); + i2.foo1(); + } +} diff --git a/src/test/test2/Inner.class b/src/test/test2/Inner.class Binary files differnew file mode 100644 index 00000000..d7506a62 --- /dev/null +++ b/src/test/test2/Inner.class diff --git a/src/test/test2/Inner.java b/src/test/test2/Inner.java new file mode 100644 index 00000000..dbfb6d6e --- /dev/null +++ b/src/test/test2/Inner.java @@ -0,0 +1,13 @@ +package test2; + +public class Inner { + public void sample() throws Exception { + java.util.Properties props = new java.util.Properties(); + java.rmi.activation.ActivationGroupDesc.CommandEnvironment ace = null; + java.rmi.activation.ActivationGroupDesc agd = new + java.rmi.activation.ActivationGroupDesc(props,ace); + } + public static void main(String args[]) { + System.out.println("Inner"); + } +} diff --git a/src/test/test2/InsertAt.class b/src/test/test2/InsertAt.class Binary files differnew file mode 100644 index 00000000..b8194bae --- /dev/null +++ b/src/test/test2/InsertAt.class diff --git a/src/test/test2/InsertAt.java b/src/test/test2/InsertAt.java new file mode 100644 index 00000000..196028ef --- /dev/null +++ b/src/test/test2/InsertAt.java @@ -0,0 +1,23 @@ +package test2; + +public class InsertAt { + public int counter = 0; + + public int foo() { + for (int i = 0; i < 3; i++) + counter++; + + return counter; + } + + public int bar() { + return bar2(7); + } + + public int bar2(int k) { + int i = 1; + int j = i + 3; + k += i + j; + return k; + } +} diff --git a/src/test/test2/InsertLocal.class b/src/test/test2/InsertLocal.class Binary files differnew file mode 100644 index 00000000..d0f32f27 --- /dev/null +++ b/src/test/test2/InsertLocal.class diff --git a/src/test/test2/InsertLocal.java b/src/test/test2/InsertLocal.java new file mode 100644 index 00000000..d400e622 --- /dev/null +++ b/src/test/test2/InsertLocal.java @@ -0,0 +1,32 @@ +package test2; + +public class InsertLocal { + public int run() { + return (int)(foo(4, 3.14, "pai") * 100) + field; + } + + private int field = 0; + + public double foo(int i, double d, String s) { + int k; + + for (k = 0; k < i; k++) + d++; + + return d; + } + + public int run2() { + String s = "."; + int k = 0; + return k + s.length(); + } + + public int run3() { + int i = 0; + int j = field; + int k = run2(); + InsertLocal obj = new InsertLocal(); + return i; + } +} diff --git a/src/test/test2/LocalVar.class b/src/test/test2/LocalVar.class Binary files differnew file mode 100644 index 00000000..a1d93574 --- /dev/null +++ b/src/test/test2/LocalVar.class diff --git a/src/test/test2/LocalVar.java b/src/test/test2/LocalVar.java new file mode 100644 index 00000000..0ba740be --- /dev/null +++ b/src/test/test2/LocalVar.java @@ -0,0 +1,6 @@ +package test2; + +public class LocalVar { + public String toString() { return "123"; } + public int foo() { return toString().length(); } +} diff --git a/src/test/test2/MakeStaticMethod.class b/src/test/test2/MakeStaticMethod.class Binary files differnew file mode 100644 index 00000000..320f0f3a --- /dev/null +++ b/src/test/test2/MakeStaticMethod.class diff --git a/src/test/test2/MethodCall.class b/src/test/test2/MethodCall.class Binary files differnew file mode 100644 index 00000000..6b8fc153 --- /dev/null +++ b/src/test/test2/MethodCall.class diff --git a/src/test/test2/MethodCall.java b/src/test/test2/MethodCall.java new file mode 100644 index 00000000..22341a08 --- /dev/null +++ b/src/test/test2/MethodCall.java @@ -0,0 +1,8 @@ +package test2;
+
+public class MethodCall {
+ public Object bar() {
+ String[] str = new String[] { "one", "two" };
+ return str.clone();
+ }
+}
diff --git a/src/test/test2/Nested$Inner3.class b/src/test/test2/Nested$Inner3.class Binary files differnew file mode 100644 index 00000000..21afc9a0 --- /dev/null +++ b/src/test/test2/Nested$Inner3.class diff --git a/src/test/test2/Nested.class b/src/test/test2/Nested.class Binary files differnew file mode 100644 index 00000000..529317ae --- /dev/null +++ b/src/test/test2/Nested.class diff --git a/src/test/test2/Nested.java b/src/test/test2/Nested.java new file mode 100644 index 00000000..70ce60ee --- /dev/null +++ b/src/test/test2/Nested.java @@ -0,0 +1,22 @@ +package test2;
+
+public class Nested {
+ private int i = 3;
+ private int geti() { return i; }
+ private static int getj(int k) { return k; }
+ public void seti(int i) { this.i = i; }
+
+ public class Inner {
+ public int geti() { return i; }
+ public void foo(Inner2 in) {}
+ }
+
+ public class Inner2 {
+ public int geti() { return i; }
+ }
+
+ public static class Inner3 {
+ public int f() { return 1; }
+ public static int g() { return 1; }
+ }
+}
diff --git a/src/test/test2/Nested2$Inner.class b/src/test/test2/Nested2$Inner.class Binary files differnew file mode 100644 index 00000000..0267e5e5 --- /dev/null +++ b/src/test/test2/Nested2$Inner.class diff --git a/src/test/test2/Nested2.class b/src/test/test2/Nested2.class Binary files differnew file mode 100644 index 00000000..7cb3b346 --- /dev/null +++ b/src/test/test2/Nested2.class diff --git a/src/test/test2/Nested2.java b/src/test/test2/Nested2.java new file mode 100644 index 00000000..f23439bd --- /dev/null +++ b/src/test/test2/Nested2.java @@ -0,0 +1,15 @@ +package test2;
+
+public class Nested2 {
+ private int i = 3;
+ private double d = 3.0;
+ private String s = "OK";
+ private int geti() { return i; }
+ private static int getj(int k) { return k; }
+ public void seti(int i) { this.i = i; }
+
+ public static class Inner {
+ public int f() { return 1; }
+ public static int g() { return 1; }
+ }
+}
diff --git a/src/test/test2/Nested3$Inner.class b/src/test/test2/Nested3$Inner.class Binary files differnew file mode 100644 index 00000000..dbc70b60 --- /dev/null +++ b/src/test/test2/Nested3$Inner.class diff --git a/src/test/test2/Nested3.class b/src/test/test2/Nested3.class Binary files differnew file mode 100644 index 00000000..a1e2a736 --- /dev/null +++ b/src/test/test2/Nested3.class diff --git a/src/test/test2/Nested3.java b/src/test/test2/Nested3.java new file mode 100644 index 00000000..570f7a5e --- /dev/null +++ b/src/test/test2/Nested3.java @@ -0,0 +1,16 @@ +package test2;
+
+public class Nested3 {
+ private int i = 0;
+ private int geti() { return i; }
+
+ Nested3(int j) { i = 1; }
+
+ private Nested3() { i = 2; }
+
+ private Nested3(String s) { i = 3; }
+
+ public static class Inner {
+ public int g() { return 1; }
+ }
+}
diff --git a/src/test/test2/Nested4$Inner.class b/src/test/test2/Nested4$Inner.class Binary files differnew file mode 100644 index 00000000..b770ef79 --- /dev/null +++ b/src/test/test2/Nested4$Inner.class diff --git a/src/test/test2/Nested4.class b/src/test/test2/Nested4.class Binary files differnew file mode 100644 index 00000000..550fb403 --- /dev/null +++ b/src/test/test2/Nested4.class diff --git a/src/test/test2/Nested4.java b/src/test/test2/Nested4.java new file mode 100644 index 00000000..5b33aea5 --- /dev/null +++ b/src/test/test2/Nested4.java @@ -0,0 +1,5 @@ +package test2;
+
+public class Nested4 {
+ private static int value = 6;
+}
diff --git a/src/test/test2/NewArray.class b/src/test/test2/NewArray.class Binary files differnew file mode 100644 index 00000000..9dfbbe63 --- /dev/null +++ b/src/test/test2/NewArray.class diff --git a/src/test/test2/NewArray.java b/src/test/test2/NewArray.java new file mode 100644 index 00000000..d61fa750 --- /dev/null +++ b/src/test/test2/NewArray.java @@ -0,0 +1,18 @@ +package test2;
+
+public class NewArray {
+ public int run() {
+ return foo(1);
+ }
+
+ public int foo(int i) {
+ String[] s1 = new String[3];
+ String[][] s2 = new String[4][];
+ String[][] s3 = new String[5][6];
+ int[] i1 = new int[7];
+ int[][] i2 = new int[8][];
+ int[][] i3 = new int[9][10];
+ int[][][] i4 = new int[11][12][];
+ return i;
+ }
+}
diff --git a/src/test/test2/NewExprInTry.class b/src/test/test2/NewExprInTry.class Binary files differnew file mode 100644 index 00000000..79ca894a --- /dev/null +++ b/src/test/test2/NewExprInTry.class diff --git a/src/test/test2/NewExprInTry.java b/src/test/test2/NewExprInTry.java new file mode 100644 index 00000000..e6e1fe90 --- /dev/null +++ b/src/test/test2/NewExprInTry.java @@ -0,0 +1,24 @@ +package test2;
+
+import java.util.HashMap;
+
+class HashMapWrapper extends HashMap {
+ HashMapWrapper(int size, int args) {
+ super(size);
+ }
+}
+
+public class NewExprInTry {
+ public int run() {
+ return foo(6);
+ }
+
+ public int foo(int size) {
+ HashMap h;
+ try {
+ h = new HashMap(size);
+ }
+ catch (Exception e) {}
+ return 1;
+ }
+}
diff --git a/src/test/test2/NewExprTry.class b/src/test/test2/NewExprTry.class Binary files differnew file mode 100644 index 00000000..f70141e6 --- /dev/null +++ b/src/test/test2/NewExprTry.class diff --git a/src/test/test2/NewExprTry.java b/src/test/test2/NewExprTry.java new file mode 100644 index 00000000..fb779d96 --- /dev/null +++ b/src/test/test2/NewExprTry.java @@ -0,0 +1,20 @@ +package test2;
+
+public class NewExprTry {
+ public NewExprTry() { this(3); }
+
+ public NewExprTry(int i) {}
+
+ public int run() {
+ return foo(3).getClass().getName().length();
+ }
+
+ public Object foo(int i) {
+ NewExprTry obj = new NewExprTry(i);
+ return obj;
+ }
+
+ public static void main(String[] args) {
+ NewExprTry obj = new NewExprTry(3);
+ }
+}
diff --git a/src/test/test2/NewOp.class b/src/test/test2/NewOp.class Binary files differnew file mode 100644 index 00000000..da62b7c3 --- /dev/null +++ b/src/test/test2/NewOp.class diff --git a/src/test/test2/NewOp.java b/src/test/test2/NewOp.java new file mode 100644 index 00000000..bf798a92 --- /dev/null +++ b/src/test/test2/NewOp.java @@ -0,0 +1,15 @@ +package test2;
+
+class NewOp2 {
+ NewOp2(long j, NewOp op, Object obj, long k) {}
+}
+
+public class NewOp {
+ java.util.Vector listenerList;
+ static int i = 0;
+ static String s;
+ static {
+ String m = "test";
+ s = m.substring(1);
+ }
+}
diff --git a/src/test/test2/NullArgTest.class b/src/test/test2/NullArgTest.class Binary files differnew file mode 100644 index 00000000..79dd7195 --- /dev/null +++ b/src/test/test2/NullArgTest.class diff --git a/src/test/test2/PrivateMethod.java b/src/test/test2/PrivateMethod.java new file mode 100644 index 00000000..51ed75f7 --- /dev/null +++ b/src/test/test2/PrivateMethod.java @@ -0,0 +1,11 @@ +package test2;
+
+class PrivateMethod2 {
+ private int f() { return 0; }
+
+ int g() { return f(); }
+}
+
+public class PrivateMethod {
+ public int i;
+}
diff --git a/src/test/test2/Prune.java b/src/test/test2/Prune.java new file mode 100644 index 00000000..1daf9cbb --- /dev/null +++ b/src/test/test2/Prune.java @@ -0,0 +1,15 @@ +package test2;
+
+public class Prune extends java.awt.Point implements Cloneable, Runnable {
+ public int value;
+
+ public Prune(int i) {
+ value = i;
+ }
+
+ public void run() {}
+
+ public int sum() {
+ return x + y;
+ }
+}
diff --git a/src/test/test2/Remove.class b/src/test/test2/Remove.class Binary files differnew file mode 100644 index 00000000..d2bab30b --- /dev/null +++ b/src/test/test2/Remove.class diff --git a/src/test/test2/Remove.java b/src/test/test2/Remove.java new file mode 100644 index 00000000..3f980f6a --- /dev/null +++ b/src/test/test2/Remove.java @@ -0,0 +1,25 @@ +package test2; + +class RemoveParent { + int p; +} + +public class Remove extends RemoveParent { + public int f1; + public int f2; + public String f3; + public Remove f4; + public int[] f5; + public int f6; + int g = 3; + + public void bar() {} + public Remove() { g = 7; } + public Remove(int i) { g = i; } + + public int foo() { + return g; + } + + public void bar2() {} +} diff --git a/src/test/test2/RemoveCall.class b/src/test/test2/RemoveCall.class Binary files differnew file mode 100644 index 00000000..1b818395 --- /dev/null +++ b/src/test/test2/RemoveCall.class diff --git a/src/test/test2/RemoveCall.java b/src/test/test2/RemoveCall.java new file mode 100644 index 00000000..909ef377 --- /dev/null +++ b/src/test/test2/RemoveCall.java @@ -0,0 +1,13 @@ +package test2;
+
+public class RemoveCall {
+ int k = 0;
+ public int bar() throws Exception {
+ foo(3);
+ return k;
+ }
+
+ public void foo(int k) throws Exception {
+ k = 1;
+ }
+}
diff --git a/src/test/test2/ReplaceClassName.class b/src/test/test2/ReplaceClassName.class Binary files differnew file mode 100644 index 00000000..db3611b3 --- /dev/null +++ b/src/test/test2/ReplaceClassName.class diff --git a/src/test/test2/ReplaceClassName.java b/src/test/test2/ReplaceClassName.java new file mode 100644 index 00000000..b41d9db0 --- /dev/null +++ b/src/test/test2/ReplaceClassName.java @@ -0,0 +1,18 @@ +package test2;
+
+class ReplaceClassName2 {
+}
+
+class ReplaceClassName3 {
+}
+
+public class ReplaceClassName {
+ ReplaceClassName2 field;
+ public ReplaceClassName(ReplaceClassName2 a) {
+ field = a;
+ }
+
+ public void foo(ReplaceClassName2 a) {
+ field = a;
+ }
+}
diff --git a/src/test/test2/SetExceptions.class b/src/test/test2/SetExceptions.class Binary files differnew file mode 100644 index 00000000..2331eb9c --- /dev/null +++ b/src/test/test2/SetExceptions.class diff --git a/src/test/test2/SetExceptions.java b/src/test/test2/SetExceptions.java new file mode 100644 index 00000000..fd3f2322 --- /dev/null +++ b/src/test/test2/SetExceptions.java @@ -0,0 +1,7 @@ +package test2;
+
+public class SetExceptions {
+ public void f() throws Exception {
+ throw new Exception();
+ }
+}
diff --git a/src/test/test2/SetSuper.class b/src/test/test2/SetSuper.class Binary files differnew file mode 100644 index 00000000..55861734 --- /dev/null +++ b/src/test/test2/SetSuper.class diff --git a/src/test/test2/SetSuperIntf.class b/src/test/test2/SetSuperIntf.class Binary files differnew file mode 100644 index 00000000..d5595567 --- /dev/null +++ b/src/test/test2/SetSuperIntf.class diff --git a/src/test/test2/SetSuperParent.class b/src/test/test2/SetSuperParent.class Binary files differnew file mode 100644 index 00000000..2825d7d7 --- /dev/null +++ b/src/test/test2/SetSuperParent.class diff --git a/src/test/test2/StaticArraysMem.java b/src/test/test2/StaticArraysMem.java new file mode 100644 index 00000000..5c220a0e --- /dev/null +++ b/src/test/test2/StaticArraysMem.java @@ -0,0 +1,5 @@ +package test2; + +public class StaticArraysMem { + int i; +} diff --git a/src/test/test2/StaticFinal.class b/src/test/test2/StaticFinal.class Binary files differnew file mode 100644 index 00000000..69be9939 --- /dev/null +++ b/src/test/test2/StaticFinal.class diff --git a/src/test/test2/StaticMember.class b/src/test/test2/StaticMember.class Binary files differnew file mode 100644 index 00000000..10a72092 --- /dev/null +++ b/src/test/test2/StaticMember.class diff --git a/src/test/test2/StaticMember.java b/src/test/test2/StaticMember.java new file mode 100644 index 00000000..10c14bda --- /dev/null +++ b/src/test/test2/StaticMember.java @@ -0,0 +1,11 @@ +package test2;
+
+interface IStaticMember {
+ int bar();
+}
+
+public class StaticMember implements IStaticMember {
+ public static int k = 3;
+ public static int foo() { return 7; }
+ public int bar() { return 3; }
+}
diff --git a/src/test/test2/StaticMember2.class b/src/test/test2/StaticMember2.class Binary files differnew file mode 100644 index 00000000..fe46c673 --- /dev/null +++ b/src/test/test2/StaticMember2.class diff --git a/src/test/test2/StaticMember2.java b/src/test/test2/StaticMember2.java new file mode 100644 index 00000000..747bb9b6 --- /dev/null +++ b/src/test/test2/StaticMember2.java @@ -0,0 +1,12 @@ +package test2;
+
+public class StaticMember2 {
+ public static final int f = 11;
+ public static final long fj = 13L;
+ public static final boolean fb = false;
+ public static final double fd = 23.7;
+
+ public static int k = 3;
+ public static int seven() { return 7; }
+ public int bar() { return 3; }
+}
diff --git a/src/test/test2/SuperCall.class b/src/test/test2/SuperCall.class Binary files differnew file mode 100644 index 00000000..b7294c22 --- /dev/null +++ b/src/test/test2/SuperCall.class diff --git a/src/test/test2/SuperCall.java b/src/test/test2/SuperCall.java new file mode 100644 index 00000000..f1c42027 --- /dev/null +++ b/src/test/test2/SuperCall.java @@ -0,0 +1,20 @@ +package test2; + +class SuperClass { + public void foo() throws Exception {} +} + +public class SuperCall extends SuperClass { + int i = 0; + public int bar() throws Exception { + foo(); + return 1; + } + + public void foo() throws Exception { + if (++i > 5) + throw new Exception("infinite regression?"); + + super.foo(); + } +} diff --git a/src/test/test2/SuperInterface1.java b/src/test/test2/SuperInterface1.java new file mode 100644 index 00000000..4bb6c49a --- /dev/null +++ b/src/test/test2/SuperInterface1.java @@ -0,0 +1,6 @@ +package test2;
+
+public interface SuperInterface1 {
+ public int getAge();
+ public int setAge(int value);
+}
diff --git a/src/test/test2/SuperInterface2.java b/src/test/test2/SuperInterface2.java new file mode 100644 index 00000000..27d5925a --- /dev/null +++ b/src/test/test2/SuperInterface2.java @@ -0,0 +1,3 @@ +package test2;
+
+public interface SuperInterface2 extends SuperInterface1 {}
diff --git a/src/test/test2/SuperInterface3.class b/src/test/test2/SuperInterface3.class Binary files differnew file mode 100644 index 00000000..4b6c7b73 --- /dev/null +++ b/src/test/test2/SuperInterface3.class diff --git a/src/test/test2/Switch.class b/src/test/test2/Switch.class Binary files differnew file mode 100644 index 00000000..78e8ea94 --- /dev/null +++ b/src/test/test2/Switch.class diff --git a/src/test/test2/Synch.class b/src/test/test2/Synch.class Binary files differnew file mode 100644 index 00000000..c5a5ddd1 --- /dev/null +++ b/src/test/test2/Synch.class diff --git a/src/test/test2/Where.java b/src/test/test2/Where.java new file mode 100644 index 00000000..29907f81 --- /dev/null +++ b/src/test/test2/Where.java @@ -0,0 +1,10 @@ +package test2;
+
+public class Where {
+ static int i = 0;
+ static String s;
+ static {
+ String m = "test";
+ s = m.substring(1);
+ }
+}
diff --git a/src/test/test3/Anno.java b/src/test/test3/Anno.java new file mode 100644 index 00000000..675b29d8 --- /dev/null +++ b/src/test/test3/Anno.java @@ -0,0 +1,15 @@ +package test3; + +public @interface Anno { + char c() default '0'; + boolean bool() default true; + byte b() default 1; + short s() default 2; + int i() default 3; + long j() default 4L; + float f() default 5.0F; + double d() default 6.0; + String str() default "7"; + Class clazz() default AnnoTest.class; + Anno2 anno2() default @Anno2(); +} diff --git a/src/test/test3/Anno2.java b/src/test/test3/Anno2.java new file mode 100644 index 00000000..627c0536 --- /dev/null +++ b/src/test/test3/Anno2.java @@ -0,0 +1,11 @@ +package test3; + +import java.lang.annotation.*; + +@Retention(RetentionPolicy.RUNTIME) +public @interface Anno2 { + int[] i() default { 1, 2, 3 }; + String[] str() default { "a", "b", "c" }; + ColorName color() default ColorName.RED; + ColorName[] color2() default { ColorName.BLUE }; +} diff --git a/src/test/test3/Anno3.java b/src/test/test3/Anno3.java new file mode 100644 index 00000000..28d98338 --- /dev/null +++ b/src/test/test3/Anno3.java @@ -0,0 +1,17 @@ +package test3; + +import java.lang.annotation.*; + +public @interface Anno3 { + char[] c() default {'0'}; + boolean[] bool() default {true}; + byte[] b() default {1}; + short[] s() default {2}; + int[] i() default {3}; + long[] j() default {4L}; + float[] f() default {5.0F}; + double[] d() default {6.0}; + String[] str() default {"7"}; + Class[] clazz() default {AnnoTest.class}; + Anno2[] anno2() default {@Anno2(i=11)}; +} diff --git a/src/test/test3/Anno6.java b/src/test/test3/Anno6.java new file mode 100644 index 00000000..deee6f74 --- /dev/null +++ b/src/test/test3/Anno6.java @@ -0,0 +1,6 @@ +package test3; + +public @interface Anno6 { + String[] str1() default {}; + String[] str2(); +} diff --git a/src/test/test3/AnnoTest.java b/src/test/test3/AnnoTest.java new file mode 100644 index 00000000..072a0ce2 --- /dev/null +++ b/src/test/test3/AnnoTest.java @@ -0,0 +1,21 @@ +package test3; + +@Anno() +public class AnnoTest {} + +@Anno(c='a', bool=false, b=11, s=12, i=13, j=14L, f=15.0F, d=16.0, + str="17", clazz=String.class, anno2=@Anno2(i={11, 12, 13})) +class AnnoTest2 {} + +@Anno() @Anno2(i={1}) +class AnnoTest3 {} + +@Anno() @Anno2() @Anno3() +class AnnoTest4 {} + +class AnnoTest5 { + @Anno() + void foo() {} + + @Anno2() int bar; +}
\ No newline at end of file diff --git a/src/test/test3/AnnoTest6.java b/src/test/test3/AnnoTest6.java new file mode 100644 index 00000000..5c3e87fe --- /dev/null +++ b/src/test/test3/AnnoTest6.java @@ -0,0 +1,6 @@ +package test3; + +@Anno6(str2={}) +public class AnnoTest6 { + int foo() { return 1; } +} diff --git a/src/test/test3/CheckModify.java b/src/test/test3/CheckModify.java new file mode 100644 index 00000000..cf35cb2d --- /dev/null +++ b/src/test/test3/CheckModify.java @@ -0,0 +1,5 @@ +package test3; + +public class CheckModify { + int i; +} diff --git a/src/test/test3/ChibaAnnotation.java b/src/test/test3/ChibaAnnotation.java new file mode 100644 index 00000000..4e917148 --- /dev/null +++ b/src/test/test3/ChibaAnnotation.java @@ -0,0 +1,11 @@ +package test3; + +import java.lang.annotation.*; + +@Retention(RetentionPolicy.RUNTIME) +public @interface ChibaAnnotation { + String name(); + String version(); + String description(); + String interfaceName(); +} diff --git a/src/test/test3/ColorName.java b/src/test/test3/ColorName.java new file mode 100644 index 00000000..17ef4805 --- /dev/null +++ b/src/test/test3/ColorName.java @@ -0,0 +1,5 @@ +package test3; + +public enum ColorName { + RED, GREEN, BLUE +} diff --git a/src/test/test3/Constructor.java b/src/test/test3/Constructor.java new file mode 100644 index 00000000..2b6e1f4e --- /dev/null +++ b/src/test/test3/Constructor.java @@ -0,0 +1,37 @@ +package test3; + +class SuperConsturctor { + SuperConsturctor() {} + SuperConsturctor(int p, int q) {} + SuperConsturctor(int p, double r, long[] s, String t) {} +} + +public class Constructor extends SuperConsturctor { + static String str = "ok?"; + int i; + + public Constructor() { + this(3); + ++i; + } + + public Constructor(int k) { + super(0, 1.0, null, "test"); + i += k; + } + + public Constructor(String s) { + this(); + i += 10; + } + + public Constructor(double d) { + super(1, 2); + i += 100; + } + + public int run() { + str = null; + return 0; + } +} diff --git a/src/test/test3/Constructor2.java b/src/test/test3/Constructor2.java new file mode 100644 index 00000000..bfc7cf27 --- /dev/null +++ b/src/test/test3/Constructor2.java @@ -0,0 +1,7 @@ +package test3; + +public class Constructor2 extends SuperConsturctor { + static String str = null; + int i = 0; + public Constructor2() {} +} diff --git a/src/test/test3/CopyAnno.java b/src/test/test3/CopyAnno.java new file mode 100644 index 00000000..cc4ac33c --- /dev/null +++ b/src/test/test3/CopyAnno.java @@ -0,0 +1,10 @@ +package test3; + +class CopyAnnoBase { + int x = 3; + @VisibleAnno public int getX() { return x; } +} + +public class CopyAnno extends CopyAnnoBase { + public int getX() { return super.getX(); } +} diff --git a/src/test/test3/EmptyCatch.java b/src/test/test3/EmptyCatch.java new file mode 100644 index 00000000..bd1122e1 --- /dev/null +++ b/src/test/test3/EmptyCatch.java @@ -0,0 +1,14 @@ +package test3; + +public class EmptyCatch { + public int test(int i) { + try { + i += 200; + } + finally { + i += 10; + } + + return i; + } +} diff --git a/src/test/test3/EmptyConstructor.java b/src/test/test3/EmptyConstructor.java new file mode 100644 index 00000000..fe53dc33 --- /dev/null +++ b/src/test/test3/EmptyConstructor.java @@ -0,0 +1,33 @@ +package test3; + +public class EmptyConstructor { + static {} + public int value; +} + +class EmptyConstructor2 extends EmptyConstructor { + static {} + public int value2; +} + +class EmptyConstructor3 extends EmptyConstructor { + public int value3; + public EmptyConstructor3() {} + public EmptyConstructor3(int x) { super(); } +} + +class EmptyConstructor4 extends EmptyConstructor3 { + public static int sv = 3; + public int value3; + EmptyConstructor4(int x) { + super(x); + } + + EmptyConstructor4(double x) { + this(); + } + + EmptyConstructor4() { + value3 = 7; + } +} diff --git a/src/test/test3/Enhancer.java b/src/test/test3/Enhancer.java new file mode 100644 index 00000000..5c9d2a25 --- /dev/null +++ b/src/test/test3/Enhancer.java @@ -0,0 +1,180 @@ +package test3; + +import javassist.*; +import java.lang.reflect.Method; +import java.lang.reflect.Field; + +/* Test code + */ +class EnhanceTest { + public EnhanceTest() { super(); } + public void foo(String s) { System.out.println(s); } +} + +public class Enhancer { + private ClassPool pool; + private CtClass superClass; + private CtClass thisClass; + private Class thisJavaClass; + private Interceptor interceptor; + private int unique; + + private static final String INTERCEPTOR = "interceptor"; + + /* Test method + */ + public static void main(String[] args) throws Exception { + Enhancer e = new Enhancer(test3.EnhanceTest.class); + e.overrideAll(); + e.setCallback(new Interceptor() { + public Object invoke(Object self, Method m, Object[] args) + throws Exception + { + System.out.println("intercept: " + m); + return m.invoke(self, args); + } + }); + Class c = e.createClass(); + EnhanceTest obj = (EnhanceTest)c.newInstance(); + obj.foo("test"); + } + + public static interface Interceptor { + Object invoke(Object self, Method m, Object[] args) throws Exception; + } + + public Enhancer(Class clazz) + throws CannotCompileException, NotFoundException + { + this(makeClassPool(clazz).get(clazz.getName())); + } + + private static ClassPool makeClassPool(Class clazz) { + ClassPool cp = new ClassPool(); + cp.appendSystemPath(); + cp.insertClassPath(new ClassClassPath(clazz)); + return cp; + } + + public Enhancer(CtClass superClass) + throws CannotCompileException, NotFoundException + { + this.pool = superClass.getClassPool(); + this.superClass = superClass; + String name = superClass.getName() + "_proxy"; + thisClass = pool.makeClass(name); + thisClass.setSuperclass(superClass); + String src = + "public static " + this.getClass().getName() + + ".Interceptor " + INTERCEPTOR + ";"; + + thisClass.addField(CtField.make(src, thisClass)); + this.thisJavaClass = null; + unique = 0; + } + + public void overrideAll() + throws CannotCompileException, NotFoundException + { + CtMethod[] methods = superClass.getMethods(); + String delegatorNamePrefix = thisClass.makeUniqueName("d"); + for (int i = 0; i < methods.length; i++) { + CtMethod m = methods[i]; + int mod = m.getModifiers(); + if (!Modifier.isFinal(mod) && !Modifier.isAbstract(mod) + && !Modifier.isStatic(mod)) + override(m, delegatorNamePrefix + i); + } + } + + public void override(CtMethod m, String delegatorName) + throws CannotCompileException, NotFoundException + { + String fieldName = "m" + unique++; + thisClass.addField( + CtField.make("private java.lang.reflect.Method " + + fieldName + ";", thisClass)); + CtMethod delegator = CtNewMethod.delegator(m, thisClass); + delegator.setModifiers(Modifier.clear(delegator.getModifiers(), + Modifier.NATIVE)); + delegator.setName(delegatorName); + thisClass.addMethod(delegator); + thisClass.addMethod(makeMethod(m, fieldName, delegatorName)); + } + + private CtMethod makeMethod(CtMethod m, String fieldName, + String delegatorName) + throws CannotCompileException, NotFoundException + { + String factory = this.getClass().getName() + ".findMethod(this, \"" + + delegatorName + "\");"; + String body + = "{ if (" + fieldName + " == null) " + + fieldName + " = " + factory + + "return ($r)" + INTERCEPTOR + ".invoke(this, " + fieldName + + ", $args); }"; + CtMethod m2 = CtNewMethod.make(m.getReturnType(), + m.getName(), + m.getParameterTypes(), + m.getExceptionTypes(), + body, thisClass); + m2.setModifiers(Modifier.clear(m.getModifiers(), + Modifier.NATIVE)); + return m2; + } + + /* A runtime support routine called by an enhanced object. + */ + public static Method findMethod(Object self, String name) { + Method[] methods = self.getClass().getMethods(); + int n = methods.length; + for (int i = 0; i < n; i++) + if (methods[i].getName().equals(name)) + return methods[i]; + + throw new RuntimeException("not found " + name + + " in " + self.getClass()); + } + + public Class createClass() { + if (thisJavaClass == null) + try { + thisClass.debugWriteFile(); + thisJavaClass = thisClass.toClass(); + setInterceptor(); + } + catch (CannotCompileException e) { + throw new RuntimeException(e); + } + + return thisJavaClass; + } + + private static void writeFile(CtClass cc) { + try { + cc.stopPruning(true); + cc.writeFile(); + cc.defrost(); + cc.stopPruning(false); + } + catch (Exception e) { + throw new RuntimeException(e); + } + } + + public void setCallback(Interceptor mi) { + interceptor = mi; + setInterceptor(); + } + + private void setInterceptor() { + if (thisJavaClass != null && interceptor != null) + try { + Field f = thisJavaClass.getField(INTERCEPTOR); + f.set(null, interceptor); + } + catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/test/test3/Erasure.java b/src/test/test3/Erasure.java new file mode 100644 index 00000000..412f439a --- /dev/null +++ b/src/test/test3/Erasure.java @@ -0,0 +1,15 @@ +package test3; + +interface ErasureGet<T> { + T get(); +} + +public class Erasure<T> { + T value; + public Erasure(T t) { value = t; } + public Erasure() { value = null; } + public int run() { + ErasureGet<String> obj = (ErasureGet<String>)new Erasure<String>("1234"); + return obj.get().length(); + } +} diff --git a/src/test/test3/FieldAccessType.java b/src/test/test3/FieldAccessType.java new file mode 100644 index 00000000..c61550d6 --- /dev/null +++ b/src/test/test3/FieldAccessType.java @@ -0,0 +1,10 @@ +package test3; + +public class FieldAccessType { + private int[] k; + public void access() { + k = new int[1]; + int i = 3; + i += k[0]; + } +} diff --git a/src/test/test3/FieldCopy.java b/src/test/test3/FieldCopy.java new file mode 100644 index 00000000..5ac52a0e --- /dev/null +++ b/src/test/test3/FieldCopy.java @@ -0,0 +1,12 @@ +package test3; + +class FieldCopy2 { + int bar; +} + +public class FieldCopy { + public @interface Test { + } + + @Test private static int foo; +} diff --git a/src/test/test3/Frozen.java b/src/test/test3/Frozen.java new file mode 100644 index 00000000..19ebdf46 --- /dev/null +++ b/src/test/test3/Frozen.java @@ -0,0 +1,7 @@ +package test3; + +public class Frozen { + int value; + public Frozen() { value = 3; } + public int get() { return value; } +} diff --git a/src/test/test3/GetMethods.java b/src/test/test3/GetMethods.java new file mode 100644 index 00000000..69cc49fa --- /dev/null +++ b/src/test/test3/GetMethods.java @@ -0,0 +1,30 @@ +package test3; + +class SuperGetMethods { + public int f0; + protected double d0; + String s0; + private char c0; + + public void mpub0() {} + protected void mpro0() {} + void mpack0() {} + private void mpri0() {} +} + +public class GetMethods extends SuperGetMethods { + public GetMethods(int i) {} + protected GetMethods(String i, int j) {} + GetMethods() {} + private GetMethods(int i, int j) {} + + public int f; + protected double d; + String s; + private char c; + + public void mpub() {} + protected void mpro() {} + void mpack() {} + private void mpri() {} +} diff --git a/src/test/test3/InheritCons.java b/src/test/test3/InheritCons.java new file mode 100644 index 00000000..d37719b0 --- /dev/null +++ b/src/test/test3/InheritCons.java @@ -0,0 +1,9 @@ +package test3; + +public class InheritCons { + int value; + public InheritCons() { this(2); } + private InheritCons(int i) { value = i; } + protected InheritCons(String s) { this(0); } + InheritCons(char c) { this(1); } +} diff --git a/src/test/test3/InnerClass.java b/src/test/test3/InnerClass.java new file mode 100644 index 00000000..411e60b8 --- /dev/null +++ b/src/test/test3/InnerClass.java @@ -0,0 +1,7 @@ +package test3; + +public class InnerClass { + int y; + public static class Inner { int x; } + public class Inner2 { int x; } +} diff --git a/src/test/test3/InnerMethod.java b/src/test/test3/InnerMethod.java new file mode 100644 index 00000000..d00aa2b0 --- /dev/null +++ b/src/test/test3/InnerMethod.java @@ -0,0 +1,17 @@ +package test3; + +public class InnerMethod { + static int f = 0; + static int counter = 3; + private static void test() {} + static Inner inner = new Inner(); + + static class Inner { + protected static void test() { f = 1; } + } + + public int foo() { + test(); + return f; + } +} diff --git a/src/test/test3/InsParam.java b/src/test/test3/InsParam.java new file mode 100644 index 00000000..68950923 --- /dev/null +++ b/src/test/test3/InsParam.java @@ -0,0 +1,16 @@ +package test3; + +public class InsParam { + public int bar(int k) { return k; } + + public int bar2(int k) { return k; } + + public int foo(int i) { + int k = bar2(i); + return k; + } + + public int poi(int i, String s) { + return i + s.length(); + } +} diff --git a/src/test/test3/InsertAfter.java b/src/test/test3/InsertAfter.java new file mode 100644 index 00000000..731a4bc6 --- /dev/null +++ b/src/test/test3/InsertAfter.java @@ -0,0 +1,17 @@ +package test3; + +public class InsertAfter { + int k; + + public InsertAfter() { + k = 3; + } + + public int test() { + foo(); + return k; + } + public void foo() { + ++k; + } +} diff --git a/src/test/test3/InsertBeforeType.java b/src/test/test3/InsertBeforeType.java new file mode 100644 index 00000000..b61db317 --- /dev/null +++ b/src/test/test3/InsertBeforeType.java @@ -0,0 +1,11 @@ +package test3; + +public class InsertBeforeType { + String value = ""; + void foo() { value += ":"; } + public int test() { + foo(); + System.out.println(value); + return value.length(); + } +} diff --git a/src/test/test3/InvokeArray.java b/src/test/test3/InvokeArray.java new file mode 100644 index 00000000..fc2eb308 --- /dev/null +++ b/src/test/test3/InvokeArray.java @@ -0,0 +1,15 @@ +package test3; + +class InvokeArrayEle { + String name; +} + +public class InvokeArray { + public int test() { + return doit(new InvokeArrayEle[3]); + } + public int doit(InvokeArrayEle[] ae) { + Object[] ae2 = (Object[])ae.clone(); + return ae2.length; + } +}
\ No newline at end of file diff --git a/src/test/test3/InvokeIntf.java b/src/test/test3/InvokeIntf.java new file mode 100644 index 00000000..d1811ce6 --- /dev/null +++ b/src/test/test3/InvokeIntf.java @@ -0,0 +1,30 @@ +package test3; + +interface InvokedIntf { + Object clone(); +} + +interface InvokedIntf2 extends InvokedIntf { +} + +class InvokedIntf3 implements InvokedIntf2 { + public Object clone() { + try { + return super.clone(); + } + catch (Exception e) { + return null; + } + } +} + +public class InvokeIntf { + public int test() { + doit(new InvokedIntf3()); + return 7; + } + public void doit(InvokedIntf2 ii) { + ii.clone(); + ii.toString(); + } +} diff --git a/src/test/test3/JIRA63.java b/src/test/test3/JIRA63.java new file mode 100644 index 00000000..2ae84c64 --- /dev/null +++ b/src/test/test3/JIRA63.java @@ -0,0 +1,5 @@ +package test3; + +public class JIRA63 { + +} diff --git a/src/test/test3/JIRA63Helper.java b/src/test/test3/JIRA63Helper.java new file mode 100644 index 00000000..1c32c678 --- /dev/null +++ b/src/test/test3/JIRA63Helper.java @@ -0,0 +1,7 @@ +package test3; + +public class JIRA63Helper { + public static JIRA63Helper getAnObject(Object o) { + return new JIRA63Helper(); + } +} diff --git a/src/test/test3/MethodRedirect.java b/src/test/test3/MethodRedirect.java new file mode 100644 index 00000000..889a3c68 --- /dev/null +++ b/src/test/test3/MethodRedirect.java @@ -0,0 +1,20 @@ +package test3; + +interface MethodRedirectIntf { + int afo(); +} + +public class MethodRedirect implements MethodRedirectIntf { + private int foo() { return 0; } + public static int poi() { return 1; } + public int bar() { return 2; } + public int afo() { return 3; } + + public int test() { + return bar(); + } + + public static void main(String[] args) { + System.out.println(new MethodRedirect().test()); + } +} diff --git a/src/test/test3/MethodRedirect2.java b/src/test/test3/MethodRedirect2.java new file mode 100644 index 00000000..81c083c1 --- /dev/null +++ b/src/test/test3/MethodRedirect2.java @@ -0,0 +1,43 @@ +package test3; + +interface MethodRedirect2SupIntf { + int foo(); + int bar(); + int bar2(); +} + +interface MethodRedirect2Intf extends MethodRedirect2SupIntf { + int bar2(); +} + +class MethodRedirect2SupSup { + public int bfo() { return 100; } + public int bfo2() { return 200; } +} + +class MethodRedirect2Sup extends MethodRedirect2SupSup { + public int afo() { return 10; } + public int afo2() { return 20; } + public int bfo() { return 300; } +} + +public class MethodRedirect2 extends MethodRedirect2Sup implements MethodRedirect2Intf { + public int foo() { return 1; } + public int bar() { return 2; } + public int bar2() { return 3; } + + public int test(MethodRedirect2Intf intf, MethodRedirect2 clazz, + MethodRedirect2SupSup sup) + { + return intf.bar() + intf.bar2() + clazz.afo() + clazz.bfo() + sup.bfo(); + } + + public int test() { + MethodRedirect2 obj = new MethodRedirect2(); + return test(obj, obj, obj); + } + + public static void main(String[] args) { + System.out.println(new MethodRedirect2().test()); + } +} diff --git a/src/test/test3/Mods.java b/src/test/test3/Mods.java new file mode 100644 index 00000000..3d4dbb1a --- /dev/null +++ b/src/test/test3/Mods.java @@ -0,0 +1,9 @@ +package test3; + +public class Mods { + public int foo; +} + +interface Mods2 { + int foo(); +} diff --git a/src/test/test3/Name.java b/src/test/test3/Name.java new file mode 100644 index 00000000..7614e304 --- /dev/null +++ b/src/test/test3/Name.java @@ -0,0 +1,17 @@ +package test3; + +public class Name { + static int k; + static { k = 3; } + + public Name() {} + public Name(int i) {} + public Name(Name n) {} + public Name(Name n, String s) {} + + public void foo() {} + public void foo2(int i) {} + public void foo3(String s) {} + public void foo4(String[] s) {} + public void foo5(int i, String s) {} +} diff --git a/src/test/test3/NestedClass.java b/src/test/test3/NestedClass.java new file mode 100644 index 00000000..75b4efe2 --- /dev/null +++ b/src/test/test3/NestedClass.java @@ -0,0 +1,24 @@ +package test3; + +public class NestedClass { + public class Inner { + int i; + } + + public static class StaticNested { + int k; + } + + public Object foo() { + return new Object() { + public String toString() { return "OK"; } + }; + } + + public Object bar() { + class Local { + int j; + } + return new Local(); + } +} diff --git a/src/test/test3/NewClass2.java b/src/test/test3/NewClass2.java new file mode 100644 index 00000000..3df0f004 --- /dev/null +++ b/src/test/test3/NewClass2.java @@ -0,0 +1,5 @@ +package test3; + +@ChibaAnnotation(name="Chiba",version="Chiba",description="Chiba",interfaceName="Chiba") +public class NewClass2 { +}
\ No newline at end of file diff --git a/src/test/test3/NewExprTryCatch.java b/src/test/test3/NewExprTryCatch.java new file mode 100644 index 00000000..193985eb --- /dev/null +++ b/src/test/test3/NewExprTryCatch.java @@ -0,0 +1,29 @@ +package test3; + +class NewExprTryCatch2 { +} + +public class NewExprTryCatch { + public void instrumentMe() { + // we need a 'new' expression to instrument, the exact type is not important + new Object(); + // if the try/catch block below is removed, the error does not occur + try { + System.out.println(); + } catch (Throwable t) { + } + } + + public void me2() throws Exception { + // the error is somehow related to the string concatenation and local variables, + // when the code below is replaced with something else, the error does not occur. + String s1 = "a"; + String s2 = s1 + "b"; + } + + public int test() throws Exception { + instrumentMe(); + me2(); + return 0; + } +} diff --git a/src/test/test3/PackName.java b/src/test/test3/PackName.java new file mode 100644 index 00000000..111d3ed7 --- /dev/null +++ b/src/test/test3/PackName.java @@ -0,0 +1,12 @@ +package test3; + +class PackName2 { + public static int k = 1; +} +public class PackName { + public static int test3 = 3; + public static int sub = 4; + public static int PackName2; + + public static int get() { return test3; } +} diff --git a/src/test/test3/ParamAnno.java b/src/test/test3/ParamAnno.java new file mode 100644 index 00000000..8277d9b1 --- /dev/null +++ b/src/test/test3/ParamAnno.java @@ -0,0 +1,9 @@ +package test3; + +public class ParamAnno { + public int foo(int i, String s, ParamAnno pa, double d) { + return i + 1; + } + + public void bar() {} +} diff --git a/src/test/test3/PublicInner.java b/src/test/test3/PublicInner.java new file mode 100644 index 00000000..72cf6345 --- /dev/null +++ b/src/test/test3/PublicInner.java @@ -0,0 +1,13 @@ +package test3; + +class PublicInner2 { + public static class PS { + int j; + } + + int i; +} + +public class PublicInner { + int i; +} diff --git a/src/test/test3/RecReplace.java b/src/test/test3/RecReplace.java new file mode 100644 index 00000000..60fa44a9 --- /dev/null +++ b/src/test/test3/RecReplace.java @@ -0,0 +1,20 @@ +package test3; + +public class RecReplace { + public int run() { + double d = 4.0; + int i = foo(3.0); + int j = bar(d); + return i + j; + } + + public int run2() { + double d = 4.0; + int i = foo(3.0); + int j = bar(d); + return i + j; + } + + int foo(double d) { return (int)d; } + int bar(double d) { return (int)d + 1; } +} diff --git a/src/test/test3/RecReplace2.java b/src/test/test3/RecReplace2.java new file mode 100644 index 00000000..6db2bee6 --- /dev/null +++ b/src/test/test3/RecReplace2.java @@ -0,0 +1,19 @@ +package test3; + +public class RecReplace2 { + int value = 3; + int value2 = 9; + int foo(int k) { return k + 1; } + public int run() { + value2 = 0; + value = 7; + value2 += 10; + return value + value2; + } + public int run2() { + value2 = 0; + value = 7; + value2 += 10; + return value + value2; + } +} diff --git a/src/test/test3/ReplaceNew.java b/src/test/test3/ReplaceNew.java new file mode 100644 index 00000000..018408eb --- /dev/null +++ b/src/test/test3/ReplaceNew.java @@ -0,0 +1,19 @@ +package test3; + +public class ReplaceNew { + public ReplaceNew() {} + public ReplaceNew(String s) {} + int i = 0; + public int run() { + i = 3; + ReplaceNew s = new ReplaceNew(); + new ReplaceNew(); + return i; + } + + static int j = 0; + public int run2() { + new ReplaceNew(new String("test")); + return j; + } +} diff --git a/src/test/test3/SetModifiers.java b/src/test/test3/SetModifiers.java new file mode 100644 index 00000000..cf5706d5 --- /dev/null +++ b/src/test/test3/SetModifiers.java @@ -0,0 +1,8 @@ +package test3; + +public class SetModifiers { + public int m; + public static final class A { + public int a; + } +} diff --git a/src/test/test3/SigAttribute.java b/src/test/test3/SigAttribute.java new file mode 100644 index 00000000..83527f8a --- /dev/null +++ b/src/test/test3/SigAttribute.java @@ -0,0 +1,6 @@ +package test3; + +public class SigAttribute<T> { + T value; + T get(T t) { return t; } +} diff --git a/src/test/test3/StrBuild.java b/src/test/test3/StrBuild.java new file mode 100644 index 00000000..fbb98035 --- /dev/null +++ b/src/test/test3/StrBuild.java @@ -0,0 +1,8 @@ +package test3; + +public class StrBuild { + public int test() { + StringBuilder sb = new StringBuilder("test"); + return sb.charAt(0); + } +} diff --git a/src/test/test3/SubValue.java b/src/test/test3/SubValue.java new file mode 100644 index 00000000..33e1c8e5 --- /dev/null +++ b/src/test/test3/SubValue.java @@ -0,0 +1,15 @@ +package test3; + +class SuperValue { + int i; +} + +public class SubValue extends SuperValue { + public SubValue after(SuperValue ret, SuperValue sup, SuperValue sup2) { + return null; + } + + public SubValue after(SuperValue ret, SubValue sup, SuperValue sub) { + return new SubValue(); + } +} diff --git a/src/test/test3/Superclass.java b/src/test/test3/Superclass.java new file mode 100644 index 00000000..32407833 --- /dev/null +++ b/src/test/test3/Superclass.java @@ -0,0 +1,15 @@ +package test3; + +class Superclass2 { + public int foo() { return 1; } + public int bar() { return 10; } +} + +class Superclass3 extends Superclass2 { + public int test() { return foo(); } + public int bar() { return 20; } +} + +public class Superclass extends Superclass2 { + public int foo() { return super.foo() + super.bar(); } +} diff --git a/src/test/test3/Switch.java b/src/test/test3/Switch.java new file mode 100644 index 00000000..636e0fae --- /dev/null +++ b/src/test/test3/Switch.java @@ -0,0 +1,30391 @@ +package test3; + +public class Switch +{ + public int test() { + Switch b = new Switch(); + b.foo(); + return 0; + } + + protected void foo() + { + int j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + j = 4; + + switch (1) + { + default: + } + } +}
\ No newline at end of file diff --git a/src/test/test3/TransNewClass.java b/src/test/test3/TransNewClass.java new file mode 100644 index 00000000..a8a7da17 --- /dev/null +++ b/src/test/test3/TransNewClass.java @@ -0,0 +1,37 @@ +package test3; + +class TransNewClassOld { + int k = 1; + TransNewClassOld() {} + TransNewClassOld(int i) { k = i; } + TransNewClassOld(TransNewClassOld obj) { k = obj.k; } +} + +class TransNewClassNew extends TransNewClassOld { + TransNewClassNew() { k = 10; } + TransNewClassNew(int i) { k = i * 10; } + TransNewClassNew(TransNewClassOld obj) { k = obj.k * 2; } +} + +class TransNewClassNot extends TransNewClassOld { + TransNewClassNot() { k = 100; } +} + +public class TransNewClass { + public static class TransNewClass2 { + public int test() { + TransNewClassOld obj = new TransNewClassOld(); + TransNewClassOld obj2 = new TransNewClassOld(); + TransNewClassOld obj3 = new TransNewClassOld(3); + return obj.k + obj2.k + obj3.k; + } + } + + public int test() { + TransNewClassOld obj = new TransNewClassOld(); + TransNewClassOld obj2 = new TransNewClassOld(4); + TransNewClassOld obj3 = new TransNewClassNot(); + TransNewClassOld obj4 = new TransNewClassOld(new TransNewClassOld()); + return obj.k + obj2.k + obj3.k + obj4.k; + } +} diff --git a/src/test/test3/TransformRead.java b/src/test/test3/TransformRead.java new file mode 100644 index 00000000..0075a237 --- /dev/null +++ b/src/test/test3/TransformRead.java @@ -0,0 +1,15 @@ +package test3; + +class TransformRead1 { + public int value = 1; + public int value2 = 10; +} + +public class TransformRead extends TransformRead1 { + public int value = 100; + public int foo() { + return value + value2 + super.value; + } + public static int getValue(Object obj) { return 1000; } + public static int getValue2(Object obj) { return 10000; } +} diff --git a/src/test/test3/Unique.java b/src/test/test3/Unique.java new file mode 100644 index 00000000..5dc8da3c --- /dev/null +++ b/src/test/test3/Unique.java @@ -0,0 +1,24 @@ +package test3; + +interface Unique5 { + void bar100(); + void bar101b(); +} + +interface Unique4 extends Unique5 { + void bar(); +} + +abstract class Unique3 implements Unique4 { + abstract void foo(); +} + +class Unique2 { + void foo() {} + void foo100() {} + void foo101() {} +} + +public class Unique extends Unique2 { + void foo() {} +} diff --git a/src/test/test3/Visible.java b/src/test/test3/Visible.java new file mode 100644 index 00000000..162f46e1 --- /dev/null +++ b/src/test/test3/Visible.java @@ -0,0 +1,15 @@ +package test3; + +class Visible2 { + public int pub; + protected int pro; + private int pri; + int pack; +} + +public class Visible { + public int pub; + protected int pro; + private int pri; + int pack; +} diff --git a/src/test/test3/VisibleAnno.java b/src/test/test3/VisibleAnno.java new file mode 100644 index 00000000..37f7c239 --- /dev/null +++ b/src/test/test3/VisibleAnno.java @@ -0,0 +1,7 @@ +package test3; + +import java.lang.annotation.*; + +@Retention(java.lang.annotation.RetentionPolicy.RUNTIME) +public @interface VisibleAnno { +} diff --git a/src/test/test3/VoidReturn.java b/src/test/test3/VoidReturn.java new file mode 100644 index 00000000..b084181f --- /dev/null +++ b/src/test/test3/VoidReturn.java @@ -0,0 +1,5 @@ +package test3; + +public class VoidReturn { + public void foo() {} +} diff --git a/src/test/test3/sub/SubPackName.java b/src/test/test3/sub/SubPackName.java new file mode 100644 index 00000000..3899e634 --- /dev/null +++ b/src/test/test3/sub/SubPackName.java @@ -0,0 +1,5 @@ +package test3.sub; + +public class SubPackName { + public static int get() { return 5; } +} diff --git a/src/test/test3/sub/Visible.java b/src/test/test3/sub/Visible.java new file mode 100644 index 00000000..5dd3c0e0 --- /dev/null +++ b/src/test/test3/sub/Visible.java @@ -0,0 +1,12 @@ +package test3.sub; + +class Visible2 extends test3.Visible { + public int pub2; +} + +public class Visible { + public int pub; + protected int pro; + private int pri; + int pack; +} diff --git a/src/test/test4/Anno.java b/src/test/test4/Anno.java new file mode 100644 index 00000000..336d4e6f --- /dev/null +++ b/src/test/test4/Anno.java @@ -0,0 +1,6 @@ +package test4; + +@Anno1 public class Anno { + @Anno1 public int value; + @Anno1 public int foo() { return 0; } +} diff --git a/src/test/test4/Anno1.java b/src/test/test4/Anno1.java new file mode 100644 index 00000000..d368ecc1 --- /dev/null +++ b/src/test/test4/Anno1.java @@ -0,0 +1,5 @@ +package test4; + +public @interface Anno1 { + String value() default "empty"; +} diff --git a/src/test/test4/CodeConv.java b/src/test/test4/CodeConv.java new file mode 100644 index 00000000..548c1d2c --- /dev/null +++ b/src/test/test4/CodeConv.java @@ -0,0 +1,19 @@ +package test4; + +public class CodeConv { + int k = 1; + public int m1() { + return k + 10; + } + public int m2() { + return k + 100; + } + public static void m3(CodeConv cc) { + cc.k++; + } + + public int run() { + int i = m1() * 1000 + m2(); + return k + i * 10; + } +} diff --git a/src/test/test4/CodeConv2.java b/src/test/test4/CodeConv2.java new file mode 100644 index 00000000..3a4ce036 --- /dev/null +++ b/src/test/test4/CodeConv2.java @@ -0,0 +1,39 @@ +package test4; + +public class CodeConv2 { + int field = 3; + static int sf = 1; + + public int run() { + field = 7; + sf = 8; + switch (field) { + case 0: + field = 1; + break; + default: + } + int r = field * 10000 + sf; + switch (field) { + case 0: + field = 1; + break; + default: + } + return r; + } + + public static void write(Object target, int value) { + if (target == null) + sf = value * 2; + else + ((CodeConv2)target).field = value * 2; + } + + public static int read(Object target) { + if (target == null) + return sf * 100; + else + return ((CodeConv2)target).field * 100; + } +} diff --git a/src/test/test4/CtArrayTest.java b/src/test/test4/CtArrayTest.java new file mode 100644 index 00000000..3967d4bd --- /dev/null +++ b/src/test/test4/CtArrayTest.java @@ -0,0 +1,4 @@ +package test4; + +public abstract class CtArrayTest { +} diff --git a/src/test/test4/GapSwitch.java b/src/test/test4/GapSwitch.java new file mode 100644 index 00000000..126bbdf9 --- /dev/null +++ b/src/test/test4/GapSwitch.java @@ -0,0 +1,83 @@ +package test4; + +public class GapSwitch { + public int value; + public int foo(int i) { return i + 1; } + public int run() { + value = 0; + int k = 0; + k = foo(k); + switch (value) { + case 0: + k++; + break; + case 1: + k *= 10; + break; + default: + k *= 100; + break; + } + + return k + value * 1000; + } + + public int run2() { + value = 0; + int k = 0; + k = foo(k); + switch (value) { + case 10: + k++; + break; + case 1300: + k *= 10; + break; + default: + k *= 100; + break; + } + + return k + value * 1000; + } + + public int run3() { + value = 1; + int k = 0; + for (int i = 0; i < 2; i++) { + k = foo(k); + switch (value) { + case 10: + k++; + k = foo(k); + break; + case 1300: + k *= 100; + k = foo(k); + break; + default: + k *= 10; + k = foo(k); + break; + } + + k = foo(k); + switch (value) { + case 10: + k++; + k = foo(k); + break; + case 13: + k *= 100; + k = foo(k); + break; + default: + k *= 10; + k = foo(k); + break; + } + } + + return k + value; + } +} diff --git a/src/test/test4/GetAllRef.java b/src/test/test4/GetAllRef.java new file mode 100644 index 00000000..c19bfabd --- /dev/null +++ b/src/test/test4/GetAllRef.java @@ -0,0 +1,33 @@ +package test4; + +enum GetAllRefEnum { A, B }; + +@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) +@interface GetAllRefAnno { + GetAllRefEnum getA(); + Class getC(); +} + +@interface GetAllRefAnnoC {} + +@interface GetAllRefAnnoC2 {} + +@interface GetAllRefAnnoC3 {} + +@interface GetAllRefAnnoC4 {} + +@GetAllRefAnno(getA = GetAllRefEnum.A, getC = String.class) +public class GetAllRef { +} + +@GetAllRefAnno(getA = GetAllRefEnum.A, getC = String.class) +class GetAllRefB { +} + +@GetAllRefAnno(getA = GetAllRefEnum.A, getC = String.class) +class GetAllRefC { + void bar(@GetAllRefAnnoC3 int i, int j, + @GetAllRefAnnoC2 @GetAllRefAnnoC4 boolean b) {} + @GetAllRefAnnoC void foo() {} + @GetAllRefAnnoC2 int value; +} diff --git a/src/test/test4/GetAllRefAnno2.java b/src/test/test4/GetAllRefAnno2.java new file mode 100644 index 00000000..dcb0956b --- /dev/null +++ b/src/test/test4/GetAllRefAnno2.java @@ -0,0 +1,6 @@ +package test4; + +public @interface GetAllRefAnno2 { + GetAllRefEnum2 getA(); + Class getC(); +} diff --git a/src/test/test4/GetAllRefEnum2.java b/src/test/test4/GetAllRefEnum2.java new file mode 100644 index 00000000..d6cf6292 --- /dev/null +++ b/src/test/test4/GetAllRefEnum2.java @@ -0,0 +1,3 @@ +package test4; + +public enum GetAllRefEnum2 { A, B } diff --git a/src/test/test4/GetAllRefInnerTest.java b/src/test/test4/GetAllRefInnerTest.java new file mode 100644 index 00000000..352b3252 --- /dev/null +++ b/src/test/test4/GetAllRefInnerTest.java @@ -0,0 +1,26 @@ +package test4; + +class GetAllRefInnerTest2<T> { + Class clazz; + T value; + void foo(T t) { value = t; } + Object poi(T t) { + return new Object() { + public String toString(T t) { return this.getClass().toString(); } + }; + } +} + +public class GetAllRefInnerTest<T> { + public T bar(T b) { + Object obj = new GetAllRefInnerTest2<java.util.HashMap>() { + void foo(java.util.HashMap a) { value = null; String s = clazz.toString() + a.toString(); } + }; + return b; + } + public Object foo() { + return new java.util.HashSet<String>() { + public String toString() { return this.getClass().toString(); } + }; + } +} diff --git a/src/test/test4/GetFieldDesc.java b/src/test/test4/GetFieldDesc.java new file mode 100644 index 00000000..605e2ad1 --- /dev/null +++ b/src/test/test4/GetFieldDesc.java @@ -0,0 +1,11 @@ +package test4; + +public class GetFieldDesc { + public int f; + public String s; +} + +class GetFieldDescSub extends GetFieldDesc { + public int f; + public int s; +} diff --git a/src/test/test4/ImportPac.java b/src/test/test4/ImportPac.java new file mode 100644 index 00000000..c6127c9c --- /dev/null +++ b/src/test/test4/ImportPac.java @@ -0,0 +1,4 @@ +package test4; + +public class ImportPac { +} diff --git a/src/test/test4/JIRA93.java b/src/test/test4/JIRA93.java new file mode 100644 index 00000000..2d94710f --- /dev/null +++ b/src/test/test4/JIRA93.java @@ -0,0 +1,5 @@ +package test4; + +public class JIRA93 { + public void foo() {} +} diff --git a/src/test/test4/LocalVars.java b/src/test/test4/LocalVars.java new file mode 100644 index 00000000..17ab6cd1 --- /dev/null +++ b/src/test/test4/LocalVars.java @@ -0,0 +1,60 @@ +package test4; + +public class LocalVars { + public int run() { + int i = 0; + int p = i; + int q = p; + int r = q; + for (int k = 1; k < 3; ++k) + p += k; + + for (int k = 3; k > 0; --k) + try { + foo(k); + p++; + } + finally { + p++; + } + + switch (p) { + case 1: + p = 100; + break; + default : + ++p; + } + return p + r; + } + + public int run2() { + int i = 0; + int p = i; + int q = p; + int r = q; + for (int k = 1; k < 3; ++k) + p += k; + + for (int k = 3; k > 0; --k) + try { + foo(k); + p++; + } + finally { + p++; + } + + switch (p) { + case 1: + p = 100; + break; + default : + ++p; + } + + return p + r; + } + + public int foo(int i) { return i; } +} diff --git a/src/test/test4/MakeMethod.java b/src/test/test4/MakeMethod.java new file mode 100644 index 00000000..4b9bb24c --- /dev/null +++ b/src/test/test4/MakeMethod.java @@ -0,0 +1,7 @@ +package test4; + +public class MakeMethod { + public static final String foo() { + return "foo"; + } +} diff --git a/src/test/test4/NestedClass.java b/src/test/test4/NestedClass.java new file mode 100644 index 00000000..3e18f7a3 --- /dev/null +++ b/src/test/test4/NestedClass.java @@ -0,0 +1,29 @@ +package test4; + +public class NestedClass { + public S.S2 s2; + public class N { + public String toString() { return "N"; } + } + public static class S { + public String toString() { return "S"; } + public static class S2 { + public String toString() { return "S2"; } + } + } + public Object foo() { + class In { + public String toString() { return "S"; } + public String toString2() { return new S().toString(); } + } + return new Object() { + public String toString() { + return new Object() { + public String toString() { + return "ok"; + } + }.toString(); + } + }; + } +} diff --git a/src/test/test4/NewImportPac.java b/src/test/test4/NewImportPac.java new file mode 100644 index 00000000..fa9f4ac3 --- /dev/null +++ b/src/test/test4/NewImportPac.java @@ -0,0 +1,4 @@ +package test4; + +public class NewImportPac { +} diff --git a/src/test/test4/NewRemover.java b/src/test/test4/NewRemover.java new file mode 100644 index 00000000..ff57ce2d --- /dev/null +++ b/src/test/test4/NewRemover.java @@ -0,0 +1,30 @@ +package test4; + +public class NewRemover { + static NewRemover obj = new NewRemover(7); + int value; + static int value2 = 5; + + public NewRemover() { + this(3); + } + + public NewRemover(int k) { + value = k; + } + + public int run() { + return make(); + } + + public int make() { + NewRemover nr = new NewRemover(value2 > 0 ? 3 : 0); + return nr.value; + } + + public static NewRemover make2(int z) { + System.out.println("make2 " + z); + obj.value += z; + return obj; + } +} diff --git a/src/test/test4/Rename.java b/src/test/test4/Rename.java new file mode 100644 index 00000000..1ded1f69 --- /dev/null +++ b/src/test/test4/Rename.java @@ -0,0 +1,24 @@ +package test4; + +interface IRename { + Rename foo(Rename r); +} + +public class Rename implements IRename { + int value = 3; + Rename next = null; + + public Rename foo(Rename r) { + Rename k = r; + if (k == null) + return null; + else + return k.next; + } + + public int run() { + next = new Rename(); + next.value = 4; + return foo(this).value; + } +} diff --git a/src/test/test4/Signature.java b/src/test/test4/Signature.java new file mode 100644 index 00000000..aa9de28b --- /dev/null +++ b/src/test/test4/Signature.java @@ -0,0 +1,16 @@ +package test4; + +public class Signature<T> { + public static class Foo { + int value; + } + + public int run() { + Signature<String> s = new Signature<String>(); + return s.foo(new Integer(3), "foo", s, null).length(); + } + + <S> T foo(S s, T t, Signature<T> signature, Signature<Signature<String>> v) { + return t; + } +} diff --git a/src/test/test4/VarArgs.java b/src/test/test4/VarArgs.java new file mode 100644 index 00000000..53c04072 --- /dev/null +++ b/src/test/test4/VarArgs.java @@ -0,0 +1,15 @@ +package test4; + +public class VarArgs { + public int test() { + return goo(1, 2, 3) + goo(1, "a", "b", "c"); + } + + public int goo(int i, int... k) { + return k.length; + } + + public int goo(int i, String... k) { + return k.length; + } +} diff --git a/src/test/test4/length.java b/src/test/test4/length.java new file mode 100644 index 00000000..8158f4c1 --- /dev/null +++ b/src/test/test4/length.java @@ -0,0 +1,5 @@ +package test4; + +public class length { + public static int m() { return 7; } +} diff --git a/src/test/testproxy/BridgeMethod.java b/src/test/testproxy/BridgeMethod.java new file mode 100644 index 00000000..de199bf0 --- /dev/null +++ b/src/test/testproxy/BridgeMethod.java @@ -0,0 +1,19 @@ +package testproxy; + +interface BridgeMethodInf { + public Long getId(); + public void setId(Long id); + public Number m1(); +} + +abstract class BridgeMethodSuper<T> { + public abstract T id(T t); +} + +public class BridgeMethod extends BridgeMethodSuper<String> implements BridgeMethodInf { + private Long id; + public Long getId() { return id; } + public void setId(Long id) { this.id = id; } + public Integer m1() { return 7; } + public String id(String s) { return s; } +} diff --git a/src/test/testproxy/ProxyFactoryPerformanceTest.java b/src/test/testproxy/ProxyFactoryPerformanceTest.java new file mode 100644 index 00000000..5ce0adb6 --- /dev/null +++ b/src/test/testproxy/ProxyFactoryPerformanceTest.java @@ -0,0 +1,195 @@ +package testproxy;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+/**
+import net.sf.cglib.proxy.CallbackFilter;
+import net.sf.cglib.proxy.Enhancer;
+import net.sf.cglib.proxy.InvocationHandler;
+import net.sf.cglib.proxy.NoOp;
+*/
+import javassist.util.proxy.MethodFilter;
+import javassist.util.proxy.MethodHandler;
+import javassist.util.proxy.ProxyFactory;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+public class ProxyFactoryPerformanceTest extends TestCase {
+
+ public static final int COUNT = 100;
+
+ public static final int MAX_THREADS = 30;
+
+ static Throwable error = null;
+
+ public ProxyFactoryPerformanceTest() {}
+
+ public ProxyFactoryPerformanceTest(String name) {
+ super(name);
+ }
+
+ public void testJavassist() throws Throwable {
+ callCreateClass("javassist", ProxyMaker.class);
+ }
+
+ /**
+ public void testCglib() throws Exception {
+ callCreateClass("cglib", EnhancerUser.class);
+ }
+ */
+
+ public void callCreateClass(String translator, Class cl) throws Throwable {
+ error = null;
+ Thread[] threads = new Thread[MAX_THREADS];
+ for (int i = 0; i < threads.length; ++i) {
+ threads[i] = (Thread)cl.newInstance();
+ }
+ long time = System.currentTimeMillis();
+ for (int i = 0; i < threads.length; ++i) {
+ threads[i].start();
+ }
+ for (int i = 0; i < threads.length; ++i) {
+ threads[i].join();
+ }
+ time = System.currentTimeMillis() - time;
+ System.out.println("ProxyFactoryPerformanceTest: " + translator + " time: " + time);
+ if (error != null)
+ throw error;
+ }
+
+ public static Test suite() {
+ return new TestSuite(ProxyFactoryPerformanceTest.class);
+ }
+
+ public static void callOnce() {
+ try {
+ Thread t = new ProxyMaker();
+ t.start();
+ t.join();
+ }
+ catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ System.out.println("** Done");
+ }
+
+ public static void main(String[] args) {
+ // callOnce();
+ ProxyFactory.useCache = args.length == 0;
+ TestRunner.run(suite());
+ }
+}
+
+class ProxyMaker extends Thread implements MethodHandler {
+ private static final MethodFilter FINALIZE_FILTER = new MethodFilter() {
+ public boolean isHandled(Method m) {
+ // skip finalize methods
+ return !( m.getParameterTypes().length == 0 && m.getName().equals( "finalize" ) );
+ }
+ };
+
+ public void run() {
+ for (int i = 0; i < ProxyFactoryPerformanceTest.COUNT; ++i) {
+ callCreateClass();
+ }
+ }
+
+ public void callCreateClass() {
+ try {
+ ProxyFactory factory = new ProxyFactory();
+ factory.setSuperclass(SampleBean.class);
+ factory.setInterfaces(SampleBean.class.getInterfaces());
+ factory.setFilter(FINALIZE_FILTER);
+ factory.setHandler(this);
+
+ Class proxyClass = factory.createClass();
+ //System.out.println("proxy name: " + proxyClass.getName());
+ } catch (Throwable e) {
+ e.printStackTrace();
+ ProxyFactoryPerformanceTest.error = e;
+ }
+ }
+
+ public Object invoke(Object arg0, Method arg1, Method arg2, Object[] arg3) throws Throwable {
+ return null;
+ }
+}
+
+/**
+class EnhancerUser extends Thread implements InvocationHandler {
+ private static final CallbackFilter FINALIZE_FILTER = new CallbackFilter() {
+ public int accept(Method method) {
+ if ( method.getParameterTypes().length == 0 && method.getName().equals("finalize") ){
+ return 1;
+ }
+ else {
+ return 0;
+ }
+ }
+ };
+
+ public void run() {
+ for (int i = 0; i < ProxyFactoryPerformanceTest.COUNT; ++i) {
+ callCreateClass();
+ }
+ }
+
+ public void callCreateClass() {
+ try {
+ Enhancer enhancer = new Enhancer();
+ enhancer.setSuperclass(SampleBean.class);
+ enhancer.setInterfaces(SampleBean.class.getInterfaces());
+ enhancer.setCallbackTypes(new Class[] { InvocationHandler.class, NoOp.class });
+ enhancer.setCallbackFilter(FINALIZE_FILTER);
+ enhancer.setInterceptDuringConstruction(false);
+ // TODO
+ enhancer.setUseCache(false);
+ enhancer.setUseFactory(false);
+ Class proxyClass = enhancer.createClass();
+ //System.out.println("proxy name: " + proxyClass.getName());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable {
+ return null;
+ }
+}
+*/
+
+class SampleBean implements Serializable {
+ long oid;
+
+ int version;
+
+ SampleBean bean;
+
+ public void setOid(long _oid) {
+ oid = _oid;
+ }
+
+ public long getOid() {
+ return oid;
+ }
+
+ public void setVersion(int _ver) {
+ version = _ver;
+ }
+
+ public int getVersion() {
+ return version;
+ }
+
+ public void setBean(SampleBean _bean) {
+ bean = _bean;
+ }
+
+ public SampleBean getBean() {
+ return bean;
+ }
+}
diff --git a/src/test/testproxy/ProxyTester.java b/src/test/testproxy/ProxyTester.java new file mode 100644 index 00000000..fe956f5e --- /dev/null +++ b/src/test/testproxy/ProxyTester.java @@ -0,0 +1,403 @@ +package testproxy;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.InvocationTargetException;
+import javassist.util.proxy.ProxyFactory;
+import javassist.util.proxy.MethodFilter;
+import javassist.util.proxy.MethodHandler;
+import javassist.util.proxy.ProxyObject;
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import java.io.*;
+
+public class ProxyTester extends TestCase {
+ public ProxyTester(String s) {
+ super(s);
+ }
+
+ public ProxyTester() {
+ this("proxy");
+ }
+
+ static class Interceptor1 implements MethodHandler {
+ int counter = 0;
+
+ public Object invoke(Object self, Method m, Method proceed,
+ Object[] args) throws Exception {
+ System.out.println("intercept: " + m + ", proceed: " + proceed
+ + ", modifier: "
+ + Modifier.toString(proceed.getModifiers()));
+ counter++;
+ return proceed.invoke(self, args);
+ }
+ }
+
+ static class Interceptor2 implements MethodHandler {
+ int counter = 0;
+ public Object invoke(Object self, Method m, Method proceed,
+ Object[] args) throws Exception {
+ System.out.println("intercept: " + m + ", proceed: " + proceed);
+ counter++;
+ if (proceed != null)
+ return proceed.invoke(self, args);
+ else
+ if (m.getReturnType() == int.class)
+ return new Integer(3);
+ else
+ return "OK";
+ }
+ }
+
+ static MethodFilter finalizeRemover = new MethodFilter() {
+ public boolean isHandled(Method m) {
+ return !m.getName().equals("finalize");
+ }
+ };
+
+ public void testTarget() throws Exception {
+ ProxyFactory f = new ProxyFactory();
+ f.setSuperclass(Target.class);
+ Interceptor1 interceptor = new Interceptor1();
+ f.setHandler(interceptor);
+ f.setFilter(finalizeRemover);
+ f.writeDirectory = ".";
+ Class c = f.createClass();
+ Target obj = (Target)c.newInstance();
+ obj.m();
+ assertEquals(true, obj.m(true));
+ assertEquals((byte)1, obj.m1((byte)1));
+ assertEquals('a', obj.m2('a'));
+ assertEquals((short)2, obj.m3((short)2));
+ assertEquals(3, obj.m(3));
+ assertEquals(4L, obj.m5(4L));
+ assertTrue(5.0F == obj.m6(5.0F));
+ assertTrue(6.0 == obj.m7(6.0));
+ assertEquals("test", obj.m("test"));
+ int[] ia = { 1, 2, 3 };
+ assertEquals(ia, obj.m7(ia));
+ String[] sa = { "1", "2" };
+ assertEquals(sa, obj.m8(sa));
+ assertEquals(obj, obj.m9(3, obj, null));
+ assertEquals(14, interceptor.counter);
+ }
+
+ public void testTarget1() throws Exception {
+ ProxyFactory f = new ProxyFactory();
+ f.setSuperclass(Target1.class);
+ Interceptor1 interceptor = new Interceptor1();
+ f.setHandler(interceptor);
+ f.setFilter(finalizeRemover);
+ Class c = f.createClass();
+ Target1 obj = (Target1)c.newInstance();
+ assertEquals(null, obj.m(null));
+ assertEquals(1, interceptor.counter);
+ }
+
+ public void testObject() throws Exception {
+ ProxyFactory f = new ProxyFactory();
+ Interceptor1 interceptor = new Interceptor1();
+ f.setHandler(interceptor);
+ f.setFilter(finalizeRemover);
+ Class c = f.createClass();
+ Object obj = (Object)c.newInstance();
+ System.out.println(obj.toString());
+ assertEquals(2, interceptor.counter);
+ }
+
+ public void testSetter() throws Exception {
+ ProxyFactory f = new ProxyFactory();
+ f.writeDirectory = ".";
+ Interceptor1 interceptor = new Interceptor1();
+ f.setHandler(interceptor);
+ f.setFilter(finalizeRemover);
+ Class c = f.createClass();
+ Object obj = (Object)c.newInstance();
+ System.out.println("setter1: " + obj.toString());
+ ((ProxyObject)obj).setHandler(new MethodHandler() {
+ public Object invoke(Object self, Method m, Method proceed,
+ Object[] args) throws Exception {
+ System.out.print("intercept: " + m);
+ return "OK";
+ }
+ });
+ assertEquals("OK", obj.toString());
+ }
+
+ public void testString() throws Exception {
+ ProxyFactory f = new ProxyFactory();
+ Interceptor1 interceptor = new Interceptor1();
+ f.setHandler(interceptor);
+ f.setFilter(finalizeRemover);
+ f.setSuperclass(String.class);
+ try {
+ Class c = f.createClass();
+ Assert.fail("String is final!");
+ }
+ catch (RuntimeException e) {
+ System.out.println(e);
+ }
+ }
+
+ public void testConstructor() throws Exception {
+ ProxyFactory f = new ProxyFactory();
+ Interceptor1 interceptor = new Interceptor1();
+ f.setHandler(interceptor);
+ f.setFilter(finalizeRemover);
+ f.setSuperclass(Target2.class);
+ Class c = f.createClass();
+ Constructor[] cons = c.getDeclaredConstructors();
+ assertEquals(3, cons.length);
+ Constructor con1 = c.getDeclaredConstructor(new Class[] { int.class });
+ Constructor con2 = c.getDeclaredConstructor(new Class[] { int.class, int.class });
+ Method m1 = c.getDeclaredMethod("get", new Class[0]);
+ Method m2 = c.getDeclaredMethod("foo", new Class[0]);
+ assertEquals(0, m1.getExceptionTypes().length);
+ assertEquals("java.io.IOException", m2.getExceptionTypes()[0].getName());
+
+ Target2 t2 = (Target2)con1.newInstance(new Object[] { new Integer(1) });
+ System.out.println(t2.toString());
+ assertEquals(2, interceptor.counter);
+
+ interceptor.counter = 0;
+ assertEquals(2, t2.foo());
+ assertEquals(4, t2._dfoo());
+ assertEquals(2, interceptor.counter);
+ }
+
+ public void testInterface() throws Exception {
+ ProxyFactory f = new ProxyFactory();
+ Interceptor2 interceptor2 = new Interceptor2();
+ f.setHandler(interceptor2);
+ f.setFilter(finalizeRemover);
+ f.setInterfaces(new Class[] { Target3.class });
+ Class c = f.createClass();
+ Target3 obj = (Target3)c.newInstance();
+ assertEquals("OK", obj.m());
+ System.out.println(obj.toString());
+ assertEquals(3, interceptor2.counter);
+ }
+
+ public void test2Interfaces() throws Exception {
+ ProxyFactory f = new ProxyFactory();
+ Interceptor2 interceptor2 = new Interceptor2();
+ f.setHandler(interceptor2);
+ f.setFilter(finalizeRemover);
+ f.setInterfaces(new Class[] { Target3.class, Target4.class });
+ Class c = f.createClass();
+ Target3 obj = (Target3)c.newInstance();
+ assertEquals("OK", obj.m());
+ System.out.println(obj.toString());
+ assertEquals(3, interceptor2.counter);
+
+ interceptor2.counter = 0;
+ Target4 obj4 = (Target4)c.newInstance();
+ assertEquals(3, obj4.bar4());
+ assertEquals(3, obj4.foo4());
+ assertEquals(2, interceptor2.counter);
+ }
+
+ public void testFilter() throws Exception {
+ ProxyFactory f = new ProxyFactory();
+ Interceptor2 interceptor2 = new Interceptor2();
+ f.setHandler(interceptor2);
+ f.setFilter(finalizeRemover);
+ f.setInterfaces(new Class[] { Target3.class });
+ f.setFilter(new MethodFilter() {
+ public boolean isHandled(Method m) {
+ return m.getDeclaringClass() != Object.class;
+ }
+ });
+ Class c = f.createClass();
+ Target3 obj = (Target3)c.newInstance();
+ assertEquals("OK", obj.m());
+ System.out.println(obj.toString());
+ assertEquals(1, interceptor2.counter);
+ }
+
+ public static boolean testInitFlag;
+
+ public void testInit() throws Exception {
+ ProxyFactory f = new ProxyFactory();
+ f.setSuperclass(TargetInit.class);
+ MethodHandler handler = new MethodHandler() {
+ public Object invoke(Object self, Method m,
+ Method proceed, Object[] args) throws Exception {
+ System.out.println("testInit " + testInitFlag);
+ return proceed.invoke(self, args);
+ }
+ };
+ testInitFlag = false;
+ Class c = f.createClass();
+ assertTrue(testInitFlag); // since 3.12. Before then, this line was assertFalse(testInitFlag);
+ System.out.println("testInit createClass(): " + testInitFlag);
+ TargetInit obj = (TargetInit)c.newInstance();
+ assertTrue(testInitFlag);
+ System.out.println("testInit newInstance(): " + testInitFlag);
+ ((ProxyObject)obj).setHandler(handler);
+ assertEquals("OK", obj.m());
+ }
+
+ public void testCreate() throws Exception {
+ ProxyFactory f = new ProxyFactory();
+ f.setSuperclass(Target5.class);
+ Interceptor1 interceptor = new Interceptor1();
+ f.setHandler(interceptor);
+ f.setFilter(finalizeRemover);
+ Class c = f.createClass();
+ Target5 obj = (Target5)f.create(new Class[] { int.class }, new Object[] { new Integer(3) });
+ assertEquals(3, obj.get());
+ }
+
+
+ public void testBridgeMethod() throws Exception {
+ ProxyFactory f = new ProxyFactory();
+ f.writeDirectory = ".";
+ f.setSuperclass(BridgeMethod.class);
+ Interceptor1 interceptor = new Interceptor1();
+ f.setHandler(interceptor);
+ f.setFilter(finalizeRemover);
+ Class c = f.createClass();
+ BridgeMethod obj = (BridgeMethod)c.newInstance();
+ Integer value = obj.m1();
+ assertEquals(7, value.intValue());
+ BridgeMethodInf inf = (BridgeMethodInf)obj;
+ Number num = inf.m1();
+ assertEquals(7, num.intValue());
+ BridgeMethodSuper sup = obj;
+ try {
+ Object x = sup.id(new Object());
+ fail("not cast error");
+ }
+ catch (ClassCastException e) {}
+ catch (Exception e) {
+ if (e instanceof InvocationTargetException)
+ if (e.getCause() instanceof ClassCastException)
+ return;
+
+ throw e;
+ }
+ }
+
+ public void testGetters() throws Exception {
+ ProxyFactory f = new ProxyFactory();
+ Class c = ProxyTester.class;
+ f.setSuperclass(c);
+ assertEquals(c, f.getSuperclass());
+ Class i = java.io.Serializable.class;
+ f.setInterfaces(new Class[] { i });
+ assertEquals(i, f.getInterfaces()[0]);
+ }
+
+ static class ProxyFactory2 extends ProxyFactory {
+ public ClassLoader getClassLoader2() {
+ return getClassLoader();
+ }
+ }
+
+ public void testProvider() throws Exception {
+ ProxyFactory.ClassLoaderProvider cp = ProxyFactory.classLoaderProvider;
+ final ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ ProxyFactory.classLoaderProvider = new ProxyFactory.ClassLoaderProvider() {
+ public ClassLoader get(ProxyFactory pf) {
+ return Thread.currentThread().getContextClassLoader();
+ }
+ };
+
+ ProxyFactory2 pf = new ProxyFactory2();
+ assertEquals(cl, pf.getClassLoader2());
+ ProxyFactory.classLoaderProvider = cp;
+ }
+
+ public void testCache() throws Exception {
+ boolean prev = ProxyFactory.useCache;
+ ProxyFactory.useCache = true;
+ ProxyFactory f = new ProxyFactory();
+ f.setSuperclass(Cache1.class);
+ Class c = f.createClass();
+ ProxyFactory f2 = new ProxyFactory();
+ f2.setSuperclass(Cache1.class);
+ assertEquals(c, f2.createClass());
+ ProxyFactory f3 = new ProxyFactory();
+ f3.setSuperclass(Cache1.class);
+ f3.setHandler(new Interceptor1());
+ assertFalse(c == f3.createClass());
+ ProxyFactory f4 = new ProxyFactory();
+ f4.setSuperclass(Cache1.class);
+ f4.setInterfaces(new Class[] { Cache2.class });
+ Class c4 = f4.createClass();
+ assertFalse(c == c4);
+ ProxyFactory f5 = new ProxyFactory();
+ f5.setSuperclass(Cache1.class);
+ f5.setInterfaces(new Class[] { Cache2.class });
+ assertEquals(c4, f5.createClass());
+ ProxyFactory f6 = new ProxyFactory();
+ f6.setInterfaces(new Class[] { Cache2.class });
+ assertFalse(c4 == f6.createClass());
+ ProxyFactory.useCache = prev;
+ }
+
+ public static class Cache1 {
+ public int foo() { return 0; }
+ }
+
+ public static interface Cache2 {
+ public int bar();
+ }
+
+ public void testReadWrite() throws Exception {
+ final String fileName = "read-write.bin";
+ ProxyFactory.ClassLoaderProvider cp = ProxyFactory.classLoaderProvider;
+ ProxyFactory.classLoaderProvider = new ProxyFactory.ClassLoaderProvider() {
+ public ClassLoader get(ProxyFactory pf) {
+ return new javassist.Loader();
+ }
+ };
+ ProxyFactory pf = new ProxyFactory();
+ pf.setSuperclass(ReadWriteData.class);
+ Object data = pf.createClass().newInstance();
+ // Object data = new ReadWriteData();
+ ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileName));
+ oos.writeObject(data);
+ oos.close();
+ ProxyFactory.classLoaderProvider = cp;
+
+ ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName));
+ Object data2 = ois.readObject();
+ ois.close();
+ int i = ((ReadWriteData)data2).foo();
+ assertEquals(4, i);
+ }
+
+ public static class ReadWriteData implements Serializable {
+ public int foo() { return 4; }
+ }
+
+ public void testWriteReplace() throws Exception {
+ ProxyFactory pf = new ProxyFactory();
+ pf.setSuperclass(WriteReplace.class);
+ Object data = pf.createClass().newInstance();
+ assertEquals(data, ((WriteReplace)data).writeReplace());
+
+ ProxyFactory pf2 = new ProxyFactory();
+ pf2.setSuperclass(WriteReplace2.class);
+ Object data2 = pf2.createClass().newInstance();
+ Method meth = data2.getClass().getDeclaredMethod("writeReplace", new Class[0]);
+ assertEquals("javassist.util.proxy.SerializedProxy",
+ meth.invoke(data2, new Object[0]).getClass().getName());
+ }
+
+ public static class WriteReplace implements Serializable {
+ public Object writeReplace() { return this; }
+ }
+
+ public static class WriteReplace2 implements Serializable {
+ public Object writeReplace(int i) { return new Integer(i); }
+ }
+
+ public static void main(String[] args) {
+ // javassist.bytecode.ClassFile.MAJOR_VERSION = javassist.bytecode.ClassFile.JAVA_6;
+ junit.textui.TestRunner.run(ProxyTester.class);
+ }
+}
diff --git a/src/test/testproxy/Target.java b/src/test/testproxy/Target.java new file mode 100644 index 00000000..ab6789f2 --- /dev/null +++ b/src/test/testproxy/Target.java @@ -0,0 +1,17 @@ +package testproxy;
+
+public class Target {
+ public void m() {}
+ public boolean m(boolean b) { return b; }
+ public byte m1(byte b) { return b; }
+ public char m2(char c) { return c; }
+ public short m3(short s) { return s; }
+ public int m(int i) { return i; }
+ public long m5(long j) { return j; }
+ public float m6(float f) { return f; }
+ public double m7(double d) { return d; }
+ public String m(String s) { return s; }
+ public int[] m7(int[] i) { return i; }
+ public String[] m8(String[] s) { return s; }
+ public Target m9(int i, Target t, Target[][] t2) { return t; }
+}
diff --git a/src/test/testproxy/Target1.java b/src/test/testproxy/Target1.java new file mode 100644 index 00000000..ce972d04 --- /dev/null +++ b/src/test/testproxy/Target1.java @@ -0,0 +1,5 @@ +package testproxy; + +public class Target1 { + public Target1[][] m(Target1[][] a) { return a; } +} diff --git a/src/test/testproxy/Target2.java b/src/test/testproxy/Target2.java new file mode 100644 index 00000000..91b57be5 --- /dev/null +++ b/src/test/testproxy/Target2.java @@ -0,0 +1,17 @@ +package testproxy;
+
+import java.io.IOException;
+
+public class Target2 {
+ private int value;
+ public Target2(int i) { value = 1; }
+ protected Target2(int i, int j) { value = 2; }
+ private Target2(int i, double j) { value = 3; }
+ Target2(int i, long k) { value = 4; }
+
+ public int get() { return value; }
+ public int foo() throws IOException { return ++value; }
+ public int _dfoo() { value += 2; return value; }
+ private int _d100() { value += 3; return value; }
+ private int _d1003foo() { value += 3; return value; }
+}
diff --git a/src/test/testproxy/Target3.java b/src/test/testproxy/Target3.java new file mode 100644 index 00000000..c9c8f66c --- /dev/null +++ b/src/test/testproxy/Target3.java @@ -0,0 +1,6 @@ +package testproxy;
+
+public interface Target3 {
+ String m();
+ String toString();
+}
diff --git a/src/test/testproxy/Target4.java b/src/test/testproxy/Target4.java new file mode 100644 index 00000000..82ddef69 --- /dev/null +++ b/src/test/testproxy/Target4.java @@ -0,0 +1,9 @@ +package testproxy;
+
+interface Target4Super {
+ int foo4();
+}
+
+public interface Target4 extends Target4Super {
+ int bar4();
+}
diff --git a/src/test/testproxy/Target5.java b/src/test/testproxy/Target5.java new file mode 100644 index 00000000..f40183a8 --- /dev/null +++ b/src/test/testproxy/Target5.java @@ -0,0 +1,7 @@ +package testproxy; + +public class Target5 { + private int value; + public Target5(int i) { value = i; } + public int get() { return value; } +} diff --git a/src/test/testproxy/TargetInit.java b/src/test/testproxy/TargetInit.java new file mode 100644 index 00000000..0654593a --- /dev/null +++ b/src/test/testproxy/TargetInit.java @@ -0,0 +1,10 @@ +package testproxy; + +public class TargetInit { + static { + System.out.println("TargetInit <clinit>"); + ProxyTester.testInitFlag = true; + } + + public String m() { return "OK"; } +} diff --git a/src/test/testproxy/sub/TargetSuper.java b/src/test/testproxy/sub/TargetSuper.java new file mode 100644 index 00000000..0e40cded --- /dev/null +++ b/src/test/testproxy/sub/TargetSuper.java @@ -0,0 +1,7 @@ +package testproxy.sub; + +public class TargetSuper { + private int poi() { return 1; } + int poi2() { return 2; } + public int poi3() { return 3; } +} |