aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>2011-08-31 10:29:34 +0000
committerchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>2011-08-31 10:29:34 +0000
commitd72870bfb6b09927e10944bdd129ce18dfcf7366 (patch)
tree27f56e4d1523a8cecc8976df60155e6b8429e504
parent76a1cba9c433e8242bb6648e72b3ed43c7a4995a (diff)
downloadjavassist-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
-rw-r--r--src/test/Readme.txt2
-rw-r--r--src/test/VisibleTop.java6
-rw-r--r--src/test/VisibleTop2.java6
-rw-r--r--src/test/annotation/Test.java35
-rw-r--r--src/test/javassist/Bench.java167
-rw-r--r--src/test/javassist/ClassPoolBench.java57
-rw-r--r--src/test/javassist/JvstTest.java1123
-rw-r--r--src/test/javassist/JvstTest2.java1502
-rw-r--r--src/test/javassist/JvstTest3.java1125
-rw-r--r--src/test/javassist/JvstTest4.java569
-rw-r--r--src/test/javassist/JvstTestRoot.java53
-rw-r--r--src/test/javassist/LoaderTestByRandall.java98
-rw-r--r--src/test/javassist/SetterTest.java111
-rw-r--r--src/test/javassist/bytecode/BytecodeTest.java572
-rw-r--r--src/test/javassist/bytecode/CodeAnalyzerTest.java47
-rw-r--r--src/test/javassist/bytecode/Gap0Example.classbin0 -> 3558 bytes
-rw-r--r--src/test/javassist/bytecode/InsertGap0.java228
-rw-r--r--src/test/javassist/compiler/CodeTest.java26
-rw-r--r--src/test/javassist/compiler/CompTest.java155
-rw-r--r--src/test/javassist/compiler/LexTest.java21
-rw-r--r--src/test/javassist/compiler/ParseTest.java13
-rw-r--r--src/test/javassist/proxyfactory/MyCls.java27
-rw-r--r--src/test/javassist/proxyfactory/ProxyFactoryTest.java93
-rw-r--r--src/test/javassist/tools/reflect/ClassMetaobjectTest.java14
-rw-r--r--src/test/javassist/tools/reflect/LoaderTest.java69
-rw-r--r--src/test/javassist/tools/reflect/Person.java64
-rw-r--r--src/test/javassist/tools/reflect/SubClass.java20
-rw-r--r--src/test/javassist/tools/reflect/SuperClass.java7
-rw-r--r--src/test/test1/AddClassInfo.java7
-rw-r--r--src/test/test1/ArrayAccess.java17
-rw-r--r--src/test/test1/BenchProceed.java83
-rw-r--r--src/test/test1/BenchProceedNew.java74
-rw-r--r--src/test/test1/BenchStaticMethod.java53
-rw-r--r--src/test/test1/CalleeAfter.java24
-rw-r--r--src/test/test1/CalleeAfter2.java50
-rw-r--r--src/test/test1/CalleeAfter3.java39
-rw-r--r--src/test/test1/CalleeBefore.java39
-rw-r--r--src/test/test1/CalleeCatch.java17
-rw-r--r--src/test/test1/Cflow.java40
-rw-r--r--src/test/test1/Clinit.java8
-rw-r--r--src/test/test1/Clinit2.java8
-rw-r--r--src/test/test1/CodeConv.java25
-rw-r--r--src/test/test1/Delegator.java12
-rw-r--r--src/test/test1/Dispatch.java15
-rw-r--r--src/test/test1/DollarClass.java21
-rw-r--r--src/test/test1/EmptyBody.java20
-rw-r--r--src/test/test1/ExprEdit.java11
-rw-r--r--src/test/test1/ExprEdit2.java8
-rw-r--r--src/test/test1/ExprEdit3.java13
-rw-r--r--src/test/test1/ExprEdit4.java16
-rw-r--r--src/test/test1/ExprEdit5.java14
-rw-r--r--src/test/test1/ExprEdit6.java15
-rw-r--r--src/test/test1/ExprEdit7.java30
-rw-r--r--src/test/test1/ExprEdit8.java16
-rw-r--r--src/test/test1/FieldInit.java17
-rw-r--r--src/test/test1/FieldInit2.java21
-rw-r--r--src/test/test1/FieldMod.java6
-rw-r--r--src/test/test1/Freeze.java4
-rw-r--r--src/test/test1/GetThrowables.java41
-rw-r--r--src/test/test1/Handler.java29
-rw-r--r--src/test/test1/Howard.java29
-rw-r--r--src/test/test1/InvokeInt.java19
-rw-r--r--src/test/test1/LineNumber.java46
-rw-r--r--src/test/test1/LocalVars.java18
-rw-r--r--src/test/test1/MakeClass.java9
-rw-r--r--src/test/test1/MySerializableClass.java34
-rw-r--r--src/test/test1/NewInterface.java5
-rw-r--r--src/test/test1/Pac.java15
-rw-r--r--src/test/test1/Point.java5
-rw-r--r--src/test/test1/Proceed.java11
-rw-r--r--src/test/test1/Proceed2.java26
-rw-r--r--src/test/test1/Proceed3.java9
-rw-r--r--src/test/test1/RenameClass.java26
-rw-r--r--src/test/test1/SetBody.java9
-rw-r--r--src/test/test1/SetName.java6
-rw-r--r--src/test/test1/SigType.java21
-rw-r--r--src/test/test1/StaticConsBody.java18
-rw-r--r--src/test/test1/StaticField.java5
-rw-r--r--src/test/test1/Subtype.java17
-rw-r--r--src/test/test1/TryCatch.java34
-rw-r--r--src/test/test2/AddCatchForConstructor.classbin0 -> 488 bytes
-rw-r--r--src/test/test2/AddCatchForConstructor.java13
-rw-r--r--src/test/test2/AddLocalVar.classbin0 -> 395 bytes
-rw-r--r--src/test/test2/AddLocalVar.java8
-rw-r--r--src/test/test2/AddMethod.java9
-rw-r--r--src/test/test2/Anon.java7
-rw-r--r--src/test/test2/ArrayAndNull.java9
-rw-r--r--src/test/test2/ArrayInit.classbin0 -> 465 bytes
-rw-r--r--src/test/test2/ArrayLenTest.classbin0 -> 366 bytes
-rw-r--r--src/test/test2/ArrayLenTest.java5
-rw-r--r--src/test/test2/ArrayLength.classbin0 -> 238 bytes
-rw-r--r--src/test/test2/Brennan.classbin0 -> 471 bytes
-rw-r--r--src/test/test2/Brennan.java5
-rw-r--r--src/test/test2/CodeGen.classbin0 -> 2052 bytes
-rw-r--r--src/test/test2/CodeGen.java15
-rw-r--r--src/test/test2/CodeGen2.classbin0 -> 700 bytes
-rw-r--r--src/test/test2/ConstBody.classbin0 -> 500 bytes
-rw-r--r--src/test/test2/ConstBody.java22
-rw-r--r--src/test/test2/ConstField.classbin0 -> 578 bytes
-rw-r--r--src/test/test2/ConstField.java13
-rw-r--r--src/test/test2/Construct.java7
-rw-r--r--src/test/test2/DotClass.classbin0 -> 1337 bytes
-rw-r--r--src/test/test2/DotClass2.classbin0 -> 578 bytes
-rw-r--r--src/test/test2/DotClass4.classbin0 -> 810 bytes
-rw-r--r--src/test/test2/Finally.classbin0 -> 1125 bytes
-rw-r--r--src/test/test2/Finally.java12
-rw-r--r--src/test/test2/Imported.classbin0 -> 166 bytes
-rw-r--r--src/test/test2/Importer.classbin0 -> 401 bytes
-rw-r--r--src/test/test2/IncOp.classbin0 -> 221 bytes
-rw-r--r--src/test/test2/Inherit.classbin0 -> 991 bytes
-rw-r--r--src/test/test2/Inherit.java26
-rw-r--r--src/test/test2/Inner.classbin0 -> 1411 bytes
-rw-r--r--src/test/test2/Inner.java13
-rw-r--r--src/test/test2/InsertAt.classbin0 -> 686 bytes
-rw-r--r--src/test/test2/InsertAt.java23
-rw-r--r--src/test/test2/InsertLocal.classbin0 -> 1088 bytes
-rw-r--r--src/test/test2/InsertLocal.java32
-rw-r--r--src/test/test2/LocalVar.classbin0 -> 550 bytes
-rw-r--r--src/test/test2/LocalVar.java6
-rw-r--r--src/test/test2/MakeStaticMethod.classbin0 -> 281 bytes
-rw-r--r--src/test/test2/MethodCall.classbin0 -> 475 bytes
-rw-r--r--src/test/test2/MethodCall.java8
-rw-r--r--src/test/test2/Nested$Inner3.classbin0 -> 593 bytes
-rw-r--r--src/test/test2/Nested.classbin0 -> 904 bytes
-rw-r--r--src/test/test2/Nested.java22
-rw-r--r--src/test/test2/Nested2$Inner.classbin0 -> 1081 bytes
-rw-r--r--src/test/test2/Nested2.classbin0 -> 1230 bytes
-rw-r--r--src/test/test2/Nested2.java15
-rw-r--r--src/test/test2/Nested3$Inner.classbin0 -> 678 bytes
-rw-r--r--src/test/test2/Nested3.classbin0 -> 944 bytes
-rw-r--r--src/test/test2/Nested3.java16
-rw-r--r--src/test/test2/Nested4$Inner.classbin0 -> 301 bytes
-rw-r--r--src/test/test2/Nested4.classbin0 -> 482 bytes
-rw-r--r--src/test/test2/Nested4.java5
-rw-r--r--src/test/test2/NewArray.classbin0 -> 864 bytes
-rw-r--r--src/test/test2/NewArray.java18
-rw-r--r--src/test/test2/NewExprInTry.classbin0 -> 681 bytes
-rw-r--r--src/test/test2/NewExprInTry.java24
-rw-r--r--src/test/test2/NewExprTry.classbin0 -> 948 bytes
-rw-r--r--src/test/test2/NewExprTry.java20
-rw-r--r--src/test/test2/NewOp.classbin0 -> 855 bytes
-rw-r--r--src/test/test2/NewOp.java15
-rw-r--r--src/test/test2/NullArgTest.classbin0 -> 426 bytes
-rw-r--r--src/test/test2/PrivateMethod.java11
-rw-r--r--src/test/test2/Prune.java15
-rw-r--r--src/test/test2/Remove.classbin0 -> 445 bytes
-rw-r--r--src/test/test2/Remove.java25
-rw-r--r--src/test/test2/RemoveCall.classbin0 -> 539 bytes
-rw-r--r--src/test/test2/RemoveCall.java13
-rw-r--r--src/test/test2/ReplaceClassName.classbin0 -> 538 bytes
-rw-r--r--src/test/test2/ReplaceClassName.java18
-rw-r--r--src/test/test2/SetExceptions.classbin0 -> 387 bytes
-rw-r--r--src/test/test2/SetExceptions.java7
-rw-r--r--src/test/test2/SetSuper.classbin0 -> 218 bytes
-rw-r--r--src/test/test2/SetSuperIntf.classbin0 -> 134 bytes
-rw-r--r--src/test/test2/SetSuperParent.classbin0 -> 178 bytes
-rw-r--r--src/test/test2/StaticArraysMem.java5
-rw-r--r--src/test/test2/StaticFinal.classbin0 -> 608 bytes
-rw-r--r--src/test/test2/StaticMember.classbin0 -> 863 bytes
-rw-r--r--src/test/test2/StaticMember.java11
-rw-r--r--src/test/test2/StaticMember2.classbin0 -> 888 bytes
-rw-r--r--src/test/test2/StaticMember2.java12
-rw-r--r--src/test/test2/SuperCall.classbin0 -> 628 bytes
-rw-r--r--src/test/test2/SuperCall.java20
-rw-r--r--src/test/test2/SuperInterface1.java6
-rw-r--r--src/test/test2/SuperInterface2.java3
-rw-r--r--src/test/test2/SuperInterface3.classbin0 -> 349 bytes
-rw-r--r--src/test/test2/Switch.classbin0 -> 784 bytes
-rw-r--r--src/test/test2/Synch.classbin0 -> 503 bytes
-rw-r--r--src/test/test2/Where.java10
-rw-r--r--src/test/test3/Anno.java15
-rw-r--r--src/test/test3/Anno2.java11
-rw-r--r--src/test/test3/Anno3.java17
-rw-r--r--src/test/test3/Anno6.java6
-rw-r--r--src/test/test3/AnnoTest.java21
-rw-r--r--src/test/test3/AnnoTest6.java6
-rw-r--r--src/test/test3/CheckModify.java5
-rw-r--r--src/test/test3/ChibaAnnotation.java11
-rw-r--r--src/test/test3/ColorName.java5
-rw-r--r--src/test/test3/Constructor.java37
-rw-r--r--src/test/test3/Constructor2.java7
-rw-r--r--src/test/test3/CopyAnno.java10
-rw-r--r--src/test/test3/EmptyCatch.java14
-rw-r--r--src/test/test3/EmptyConstructor.java33
-rw-r--r--src/test/test3/Enhancer.java180
-rw-r--r--src/test/test3/Erasure.java15
-rw-r--r--src/test/test3/FieldAccessType.java10
-rw-r--r--src/test/test3/FieldCopy.java12
-rw-r--r--src/test/test3/Frozen.java7
-rw-r--r--src/test/test3/GetMethods.java30
-rw-r--r--src/test/test3/InheritCons.java9
-rw-r--r--src/test/test3/InnerClass.java7
-rw-r--r--src/test/test3/InnerMethod.java17
-rw-r--r--src/test/test3/InsParam.java16
-rw-r--r--src/test/test3/InsertAfter.java17
-rw-r--r--src/test/test3/InsertBeforeType.java11
-rw-r--r--src/test/test3/InvokeArray.java15
-rw-r--r--src/test/test3/InvokeIntf.java30
-rw-r--r--src/test/test3/JIRA63.java5
-rw-r--r--src/test/test3/JIRA63Helper.java7
-rw-r--r--src/test/test3/MethodRedirect.java20
-rw-r--r--src/test/test3/MethodRedirect2.java43
-rw-r--r--src/test/test3/Mods.java9
-rw-r--r--src/test/test3/Name.java17
-rw-r--r--src/test/test3/NestedClass.java24
-rw-r--r--src/test/test3/NewClass2.java5
-rw-r--r--src/test/test3/NewExprTryCatch.java29
-rw-r--r--src/test/test3/PackName.java12
-rw-r--r--src/test/test3/ParamAnno.java9
-rw-r--r--src/test/test3/PublicInner.java13
-rw-r--r--src/test/test3/RecReplace.java20
-rw-r--r--src/test/test3/RecReplace2.java19
-rw-r--r--src/test/test3/ReplaceNew.java19
-rw-r--r--src/test/test3/SetModifiers.java8
-rw-r--r--src/test/test3/SigAttribute.java6
-rw-r--r--src/test/test3/StrBuild.java8
-rw-r--r--src/test/test3/SubValue.java15
-rw-r--r--src/test/test3/Superclass.java15
-rw-r--r--src/test/test3/Switch.java30391
-rw-r--r--src/test/test3/TransNewClass.java37
-rw-r--r--src/test/test3/TransformRead.java15
-rw-r--r--src/test/test3/Unique.java24
-rw-r--r--src/test/test3/Visible.java15
-rw-r--r--src/test/test3/VisibleAnno.java7
-rw-r--r--src/test/test3/VoidReturn.java5
-rw-r--r--src/test/test3/sub/SubPackName.java5
-rw-r--r--src/test/test3/sub/Visible.java12
-rw-r--r--src/test/test4/Anno.java6
-rw-r--r--src/test/test4/Anno1.java5
-rw-r--r--src/test/test4/CodeConv.java19
-rw-r--r--src/test/test4/CodeConv2.java39
-rw-r--r--src/test/test4/CtArrayTest.java4
-rw-r--r--src/test/test4/GapSwitch.java83
-rw-r--r--src/test/test4/GetAllRef.java33
-rw-r--r--src/test/test4/GetAllRefAnno2.java6
-rw-r--r--src/test/test4/GetAllRefEnum2.java3
-rw-r--r--src/test/test4/GetAllRefInnerTest.java26
-rw-r--r--src/test/test4/GetFieldDesc.java11
-rw-r--r--src/test/test4/ImportPac.java4
-rw-r--r--src/test/test4/JIRA93.java5
-rw-r--r--src/test/test4/LocalVars.java60
-rw-r--r--src/test/test4/MakeMethod.java7
-rw-r--r--src/test/test4/NestedClass.java29
-rw-r--r--src/test/test4/NewImportPac.java4
-rw-r--r--src/test/test4/NewRemover.java30
-rw-r--r--src/test/test4/Rename.java24
-rw-r--r--src/test/test4/Signature.java16
-rw-r--r--src/test/test4/VarArgs.java15
-rw-r--r--src/test/test4/length.java5
-rw-r--r--src/test/testproxy/BridgeMethod.java19
-rw-r--r--src/test/testproxy/ProxyFactoryPerformanceTest.java195
-rw-r--r--src/test/testproxy/ProxyTester.java403
-rw-r--r--src/test/testproxy/Target.java17
-rw-r--r--src/test/testproxy/Target1.java5
-rw-r--r--src/test/testproxy/Target2.java17
-rw-r--r--src/test/testproxy/Target3.java6
-rw-r--r--src/test/testproxy/Target4.java9
-rw-r--r--src/test/testproxy/Target5.java7
-rw-r--r--src/test/testproxy/TargetInit.java10
-rw-r--r--src/test/testproxy/sub/TargetSuper.java7
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
new file mode 100644
index 00000000..f705a904
--- /dev/null
+++ b/src/test/javassist/bytecode/Gap0Example.class
Binary files differ
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
new file mode 100644
index 00000000..9b5e937f
--- /dev/null
+++ b/src/test/test2/AddCatchForConstructor.class
Binary files differ
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
new file mode 100644
index 00000000..ad5f1d94
--- /dev/null
+++ b/src/test/test2/AddLocalVar.class
Binary files differ
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
new file mode 100644
index 00000000..1786a0e6
--- /dev/null
+++ b/src/test/test2/ArrayInit.class
Binary files differ
diff --git a/src/test/test2/ArrayLenTest.class b/src/test/test2/ArrayLenTest.class
new file mode 100644
index 00000000..0987cc07
--- /dev/null
+++ b/src/test/test2/ArrayLenTest.class
Binary files differ
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
new file mode 100644
index 00000000..9577874c
--- /dev/null
+++ b/src/test/test2/ArrayLength.class
Binary files differ
diff --git a/src/test/test2/Brennan.class b/src/test/test2/Brennan.class
new file mode 100644
index 00000000..9c7f3954
--- /dev/null
+++ b/src/test/test2/Brennan.class
Binary files differ
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
new file mode 100644
index 00000000..65c24e6c
--- /dev/null
+++ b/src/test/test2/CodeGen.class
Binary files differ
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
new file mode 100644
index 00000000..fea25cc5
--- /dev/null
+++ b/src/test/test2/CodeGen2.class
Binary files differ
diff --git a/src/test/test2/ConstBody.class b/src/test/test2/ConstBody.class
new file mode 100644
index 00000000..41175d14
--- /dev/null
+++ b/src/test/test2/ConstBody.class
Binary files differ
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
new file mode 100644
index 00000000..5f7a4d8b
--- /dev/null
+++ b/src/test/test2/ConstField.class
Binary files differ
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
new file mode 100644
index 00000000..6cc7a6bd
--- /dev/null
+++ b/src/test/test2/DotClass.class
Binary files differ
diff --git a/src/test/test2/DotClass2.class b/src/test/test2/DotClass2.class
new file mode 100644
index 00000000..aa67fb10
--- /dev/null
+++ b/src/test/test2/DotClass2.class
Binary files differ
diff --git a/src/test/test2/DotClass4.class b/src/test/test2/DotClass4.class
new file mode 100644
index 00000000..48e51b7e
--- /dev/null
+++ b/src/test/test2/DotClass4.class
Binary files differ
diff --git a/src/test/test2/Finally.class b/src/test/test2/Finally.class
new file mode 100644
index 00000000..f680dbc3
--- /dev/null
+++ b/src/test/test2/Finally.class
Binary files differ
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
new file mode 100644
index 00000000..3ae65fdd
--- /dev/null
+++ b/src/test/test2/Imported.class
Binary files differ
diff --git a/src/test/test2/Importer.class b/src/test/test2/Importer.class
new file mode 100644
index 00000000..24da5de9
--- /dev/null
+++ b/src/test/test2/Importer.class
Binary files differ
diff --git a/src/test/test2/IncOp.class b/src/test/test2/IncOp.class
new file mode 100644
index 00000000..f75a9eb1
--- /dev/null
+++ b/src/test/test2/IncOp.class
Binary files differ
diff --git a/src/test/test2/Inherit.class b/src/test/test2/Inherit.class
new file mode 100644
index 00000000..ef886ce1
--- /dev/null
+++ b/src/test/test2/Inherit.class
Binary files differ
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
new file mode 100644
index 00000000..d7506a62
--- /dev/null
+++ b/src/test/test2/Inner.class
Binary files differ
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
new file mode 100644
index 00000000..b8194bae
--- /dev/null
+++ b/src/test/test2/InsertAt.class
Binary files differ
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
new file mode 100644
index 00000000..d0f32f27
--- /dev/null
+++ b/src/test/test2/InsertLocal.class
Binary files differ
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
new file mode 100644
index 00000000..a1d93574
--- /dev/null
+++ b/src/test/test2/LocalVar.class
Binary files differ
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
new file mode 100644
index 00000000..320f0f3a
--- /dev/null
+++ b/src/test/test2/MakeStaticMethod.class
Binary files differ
diff --git a/src/test/test2/MethodCall.class b/src/test/test2/MethodCall.class
new file mode 100644
index 00000000..6b8fc153
--- /dev/null
+++ b/src/test/test2/MethodCall.class
Binary files differ
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
new file mode 100644
index 00000000..21afc9a0
--- /dev/null
+++ b/src/test/test2/Nested$Inner3.class
Binary files differ
diff --git a/src/test/test2/Nested.class b/src/test/test2/Nested.class
new file mode 100644
index 00000000..529317ae
--- /dev/null
+++ b/src/test/test2/Nested.class
Binary files differ
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
new file mode 100644
index 00000000..0267e5e5
--- /dev/null
+++ b/src/test/test2/Nested2$Inner.class
Binary files differ
diff --git a/src/test/test2/Nested2.class b/src/test/test2/Nested2.class
new file mode 100644
index 00000000..7cb3b346
--- /dev/null
+++ b/src/test/test2/Nested2.class
Binary files differ
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
new file mode 100644
index 00000000..dbc70b60
--- /dev/null
+++ b/src/test/test2/Nested3$Inner.class
Binary files differ
diff --git a/src/test/test2/Nested3.class b/src/test/test2/Nested3.class
new file mode 100644
index 00000000..a1e2a736
--- /dev/null
+++ b/src/test/test2/Nested3.class
Binary files differ
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
new file mode 100644
index 00000000..b770ef79
--- /dev/null
+++ b/src/test/test2/Nested4$Inner.class
Binary files differ
diff --git a/src/test/test2/Nested4.class b/src/test/test2/Nested4.class
new file mode 100644
index 00000000..550fb403
--- /dev/null
+++ b/src/test/test2/Nested4.class
Binary files differ
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
new file mode 100644
index 00000000..9dfbbe63
--- /dev/null
+++ b/src/test/test2/NewArray.class
Binary files differ
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
new file mode 100644
index 00000000..79ca894a
--- /dev/null
+++ b/src/test/test2/NewExprInTry.class
Binary files differ
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
new file mode 100644
index 00000000..f70141e6
--- /dev/null
+++ b/src/test/test2/NewExprTry.class
Binary files differ
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
new file mode 100644
index 00000000..da62b7c3
--- /dev/null
+++ b/src/test/test2/NewOp.class
Binary files differ
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
new file mode 100644
index 00000000..79dd7195
--- /dev/null
+++ b/src/test/test2/NullArgTest.class
Binary files differ
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
new file mode 100644
index 00000000..d2bab30b
--- /dev/null
+++ b/src/test/test2/Remove.class
Binary files differ
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
new file mode 100644
index 00000000..1b818395
--- /dev/null
+++ b/src/test/test2/RemoveCall.class
Binary files differ
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
new file mode 100644
index 00000000..db3611b3
--- /dev/null
+++ b/src/test/test2/ReplaceClassName.class
Binary files differ
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
new file mode 100644
index 00000000..2331eb9c
--- /dev/null
+++ b/src/test/test2/SetExceptions.class
Binary files differ
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
new file mode 100644
index 00000000..55861734
--- /dev/null
+++ b/src/test/test2/SetSuper.class
Binary files differ
diff --git a/src/test/test2/SetSuperIntf.class b/src/test/test2/SetSuperIntf.class
new file mode 100644
index 00000000..d5595567
--- /dev/null
+++ b/src/test/test2/SetSuperIntf.class
Binary files differ
diff --git a/src/test/test2/SetSuperParent.class b/src/test/test2/SetSuperParent.class
new file mode 100644
index 00000000..2825d7d7
--- /dev/null
+++ b/src/test/test2/SetSuperParent.class
Binary files differ
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
new file mode 100644
index 00000000..69be9939
--- /dev/null
+++ b/src/test/test2/StaticFinal.class
Binary files differ
diff --git a/src/test/test2/StaticMember.class b/src/test/test2/StaticMember.class
new file mode 100644
index 00000000..10a72092
--- /dev/null
+++ b/src/test/test2/StaticMember.class
Binary files differ
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
new file mode 100644
index 00000000..fe46c673
--- /dev/null
+++ b/src/test/test2/StaticMember2.class
Binary files differ
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
new file mode 100644
index 00000000..b7294c22
--- /dev/null
+++ b/src/test/test2/SuperCall.class
Binary files differ
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
new file mode 100644
index 00000000..4b6c7b73
--- /dev/null
+++ b/src/test/test2/SuperInterface3.class
Binary files differ
diff --git a/src/test/test2/Switch.class b/src/test/test2/Switch.class
new file mode 100644
index 00000000..78e8ea94
--- /dev/null
+++ b/src/test/test2/Switch.class
Binary files differ
diff --git a/src/test/test2/Synch.class b/src/test/test2/Synch.class
new file mode 100644
index 00000000..c5a5ddd1
--- /dev/null
+++ b/src/test/test2/Synch.class
Binary files differ
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; }
+}