Index: src/org/jruby/Ruby.java
===================================================================
RCS file: /cvsroot/jruby/jruby/src/org/jruby/Ruby.java,v
retrieving revision 1.67.2.3
diff -u -r1.67.2.3 Ruby.java
--- src/org/jruby/Ruby.java	6 Jan 2006 00:44:21 -0000	1.67.2.3
+++ src/org/jruby/Ruby.java	22 Jan 2006 10:04:59 -0000
@@ -407,6 +407,7 @@
         objectClass.defineConstant("NIL", getNil());
         
         // Pre-create the core classes we know we will get referenced by starting up the runtime.
+        RubyBinding.createBindingModule(this);
         RubyBoolean.createFalseClass(this);
         RubyBoolean.createTrueClass(this);
         RubyComparable.createComparable(this);
Index: src/org/jruby/RubyKernel.java
===================================================================
RCS file: /cvsroot/jruby/jruby/src/org/jruby/RubyKernel.java,v
retrieving revision 1.11.2.1
diff -u -r1.11.2.1 RubyKernel.java
--- src/org/jruby/RubyKernel.java	2 Jan 2006 07:07:09 -0000	1.11.2.1
+++ src/org/jruby/RubyKernel.java	22 Jan 2006 10:05:00 -0000
@@ -72,7 +72,7 @@
         module.defineModuleFunction("at_exit", callbackFactory.getSingletonMethod("at_exit"));
         module.defineModuleFunction("autoload", callbackFactory.getSingletonMethod("autoload", IRubyObject.class, IRubyObject.class));
         // TODO: Implement Kernel#autoload?
-        // TODO: Implement Kernel#binding
+        module.defineModuleFunction("binding", callbackFactory.getSingletonMethod("binding"));
         module.defineModuleFunction("block_given?", callbackFactory.getSingletonMethod("block_given"));
         // TODO: Implement Kernel#callcc
         module.defineModuleFunction("caller", callbackFactory.getOptSingletonMethod("caller"));
@@ -459,6 +459,10 @@
         return localVariables;
     }
 
+    public static RubyBinding binding(IRubyObject recv) {
+        return new RubyBinding(recv.getRuntime(), recv.getRuntime().getCurrentContext().createBinding());
+    }
+
     public static RubyBoolean block_given(IRubyObject recv) {
         return recv.getRuntime().newBoolean(recv.getRuntime().getCurrentContext().isFBlockGiven());
     }
Index: src/org/jruby/RubyObject.java
===================================================================
RCS file: /cvsroot/jruby/jruby/src/org/jruby/RubyObject.java,v
retrieving revision 1.50.2.2
diff -u -r1.50.2.2 RubyObject.java
--- src/org/jruby/RubyObject.java	2 Jan 2006 07:42:27 -0000	1.50.2.2
+++ src/org/jruby/RubyObject.java	22 Jan 2006 10:05:00 -0000
@@ -622,6 +622,7 @@
 
         ISourcePosition savedPosition = threadContext.getPosition();
         Iter iter = threadContext.getCurrentFrame().getIter();
+        ThreadContext oldBinding = null;
         if (file == null) {
             file = threadContext.getSourceFile();
         }
@@ -629,6 +630,10 @@
             if (threadContext.getPreviousFrame() != null) {
                 threadContext.getCurrentFrame().setIter(threadContext.getPreviousFrame().getIter());
             }
+        } else if (scope instanceof RubyBinding) {
+            oldBinding = threadContext.swapContext(((RubyBinding)scope).getContext());
+        } else {
+            throw getRuntime().newTypeError(getRuntime().getClass("String"), getRuntime().getClass("Binding"));
         }
         IRubyObject result = getRuntime().getNil();
         try {
@@ -636,6 +641,8 @@
         } finally {
             if (scope.isNil()) {
                 threadContext.getCurrentFrame().setIter(iter);
+            } else if (oldBinding != null) {
+                threadContext.swapContext(oldBinding);
             }
             threadContext.setPosition(savedPosition);
 			threadContext.popRubyClass();
Index: src/org/jruby/internal/runtime/ThreadService.java
===================================================================
RCS file: /cvsroot/jruby/jruby/src/org/jruby/internal/runtime/ThreadService.java,v
retrieving revision 1.7.2.1
diff -u -r1.7.2.1 ThreadService.java
--- src/org/jruby/internal/runtime/ThreadService.java	2 Jan 2006 07:07:13 -0000	1.7.2.1
+++ src/org/jruby/internal/runtime/ThreadService.java	22 Jan 2006 10:05:00 -0000
@@ -65,6 +65,10 @@
         return (ThreadContext) localContext.get();
     }
 
+    public void setCurrentContext(ThreadContext tc) {
+        localContext.set(tc);
+    }
+
     public RubyThread getMainThread() {
         return mainContext.getThread();
     }
Index: src/org/jruby/runtime/ThreadContext.java
===================================================================
RCS file: /cvsroot/jruby/jruby/src/org/jruby/runtime/ThreadContext.java,v
retrieving revision 1.44.2.5
diff -u -r1.44.2.5 ThreadContext.java
--- src/org/jruby/runtime/ThreadContext.java	14 Jan 2006 15:40:09 -0000	1.44.2.5
+++ src/org/jruby/runtime/ThreadContext.java	22 Jan 2006 10:05:01 -0000
@@ -89,9 +89,42 @@
         pushDynamicVars();
     }
     
+    private ThreadContext(ThreadContext tc) {
+        this.runtime = tc.runtime;
+        
+        // BlockStack does not support clone yet
+        //this.blockStack = (BlockStack)tc.blockStack.clone();
+        this.blockStack = new BlockStack();
+        this.dynamicVarsStack = (Stack)tc.dynamicVarsStack.clone();
+        this.frameStack = (Stack)tc.frameStack.clone();
+        this.iterStack = (Stack)tc.iterStack.clone();
+        this.parentStack = (Stack)tc.parentStack.clone();
+        
+        this.wrapper = tc.wrapper;
+        this.thread = tc.thread;
+        this.sourcePosition = tc.sourcePosition;
+        
+        // escape from items pushed for binding()
+        postReflectedMethodInternalCall();
+    }
+    
     Visibility lastVis;
     CallType lastCallType;
     
+    public ThreadContext createBinding() {
+        return (ThreadContext)clone();
+    }
+    
+    public Object clone() {
+        return new ThreadContext(this);
+    }
+    
+    public ThreadContext swapContext(ThreadContext tc) {
+        runtime.getThreadService().setCurrentContext(tc);
+        
+        return this;
+    }
+    
     public IRuby getRuntime() {
         return runtime;
     }
Index: src/org/jruby/RubyBinding.java
===================================================================
RCS file: src/org/jruby/RubyBinding.java
diff -N src/org/jruby/RubyBinding.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/jruby/RubyBinding.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,56 @@
+/***** BEGIN LICENSE BLOCK *****
+ * Version: CPL 1.0/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Common Public
+ * License Version 1.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.eclipse.org/legal/cpl-v10.html
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * Copyright (C) 2006 Charles O Nutter <headius@headius.com>
+ * 
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the CPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the CPL, the GPL or the LGPL.
+ ***** END LICENSE BLOCK *****/
+package org.jruby;
+
+import org.jruby.runtime.ThreadContext;
+
+public class RubyBinding extends RubyObject {
+    private ThreadContext context;
+    
+    public RubyBinding(IRuby runtime, ThreadContext context) {
+        super(runtime, runtime.getClass("Binding"));
+        
+        this.context = context;
+    }
+    
+    /** Create the Math module and add it to the Ruby runtime.
+     * 
+     */
+    public static RubyModule createBindingModule(IRuby runtime) {
+        RubyModule result = runtime.defineClass("Binding", runtime.getObject());
+        
+        result.undefineMethod("initialize");
+        result.undefineMethod("new");
+        
+        return result;
+    }
+    
+    public ThreadContext getContext() {
+        return context;
+    }
+}
