You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by cc...@apache.org on 2015/09/21 09:32:11 UTC

[1/2] incubator-groovy git commit: Added a compiler performance test module

Repository: incubator-groovy
Updated Branches:
  refs/heads/master 8e9716256 -> 6dbfae85e


http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/6dbfae85/benchmark/bench/moments.java
----------------------------------------------------------------------
diff --git a/benchmark/bench/moments.java b/benchmark/bench/moments.java
index 56ce716..7f08dd1 100644
--- a/benchmark/bench/moments.java
+++ b/benchmark/bench/moments.java
@@ -1,77 +1,77 @@
-// $Id: moments.java,v 1.1 2004-11-23 08:08:44 bfulgham Exp $
-// http://www.bagley.org/~doug/shootout/
-
-import java.io.*;
-import java.util.*;
-import java.text.*;
-import java.lang.Math;
-
-public class moments {
-    public static void main(String[] args) {
-    String line;
-    Vector nums = new Vector();
-    double num, sum = 0.0;
-    double mean = 0.0;
-    double average_deviation = 0.0;
-    double standard_deviation = 0.0;
-    double variance = 0.0;
-    double skew = 0.0;
-    double kurtosis = 0.0;
-    double median = 0.0;
-    double deviation = 0.0;
-    int i, n, mid = 0;
-
-        try {
-            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
-            while ((line = in.readLine()) != null) {
-        num = Double.parseDouble(line);
-        sum += num;
-        nums.add(new Double(num));
-            }
-        } catch (IOException e) {
-            System.err.println(e);
-            return;
-        }
-
-    n = nums.size();
-    mean = sum/n;
-    for (i=0; i<n; i++) {
-        deviation = ((Double)nums.get(i)).doubleValue() - mean;
-        average_deviation += Math.abs(deviation);
-        variance += Math.pow(deviation,2);
-        skew += Math.pow(deviation,3);
-        kurtosis += Math.pow(deviation,4);
-    }
-    average_deviation /= n;
-    variance /= (n - 1);
-    standard_deviation = Math.sqrt(variance);
-    if (variance != 0.0) {
-        skew /= (n * variance * standard_deviation);
-        kurtosis = kurtosis/(n * variance * variance) - 3.0;
-    }
-    
-    Collections.sort(nums);
-
-    mid = (n/2);
-    median = (n % 2 != 0) ?
-        ((Double)nums.get(mid)).doubleValue() :
-        (((Double)nums.get(mid)).doubleValue() +
-         ((Double)nums.get(mid-1)).doubleValue())/2;
-    
-    NumberFormat nf = NumberFormat.getInstance();
-    nf.setMaximumFractionDigits(13);
-    nf.setGroupingUsed(false);
-    nf.setMaximumFractionDigits(6);
-    nf.setMinimumFractionDigits(6);
-
-    System.out.println("n:                  " + n);
-    System.out.println("median:             " + nf.format(median));
-    System.out.println("mean:               " + nf.format(mean));
-    System.out.println("average_deviation:  " + nf.format(average_deviation));
-    System.out.println("standard_deviation: " + nf.format(standard_deviation));
-    System.out.println("variance:           " + nf.format(variance));
-    System.out.println("skew:               " + nf.format(skew));
-    System.out.println("kurtosis:           " + nf.format(kurtosis));
-    }
-}
-
+// $Id: moments.java,v 1.1 2004-11-23 08:08:44 bfulgham Exp $
+// http://www.bagley.org/~doug/shootout/
+
+import java.io.*;
+import java.util.*;
+import java.text.*;
+import java.lang.Math;
+
+public class moments {
+    public static void main(String[] args) {
+    String line;
+    Vector nums = new Vector();
+    double num, sum = 0.0;
+    double mean = 0.0;
+    double average_deviation = 0.0;
+    double standard_deviation = 0.0;
+    double variance = 0.0;
+    double skew = 0.0;
+    double kurtosis = 0.0;
+    double median = 0.0;
+    double deviation = 0.0;
+    int i, n, mid = 0;
+
+        try {
+            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
+            while ((line = in.readLine()) != null) {
+        num = Double.parseDouble(line);
+        sum += num;
+        nums.add(new Double(num));
+            }
+        } catch (IOException e) {
+            System.err.println(e);
+            return;
+        }
+
+    n = nums.size();
+    mean = sum/n;
+    for (i=0; i<n; i++) {
+        deviation = ((Double)nums.get(i)).doubleValue() - mean;
+        average_deviation += Math.abs(deviation);
+        variance += Math.pow(deviation,2);
+        skew += Math.pow(deviation,3);
+        kurtosis += Math.pow(deviation,4);
+    }
+    average_deviation /= n;
+    variance /= (n - 1);
+    standard_deviation = Math.sqrt(variance);
+    if (variance != 0.0) {
+        skew /= (n * variance * standard_deviation);
+        kurtosis = kurtosis/(n * variance * variance) - 3.0;
+    }
+    
+    Collections.sort(nums);
+
+    mid = (n/2);
+    median = (n % 2 != 0) ?
+        ((Double)nums.get(mid)).doubleValue() :
+        (((Double)nums.get(mid)).doubleValue() +
+         ((Double)nums.get(mid-1)).doubleValue())/2;
+    
+    NumberFormat nf = NumberFormat.getInstance();
+    nf.setMaximumFractionDigits(13);
+    nf.setGroupingUsed(false);
+    nf.setMaximumFractionDigits(6);
+    nf.setMinimumFractionDigits(6);
+
+    System.out.println("n:                  " + n);
+    System.out.println("median:             " + nf.format(median));
+    System.out.println("mean:               " + nf.format(mean));
+    System.out.println("average_deviation:  " + nf.format(average_deviation));
+    System.out.println("standard_deviation: " + nf.format(standard_deviation));
+    System.out.println("variance:           " + nf.format(variance));
+    System.out.println("skew:               " + nf.format(skew));
+    System.out.println("kurtosis:           " + nf.format(kurtosis));
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/6dbfae85/benchmark/bench/wordfreq.groovy
----------------------------------------------------------------------
diff --git a/benchmark/bench/wordfreq.groovy b/benchmark/bench/wordfreq.groovy
index d4c7855..4bab668 100644
--- a/benchmark/bench/wordfreq.groovy
+++ b/benchmark/bench/wordfreq.groovy
@@ -1,5 +1,5 @@
-/*
- * The Great Computer Language Shootout
+/**
+ * The Computer Language Shootout
  * http://shootout.alioth.debian.org/
  *
  * contributed by Jochen Hinrichsen
@@ -13,7 +13,7 @@ System.in.eachLine() { line ->
     line.split("\\W").each() { word ->
         def s = word.toLowerCase()
         def entry = dict[s]
-        dict[s] = (entry == null) ? 1 : entry+1
+        dict[s] = (entry == null) ? 1 : entry + 1
     }
 }
 
@@ -21,7 +21,7 @@ System.in.eachLine() { line ->
 // sort for multiple properties: [ it.value, it.key ]
 assert dict != null
 assert dict.values() != null
-assert (dict.values().sort({ l, r -> r <=> l})) != null
-dict.values().sort({ l, r -> r <=> l}).each() { value ->
+assert (dict.values().sort({ l, r -> r <=> l })) != null
+dict.values().sort({ l, r -> r <=> l }).each() { value ->
     println "${value.toString().padLeft(8)}"
 }

http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/6dbfae85/settings.gradle
----------------------------------------------------------------------
diff --git a/settings.gradle b/settings.gradle
index e09d8a1..eccf7e8 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -31,12 +31,17 @@ def subprojects = ['groovy-ant',
         'groovy-templates',
         'groovy-test',
         'groovy-testng',
-        'groovy-xml']
+        'groovy-xml'
+]
 
 if(JavaVersion.current().isJava7Compatible()) {
     subprojects << 'groovy-nio'
 }
- 
+
+if (JavaVersion.current().isJava8Compatible()) {
+    subprojects << 'performance'
+}
+
 include(subprojects as String[])
         
 rootProject.children.each { prj ->

http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/6dbfae85/subprojects/performance/build.gradle
----------------------------------------------------------------------
diff --git a/subprojects/performance/build.gradle b/subprojects/performance/build.gradle
new file mode 100644
index 0000000..e7136a0
--- /dev/null
+++ b/subprojects/performance/build.gradle
@@ -0,0 +1,90 @@
+import java.text.DecimalFormat
+
+configurations {
+    stats
+    testCompile.extendsFrom(stats)
+}
+
+dependencies {
+    testCompile 'org.codehaus.groovy:groovy:2.4.4'
+    stats 'org.apache.commons:commons-math3:3.5'
+}
+
+sourceCompatibility = 1.8
+targetCompatibility = 1.8
+
+task performanceTests {
+    ext.outputDir = file("$buildDir/compilation")
+    ext.dataFile = file("$buildDir/compilation-stats.csv")
+
+    dependsOn rootProject.jarAll
+    doLast {
+        ext.outputDir.deleteDir()
+        def versions = []
+        dataFile.eachLine {
+            def (version, mean, stdDev) = it.split(';')
+            mean = Double.valueOf(mean)
+            stdDev = Double.valueOf(stdDev)
+            versions << [version == project.version ? 'current' : version, mean, stdDev]
+        }
+        versions = versions.sort { it[1] }
+        def fastest = versions[0][1]
+        versions.each { version, mean, stdDev ->
+            print "Groovy $version Average ${mean}ms ± ${new DecimalFormat("#.##").format(stdDev)}ms "
+            if (mean > fastest) {
+                def diff = 100 * (mean - fastest) / fastest
+                print "(${new DecimalFormat("#.##").format(diff)}% slower)"
+            }
+            println()
+        }
+        dataFile.delete()
+    }
+}
+
+['1.8.9', '2.0.8', '2.1.9', '2.2.2', '2.3.10', '2.3.11', '2.4.4', 'current'].each { version ->
+    def t = task "performanceTestGroovy${version.replace('.', '_')}"(type: JavaExec) {
+        dependsOn compileTestJava
+        def groovyConf = configurations.detachedConfiguration(
+                dependencies.create(
+                        'current' == version ? files(rootProject.jarAll.archivePath) : "org.codehaus.groovy:groovy-all:$version")
+        )
+        groovyConf.transitive = false
+        main = 'org.apache.groovy.perf.CompilerPerformanceTest'
+        classpath = groovyConf + sourceSets.test.output + configurations.stats
+        jvmArgs = ['-Xms512m', '-Xmx512m', '-XX:MaxPermSize=512m']
+        def compileClassPath = [
+                '-cp',
+                groovyConf.files[0]
+        ]
+        rootProject.sourceSets.test.compileClasspath.files
+                .findAll { it.name.endsWith('jar') && !it.name.contains('groovy') }
+                .collect(compileClassPath) { it.absolutePath }
+
+        // configure some files to compile. This is an arbitrary set of files which can be compiled
+        // independently of the version of Groovy being tested
+        def testFiles = ['gls/CompilableTestSupport.groovy',
+                         'groovy/beans',
+                         'groovy/benchmarks',
+                         'groovy/execute',
+                         'groovy/gpath',
+                         'groovy/io',
+                         'groovy/script',
+                         'groovy/time',
+                         'groovy/tree',
+                         'gls/syntax'].collect { "../../src/test/$it" }
+        ['groovy-ant', 'groovy-test', 'groovy-jsr223'].collect(testFiles) { "../../subprojects/$it/src/test/groovy" }
+
+        ['ackermann', 'fibo', 'random', 'spectralnorm', 'ary', 'hello', 'recursive', 'threadring',
+         'binarytrees', 'mandelbrot', 'regexdna', 'wordfreq',
+         'fannkuch', 'nsieve', 'revcomp'].collect(testFiles) {
+            "../../benchmark/bench/${it}.groovy"
+        }
+
+        args = [
+                *testFiles,
+                *compileClassPath
+        ]
+
+    }
+    performanceTests.dependsOn(t)
+}

http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/6dbfae85/subprojects/performance/src/test/java/org/apache/groovy/perf/CompilerPerformanceTest.java
----------------------------------------------------------------------
diff --git a/subprojects/performance/src/test/java/org/apache/groovy/perf/CompilerPerformanceTest.java b/subprojects/performance/src/test/java/org/apache/groovy/perf/CompilerPerformanceTest.java
new file mode 100644
index 0000000..a31fa55
--- /dev/null
+++ b/subprojects/performance/src/test/java/org/apache/groovy/perf/CompilerPerformanceTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2003-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.groovy.perf;
+
+import groovy.lang.GroovySystem;
+import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+public class CompilerPerformanceTest {
+    private final static String GROOVY_VERSION = GroovySystem.getVersion();
+    private final static int WARMUP = 200;
+    private final static int REPEAT = 1000;
+
+    public static void main(String[] args) throws Exception {
+        List<File> sources = new ArrayList<>();
+        List<URL> classpath = new ArrayList<>();
+        boolean isCp = false;
+        for (String arg : args) {
+            if ("-cp".equals(arg)) {
+                isCp = true;
+            } else if (isCp) {
+                classpath.add(new File(arg).toURI().toURL());
+            } else {
+                sources.add(new File(arg));
+            }
+        }
+        ScriptCompilationExecuter executer = new ScriptCompilationExecuter(
+                sources.toArray(new File[sources.size()]),
+                classpath
+        );
+        System.out.println("Using Groovy " + GROOVY_VERSION);
+
+        DescriptiveStatistics stats = new DescriptiveStatistics();
+
+        for (int i=0;i<WARMUP+REPEAT;i++) {
+            if (i<WARMUP) {
+                System.out.println("Warmup #" + (i+1));
+            } else {
+                System.out.println("Round #" + (i-WARMUP));
+            }
+            long dur = executer.execute();
+            System.gc();
+            System.out.printf("Compile time = %dms%n", dur);
+            if (i>=WARMUP) {
+                stats.addValue((double) dur);
+            }
+        }
+
+
+        System.out.println("Compilation took " + stats.getMean() + "ms ± " + stats.getStandardDeviation() + "ms");
+        FileWriter wrt = new FileWriter(new File("target/compilation-stats.csv"), true);
+        wrt.append(String.format("%s;%s;%s\n", GROOVY_VERSION, stats.getMean(), stats.getStandardDeviation()));
+        wrt.close();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/6dbfae85/subprojects/performance/src/test/java/org/apache/groovy/perf/ScriptCompilationExecuter.java
----------------------------------------------------------------------
diff --git a/subprojects/performance/src/test/java/org/apache/groovy/perf/ScriptCompilationExecuter.java b/subprojects/performance/src/test/java/org/apache/groovy/perf/ScriptCompilationExecuter.java
new file mode 100644
index 0000000..7c97580
--- /dev/null
+++ b/subprojects/performance/src/test/java/org/apache/groovy/perf/ScriptCompilationExecuter.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2003-2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.groovy.perf;
+
+import groovy.lang.GroovyClassLoader;
+import org.codehaus.groovy.control.CompilationUnit;
+import org.codehaus.groovy.control.CompilePhase;
+import org.codehaus.groovy.control.CompilerConfiguration;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.Files;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+public class ScriptCompilationExecuter {
+    private final File[] sources;
+    private final URL[] classpath;
+
+    public ScriptCompilationExecuter(File[] sourceDirectories, final List<URL> classpath) throws IOException {
+        this.classpath = classpath.toArray(new URL[classpath.size()]);
+        Set<File> sources = new HashSet<>();
+        for (File sourceDirectory : sourceDirectories) {
+            Files.walk(sourceDirectory.toPath())
+                    .filter(path -> {
+                        File file = path.toFile();
+                        return file.isFile()
+                                && file.getName().endsWith(".groovy");
+                    })
+                    .forEach(path -> sources.add(path.toFile()));
+        }
+        this.sources = sources.toArray(new File[sources.size()]);
+        System.out.println("sources = " + sources.size());
+    }
+
+    public long execute() throws Exception {
+        ClassLoader cl = new URLClassLoader(classpath, ClassLoader.getSystemClassLoader().getParent());
+        GroovyClassLoader gcl = new GroovyClassLoader(cl);
+        CompilationUnit cu = new CompilationUnit(new CompilerConfiguration(), null, gcl, new GroovyClassLoader(this.getClass().getClassLoader()));
+        for (File source : sources) {
+            cu.addSource(source);
+        }
+        long sd = System.nanoTime();
+        cu.compile(CompilePhase.CLASS_GENERATION.getPhaseNumber());
+        long dur = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - sd);
+        return dur;
+    }
+}


[2/2] incubator-groovy git commit: Added a compiler performance test module

Posted by cc...@apache.org.
Added a compiler performance test module


Project: http://git-wip-us.apache.org/repos/asf/incubator-groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-groovy/commit/6dbfae85
Tree: http://git-wip-us.apache.org/repos/asf/incubator-groovy/tree/6dbfae85
Diff: http://git-wip-us.apache.org/repos/asf/incubator-groovy/diff/6dbfae85

Branch: refs/heads/master
Commit: 6dbfae85e537df0ce72471e2027a6d6209bb8834
Parents: 8e97162
Author: Cedric Champeau <cc...@apache.org>
Authored: Mon Sep 21 09:31:34 2015 +0200
Committer: Cedric Champeau <cc...@apache.org>
Committed: Mon Sep 21 09:31:34 2015 +0200

----------------------------------------------------------------------
 benchmark/bench/chameneos.java                  | 266 ++---
 benchmark/bench/magicsquares.java               | 468 ++++-----
 benchmark/bench/mandelbrot.java                 | 166 ++--
 benchmark/bench/message.java                    | 200 ++--
 benchmark/bench/meteor.java                     | 988 +++++++++----------
 benchmark/bench/moments.java                    | 154 +--
 benchmark/bench/wordfreq.groovy                 |  10 +-
 settings.gradle                                 |   9 +-
 subprojects/performance/build.gradle            |  90 ++
 .../groovy/perf/CompilerPerformanceTest.java    |  73 ++
 .../groovy/perf/ScriptCompilationExecuter.java  |  65 ++
 11 files changed, 1361 insertions(+), 1128 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/6dbfae85/benchmark/bench/chameneos.java
----------------------------------------------------------------------
diff --git a/benchmark/bench/chameneos.java b/benchmark/bench/chameneos.java
index da7bc67..efd6ceb 100644
--- a/benchmark/bench/chameneos.java
+++ b/benchmark/bench/chameneos.java
@@ -1,133 +1,133 @@
-/* The Computer Language Shootout
-   http://shootout.alioth.debian.org/
-
-   contributed by Keenan Tims
-   modified by Michael Barker
-*/
-
-
-public class chameneos {
-
-    private MeetingPlace mp;
-
-    public static final Colour[] COLOURS = { Colour.BLUE, Colour.RED, Colour.YELLOW, Colour.BLUE };
-
-    private Creature[] creatures = new Creature[COLOURS.length];
-
-    public enum Colour {
-        RED, BLUE, YELLOW, FADED
-    }
-
-    public class Creature extends Thread {
-
-        private MeetingPlace mp;
-        private Colour colour;
-        private int met = 0;
-        private Colour other;
-
-        public Creature(Colour c, MeetingPlace mp) {
-            this.colour = c;
-            this.mp = mp;
-        }
-
-        public void run() {
-            try {
-                while (colour != Colour.FADED) {
-                    mp.meet(this);
-                    if (other == Colour.FADED)
-                        colour = Colour.FADED;
-                    else {
-                        met++;
-                        colour = complement(other);
-                    }
-                }
-            } catch (InterruptedException e) {
-                // Let the thread exit.
-            }
-        }
-
-        private Colour complement(Colour other) {
-            if (colour == other)
-                return colour;
-            switch (colour) {
-            case BLUE:
-                return other == Colour.RED ? Colour.YELLOW : Colour.RED;
-            case RED:
-                return other == Colour.BLUE ? Colour.YELLOW : Colour.BLUE;
-            case YELLOW:
-                return other == Colour.BLUE ? Colour.RED : Colour.BLUE;
-            default:
-                return colour;
-            }
-        }
-
-        public int getCreaturesMet() {
-            return met;
-        }
-
-        public Colour getColour() {
-            return colour;
-        }
-
-        public void setOther(Colour other) throws InterruptedException {
-            this.other = other;
-        }
-    }
-
-    public class MeetingPlace {
-
-        int n;
-
-        public MeetingPlace(int n) {
-            this.n = n;
-        }
-
-        Creature other = null;
-        public void meet(Creature c) throws InterruptedException {
-
-            synchronized (this) {
-                if (n > 0) {
-                    if (other == null) {
-                        other = c;
-                        this.wait();
-                    } else {
-                        other.setOther(c.getColour());
-                        c.setOther(other.getColour());
-                        other = null;
-                        n--;
-                        this.notify();
-                    }
-                } else {
-                    c.setOther(Colour.FADED);
-                }
-            }
-        }
-    }
-
-    public chameneos(int n) throws InterruptedException {
-        int meetings = 0;
-        mp = new MeetingPlace(n);
-
-        for (int i = 0; i < COLOURS.length; i++) {
-            creatures[i] = new Creature(COLOURS[i], mp);
-            creatures[i].start();
-        }
-
-        // wait for all threads to complete
-        for (int i = 0; i < COLOURS.length; i++)
-            creatures[i].join();
-
-        // sum all the meetings
-        for (int i = 0; i < COLOURS.length; i++) {
-            meetings += creatures[i].getCreaturesMet();
-        }
-
-        System.out.println(meetings);
-    }
-
-    public static void main(String[] args) throws Exception {
-        if (args.length < 1)
-            throw new IllegalArgumentException();
-        new chameneos(Integer.parseInt(args[0]));
-    }
-}
+/* The Computer Language Shootout
+   http://shootout.alioth.debian.org/
+
+   contributed by Keenan Tims
+   modified by Michael Barker
+*/
+
+
+public class chameneos {
+
+    private MeetingPlace mp;
+
+    public static final Colour[] COLOURS = { Colour.BLUE, Colour.RED, Colour.YELLOW, Colour.BLUE };
+
+    private Creature[] creatures = new Creature[COLOURS.length];
+
+    public enum Colour {
+        RED, BLUE, YELLOW, FADED
+    }
+
+    public class Creature extends Thread {
+
+        private MeetingPlace mp;
+        private Colour colour;
+        private int met = 0;
+        private Colour other;
+
+        public Creature(Colour c, MeetingPlace mp) {
+            this.colour = c;
+            this.mp = mp;
+        }
+
+        public void run() {
+            try {
+                while (colour != Colour.FADED) {
+                    mp.meet(this);
+                    if (other == Colour.FADED)
+                        colour = Colour.FADED;
+                    else {
+                        met++;
+                        colour = complement(other);
+                    }
+                }
+            } catch (InterruptedException e) {
+                // Let the thread exit.
+            }
+        }
+
+        private Colour complement(Colour other) {
+            if (colour == other)
+                return colour;
+            switch (colour) {
+            case BLUE:
+                return other == Colour.RED ? Colour.YELLOW : Colour.RED;
+            case RED:
+                return other == Colour.BLUE ? Colour.YELLOW : Colour.BLUE;
+            case YELLOW:
+                return other == Colour.BLUE ? Colour.RED : Colour.BLUE;
+            default:
+                return colour;
+            }
+        }
+
+        public int getCreaturesMet() {
+            return met;
+        }
+
+        public Colour getColour() {
+            return colour;
+        }
+
+        public void setOther(Colour other) throws InterruptedException {
+            this.other = other;
+        }
+    }
+
+    public class MeetingPlace {
+
+        int n;
+
+        public MeetingPlace(int n) {
+            this.n = n;
+        }
+
+        Creature other = null;
+        public void meet(Creature c) throws InterruptedException {
+
+            synchronized (this) {
+                if (n > 0) {
+                    if (other == null) {
+                        other = c;
+                        this.wait();
+                    } else {
+                        other.setOther(c.getColour());
+                        c.setOther(other.getColour());
+                        other = null;
+                        n--;
+                        this.notify();
+                    }
+                } else {
+                    c.setOther(Colour.FADED);
+                }
+            }
+        }
+    }
+
+    public chameneos(int n) throws InterruptedException {
+        int meetings = 0;
+        mp = new MeetingPlace(n);
+
+        for (int i = 0; i < COLOURS.length; i++) {
+            creatures[i] = new Creature(COLOURS[i], mp);
+            creatures[i].start();
+        }
+
+        // wait for all threads to complete
+        for (int i = 0; i < COLOURS.length; i++)
+            creatures[i].join();
+
+        // sum all the meetings
+        for (int i = 0; i < COLOURS.length; i++) {
+            meetings += creatures[i].getCreaturesMet();
+        }
+
+        System.out.println(meetings);
+    }
+
+    public static void main(String[] args) throws Exception {
+        if (args.length < 1)
+            throw new IllegalArgumentException();
+        new chameneos(Integer.parseInt(args[0]));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/6dbfae85/benchmark/bench/magicsquares.java
----------------------------------------------------------------------
diff --git a/benchmark/bench/magicsquares.java b/benchmark/bench/magicsquares.java
index 2ecc74f..766991f 100644
--- a/benchmark/bench/magicsquares.java
+++ b/benchmark/bench/magicsquares.java
@@ -1,234 +1,234 @@
-/* The Computer Language Shootout
-   http://shootout.alioth.debian.org/
-
-   benchmark implementation (not optimized)
-   JRE 1.5 only
-   contributed by Josh Goldfoot */
-
-import java.io.*;
-import java.lang.*;
-import java.util.*;
-
-public class magicsquares {
-    
-    static int n;
-    static int mn;
-    
-    public static class FfmResult {
-        public int x;
-        public int y;
-        public int[] moves;
-        public FfmResult(int ix, int iy, int[] imoves) {
-            x = ix;
-            y = iy;
-            moves = (int[]) imoves.clone();
-        }
-    }
-    
-    public static class PQNode implements Comparable {
-        public int [] grid;
-        boolean priorityCalculated;
-        private int priority;
-        private FfmResult ffm;
-        
-        public PQNode() {
-            grid = new int [n * n];
-            int i;
-            for (i = 0; i < n * n; i++)
-                grid[i] = 0;
-            priorityCalculated = false;
-            ffm = null;
-        }
-        public PQNode(PQNode other) {
-            grid = (int[]) other.grid.clone();
-            priorityCalculated = false;
-        }
-
-        public int[] gridRow(int y) {
-            int[] r = new int[n];
-            int x;
-            for (x = 0; x < n; x++)
-                r[x] = grid[x + y * n];
-            return r;
-        }
-
-        public int[] gridCol(int x) {
-            int[] r = new int[n];
-            int y;
-            for (y = 0; y < n; y++)
-                r[y] = grid[x + y * n];
-            return r;
-        }
-
-        public int[] diagonal(int q) {
-            int[] r = new int[n];
-            int i;
-            for (i = 0; i < n; i++) {
-                if (q == 1)
-                    r[i] = grid[i + i * n];
-                else if (q == 2) {
-                    r[i] = grid[i + (n - 1 - i) * n];
-                }
-            }
-            return r;
-        }
-
-        public int[] possibleMoves(int x, int y) {
-            int zerocount, sum, highest, j, i;
-            
-            if (grid[x + y * n] != 0)
-                return ( new int [] { });
-            ArrayList<int[]> cellGroups = new ArrayList<int[]>();
-            cellGroups.add(gridCol(x));
-            cellGroups.add(gridRow(y));
-            if (x == y)
-                cellGroups.add(diagonal(1));
-            if (x + y == n - 1)
-                cellGroups.add(diagonal(2));
-            HashSet<Integer> usedNumbers = new HashSet<Integer>();
-            for (i = 0; i < grid.length; i++)
-                usedNumbers.add(new Integer(grid[i]));
-            HashSet<Integer> onePossible = new HashSet<Integer>();
-            highest = n * n;
-            for (int[] group: cellGroups) {
-                zerocount = 0;
-                sum = 0;
-                for (int num: group) {
-                    if (num == 0)
-                        zerocount++;
-                    sum += num;
-                }
-                if (zerocount == 1)
-                    onePossible.add(new Integer(mn - sum));
-                if (mn - sum < highest)
-                    highest = mn - sum;
-            }
-            if (onePossible.size() == 1) {
-                Integer onlyPossibleMove = (Integer) onePossible.iterator().next();
-                int opmint = onlyPossibleMove.intValue();
-                if (opmint >= 1 && 
-                        opmint <= n * n && 
-                        ! usedNumbers.contains(onlyPossibleMove))
-                    return (new int[] { opmint });
-                else
-                    return ( new int [] { });
-            } else if (onePossible.size() > 1)
-                return ( new int [] { });
-            ArrayList<Integer> moves = new ArrayList<Integer>();
-            for (i = 1; i <= highest; i++) {
-                Integer ii = new Integer(i);
-                if (! usedNumbers.contains(ii))
-                    moves.add(ii);
-            }
-            int[] r = new int[moves.size()];
-            i = 0;
-            for (Integer move: moves) {
-                r[i++] = move.intValue();
-            }
-            return r;
-        }
-
-        public FfmResult findFewestMoves() {
-            if (ffm != null)
-                return ffm;
-            int x, y, mx, my, ind;
-            int[] minmoves = (new int[] { });
-            int[] moves;
-            mx = my = -1;
-            for (y = 0; y < n; y++)
-                for (x = 0; x < n; x++) {
-                    ind = x + y * n;
-                    if (grid[ind] == 0) {
-                        moves = possibleMoves(x,y);
-                        if (mx == -1 || moves.length < minmoves.length) {
-                            mx = x;
-                            my = y;
-                            minmoves = (int[]) moves.clone();
-                        }
-                    }
-                }
-            ffm = new FfmResult(mx, my, minmoves);
-            return ffm;
-        }
-        
-        public void calculatePriority()
-        {
-            int i, zerocount;
-            zerocount = 0;
-            for (int cell: grid)
-                if (cell == 0)
-                    zerocount++;
-            priority = zerocount + findFewestMoves().moves.length;
-            priorityCalculated = true;
-        }
-        
-        public int getPriority()
-        {
-            if (priorityCalculated)
-                return priority;
-            else {
-                calculatePriority();
-                return priority;
-            }
-        }
-        
-        public int compareTo(Object anotherMSquare) throws ClassCastException {
-            if (!(anotherMSquare instanceof PQNode))
-                throw new ClassCastException();
-            PQNode other = (PQNode) anotherMSquare;
-            int c = getPriority() - other.getPriority();
-            if (c == 0) {
-                int i = 0;
-                while (c == 0 && i < n * n) {
-                    c = grid[i] - other.grid[i];
-                    i++;
-                }
-            }
-            return c;
-        }
-
-        public String toString() {
-            StringBuilder sb = new StringBuilder();
-            int y, x;
-            for (y = 0; y < n; y++) {
-                for (x = 0; x < n; x++) {
-                    sb.append(grid[x + y * n]);
-                    if (x < n-1)
-                        sb.append(' ');
-                }
-                if (y < n-1)
-                    sb.append('\n');
-            }
-            return sb.toString();
-        }
-
-        
-    }
-    
-    public magicsquares() { }
-    
-    public static void main(String[] args) {
-        n = 3;
-        if (args.length > 0) 
-            n = Integer.parseInt(args[0]);
-        mn = n * (1 + n * n) / 2;
-        PriorityQueue<magicsquares.PQNode> pq = new PriorityQueue<magicsquares.PQNode>(); 
-        pq.offer(new magicsquares.PQNode() );
-        while (! pq.isEmpty()) {
-            PQNode topSquare = pq.poll();
-            if (topSquare.getPriority() == 0) {
-                System.out.println(topSquare);
-                break;
-            }
-            magicsquares.FfmResult result = topSquare.findFewestMoves();
-
-            int ind = result.x + result.y * n;
-            for (int move: result.moves) {
-                magicsquares.PQNode newSquare = new magicsquares.PQNode(topSquare);
-                newSquare.grid[ind] = move;
-                pq.offer(newSquare);
-            }
-        }
-                
-    }
-}
+/* The Computer Language Shootout
+   http://shootout.alioth.debian.org/
+
+   benchmark implementation (not optimized)
+   JRE 1.5 only
+   contributed by Josh Goldfoot */
+
+import java.io.*;
+import java.lang.*;
+import java.util.*;
+
+public class magicsquares {
+    
+    static int n;
+    static int mn;
+    
+    public static class FfmResult {
+        public int x;
+        public int y;
+        public int[] moves;
+        public FfmResult(int ix, int iy, int[] imoves) {
+            x = ix;
+            y = iy;
+            moves = (int[]) imoves.clone();
+        }
+    }
+    
+    public static class PQNode implements Comparable {
+        public int [] grid;
+        boolean priorityCalculated;
+        private int priority;
+        private FfmResult ffm;
+        
+        public PQNode() {
+            grid = new int [n * n];
+            int i;
+            for (i = 0; i < n * n; i++)
+                grid[i] = 0;
+            priorityCalculated = false;
+            ffm = null;
+        }
+        public PQNode(PQNode other) {
+            grid = (int[]) other.grid.clone();
+            priorityCalculated = false;
+        }
+
+        public int[] gridRow(int y) {
+            int[] r = new int[n];
+            int x;
+            for (x = 0; x < n; x++)
+                r[x] = grid[x + y * n];
+            return r;
+        }
+
+        public int[] gridCol(int x) {
+            int[] r = new int[n];
+            int y;
+            for (y = 0; y < n; y++)
+                r[y] = grid[x + y * n];
+            return r;
+        }
+
+        public int[] diagonal(int q) {
+            int[] r = new int[n];
+            int i;
+            for (i = 0; i < n; i++) {
+                if (q == 1)
+                    r[i] = grid[i + i * n];
+                else if (q == 2) {
+                    r[i] = grid[i + (n - 1 - i) * n];
+                }
+            }
+            return r;
+        }
+
+        public int[] possibleMoves(int x, int y) {
+            int zerocount, sum, highest, j, i;
+            
+            if (grid[x + y * n] != 0)
+                return ( new int [] { });
+            ArrayList<int[]> cellGroups = new ArrayList<int[]>();
+            cellGroups.add(gridCol(x));
+            cellGroups.add(gridRow(y));
+            if (x == y)
+                cellGroups.add(diagonal(1));
+            if (x + y == n - 1)
+                cellGroups.add(diagonal(2));
+            HashSet<Integer> usedNumbers = new HashSet<Integer>();
+            for (i = 0; i < grid.length; i++)
+                usedNumbers.add(new Integer(grid[i]));
+            HashSet<Integer> onePossible = new HashSet<Integer>();
+            highest = n * n;
+            for (int[] group: cellGroups) {
+                zerocount = 0;
+                sum = 0;
+                for (int num: group) {
+                    if (num == 0)
+                        zerocount++;
+                    sum += num;
+                }
+                if (zerocount == 1)
+                    onePossible.add(new Integer(mn - sum));
+                if (mn - sum < highest)
+                    highest = mn - sum;
+            }
+            if (onePossible.size() == 1) {
+                Integer onlyPossibleMove = (Integer) onePossible.iterator().next();
+                int opmint = onlyPossibleMove.intValue();
+                if (opmint >= 1 && 
+                        opmint <= n * n && 
+                        ! usedNumbers.contains(onlyPossibleMove))
+                    return (new int[] { opmint });
+                else
+                    return ( new int [] { });
+            } else if (onePossible.size() > 1)
+                return ( new int [] { });
+            ArrayList<Integer> moves = new ArrayList<Integer>();
+            for (i = 1; i <= highest; i++) {
+                Integer ii = new Integer(i);
+                if (! usedNumbers.contains(ii))
+                    moves.add(ii);
+            }
+            int[] r = new int[moves.size()];
+            i = 0;
+            for (Integer move: moves) {
+                r[i++] = move.intValue();
+            }
+            return r;
+        }
+
+        public FfmResult findFewestMoves() {
+            if (ffm != null)
+                return ffm;
+            int x, y, mx, my, ind;
+            int[] minmoves = (new int[] { });
+            int[] moves;
+            mx = my = -1;
+            for (y = 0; y < n; y++)
+                for (x = 0; x < n; x++) {
+                    ind = x + y * n;
+                    if (grid[ind] == 0) {
+                        moves = possibleMoves(x,y);
+                        if (mx == -1 || moves.length < minmoves.length) {
+                            mx = x;
+                            my = y;
+                            minmoves = (int[]) moves.clone();
+                        }
+                    }
+                }
+            ffm = new FfmResult(mx, my, minmoves);
+            return ffm;
+        }
+        
+        public void calculatePriority()
+        {
+            int i, zerocount;
+            zerocount = 0;
+            for (int cell: grid)
+                if (cell == 0)
+                    zerocount++;
+            priority = zerocount + findFewestMoves().moves.length;
+            priorityCalculated = true;
+        }
+        
+        public int getPriority()
+        {
+            if (priorityCalculated)
+                return priority;
+            else {
+                calculatePriority();
+                return priority;
+            }
+        }
+        
+        public int compareTo(Object anotherMSquare) throws ClassCastException {
+            if (!(anotherMSquare instanceof PQNode))
+                throw new ClassCastException();
+            PQNode other = (PQNode) anotherMSquare;
+            int c = getPriority() - other.getPriority();
+            if (c == 0) {
+                int i = 0;
+                while (c == 0 && i < n * n) {
+                    c = grid[i] - other.grid[i];
+                    i++;
+                }
+            }
+            return c;
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            int y, x;
+            for (y = 0; y < n; y++) {
+                for (x = 0; x < n; x++) {
+                    sb.append(grid[x + y * n]);
+                    if (x < n-1)
+                        sb.append(' ');
+                }
+                if (y < n-1)
+                    sb.append('\n');
+            }
+            return sb.toString();
+        }
+
+        
+    }
+    
+    public magicsquares() { }
+    
+    public static void main(String[] args) {
+        n = 3;
+        if (args.length > 0) 
+            n = Integer.parseInt(args[0]);
+        mn = n * (1 + n * n) / 2;
+        PriorityQueue<magicsquares.PQNode> pq = new PriorityQueue<magicsquares.PQNode>(); 
+        pq.offer(new magicsquares.PQNode() );
+        while (! pq.isEmpty()) {
+            PQNode topSquare = pq.poll();
+            if (topSquare.getPriority() == 0) {
+                System.out.println(topSquare);
+                break;
+            }
+            magicsquares.FfmResult result = topSquare.findFewestMoves();
+
+            int ind = result.x + result.y * n;
+            for (int move: result.moves) {
+                magicsquares.PQNode newSquare = new magicsquares.PQNode(topSquare);
+                newSquare.grid[ind] = move;
+                pq.offer(newSquare);
+            }
+        }
+                
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/6dbfae85/benchmark/bench/mandelbrot.java
----------------------------------------------------------------------
diff --git a/benchmark/bench/mandelbrot.java b/benchmark/bench/mandelbrot.java
index 6b7a6cc..988182f 100644
--- a/benchmark/bench/mandelbrot.java
+++ b/benchmark/bench/mandelbrot.java
@@ -1,83 +1,83 @@
-/* The Computer Language Benchmarks Game
-   http://shootout.alioth.debian.org/
-   contributed by Stefan Krause
-   slightly modified by Chad Whipkey
-*/
-
-import java.io.IOException;
-import java.io.PrintStream;
-
-class mandelbrot {
-
-   public static void main(String[] args) throws Exception {
-       new Mandelbrot(Integer.parseInt(args[0])).compute();
-   }
-
-   public static class Mandelbrot {
-       private static final int BUFFER_SIZE = 8192;
-
-       public Mandelbrot(int size) {
-         this.size = size;
-         fac = 2.0 / size;
-         out = System.out;
-         shift = size % 8 == 0 ? 0 : (8- size % 8);
-      }
-      final int size;
-      final PrintStream out;
-      final byte [] buf = new byte[BUFFER_SIZE];
-      int bufLen = 0;
-      final double fac;
-      final int shift;
-
-      public void compute() throws IOException
-      {
-         out.format("P4\n%d %d\n",size,size);
-         for (int y = 0; y<size; y++)
-            computeRow(y);
-         out.write( buf, 0, bufLen);
-         out.close();
-      }
-
-      private void computeRow(int y) throws IOException
-      {
-         int bits = 0;
-
-         final double Ci = (y*fac - 1.0);
-          final byte[] bufLocal = buf;
-          for (int x = 0; x<size;x++) {
-            double Zr = 0.0;
-            double Zi = 0.0;
-            double Cr = (x*fac - 1.5);
-            int i = 50;
-            double ZrN = 0;
-            double ZiN = 0;
-            do {
-               Zi = 2.0 * Zr * Zi + Ci;
-               Zr = ZrN - ZiN + Cr;
-               ZiN = Zi * Zi;
-               ZrN = Zr * Zr;
-            } while (!(ZiN + ZrN > 4.0) && --i > 0);
-
-            bits = bits << 1;
-            if (i == 0) bits++;
-
-            if (x%8 == 7) {
-                bufLocal[bufLen++] = (byte) bits;
-                if ( bufLen == BUFFER_SIZE) {
-                    out.write(bufLocal, 0, BUFFER_SIZE);
-                    bufLen = 0;
-                }
-               bits = 0;
-            }
-         }
-         if (shift!=0) {
-            bits = bits << shift;
-            bufLocal[bufLen++] = (byte) bits;
-            if ( bufLen == BUFFER_SIZE) {
-                out.write(bufLocal, 0, BUFFER_SIZE);
-                bufLen = 0;
-            }
-         }
-      }
-   }
-}
+/* The Computer Language Benchmarks Game
+   http://shootout.alioth.debian.org/
+   contributed by Stefan Krause
+   slightly modified by Chad Whipkey
+*/
+
+import java.io.IOException;
+import java.io.PrintStream;
+
+class mandelbrot {
+
+   public static void main(String[] args) throws Exception {
+       new Mandelbrot(Integer.parseInt(args[0])).compute();
+   }
+
+   public static class Mandelbrot {
+       private static final int BUFFER_SIZE = 8192;
+
+       public Mandelbrot(int size) {
+         this.size = size;
+         fac = 2.0 / size;
+         out = System.out;
+         shift = size % 8 == 0 ? 0 : (8- size % 8);
+      }
+      final int size;
+      final PrintStream out;
+      final byte [] buf = new byte[BUFFER_SIZE];
+      int bufLen = 0;
+      final double fac;
+      final int shift;
+
+      public void compute() throws IOException
+      {
+         out.format("P4\n%d %d\n",size,size);
+         for (int y = 0; y<size; y++)
+            computeRow(y);
+         out.write( buf, 0, bufLen);
+         out.close();
+      }
+
+      private void computeRow(int y) throws IOException
+      {
+         int bits = 0;
+
+         final double Ci = (y*fac - 1.0);
+          final byte[] bufLocal = buf;
+          for (int x = 0; x<size;x++) {
+            double Zr = 0.0;
+            double Zi = 0.0;
+            double Cr = (x*fac - 1.5);
+            int i = 50;
+            double ZrN = 0;
+            double ZiN = 0;
+            do {
+               Zi = 2.0 * Zr * Zi + Ci;
+               Zr = ZrN - ZiN + Cr;
+               ZiN = Zi * Zi;
+               ZrN = Zr * Zr;
+            } while (!(ZiN + ZrN > 4.0) && --i > 0);
+
+            bits = bits << 1;
+            if (i == 0) bits++;
+
+            if (x%8 == 7) {
+                bufLocal[bufLen++] = (byte) bits;
+                if ( bufLen == BUFFER_SIZE) {
+                    out.write(bufLocal, 0, BUFFER_SIZE);
+                    bufLen = 0;
+                }
+               bits = 0;
+            }
+         }
+         if (shift!=0) {
+            bits = bits << shift;
+            bufLocal[bufLen++] = (byte) bits;
+            if ( bufLen == BUFFER_SIZE) {
+                out.write(bufLocal, 0, BUFFER_SIZE);
+                bufLen = 0;
+            }
+         }
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/6dbfae85/benchmark/bench/message.java
----------------------------------------------------------------------
diff --git a/benchmark/bench/message.java b/benchmark/bench/message.java
index 4735b07..30fd122 100644
--- a/benchmark/bench/message.java
+++ b/benchmark/bench/message.java
@@ -1,100 +1,100 @@
-/* The Computer Language Benchmarks Game
- http://shootout.alioth.debian.org/
-
- contributed by Mattias Bergander
- */
-
-import java.util.LinkedList;
-import java.util.List;
-
-public class message {
-    public static final int numberOfThreads = 500;
-
-    public static int numberOfMessagesToSend;
-
-    public static void main(String args[]) {
-        numberOfMessagesToSend = Integer.parseInt(args[0]);
-
-        MessageThread chain = null;
-        for (int i = 0; i < numberOfThreads; i++) {
-            chain = new MessageThread(chain);
-            new Thread(chain).start();
-        }
-
-        for (int i = 0; i < numberOfMessagesToSend; i++) {
-            chain.enqueue(new MutableInteger(0));
-        }
-
-    }
-}
-
-class MutableInteger {
-    int value;
-
-    public MutableInteger() {
-        this(0);
-    }
-
-    public MutableInteger(int value) {
-        this.value = value;
-    }
-
-    public MutableInteger increment() {
-        value++;
-        return this;
-    }
-
-    public int intValue() {
-        return value;
-    }
-}
-
-class MessageThread implements Runnable {
-    MessageThread nextThread;
-
-    List<MutableInteger> list = new LinkedList<MutableInteger>();
-
-    MessageThread(MessageThread nextThread) {
-        this.nextThread = nextThread;
-    }
-
-    public void run() {
-        if (nextThread != null) {
-            while (true) {
-                nextThread.enqueue(dequeue());
-            }
-        } else {
-            int sum = 0;
-            int finalSum = message.numberOfThreads * message.numberOfMessagesToSend;
-            while (sum < finalSum) {
-                sum += dequeue().intValue();
-            }
-            System.out.println(sum);
-            System.exit(0);
-        }
-    }
-
-    /**
-     * @param message
-     */
-    public void enqueue(MutableInteger message) {
-        synchronized (list) {
-            list.add(message);
-            if (list.size() == 1) {
-                list.notify();
-            }
-        }
-    }
-
-    public MutableInteger dequeue() {
-        synchronized (list) {
-            while (list.size() == 0) {
-                try {
-                    list.wait();
-                } catch (InterruptedException e) {
-                }
-            }
-            return list.remove(0).increment();
-        }
-    }
-}
+/* The Computer Language Benchmarks Game
+ http://shootout.alioth.debian.org/
+
+ contributed by Mattias Bergander
+ */
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class message {
+    public static final int numberOfThreads = 500;
+
+    public static int numberOfMessagesToSend;
+
+    public static void main(String args[]) {
+        numberOfMessagesToSend = Integer.parseInt(args[0]);
+
+        MessageThread chain = null;
+        for (int i = 0; i < numberOfThreads; i++) {
+            chain = new MessageThread(chain);
+            new Thread(chain).start();
+        }
+
+        for (int i = 0; i < numberOfMessagesToSend; i++) {
+            chain.enqueue(new MutableInteger(0));
+        }
+
+    }
+}
+
+class MutableInteger {
+    int value;
+
+    public MutableInteger() {
+        this(0);
+    }
+
+    public MutableInteger(int value) {
+        this.value = value;
+    }
+
+    public MutableInteger increment() {
+        value++;
+        return this;
+    }
+
+    public int intValue() {
+        return value;
+    }
+}
+
+class MessageThread implements Runnable {
+    MessageThread nextThread;
+
+    List<MutableInteger> list = new LinkedList<MutableInteger>();
+
+    MessageThread(MessageThread nextThread) {
+        this.nextThread = nextThread;
+    }
+
+    public void run() {
+        if (nextThread != null) {
+            while (true) {
+                nextThread.enqueue(dequeue());
+            }
+        } else {
+            int sum = 0;
+            int finalSum = message.numberOfThreads * message.numberOfMessagesToSend;
+            while (sum < finalSum) {
+                sum += dequeue().intValue();
+            }
+            System.out.println(sum);
+            System.exit(0);
+        }
+    }
+
+    /**
+     * @param message
+     */
+    public void enqueue(MutableInteger message) {
+        synchronized (list) {
+            list.add(message);
+            if (list.size() == 1) {
+                list.notify();
+            }
+        }
+    }
+
+    public MutableInteger dequeue() {
+        synchronized (list) {
+            while (list.size() == 0) {
+                try {
+                    list.wait();
+                } catch (InterruptedException e) {
+                }
+            }
+            return list.remove(0).increment();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-groovy/blob/6dbfae85/benchmark/bench/meteor.java
----------------------------------------------------------------------
diff --git a/benchmark/bench/meteor.java b/benchmark/bench/meteor.java
index c3104b6..b5a46b7 100644
--- a/benchmark/bench/meteor.java
+++ b/benchmark/bench/meteor.java
@@ -1,494 +1,494 @@
-/* The Computer Language Shootout
-   http://shootout.alioth.debian.org/
-
-   contributed by Tony Seebregts
-   modified by 
-*/
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-/** First hack at a Java solver for the meteor puzzle - just the IBM 
-  * developerWorks article algorithm optimized with precalculated shapes 
-  * and bitmasks. Should be possible to optimize it some more to take 
-  * advantage of reflections but its turning out to be less obvious 
-  * than expected :-).
-  * <p>
-  * Notes:
-  * <ul>
-  * <li>Seems to run faster without the -server switch.
-  * <li>Testing for islands seems to be slower than just fitting pieces.
-  * </ul>
-  * 
-  * @author Tony Seebregts
-  *
-  */
-  
-public class meteor
-   { // CONSTANTS
-       
-     private static final int[]    SHIFT = { 0,6,11,17,22,28,33,39,44,50 };
-     private static final long[][] MASK  = { { 0x01L,      0x02L,      0x04L,      0x08L,      0x10L   },
-                     { 0x01L << 6, 0x02L << 6, 0x04L << 6, 0x08L <<  6,0x10L << 6  },
-                     { 0x01L << 11,0x02L << 11,0x04L << 11,0x08L << 11,0x10L << 11 },
-                     { 0x01L << 17,0x02L << 17,0x04L << 17,0x08L << 17,0x10L << 17 },
-                     { 0x01L << 22,0x02L << 22,0x04L << 22,0x08L << 22,0x10L << 22 },
-                     { 0x01L << 28,0x02L << 28,0x04L << 28,0x08L << 28,0x10L << 28 },
-                     { 0x01L << 33,0x02L << 33,0x04L << 33,0x08L << 33,0x10L << 33 },
-                     { 0x01L << 39,0x02L << 39,0x04L << 39,0x08L << 39,0x10L << 39 },
-                     { 0x01L << 44,0x02L << 44,0x04L << 44,0x08L << 44,0x10L << 44 },
-                     { 0x01L << 50,0x02L << 50,0x04L << 50,0x08L << 50,0x10L << 50 }
-                       };
-     
-     private static final boolean DEBUG = false;
-
-     // CLASS VARIABLES
-     
-     // INSTANCE VARIABLES
-     
-     private SortedSet<String> solutions = new TreeSet<String>();
-     private Entry[]       solution  = new Entry[10];
-     private int       depth     = 0;
-     private Piece[]       pieces    = { new Piece(PIECE0),
-                     new Piece(PIECE1),
-                     new Piece(PIECE2),
-                     new Piece(PIECE3),
-                     new Piece(PIECE4),
-                     new Piece(PIECE5),
-                     new Piece(PIECE6),
-                     new Piece(PIECE7),
-                     new Piece(PIECE8),
-                     new Piece(PIECE9)
-                       };
-       
-     // CLASS METHODS
-
-     /** Application entry point.
-       * 
-       * @param args  Command line arguments:
-       *      <ul>
-       *      <li> solution limit
-       *      </ul>
-       */
-     
-     public static void main(String[] args)
-        { int N = 2098;
-        
-          // ... parse command line arguments
-        
-          if (args.length > 0)
-         if (args[0].matches("\\d+"))
-            N = Integer.parseInt(args[0]);
-            
-          // ... solve puzzle
-          
-          meteor        puzzle = new meteor ();
-          Date      start;
-          Date      end;
-          long      time;
-          SortedSet<String> solutions;
-          
-          start     = new Date();
-          solutions = puzzle.solve();
-          end   = new Date();
-          time      = end.getTime() - start.getTime();      
-          
-          // ... print result
-            
-          if (solutions.size() > N)
-         System.out.println("ERROR");
-         else if (solutions.size() < N)
-         System.out.println("TIMEOUT");
-         else
-         { if (DEBUG)
-              { System.out.println("START    : " + start);
-            System.out.println("END      : " + end);
-            System.out.println("TIME     : " + time);
-            System.out.println("SOLUTIONS: " + solutions.size ());
-            System.out.println("FIRST    : " + solutions.first());
-            System.out.println("LAST     : " + solutions.last ());
-            System.out.println();
-              }
-           
-           System.out.print(solutions.size () + " solutions found\n\n");
-           print(solutions.first());
-           System.out.print("\n");
-           print(solutions.last ());
-           System.out.print("\n");
-         }
-        }
-
-     /** Prints out the puzzle.
-       * 
-       * 
-       */
-    
-     private static void print (String solution)
-         { System.out.print(solution.replaceAll("(\\d{5})(\\d{5})","$1 $2")
-                    .replaceAll("(\\d{5})","$1\n")
-                    .replaceAll("(\\d)","$1 "));
-         }
-
-     // CONSTRUCTORS
-     
-     /** Initialises the puzzle.
-       * 
-       */
-
-     public meteor ()
-        { for (int i=0; i<10; i++)
-          solution[i] = new Entry();
-        }
-     
-     // INSTANCE METHODS
-     
-     /** Initialises the puzzle and solution set at [0,0]
-       *
-       * @return Sorted list of solution strings.
-       */ 
-     
-     private SortedSet<String> solve()
-         { solve(0x0002004008010020L,0,0);
-         
-           return solutions;
-         }
-     
-     /** Recursively solves the puzzle by fitting pieces into the 
-       * next available hexagon.
-       * 
-       * @param puzzle  Current puzzle bitmask.
-       * @param row     Row of next available hexagon. 
-       * @param col     Column next available hexagon. 
-       * 
-       */
-      
-     private void solve (long puzzle,int row,int col)
-         { for (int ix=0; ix<pieces.length; ix++)
-           { Piece   piece;
-             Shape[] list;
- 
-             // ... find shapes that fit
-             
-             if ((piece = pieces[ix]) == null)
-            continue;
-            else
-            list  = pieces[ix].shapes(row,col);
-               
-             for (Shape shape: list)
-             { // ... fits badly ?
-          
-               if ((shape.bitmap & puzzle) != 0)
-                  continue;
-               
-               // ... try piece in puzzle
- 
-               long clone = puzzle | shape.bitmap;
- 
-               // ... find next position
-                
-               int irow = row;
-               int icol = col/2 + 1;
-                
-               next:
-               while (irow < 10)
-                 { while (icol < 5)
-                     { if ((clone & MASK[irow][icol]) == 0)
-                      break next;
-                              
-                       icol++;
-                     }
-                         
-                   irow++;
-                   icol = 0;
-                 }
-                 
-               // ... solve next
-               
-               Entry entry;
-                 
-               pieces[ix]  = null;
-               entry   = solution[depth++];
-               entry.row   = row;
-               entry.col   = col;
-               entry.shape = shape;
- 
-               if (depth == 10)
-                  solutions.add(serialize(solution));
-                  else
-                  solve (clone,irow,2*icol + (irow % 2));
-                
-               depth--;
-               pieces[ix] = piece;
-             }
-           }
-         }
-      
-     /** Serializes the current solution to a string.
-       * 
-       */
-      
-     private String serialize (Entry[] solution)
-         { char[] puzzle = new char[50];
-           Shape   shape;
-           int     row;
-           int     col;
-           
-           for (Entry entry: solution)
-           { shape = entry.shape;
-             row   = entry.row;
-             col   = entry.col;
-             
-             for (int[] xy: shape.vector)
-             puzzle[5 * (row + xy[0]) + (col + xy[1])/2] = shape.symbol;
-           }
-      
-           return new String(puzzle);
-         }
-    
-     // INNER CLASSES
-     
-     /** Container class for a solution set entry.
-       * 
-       */
-     
-     private static class Entry
-         { public int   row;
-           public int   col;
-           public Shape shape; 
-         }
-     
-     /** Container class for the shapes for a single puzzle piece.
-       * 
-       * 
-       */
-     
-     private static class Piece
-         { private Shape[][][] shapes = new Shape[10][10][];
-         
-           @SuppressWarnings("unchecked")
-           private Piece (Shape[] list)
-               { // ... initialise
-               
-             ArrayList[][] array = new ArrayList[10][10];
-             
-             for (int i=0; i<10; i++)
-                 for (int j=0; j<10; j++)
-                 array[i][j] = new ArrayList<Shape>();
-             
-             // ... generate list
-             
-             for (Shape mutant: list)
-                 for (int row=0; row<=mutant.maxRow; row++)
-                 for (int col=mutant.minCol; col<=mutant.maxCol; col++)
-                     { if (!mutant.islet)
-                      array[row][col].add(new Shape(mutant,row,col));
-                      else if ((row != 0) || (col != 0))
-                      array[row][col].add(new Shape(mutant,row,col));
-                     }
-             
-             for (int row=0; row<10; row++)
-                 for (int col=0; col<10; col++)
-                 shapes[row][col] = (Shape[]) array[row][col].toArray(new Shape[0]);
-               }
-           
-           @SuppressWarnings("unchecked")
-           private Shape[] shapes(int row,int col)
-               { return shapes[row][col];
-               }
-         
-         }
-
-     /** Container class for the shape vector and bitmap single puzzle piece mutation.
-       * 
-       * 
-       */
-     
-     private static class Shape
-        { private char    symbol;
-          private int[][] vector;
-          private long    bitmap;
-          private int     shift;
-          
-          private boolean islet;
-          private int     maxRow;
-          private int     minCol;
-          private int     maxCol;
-          
-          private Shape (char    symbol,
-                 int[][] vector,
-                 long    bitmap,
-                 int     shift,
-                 boolean islet,
-                 int     maxRow,
-                 int     minCol,
-                 int     maxCol)
-              { this.symbol  = symbol;
-            this.vector  = vector;
-            this.bitmap  = bitmap;
-            this.shift   = shift;
-            
-            this.islet   = islet;
-            this.maxRow  = maxRow;
-            this.minCol  = minCol;
-            this.maxCol  = maxCol;
-              }
-          
-          private Shape (Shape shape,
-                 int   row,
-                 int   col)
-              { this.symbol  = shape.symbol;
-            this.vector  = shape.vector;
-            this.bitmap  = shape.bitmap << ((SHIFT[row] + (col - (row % 2))/2) - shape.shift);
-            
-            this.islet   = shape.islet;
-            this.maxRow  = shape.maxRow;
-            this.minCol  = shape.minCol;
-            this.maxCol  = shape.maxCol;
-              }
-        }
-     
-     // PIECES
-
-     private static final Shape[] PIECE0 = { new Shape ('0',new int[][] {{3, 5},{2, 4},{1, 3},{0, 2},{0, 0}},0x0000000000082083L,0,false,6,0,4),
-                     new Shape ('0',new int[][] {{4,-2},{3,-1},{2, 0},{1, 1},{0, 0}},0x0000000000421082L,1,false,5,2,8),
-                     new Shape ('0',new int[][] {{1,-7},{1,-5},{1,-3},{1,-1},{0, 0}},0x00000000000003D0L,4,false,8,7,9),
-                     new Shape ('0',new int[][] {{0, 0},{1, 1},{2, 2},{3, 3},{3, 5}},0x00000000000C1041L,0,false,6,0,4),
-                     new Shape ('0',new int[][] {{0, 0},{1,-1},{2,-2},{3,-3},{4,-2}},0x0000000000821084L,2,false,5,3,9),
-                     new Shape ('0',new int[][] {{0, 6},{0, 4},{0, 2},{0, 0},{1,-1}},0x000000000000005EL,1,false,8,1,3),
-                     new Shape ('0',new int[][] {{0, 0},{1, 1},{2, 2},{3, 3},{4, 2}},0x0000000000841041L,0,false,5,0,6),
-                     new Shape ('0',new int[][] {{0, 0},{1,-1},{2,-2},{3,-3},{3,-5}},0x0000000000062108L,3,false,6,5,9),
-                     new Shape ('0',new int[][] {{1, 7},{1, 5},{1, 3},{1, 1},{0, 0}},0x00000000000003C1L,0,false,8,0,2),
-                     new Shape ('0',new int[][] {{4, 2},{3, 1},{2, 0},{1,-1},{0, 0}},0x0000000001041042L,1,false,5,1,7),
-                     new Shape ('0',new int[][] {{3,-3},{2,-2},{1,-1},{0, 0},{0, 2}},0x000000000002108CL,2,false,6,3,7),
-                     new Shape ('0',new int[][] {{0, 0},{0, 2},{0, 4},{0, 6},{1, 7}},0x000000000000020FL,0,false,8,0,2)
-                       };
-
-     private static final Shape[] PIECE1 = { new Shape ('1',new int[][] {{0, 2},{0, 0},{1,-1},{2, 0},{3,-1}},0x0000000000021046L,1,false,6,1,7),
-                     new Shape ('1',new int[][] {{1, 3},{0, 2},{0, 0},{1,-1},{1,-3}},0x00000000000002CCL,2,false,8,3,6),
-                     new Shape ('1',new int[][] {{3, 3},{2, 4},{1, 3},{1, 1},{0, 0}},0x00000000000420C1L,0,false,6,0,5),
-                     new Shape ('1',new int[][] {{3,-3},{3,-1},{2, 0},{1,-1},{0, 0}},0x0000000000062084L,2,false,6,3,9),
-                     new Shape ('1',new int[][] {{0, 0},{1, 1},{1, 3},{0, 4},{0, 6}},0x00000000000000CDL,0,true, 8,0,3),
-                     new Shape ('1',new int[][] {{0, 0},{1,-1},{2, 0},{2, 2},{3, 3}},0x0000000000083042L,1,false,6,1,6),
-                     new Shape ('1',new int[][] {{0, 6},{1, 5},{1, 3},{0, 2},{0, 0}},0x000000000000018BL,0,true, 8,0,3),
-                     new Shape ('1',new int[][] {{3, 3},{3, 1},{2, 0},{1, 1},{0, 0}},0x0000000000060841L,0,false,6,0,6),
-                     new Shape ('1',new int[][] {{3,-3},{2,-4},{1,-3},{1,-1},{0, 0}},0x00000000000208C4L,2,false,6,4,9),
-                     new Shape ('1',new int[][] {{1,-1},{0, 0},{0, 2},{1, 3},{1, 5}},0x0000000000000346L,1,false,8,1,4),
-                     new Shape ('1',new int[][] {{0, 0},{0, 2},{1, 3},{2, 2},{3, 3}},0x0000000000041083L,0,false,6,0,6),
-                     new Shape ('1',new int[][] {{0, 0},{1, 1},{2, 0},{2,-2},{3,-3}},0x0000000000023104L,2,false,6,3,8)
-                       };
-
-     private static final Shape[] PIECE2 = { new Shape ('2',new int[][] {{1, 1},{0, 0},{2, 0},{2,-2},{2,-4}},0x0000000000003904L,2,false,7,4,8),
-                     new Shape ('2',new int[][] {{2, 4},{1, 5},{2, 2},{1, 1},{0, 0}},0x0000000000003141L,0,false,7,0,4),
-                     new Shape ('2',new int[][] {{3,-1},{3, 1},{2,-2},{1,-1},{0, 0}},0x0000000000060842L,1,false,6,2,8),
-                     new Shape ('2',new int[][] {{1,-1},{2, 0},{0, 0},{0, 2},{0, 4}},0x000000000000104EL,1,false,7,1,5),
-                     new Shape ('2',new int[][] {{0, 0},{1,-1},{0, 2},{1, 3},{2, 4}},0x0000000000004146L,1,false,7,1,5),
-                     new Shape ('2',new int[][] {{0, 2},{0, 0},{1, 3},{2, 2},{3, 1}},0x0000000000021083L,0,true, 6,0,6),
-                     new Shape ('2',new int[][] {{0, 2},{1, 3},{0, 0},{1,-1},{2,-2}},0x0000000000000946L,1,false,7,2,6),
-                     new Shape ('2',new int[][] {{1, 5},{2, 4},{0, 4},{0, 2},{0, 0}},0x0000000000002107L,0,false,7,0,4),
-                     new Shape ('2',new int[][] {{3, 1},{3,-1},{2, 2},{1, 1},{0, 0}},0x0000000000062082L,1,false,6,1,7),
-                     new Shape ('2',new int[][] {{2,-4},{1,-5},{2,-2},{1,-1},{0, 0}},0x0000000000003148L,3,false,7,5,9),
-                     new Shape ('2',new int[][] {{1,-1},{0, 0},{2, 0},{2, 2},{2, 4}},0x0000000000007042L,1,false,7,1,5),
-                     new Shape ('2',new int[][] {{0, 0},{0, 2},{1,-1},{2, 0},{3, 1}},0x0000000000041046L,1,false,6,1,7)
-                       };
-
-     private static final Shape[] PIECE3 = { new Shape ('3',new int[][] {{0, 0},{2, 0},{1,-1},{2,-2},{2,-4}},0x0000000000003884L,2,false,7,4,9),
-                     new Shape ('3',new int[][] {{1, 5},{2, 2},{1, 3},{1, 1},{0, 0}},0x00000000000011C1L,0,false,7,0,4),
-                     new Shape ('3',new int[][] {{3, 1},{2,-2},{2, 0},{1,-1},{0, 0}},0x0000000000041842L,1,false,6,2,8),
-                     new Shape ('3',new int[][] {{2, 0},{0, 0},{1, 1},{0, 2},{0, 4}},0x0000000000000847L,0,false,7,0,5),
-                     new Shape ('3',new int[][] {{1,-3},{0, 0},{1,-1},{1, 1},{2, 2}},0x00000000000041C4L,2,false,7,3,7),
-                     new Shape ('3',new int[][] {{0, 0},{1, 3},{1, 1},{2, 2},{3, 1}},0x00000000000210C1L,0,true, 6,0,6),
-                     new Shape ('3',new int[][] {{1, 3},{0, 0},{1, 1},{1,-1},{2,-2}},0x00000000000009C2L,1,false,7,2,6),
-                     new Shape ('3',new int[][] {{2, 4},{0, 4},{1, 3},{0, 2},{0, 0}},0x0000000000002087L,0,false,7,0,5),
-                     new Shape ('3',new int[][] {{3,-1},{2, 2},{2, 0},{1, 1},{0, 0}},0x0000000000023082L,1,false,6,1,7),
-                     new Shape ('3',new int[][] {{1,-5},{2,-2},{1,-3},{1,-1},{0, 0}},0x00000000000021C8L,3,false,7,5,9),
-                     new Shape ('3',new int[][] {{0, 0},{2, 0},{1, 1},{2, 2},{2, 4}},0x0000000000003841L,0,false,7,0,5),
-                     new Shape ('3',new int[][] {{0, 0},{1,-3},{1,-1},{2,-2},{3,-1}},0x00000000000410C4L,2,false,6,3,9)
-                       };
-
-     private static final Shape[] PIECE4 = { new Shape ('4',new int[][] {{1, 5},{2, 2},{1, 3},{0, 2},{0, 0}},0x0000000000001183L,0,false,7,0,4),
-                     new Shape ('4',new int[][] {{3, 1},{2,-2},{2, 0},{1, 1},{0, 0}},0x0000000000041882L,1,false,6,2,8),
-                     new Shape ('4',new int[][] {{2, 0},{0, 0},{1, 1},{1, 3},{0, 4}},0x00000000000008C5L,0,true, 7,0,5),
-                     new Shape ('4',new int[][] {{1,-3},{0, 0},{1,-1},{2, 0},{2, 2}},0x00000000000060C4L,2,false,7,3,7),
-                     new Shape ('4',new int[][] {{0, 0},{1, 3},{1, 1},{2, 0},{3, 1}},0x00000000000208C1L,0,false,6,0,6),
-                     new Shape ('4',new int[][] {{0, 0},{2, 0},{1,-1},{1,-3},{2,-4}},0x00000000000028C4L,2,false,7,4,9),
-                     new Shape ('4',new int[][] {{0, 0},{1,-3},{1,-1},{2, 0},{3,-1}},0x00000000000420C4L,2,false,6,3,9),
-                     new Shape ('4',new int[][] {{1, 3},{0, 0},{1, 1},{2, 0},{2,-2}},0x0000000000001982L,1,false,7,2,6),
-                     new Shape ('4',new int[][] {{2, 4},{0, 4},{1, 3},{1, 1},{0, 0}},0x00000000000020C5L,0,true, 7,0,5),
-                     new Shape ('4',new int[][] {{3,-1},{2, 2},{2, 0},{1,-1},{0, 0}},0x0000000000023042L,1,false,6,1,7),
-                     new Shape ('4',new int[][] {{1,-3},{2, 0},{1,-1},{0, 0},{0, 2}},0x00000000000020CCL,2,false,7,3,7),
-                     new Shape ('4',new int[][] {{0, 0},{2, 0},{1, 1},{1, 3},{2, 4}},0x00000000000028C1L,0,false,7,0,5)
-                       };
-
-     private static final Shape[] PIECE5 = { new Shape ('5',new int[][] {{0, 2},{1, 1},{0, 0},{1,-1},{2,-2}},0x00000000000008C6L,1,false,7,2,7),
-                     new Shape ('5',new int[][] {{1, 5},{1, 3},{0, 4},{0, 2},{0, 0}},0x0000000000000187L,0,false,8,0,4),
-                     new Shape ('5',new int[][] {{3, 1},{2, 0},{2, 2},{1, 1},{0, 0}},0x0000000000021841L,0,false,6,0,7),
-                     new Shape ('5',new int[][] {{2,-4},{1,-3},{2,-2},{1,-1},{0, 0}},0x00000000000018C4L,2,false,7,4,9),
-                     new Shape ('5',new int[][] {{0, 0},{0, 2},{1, 1},{1, 3},{1, 5}},0x00000000000001C3L,0,false,8,0,4),
-                     new Shape ('5',new int[][] {{0, 0},{1, 1},{1,-1},{2, 0},{3, 1}},0x00000000000410C2L,1,false,6,1,8),
-                     new Shape ('5',new int[][] {{0, 2},{0, 0},{1, 1},{1,-1},{1,-3}},0x00000000000001CCL,2,false,8,3,7),
-                     new Shape ('5',new int[][] {{2, 4},{1, 3},{2, 2},{1, 1},{0, 0}},0x00000000000030C1L,0,false,7,0,5),
-                     new Shape ('5',new int[][] {{3,-1},{2, 0},{2,-2},{1,-1},{0, 0}},0x0000000000021842L,1,false,6,2,9),
-                     new Shape ('5',new int[][] {{1,-1},{1, 1},{0, 0},{0, 2},{0, 4}},0x00000000000000CEL,1,false,8,1,5),
-                     new Shape ('5',new int[][] {{0, 0},{1, 1},{0, 2},{1, 3},{2, 4}},0x00000000000020C3L,0,false,7,0,5),
-                     new Shape ('5',new int[][] {{0, 0},{1,-1},{1, 1},{2, 0},{3,-1}},0x00000000000210C2L,1,false,6,1,8)
-                       };
-
-     private static final Shape[] PIECE6 = { new Shape ('6',new int[][] {{1, 1},{0, 0},{1,-1},{1,-3},{2,-4}},0x00000000000009C4L,2,false,7,4,8),
-                     new Shape ('6',new int[][] {{2, 4},{1, 5},{1, 3},{0, 2},{0, 0}},0x0000000000002183L,0,false,7,0,4),
-                     new Shape ('6',new int[][] {{3,-1},{3, 1},{2, 0},{1, 1},{0, 0}},0x0000000000061082L,1,false,6,1,8),
-                     new Shape ('6',new int[][] {{1,-5},{2,-4},{1,-3},{1,-1},{0, 0}},0x00000000000011C8L,3,false,7,5,9),
-                     new Shape ('6',new int[][] {{0, 0},{1,-1},{1, 1},{2, 2},{2, 4}},0x00000000000060C2L,1,false,7,1,5),
-                     new Shape ('6',new int[][] {{0, 2},{0, 0},{1, 1},{2, 0},{3, 1}},0x0000000000020843L,0,false,6,0,7),
-                     new Shape ('6',new int[][] {{0, 0},{1, 1},{1,-1},{2,-2},{2,-4}},0x0000000000001984L,2,false,7,4,8),
-                     new Shape ('6',new int[][] {{1, 5},{2, 4},{1, 3},{1, 1},{0, 0}},0x00000000000021C1L,0,false,7,0,4),
-                     new Shape ('6',new int[][] {{3, 1},{3,-1},{2, 0},{1,-1},{0, 0}},0x0000000000061042L,1,false,6,1,8),
-                     new Shape ('6',new int[][] {{2,-2},{1,-3},{1,-1},{0, 0},{0, 2}},0x00000000000010CCL,2,false,7,3,7),
-                     new Shape ('6',new int[][] {{1,-1},{0, 0},{1, 1},{1, 3},{2, 4}},0x00000000000041C2L,1,false,7,1,5),
-                     new Shape ('6',new int[][] {{0, 0},{0, 2},{1, 1},{2, 2},{3, 1}},0x0000000000021043L,0,false,6,0,7)
-                       };
-
-     private static final Shape[] PIECE7 = { new Shape ('7',new int[][] {{0, 2},{1, 1},{0, 0},{2, 0},{2,-2}},0x0000000000001886L,1,false,7,2,7),
-                     new Shape ('7',new int[][] {{1, 5},{1, 3},{0, 4},{1, 1},{0, 0}},0x00000000000001C5L,0,true, 8,0,4),
-                     new Shape ('7',new int[][] {{3, 1},{2, 0},{2, 2},{1,-1},{0, 0}},0x0000000000043042L,1,false,6,1,7),
-                     new Shape ('7',new int[][] {{2,-2},{1,-1},{2, 0},{0, 0},{0, 2}},0x0000000000001846L,1,false,7,2,7),
-                     new Shape ('7',new int[][] {{0, 0},{0, 2},{1, 1},{0, 4},{1, 5}},0x0000000000000147L,0,false,8,0,4),
-                     new Shape ('7',new int[][] {{0, 0},{1, 1},{1,-1},{2, 2},{3, 1}},0x00000000000420C2L,1,false,6,1,7),
-                     new Shape ('7',new int[][] {{0, 4},{0, 2},{1, 3},{0, 0},{1,-1}},0x000000000000014EL,1,false,8,1,5),
-                     new Shape ('7',new int[][] {{2, 4},{1, 3},{2, 2},{0, 2},{0, 0}},0x0000000000003083L,0,false,7,0,5),
-                     new Shape ('7',new int[][] {{3,-1},{2, 0},{2,-2},{1, 1},{0, 0}},0x0000000000021882L,1,false,6,2,8),
-                     new Shape ('7',new int[][] {{1,-1},{1, 1},{0, 0},{1, 3},{0, 4}},0x00000000000001CAL,1,false,8,1,5),
-                     new Shape ('7',new int[][] {{0, 0},{1, 1},{0, 2},{2, 2},{2, 4}},0x0000000000003043L,0,false,7,0,5),
-                     new Shape ('7',new int[][] {{0, 0},{1,-1},{1, 1},{2,-2},{3,-1}},0x00000000000208C2L,1,false,6,2,8)
-                       };
-
-     private static final Shape[] PIECE8 = { new Shape ('8',new int[][] {{4, 2},{3, 1},{2, 0},{1, 1},{0, 0}},0x0000000000820841L,0,false,5,0,7),
-                     new Shape ('8',new int[][] {{3,-5},{2,-4},{1,-3},{1,-1},{0, 0}},0x0000000000021188L,3,false,6,5,9),
-                     new Shape ('8',new int[][] {{0, 0},{0, 2},{0, 4},{1, 5},{1, 7}},0x0000000000000307L,0,false,8,0,2),
-                     new Shape ('8',new int[][] {{0, 0},{1, 1},{2, 2},{3, 1},{4, 2}},0x0000000000821041L,0,true, 5,0,7),
-                     new Shape ('8',new int[][] {{0, 0},{1,-1},{2,-2},{2,-4},{3,-5}},0x0000000000023108L,3,false,6,5,9),
-                     new Shape ('8',new int[][] {{1, 7},{1, 5},{1, 3},{0, 2},{0, 0}},0x0000000000000383L,0,false,8,0,2),
-                     new Shape ('8',new int[][] {{0, 0},{1, 1},{2, 2},{2, 4},{3, 5}},0x0000000000083041L,0,false,6,0,4),
-                     new Shape ('8',new int[][] {{0, 0},{1,-1},{2,-2},{3,-1},{4,-2}},0x0000000000420842L,1,false,5,2,9),
-                     new Shape ('8',new int[][] {{0, 4},{0, 2},{0, 0},{1,-1},{1,-3}},0x00000000000000DCL,2,false,8,3,5),
-                     new Shape ('8',new int[][] {{3, 5},{2, 4},{1, 3},{1, 1},{0, 0}},0x00000000000820C1L,0,false,6,0,4),
-                     new Shape ('8',new int[][] {{4,-2},{3,-1},{2, 0},{1,-1},{0, 0}},0x0000000000421042L,1,false,5,2,9),
-                     new Shape ('8',new int[][] {{1,-5},{1,-3},{1,-1},{0, 0},{0, 2}},0x00000000000001D8L,3,false,8,5,7)
-                       };
-
-     private static final Shape[] PIECE9 = { new Shape ('9',new int[][] {{3, 3},{2, 2},{1, 1},{0, 0},{0, 2}},0x0000000000041043L,0,false,6,0,6),
-                     new Shape ('9',new int[][] {{3,-3},{2,-2},{1,-1},{0, 0},{1, 1}},0x0000000000021184L,2,false,6,3,8),
-                     new Shape ('9',new int[][] {{0, 0},{0, 2},{0, 4},{0, 6},{1, 5}},0x000000000000010FL,0,false,8,0,3),
-                     new Shape ('9',new int[][] {{0, 0},{1, 1},{2, 2},{3, 3},{3, 1}},0x0000000000061041L,0,true, 6,0,6),
-                     new Shape ('9',new int[][] {{0, 0},{1,-1},{2,-2},{3,-3},{2,-4}},0x0000000000021884L,2,false,6,4,9),
-                     new Shape ('9',new int[][] {{1, 5},{1, 3},{1, 1},{1,-1},{0, 0}},0x00000000000003C2L,1,false,8,1,4),
-                     new Shape ('9',new int[][] {{0, 0},{1, 1},{2, 2},{3, 3},{2, 4}},0x0000000000043041L,0,false,6,0,5),
-                     new Shape ('9',new int[][] {{0, 0},{1,-1},{2,-2},{3,-3},{3,-1}},0x0000000000061084L,2,false,6,3,9),
-                     new Shape ('9',new int[][] {{0, 6},{0, 4},{0, 2},{0, 0},{1, 1}},0x000000000000004FL,0,false,8,0,3),
-                     new Shape ('9',new int[][] {{3, 3},{2, 2},{1, 1},{0, 0},{1,-1}},0x00000000000820C2L,1,false,6,1,6),
-                     new Shape ('9',new int[][] {{3,-1},{2, 0},{1, 1},{0, 2},{0, 0}},0x0000000000021086L,1,false,6,1,7),
-                     new Shape ('9',new int[][] {{1,-5},{1,-3},{1,-1},{1, 1},{0, 0}},0x00000000000003C8L,3,false,8,5,8)
-                       };
-                       
-    }
+/* The Computer Language Shootout
+   http://shootout.alioth.debian.org/
+
+   contributed by Tony Seebregts
+   modified by 
+*/
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/** First hack at a Java solver for the meteor puzzle - just the IBM 
+  * developerWorks article algorithm optimized with precalculated shapes 
+  * and bitmasks. Should be possible to optimize it some more to take 
+  * advantage of reflections but its turning out to be less obvious 
+  * than expected :-).
+  * <p>
+  * Notes:
+  * <ul>
+  * <li>Seems to run faster without the -server switch.
+  * <li>Testing for islands seems to be slower than just fitting pieces.
+  * </ul>
+  * 
+  * @author Tony Seebregts
+  *
+  */
+  
+public class meteor
+   { // CONSTANTS
+       
+     private static final int[]    SHIFT = { 0,6,11,17,22,28,33,39,44,50 };
+     private static final long[][] MASK  = { { 0x01L,      0x02L,      0x04L,      0x08L,      0x10L   },
+                     { 0x01L << 6, 0x02L << 6, 0x04L << 6, 0x08L <<  6,0x10L << 6  },
+                     { 0x01L << 11,0x02L << 11,0x04L << 11,0x08L << 11,0x10L << 11 },
+                     { 0x01L << 17,0x02L << 17,0x04L << 17,0x08L << 17,0x10L << 17 },
+                     { 0x01L << 22,0x02L << 22,0x04L << 22,0x08L << 22,0x10L << 22 },
+                     { 0x01L << 28,0x02L << 28,0x04L << 28,0x08L << 28,0x10L << 28 },
+                     { 0x01L << 33,0x02L << 33,0x04L << 33,0x08L << 33,0x10L << 33 },
+                     { 0x01L << 39,0x02L << 39,0x04L << 39,0x08L << 39,0x10L << 39 },
+                     { 0x01L << 44,0x02L << 44,0x04L << 44,0x08L << 44,0x10L << 44 },
+                     { 0x01L << 50,0x02L << 50,0x04L << 50,0x08L << 50,0x10L << 50 }
+                       };
+     
+     private static final boolean DEBUG = false;
+
+     // CLASS VARIABLES
+     
+     // INSTANCE VARIABLES
+     
+     private SortedSet<String> solutions = new TreeSet<String>();
+     private Entry[]       solution  = new Entry[10];
+     private int       depth     = 0;
+     private Piece[]       pieces    = { new Piece(PIECE0),
+                     new Piece(PIECE1),
+                     new Piece(PIECE2),
+                     new Piece(PIECE3),
+                     new Piece(PIECE4),
+                     new Piece(PIECE5),
+                     new Piece(PIECE6),
+                     new Piece(PIECE7),
+                     new Piece(PIECE8),
+                     new Piece(PIECE9)
+                       };
+       
+     // CLASS METHODS
+
+     /** Application entry point.
+       * 
+       * @param args  Command line arguments:
+       *      <ul>
+       *      <li> solution limit
+       *      </ul>
+       */
+     
+     public static void main(String[] args)
+        { int N = 2098;
+        
+          // ... parse command line arguments
+        
+          if (args.length > 0)
+         if (args[0].matches("\\d+"))
+            N = Integer.parseInt(args[0]);
+            
+          // ... solve puzzle
+          
+          meteor        puzzle = new meteor ();
+          Date      start;
+          Date      end;
+          long      time;
+          SortedSet<String> solutions;
+          
+          start     = new Date();
+          solutions = puzzle.solve();
+          end   = new Date();
+          time      = end.getTime() - start.getTime();      
+          
+          // ... print result
+            
+          if (solutions.size() > N)
+         System.out.println("ERROR");
+         else if (solutions.size() < N)
+         System.out.println("TIMEOUT");
+         else
+         { if (DEBUG)
+              { System.out.println("START    : " + start);
+            System.out.println("END      : " + end);
+            System.out.println("TIME     : " + time);
+            System.out.println("SOLUTIONS: " + solutions.size ());
+            System.out.println("FIRST    : " + solutions.first());
+            System.out.println("LAST     : " + solutions.last ());
+            System.out.println();
+              }
+           
+           System.out.print(solutions.size () + " solutions found\n\n");
+           print(solutions.first());
+           System.out.print("\n");
+           print(solutions.last ());
+           System.out.print("\n");
+         }
+        }
+
+     /** Prints out the puzzle.
+       * 
+       * 
+       */
+    
+     private static void print (String solution)
+         { System.out.print(solution.replaceAll("(\\d{5})(\\d{5})","$1 $2")
+                    .replaceAll("(\\d{5})","$1\n")
+                    .replaceAll("(\\d)","$1 "));
+         }
+
+     // CONSTRUCTORS
+     
+     /** Initialises the puzzle.
+       * 
+       */
+
+     public meteor ()
+        { for (int i=0; i<10; i++)
+          solution[i] = new Entry();
+        }
+     
+     // INSTANCE METHODS
+     
+     /** Initialises the puzzle and solution set at [0,0]
+       *
+       * @return Sorted list of solution strings.
+       */ 
+     
+     private SortedSet<String> solve()
+         { solve(0x0002004008010020L,0,0);
+         
+           return solutions;
+         }
+     
+     /** Recursively solves the puzzle by fitting pieces into the 
+       * next available hexagon.
+       * 
+       * @param puzzle  Current puzzle bitmask.
+       * @param row     Row of next available hexagon. 
+       * @param col     Column next available hexagon. 
+       * 
+       */
+      
+     private void solve (long puzzle,int row,int col)
+         { for (int ix=0; ix<pieces.length; ix++)
+           { Piece   piece;
+             Shape[] list;
+ 
+             // ... find shapes that fit
+             
+             if ((piece = pieces[ix]) == null)
+            continue;
+            else
+            list  = pieces[ix].shapes(row,col);
+               
+             for (Shape shape: list)
+             { // ... fits badly ?
+          
+               if ((shape.bitmap & puzzle) != 0)
+                  continue;
+               
+               // ... try piece in puzzle
+ 
+               long clone = puzzle | shape.bitmap;
+ 
+               // ... find next position
+                
+               int irow = row;
+               int icol = col/2 + 1;
+                
+               next:
+               while (irow < 10)
+                 { while (icol < 5)
+                     { if ((clone & MASK[irow][icol]) == 0)
+                      break next;
+                              
+                       icol++;
+                     }
+                         
+                   irow++;
+                   icol = 0;
+                 }
+                 
+               // ... solve next
+               
+               Entry entry;
+                 
+               pieces[ix]  = null;
+               entry   = solution[depth++];
+               entry.row   = row;
+               entry.col   = col;
+               entry.shape = shape;
+ 
+               if (depth == 10)
+                  solutions.add(serialize(solution));
+                  else
+                  solve (clone,irow,2*icol + (irow % 2));
+                
+               depth--;
+               pieces[ix] = piece;
+             }
+           }
+         }
+      
+     /** Serializes the current solution to a string.
+       * 
+       */
+      
+     private String serialize (Entry[] solution)
+         { char[] puzzle = new char[50];
+           Shape   shape;
+           int     row;
+           int     col;
+           
+           for (Entry entry: solution)
+           { shape = entry.shape;
+             row   = entry.row;
+             col   = entry.col;
+             
+             for (int[] xy: shape.vector)
+             puzzle[5 * (row + xy[0]) + (col + xy[1])/2] = shape.symbol;
+           }
+      
+           return new String(puzzle);
+         }
+    
+     // INNER CLASSES
+     
+     /** Container class for a solution set entry.
+       * 
+       */
+     
+     private static class Entry
+         { public int   row;
+           public int   col;
+           public Shape shape; 
+         }
+     
+     /** Container class for the shapes for a single puzzle piece.
+       * 
+       * 
+       */
+     
+     private static class Piece
+         { private Shape[][][] shapes = new Shape[10][10][];
+         
+           @SuppressWarnings("unchecked")
+           private Piece (Shape[] list)
+               { // ... initialise
+               
+             ArrayList[][] array = new ArrayList[10][10];
+             
+             for (int i=0; i<10; i++)
+                 for (int j=0; j<10; j++)
+                 array[i][j] = new ArrayList<Shape>();
+             
+             // ... generate list
+             
+             for (Shape mutant: list)
+                 for (int row=0; row<=mutant.maxRow; row++)
+                 for (int col=mutant.minCol; col<=mutant.maxCol; col++)
+                     { if (!mutant.islet)
+                      array[row][col].add(new Shape(mutant,row,col));
+                      else if ((row != 0) || (col != 0))
+                      array[row][col].add(new Shape(mutant,row,col));
+                     }
+             
+             for (int row=0; row<10; row++)
+                 for (int col=0; col<10; col++)
+                 shapes[row][col] = (Shape[]) array[row][col].toArray(new Shape[0]);
+               }
+           
+           @SuppressWarnings("unchecked")
+           private Shape[] shapes(int row,int col)
+               { return shapes[row][col];
+               }
+         
+         }
+
+     /** Container class for the shape vector and bitmap single puzzle piece mutation.
+       * 
+       * 
+       */
+     
+     private static class Shape
+        { private char    symbol;
+          private int[][] vector;
+          private long    bitmap;
+          private int     shift;
+          
+          private boolean islet;
+          private int     maxRow;
+          private int     minCol;
+          private int     maxCol;
+          
+          private Shape (char    symbol,
+                 int[][] vector,
+                 long    bitmap,
+                 int     shift,
+                 boolean islet,
+                 int     maxRow,
+                 int     minCol,
+                 int     maxCol)
+              { this.symbol  = symbol;
+            this.vector  = vector;
+            this.bitmap  = bitmap;
+            this.shift   = shift;
+            
+            this.islet   = islet;
+            this.maxRow  = maxRow;
+            this.minCol  = minCol;
+            this.maxCol  = maxCol;
+              }
+          
+          private Shape (Shape shape,
+                 int   row,
+                 int   col)
+              { this.symbol  = shape.symbol;
+            this.vector  = shape.vector;
+            this.bitmap  = shape.bitmap << ((SHIFT[row] + (col - (row % 2))/2) - shape.shift);
+            
+            this.islet   = shape.islet;
+            this.maxRow  = shape.maxRow;
+            this.minCol  = shape.minCol;
+            this.maxCol  = shape.maxCol;
+              }
+        }
+     
+     // PIECES
+
+     private static final Shape[] PIECE0 = { new Shape ('0',new int[][] {{3, 5},{2, 4},{1, 3},{0, 2},{0, 0}},0x0000000000082083L,0,false,6,0,4),
+                     new Shape ('0',new int[][] {{4,-2},{3,-1},{2, 0},{1, 1},{0, 0}},0x0000000000421082L,1,false,5,2,8),
+                     new Shape ('0',new int[][] {{1,-7},{1,-5},{1,-3},{1,-1},{0, 0}},0x00000000000003D0L,4,false,8,7,9),
+                     new Shape ('0',new int[][] {{0, 0},{1, 1},{2, 2},{3, 3},{3, 5}},0x00000000000C1041L,0,false,6,0,4),
+                     new Shape ('0',new int[][] {{0, 0},{1,-1},{2,-2},{3,-3},{4,-2}},0x0000000000821084L,2,false,5,3,9),
+                     new Shape ('0',new int[][] {{0, 6},{0, 4},{0, 2},{0, 0},{1,-1}},0x000000000000005EL,1,false,8,1,3),
+                     new Shape ('0',new int[][] {{0, 0},{1, 1},{2, 2},{3, 3},{4, 2}},0x0000000000841041L,0,false,5,0,6),
+                     new Shape ('0',new int[][] {{0, 0},{1,-1},{2,-2},{3,-3},{3,-5}},0x0000000000062108L,3,false,6,5,9),
+                     new Shape ('0',new int[][] {{1, 7},{1, 5},{1, 3},{1, 1},{0, 0}},0x00000000000003C1L,0,false,8,0,2),
+                     new Shape ('0',new int[][] {{4, 2},{3, 1},{2, 0},{1,-1},{0, 0}},0x0000000001041042L,1,false,5,1,7),
+                     new Shape ('0',new int[][] {{3,-3},{2,-2},{1,-1},{0, 0},{0, 2}},0x000000000002108CL,2,false,6,3,7),
+                     new Shape ('0',new int[][] {{0, 0},{0, 2},{0, 4},{0, 6},{1, 7}},0x000000000000020FL,0,false,8,0,2)
+                       };
+
+     private static final Shape[] PIECE1 = { new Shape ('1',new int[][] {{0, 2},{0, 0},{1,-1},{2, 0},{3,-1}},0x0000000000021046L,1,false,6,1,7),
+                     new Shape ('1',new int[][] {{1, 3},{0, 2},{0, 0},{1,-1},{1,-3}},0x00000000000002CCL,2,false,8,3,6),
+                     new Shape ('1',new int[][] {{3, 3},{2, 4},{1, 3},{1, 1},{0, 0}},0x00000000000420C1L,0,false,6,0,5),
+                     new Shape ('1',new int[][] {{3,-3},{3,-1},{2, 0},{1,-1},{0, 0}},0x0000000000062084L,2,false,6,3,9),
+                     new Shape ('1',new int[][] {{0, 0},{1, 1},{1, 3},{0, 4},{0, 6}},0x00000000000000CDL,0,true, 8,0,3),
+                     new Shape ('1',new int[][] {{0, 0},{1,-1},{2, 0},{2, 2},{3, 3}},0x0000000000083042L,1,false,6,1,6),
+                     new Shape ('1',new int[][] {{0, 6},{1, 5},{1, 3},{0, 2},{0, 0}},0x000000000000018BL,0,true, 8,0,3),
+                     new Shape ('1',new int[][] {{3, 3},{3, 1},{2, 0},{1, 1},{0, 0}},0x0000000000060841L,0,false,6,0,6),
+                     new Shape ('1',new int[][] {{3,-3},{2,-4},{1,-3},{1,-1},{0, 0}},0x00000000000208C4L,2,false,6,4,9),
+                     new Shape ('1',new int[][] {{1,-1},{0, 0},{0, 2},{1, 3},{1, 5}},0x0000000000000346L,1,false,8,1,4),
+                     new Shape ('1',new int[][] {{0, 0},{0, 2},{1, 3},{2, 2},{3, 3}},0x0000000000041083L,0,false,6,0,6),
+                     new Shape ('1',new int[][] {{0, 0},{1, 1},{2, 0},{2,-2},{3,-3}},0x0000000000023104L,2,false,6,3,8)
+                       };
+
+     private static final Shape[] PIECE2 = { new Shape ('2',new int[][] {{1, 1},{0, 0},{2, 0},{2,-2},{2,-4}},0x0000000000003904L,2,false,7,4,8),
+                     new Shape ('2',new int[][] {{2, 4},{1, 5},{2, 2},{1, 1},{0, 0}},0x0000000000003141L,0,false,7,0,4),
+                     new Shape ('2',new int[][] {{3,-1},{3, 1},{2,-2},{1,-1},{0, 0}},0x0000000000060842L,1,false,6,2,8),
+                     new Shape ('2',new int[][] {{1,-1},{2, 0},{0, 0},{0, 2},{0, 4}},0x000000000000104EL,1,false,7,1,5),
+                     new Shape ('2',new int[][] {{0, 0},{1,-1},{0, 2},{1, 3},{2, 4}},0x0000000000004146L,1,false,7,1,5),
+                     new Shape ('2',new int[][] {{0, 2},{0, 0},{1, 3},{2, 2},{3, 1}},0x0000000000021083L,0,true, 6,0,6),
+                     new Shape ('2',new int[][] {{0, 2},{1, 3},{0, 0},{1,-1},{2,-2}},0x0000000000000946L,1,false,7,2,6),
+                     new Shape ('2',new int[][] {{1, 5},{2, 4},{0, 4},{0, 2},{0, 0}},0x0000000000002107L,0,false,7,0,4),
+                     new Shape ('2',new int[][] {{3, 1},{3,-1},{2, 2},{1, 1},{0, 0}},0x0000000000062082L,1,false,6,1,7),
+                     new Shape ('2',new int[][] {{2,-4},{1,-5},{2,-2},{1,-1},{0, 0}},0x0000000000003148L,3,false,7,5,9),
+                     new Shape ('2',new int[][] {{1,-1},{0, 0},{2, 0},{2, 2},{2, 4}},0x0000000000007042L,1,false,7,1,5),
+                     new Shape ('2',new int[][] {{0, 0},{0, 2},{1,-1},{2, 0},{3, 1}},0x0000000000041046L,1,false,6,1,7)
+                       };
+
+     private static final Shape[] PIECE3 = { new Shape ('3',new int[][] {{0, 0},{2, 0},{1,-1},{2,-2},{2,-4}},0x0000000000003884L,2,false,7,4,9),
+                     new Shape ('3',new int[][] {{1, 5},{2, 2},{1, 3},{1, 1},{0, 0}},0x00000000000011C1L,0,false,7,0,4),
+                     new Shape ('3',new int[][] {{3, 1},{2,-2},{2, 0},{1,-1},{0, 0}},0x0000000000041842L,1,false,6,2,8),
+                     new Shape ('3',new int[][] {{2, 0},{0, 0},{1, 1},{0, 2},{0, 4}},0x0000000000000847L,0,false,7,0,5),
+                     new Shape ('3',new int[][] {{1,-3},{0, 0},{1,-1},{1, 1},{2, 2}},0x00000000000041C4L,2,false,7,3,7),
+                     new Shape ('3',new int[][] {{0, 0},{1, 3},{1, 1},{2, 2},{3, 1}},0x00000000000210C1L,0,true, 6,0,6),
+                     new Shape ('3',new int[][] {{1, 3},{0, 0},{1, 1},{1,-1},{2,-2}},0x00000000000009C2L,1,false,7,2,6),
+                     new Shape ('3',new int[][] {{2, 4},{0, 4},{1, 3},{0, 2},{0, 0}},0x0000000000002087L,0,false,7,0,5),
+                     new Shape ('3',new int[][] {{3,-1},{2, 2},{2, 0},{1, 1},{0, 0}},0x0000000000023082L,1,false,6,1,7),
+                     new Shape ('3',new int[][] {{1,-5},{2,-2},{1,-3},{1,-1},{0, 0}},0x00000000000021C8L,3,false,7,5,9),
+                     new Shape ('3',new int[][] {{0, 0},{2, 0},{1, 1},{2, 2},{2, 4}},0x0000000000003841L,0,false,7,0,5),
+                     new Shape ('3',new int[][] {{0, 0},{1,-3},{1,-1},{2,-2},{3,-1}},0x00000000000410C4L,2,false,6,3,9)
+                       };
+
+     private static final Shape[] PIECE4 = { new Shape ('4',new int[][] {{1, 5},{2, 2},{1, 3},{0, 2},{0, 0}},0x0000000000001183L,0,false,7,0,4),
+                     new Shape ('4',new int[][] {{3, 1},{2,-2},{2, 0},{1, 1},{0, 0}},0x0000000000041882L,1,false,6,2,8),
+                     new Shape ('4',new int[][] {{2, 0},{0, 0},{1, 1},{1, 3},{0, 4}},0x00000000000008C5L,0,true, 7,0,5),
+                     new Shape ('4',new int[][] {{1,-3},{0, 0},{1,-1},{2, 0},{2, 2}},0x00000000000060C4L,2,false,7,3,7),
+                     new Shape ('4',new int[][] {{0, 0},{1, 3},{1, 1},{2, 0},{3, 1}},0x00000000000208C1L,0,false,6,0,6),
+                     new Shape ('4',new int[][] {{0, 0},{2, 0},{1,-1},{1,-3},{2,-4}},0x00000000000028C4L,2,false,7,4,9),
+                     new Shape ('4',new int[][] {{0, 0},{1,-3},{1,-1},{2, 0},{3,-1}},0x00000000000420C4L,2,false,6,3,9),
+                     new Shape ('4',new int[][] {{1, 3},{0, 0},{1, 1},{2, 0},{2,-2}},0x0000000000001982L,1,false,7,2,6),
+                     new Shape ('4',new int[][] {{2, 4},{0, 4},{1, 3},{1, 1},{0, 0}},0x00000000000020C5L,0,true, 7,0,5),
+                     new Shape ('4',new int[][] {{3,-1},{2, 2},{2, 0},{1,-1},{0, 0}},0x0000000000023042L,1,false,6,1,7),
+                     new Shape ('4',new int[][] {{1,-3},{2, 0},{1,-1},{0, 0},{0, 2}},0x00000000000020CCL,2,false,7,3,7),
+                     new Shape ('4',new int[][] {{0, 0},{2, 0},{1, 1},{1, 3},{2, 4}},0x00000000000028C1L,0,false,7,0,5)
+                       };
+
+     private static final Shape[] PIECE5 = { new Shape ('5',new int[][] {{0, 2},{1, 1},{0, 0},{1,-1},{2,-2}},0x00000000000008C6L,1,false,7,2,7),
+                     new Shape ('5',new int[][] {{1, 5},{1, 3},{0, 4},{0, 2},{0, 0}},0x0000000000000187L,0,false,8,0,4),
+                     new Shape ('5',new int[][] {{3, 1},{2, 0},{2, 2},{1, 1},{0, 0}},0x0000000000021841L,0,false,6,0,7),
+                     new Shape ('5',new int[][] {{2,-4},{1,-3},{2,-2},{1,-1},{0, 0}},0x00000000000018C4L,2,false,7,4,9),
+                     new Shape ('5',new int[][] {{0, 0},{0, 2},{1, 1},{1, 3},{1, 5}},0x00000000000001C3L,0,false,8,0,4),
+                     new Shape ('5',new int[][] {{0, 0},{1, 1},{1,-1},{2, 0},{3, 1}},0x00000000000410C2L,1,false,6,1,8),
+                     new Shape ('5',new int[][] {{0, 2},{0, 0},{1, 1},{1,-1},{1,-3}},0x00000000000001CCL,2,false,8,3,7),
+                     new Shape ('5',new int[][] {{2, 4},{1, 3},{2, 2},{1, 1},{0, 0}},0x00000000000030C1L,0,false,7,0,5),
+                     new Shape ('5',new int[][] {{3,-1},{2, 0},{2,-2},{1,-1},{0, 0}},0x0000000000021842L,1,false,6,2,9),
+                     new Shape ('5',new int[][] {{1,-1},{1, 1},{0, 0},{0, 2},{0, 4}},0x00000000000000CEL,1,false,8,1,5),
+                     new Shape ('5',new int[][] {{0, 0},{1, 1},{0, 2},{1, 3},{2, 4}},0x00000000000020C3L,0,false,7,0,5),
+                     new Shape ('5',new int[][] {{0, 0},{1,-1},{1, 1},{2, 0},{3,-1}},0x00000000000210C2L,1,false,6,1,8)
+                       };
+
+     private static final Shape[] PIECE6 = { new Shape ('6',new int[][] {{1, 1},{0, 0},{1,-1},{1,-3},{2,-4}},0x00000000000009C4L,2,false,7,4,8),
+                     new Shape ('6',new int[][] {{2, 4},{1, 5},{1, 3},{0, 2},{0, 0}},0x0000000000002183L,0,false,7,0,4),
+                     new Shape ('6',new int[][] {{3,-1},{3, 1},{2, 0},{1, 1},{0, 0}},0x0000000000061082L,1,false,6,1,8),
+                     new Shape ('6',new int[][] {{1,-5},{2,-4},{1,-3},{1,-1},{0, 0}},0x00000000000011C8L,3,false,7,5,9),
+                     new Shape ('6',new int[][] {{0, 0},{1,-1},{1, 1},{2, 2},{2, 4}},0x00000000000060C2L,1,false,7,1,5),
+                     new Shape ('6',new int[][] {{0, 2},{0, 0},{1, 1},{2, 0},{3, 1}},0x0000000000020843L,0,false,6,0,7),
+                     new Shape ('6',new int[][] {{0, 0},{1, 1},{1,-1},{2,-2},{2,-4}},0x0000000000001984L,2,false,7,4,8),
+                     new Shape ('6',new int[][] {{1, 5},{2, 4},{1, 3},{1, 1},{0, 0}},0x00000000000021C1L,0,false,7,0,4),
+                     new Shape ('6',new int[][] {{3, 1},{3,-1},{2, 0},{1,-1},{0, 0}},0x0000000000061042L,1,false,6,1,8),
+                     new Shape ('6',new int[][] {{2,-2},{1,-3},{1,-1},{0, 0},{0, 2}},0x00000000000010CCL,2,false,7,3,7),
+                     new Shape ('6',new int[][] {{1,-1},{0, 0},{1, 1},{1, 3},{2, 4}},0x00000000000041C2L,1,false,7,1,5),
+                     new Shape ('6',new int[][] {{0, 0},{0, 2},{1, 1},{2, 2},{3, 1}},0x0000000000021043L,0,false,6,0,7)
+                       };
+
+     private static final Shape[] PIECE7 = { new Shape ('7',new int[][] {{0, 2},{1, 1},{0, 0},{2, 0},{2,-2}},0x0000000000001886L,1,false,7,2,7),
+                     new Shape ('7',new int[][] {{1, 5},{1, 3},{0, 4},{1, 1},{0, 0}},0x00000000000001C5L,0,true, 8,0,4),
+                     new Shape ('7',new int[][] {{3, 1},{2, 0},{2, 2},{1,-1},{0, 0}},0x0000000000043042L,1,false,6,1,7),
+                     new Shape ('7',new int[][] {{2,-2},{1,-1},{2, 0},{0, 0},{0, 2}},0x0000000000001846L,1,false,7,2,7),
+                     new Shape ('7',new int[][] {{0, 0},{0, 2},{1, 1},{0, 4},{1, 5}},0x0000000000000147L,0,false,8,0,4),
+                     new Shape ('7',new int[][] {{0, 0},{1, 1},{1,-1},{2, 2},{3, 1}},0x00000000000420C2L,1,false,6,1,7),
+                     new Shape ('7',new int[][] {{0, 4},{0, 2},{1, 3},{0, 0},{1,-1}},0x000000000000014EL,1,false,8,1,5),
+                     new Shape ('7',new int[][] {{2, 4},{1, 3},{2, 2},{0, 2},{0, 0}},0x0000000000003083L,0,false,7,0,5),
+                     new Shape ('7',new int[][] {{3,-1},{2, 0},{2,-2},{1, 1},{0, 0}},0x0000000000021882L,1,false,6,2,8),
+                     new Shape ('7',new int[][] {{1,-1},{1, 1},{0, 0},{1, 3},{0, 4}},0x00000000000001CAL,1,false,8,1,5),
+                     new Shape ('7',new int[][] {{0, 0},{1, 1},{0, 2},{2, 2},{2, 4}},0x0000000000003043L,0,false,7,0,5),
+                     new Shape ('7',new int[][] {{0, 0},{1,-1},{1, 1},{2,-2},{3,-1}},0x00000000000208C2L,1,false,6,2,8)
+                       };
+
+     private static final Shape[] PIECE8 = { new Shape ('8',new int[][] {{4, 2},{3, 1},{2, 0},{1, 1},{0, 0}},0x0000000000820841L,0,false,5,0,7),
+                     new Shape ('8',new int[][] {{3,-5},{2,-4},{1,-3},{1,-1},{0, 0}},0x0000000000021188L,3,false,6,5,9),
+                     new Shape ('8',new int[][] {{0, 0},{0, 2},{0, 4},{1, 5},{1, 7}},0x0000000000000307L,0,false,8,0,2),
+                     new Shape ('8',new int[][] {{0, 0},{1, 1},{2, 2},{3, 1},{4, 2}},0x0000000000821041L,0,true, 5,0,7),
+                     new Shape ('8',new int[][] {{0, 0},{1,-1},{2,-2},{2,-4},{3,-5}},0x0000000000023108L,3,false,6,5,9),
+                     new Shape ('8',new int[][] {{1, 7},{1, 5},{1, 3},{0, 2},{0, 0}},0x0000000000000383L,0,false,8,0,2),
+                     new Shape ('8',new int[][] {{0, 0},{1, 1},{2, 2},{2, 4},{3, 5}},0x0000000000083041L,0,false,6,0,4),
+                     new Shape ('8',new int[][] {{0, 0},{1,-1},{2,-2},{3,-1},{4,-2}},0x0000000000420842L,1,false,5,2,9),
+                     new Shape ('8',new int[][] {{0, 4},{0, 2},{0, 0},{1,-1},{1,-3}},0x00000000000000DCL,2,false,8,3,5),
+                     new Shape ('8',new int[][] {{3, 5},{2, 4},{1, 3},{1, 1},{0, 0}},0x00000000000820C1L,0,false,6,0,4),
+                     new Shape ('8',new int[][] {{4,-2},{3,-1},{2, 0},{1,-1},{0, 0}},0x0000000000421042L,1,false,5,2,9),
+                     new Shape ('8',new int[][] {{1,-5},{1,-3},{1,-1},{0, 0},{0, 2}},0x00000000000001D8L,3,false,8,5,7)
+                       };
+
+     private static final Shape[] PIECE9 = { new Shape ('9',new int[][] {{3, 3},{2, 2},{1, 1},{0, 0},{0, 2}},0x0000000000041043L,0,false,6,0,6),
+                     new Shape ('9',new int[][] {{3,-3},{2,-2},{1,-1},{0, 0},{1, 1}},0x0000000000021184L,2,false,6,3,8),
+                     new Shape ('9',new int[][] {{0, 0},{0, 2},{0, 4},{0, 6},{1, 5}},0x000000000000010FL,0,false,8,0,3),
+                     new Shape ('9',new int[][] {{0, 0},{1, 1},{2, 2},{3, 3},{3, 1}},0x0000000000061041L,0,true, 6,0,6),
+                     new Shape ('9',new int[][] {{0, 0},{1,-1},{2,-2},{3,-3},{2,-4}},0x0000000000021884L,2,false,6,4,9),
+                     new Shape ('9',new int[][] {{1, 5},{1, 3},{1, 1},{1,-1},{0, 0}},0x00000000000003C2L,1,false,8,1,4),
+                     new Shape ('9',new int[][] {{0, 0},{1, 1},{2, 2},{3, 3},{2, 4}},0x0000000000043041L,0,false,6,0,5),
+                     new Shape ('9',new int[][] {{0, 0},{1,-1},{2,-2},{3,-3},{3,-1}},0x0000000000061084L,2,false,6,3,9),
+                     new Shape ('9',new int[][] {{0, 6},{0, 4},{0, 2},{0, 0},{1, 1}},0x000000000000004FL,0,false,8,0,3),
+                     new Shape ('9',new int[][] {{3, 3},{2, 2},{1, 1},{0, 0},{1,-1}},0x00000000000820C2L,1,false,6,1,6),
+                     new Shape ('9',new int[][] {{3,-1},{2, 0},{1, 1},{0, 2},{0, 0}},0x0000000000021086L,1,false,6,1,7),
+                     new Shape ('9',new int[][] {{1,-5},{1,-3},{1,-1},{1, 1},{0, 0}},0x00000000000003C8L,3,false,8,5,8)
+                       };
+                       
+    }