Moved compile_command() here from code.py, so JPython can provide its
own version.
diff --git a/Lib/codeop.py b/Lib/codeop.py
new file mode 100644
index 0000000..080e00b
--- /dev/null
+++ b/Lib/codeop.py
@@ -0,0 +1,86 @@
+"""Utility to compile possibly incomplete Python source code."""
+
+import sys
+import string
+import traceback
+
+def compile_command(source, filename="<input>", symbol="single"):
+    r"""Compile a command and determine whether it is incomplete.
+
+    Arguments:
+
+    source -- the source string; may contain \n characters
+    filename -- optional filename from which source was read; default "<input>"
+    symbol -- optional grammar start symbol; "single" (default) or "eval"
+
+    Return value / exceptions raised:
+
+    - Return a code object if the command is complete and valid
+    - Return None if the command is incomplete
+    - Raise SyntaxError or OverflowError if the command is a syntax error
+      (OverflowError if the error is in a numeric constant)
+
+    Approach:
+
+    First, check if the source consists entirely of blank lines and
+    comments; if so, replace it with 'pass', because the built-in
+    parser doesn't always do the right thing for these.
+
+    Compile three times: as is, with \n, and with \n\n appended.  If
+    it compiles as is, it's complete.  If it compiles with one \n
+    appended, we expect more.  If it doesn't compile either way, we
+    compare the error we get when compiling with \n or \n\n appended.
+    If the errors are the same, the code is broken.  But if the errors
+    are different, we expect more.  Not intuitive; not even guaranteed
+    to hold in future releases; but this matches the compiler's
+    behavior from Python 1.4 through 1.5.2, at least.
+
+    Caveat:
+
+    It is possible (but not likely) that the parser stops parsing
+    with a successful outcome before reaching the end of the source;
+    in this case, trailing symbols may be ignored instead of causing an
+    error.  For example, a backslash followed by two newlines may be
+    followed by arbitrary garbage.  This will be fixed once the API
+    for the parser is better.
+
+    """
+
+    # Check for source consisting of only blank lines and comments
+    for line in string.split(source, "\n"):
+        line = string.strip(line)
+        if line and line[0] != '#':
+            break               # Leave it alone
+    else:
+        source = "pass"         # Replace it with a 'pass' statement
+
+    err = err1 = err2 = None
+    code = code1 = code2 = None
+
+    try:
+        code = compile(source, filename, symbol)
+    except SyntaxError, err:
+        pass
+
+    try:
+        code1 = compile(source + "\n", filename, symbol)
+    except SyntaxError, err1:
+        pass
+
+    try:
+        code2 = compile(source + "\n\n", filename, symbol)
+    except SyntaxError, err2:
+        pass
+
+    if code:
+        return code
+    try:
+        e1 = err1.__dict__
+    except AttributeError:
+        e1 = err1
+    try:
+        e2 = err2.__dict__
+    except AttributeError:
+        e2 = err2
+    if not code1 and e1 == e2:
+        raise SyntaxError, err1