Index: src/java/org/apache/log/util/StackIntrospector.java
===================================================================
RCS file: /home/cvspublic/jakarta-avalon-logkit/src/java/org/apache/log/util/StackIntrospector.java,v
retrieving revision 1.1
diff -u -r1.1 StackIntrospector.java
--- src/java/org/apache/log/util/StackIntrospector.java	2001/07/26 13:16:03	1.1
+++ src/java/org/apache/log/util/StackIntrospector.java	2001/08/13 18:22:46
@@ -177,4 +177,96 @@
 
         return "";
     }
+
+
+    /**
+     * Return the current call stack as a String, starting with the first call
+     * in the stack after a reference to the <code>clazz</code> class, and then
+     * display <code>entries</code> entries.
+     *
+     * <p>This can be useful for debugging code to determine where calls to a
+     * method are coming from.</p>
+     *
+     * @param clazz the last class on the stack you are <i>not</i> interested in!
+     * @param entries the number of stack lines to return.
+     *
+     * @returns The method path name in the form "the.package.path.Method"
+     */
+    public final static String getRecentStack( final Class clazz, int entries ) 
+    {
+        final String className = clazz.getName();
+
+        //Extract stack into a StringBuffer
+        final StringWriter sw = new StringWriter();
+        final Throwable throwable = new Throwable();
+        throwable.printStackTrace( new PrintWriter( sw, true ) );
+        final StringBuffer buffer = sw.getBuffer();
+
+        //Cache vars used in loop 
+        final StringBuffer line = new StringBuffer();
+        final StringBuffer stack = new StringBuffer();
+        final int length = buffer.length();
+
+        //setup state
+        boolean found = false;
+        int state = 0;
+
+        //parse line
+        for( int i = 0; i < length; i++ )
+        {
+            final char ch = buffer.charAt( i );
+
+            switch( state ) 
+            {
+            case 0:
+                //Strip the first line from input
+                if( '\n' == ch ) state = 1;
+                break;
+
+            case 1:
+                //strip 't' from 'at'
+                if( 't' == ch ) state = 2;
+                break;
+
+            case 2:
+                //Strip space after 'at'
+                line.setLength( 0 );
+                state = 3;
+                break;
+
+            case 3:
+                //accumulate all characters to end of line
+                if( '\n' != ch ) line.append( ch );
+                else
+                {
+                    //At this stage you have the line that looks like
+                    //com.biz.SomeClass.someMethod(SomeClass.java:22)
+                    final String method = line.toString();
+                    
+                    ///Determine if line is a match for class
+                    final boolean match = method.startsWith( className );
+                    if( !found && match )
+                    {
+                        //If this is the first time we cound class then 
+                        //set found to true and look for caller into class
+                        found = true;
+                    }
+                    else if( found && !match )
+                    {
+                        //We are looking at the callers of Clazz
+                        stack.append(method);
+                        entries--;
+                        if (entries == 0) return stack.toString();
+                        stack.append("\n");
+                    }
+                    
+                    //start parsing from start of line again
+                    state = 1;
+                }
+            }
+        }
+
+        return "";
+    }
 }
+
