diff --git a/CHANGES b/CHANGES
index 91bd57a2b50dcdd2c0c4b1a1703d18f64a1df1fe..956942e178d605f09ca6e63b2e9cc1907935f191 100644
--- a/CHANGES
+++ b/CHANGES
@@ -7,6 +7,7 @@ either one "#" sign or two for now; two is preferred going forward, i.e.
 ## coding:<someencoding>. 
 - a new multiline comment form of [PICK ONE:]"#* a comment *#"/"<%doc> a comment </%doc>"
 - UNDEFINED evaluates to False
+- improvement to scoping of "caller" variable when using <%call> tag
 
 0.1.2
 - fix to parsing of code/expression blocks to insure that non-ascii
diff --git a/lib/mako/codegen.py b/lib/mako/codegen.py
index 477ccadd98cac5581ead03429bef0d01ba94647d..285e3927efb88800fd383ff256c0ad4a21e6f700 100644
--- a/lib/mako/codegen.py
+++ b/lib/mako/codegen.py
@@ -523,14 +523,15 @@ class _GenerateRenderMethod(object):
 
         self.printer.writelines(
             # push on global "caller" to be picked up by the next ccall
-            "context.caller_stack.append(runtime.Namespace('caller', context, callables=ccall(context.caller_stack[-1])))",
+            "caller = context['caller']._get_actual_caller()",
+            "context.push_caller(runtime.Namespace('caller', context, callables=ccall(runtime._StackFacade(context, caller))))",
             "try:")
         self.write_source_comment(node)
         self.printer.writelines(
                 "context.write(unicode(%s))" % node.attributes['expr'],
             "finally:",
                 # pop it off
-                "context.caller_stack.pop()",
+                "context.pop_caller()",
             None
         )
 
diff --git a/lib/mako/runtime.py b/lib/mako/runtime.py
index 20748b9e41dbf87c547cfe5e7ab020ba6cc4b0d4..e6e640b85519a0a42ae2d092a245135678b5f1b7 100644
--- a/lib/mako/runtime.py
+++ b/lib/mako/runtime.py
@@ -23,9 +23,13 @@ class Context(object):
         
         # "caller" stack used by def calls with content
         self.caller_stack = [Undefined]
-        data['caller'] = _StackFacade(self.caller_stack)
+        data['caller'] = _StackFacade(self, None)
     lookup = property(lambda self:self._with_template.lookup)
     kwargs = property(lambda self:self._kwargs.copy())
+    def push_caller(self, caller):
+        self.caller_stack.append(caller)
+    def pop_caller(self):
+        del self.caller_stack[-1]
     def keys(self):
         return self._data.keys()
     def __getitem__(self, key):
@@ -67,10 +71,26 @@ class Context(object):
         return c
 
 class _StackFacade(object):
-    def __init__(self, stack):
-        self.target = stack
+    def __init__(self, context, local):
+        self.__stack = context.caller_stack
+        self.__local = local
+    def _get_actual_caller(self):
+        caller = self.__stack[-1]
+        if caller is None:
+            return self.__local
+        else:
+            return caller
     def __getattr__(self, key):
-        return getattr(self.target[-1], key)
+        caller = self._get_actual_caller()
+        callable_ = getattr(caller, key)
+        def call_wno_caller(*args, **kwargs):
+            try:
+                self.__stack.append(None)
+                return callable_(*args, **kwargs)
+            finally:
+                self.__stack.pop()
+        return call_wno_caller
+        
         
 class Undefined(object):
     """represents an undefined value in a template."""
diff --git a/test/call.py b/test/call.py
index 28d8656eff657ecf114ddee10c450229e91b9f38..41fc27ce968bcd63a2dac350da98a97f6daf1205 100644
--- a/test/call.py
+++ b/test/call.py
@@ -58,7 +58,33 @@ class CallTest(unittest.TestCase):
             self.test_compound_call()
         finally:
             util.Set = oldset
-            
+   
+    def test_ccall_caller(self):
+        t = Template("""
+        <%def name="outer_func()">
+        OUTER BEGIN
+            <%call expr="caller.inner_func()">
+                INNER CALL
+            </%call>
+        OUTER END
+        </%def>
+
+        <%call expr="outer_func()">
+            <%def name="inner_func()">
+                INNER BEGIN
+                ${caller.body()}
+                INNER END
+            </%def>
+        </%call>
+
+        """)
+        assert result_lines(t.render()) == [
+            "OUTER BEGIN",
+            "INNER BEGIN",
+            "INNER CALL",
+            "INNER END",
+            "OUTER END",
+        ]
     def test_chained_call(self):
         """test %calls that are chained through their targets"""
         t = Template("""
@@ -167,6 +193,8 @@ class CallTest(unittest.TestCase):
             </%def>
             ${embedded()}
 """)
+        #print t.code
+        #print result_lines(t.render())
         assert result_lines(t.render()) == [
             'this is a.',
             'this is b. heres my body:',