Index: XmlRpcListableHandlerMapping.java
===================================================================
--- XmlRpcListableHandlerMapping.java	(revision 0)
+++ XmlRpcListableHandlerMapping.java	(revision 0)
@@ -0,0 +1,36 @@
+/*
+ * Copyright 1999,2005 The Apache Software Foundation.
+ * 
+ * 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.xmlrpc;
+
+/**
+ * Maps from a handler name to a handler object, and allows listing registered handler
+ * names.
+ *
+ * @author <a href="mailto:Walter.Mundt@coleengineering.com">Walter Mundt</a>
+ */
+public interface XmlRpcListableHandlerMapping extends XmlRpcHandlerMapping
+{
+  /**
+   * Return an enumeration of registered handler names.  The returned Enumeration
+   * may be empty, but if it is not it will consist solely of String objects.
+   *
+   * @return java.util.Enumeration an enumeration of handler names.
+   */
+  public java.util.Enumeration getRegisteredHandlers();
+}
+
Index: IntrospectiveXmlRpcHandler.java
===================================================================
--- IntrospectiveXmlRpcHandler.java	(revision 0)
+++ IntrospectiveXmlRpcHandler.java	(revision 0)
@@ -0,0 +1,68 @@
+/* XmlRpcIntrospectiveHandler.java - Part of Java XML-RPC introspection.
+ * Copyright 2001 Eric Kidd
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+package org.apache.xmlrpc;
+
+import java.util.Vector;
+
+/**
+ * The XML-RPC server uses this interface to perform introspection.  If
+ * your handler class implements this interface, users will be able to
+ * automatically generate documentation and/or proxy classes from your
+ * server.
+ */
+public interface IntrospectiveXmlRpcHandler
+{
+    /**
+     * Return a vector of strings, listing the unique method names
+     * supported by this object.  The handler name should not be
+     * included; this will be added automatically by the server.
+     * @return Unique method names supported by this object.
+     */
+    public Vector listMethods () throws XmlRpcException;
+
+    /**
+     * Return a vector of vectors of strings, containing method signatures
+     * of the form documented at the <a
+     * href="http://xmlrpc.usefulinc.com/doc/sysmethodsig.html">PHP
+     * introspection page</a>.
+     * @param methodName The bare method name, not including the handler
+     * name.
+     * @return The allowable signatures for this method.
+     */
+    public Vector methodSignature (String methodName) throws XmlRpcException;
+
+    /**
+     * Return a help string for the specified message.  This <em>may</em>
+     * contain HTML markup, but it's usually better to return a single,
+     * long line of ASCII text.
+     * @param methodName The bare method name, not including the handler
+     * name.
+     * @return A help string.
+     */
+    public String methodHelp (String methodName) throws XmlRpcException;
+}
Index: IntrospectiveInvoker.java
===================================================================
--- IntrospectiveInvoker.java	(revision 0)
+++ IntrospectiveInvoker.java	(revision 0)
@@ -0,0 +1,207 @@
+/*
+ * Copyright 1999,2005 The Apache Software Foundation.
+ * 
+ * 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.xmlrpc;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+/**
+ * Uses Java introspection to implement XML-RPC introspection.
+ *
+ * @author <a href="mailto:Walter.Mundt@coleengineering.com">Walter Mundt</a>
+ */
+public class IntrospectiveInvoker extends Invoker implements IntrospectiveXmlRpcHandler
+{
+    private static Hashtable xmlRpcTypeMap;
+
+    static
+    {
+	xmlRpcTypeMap = new Hashtable();
+	xmlRpcTypeMap.put(Integer.TYPE, "int");
+	xmlRpcTypeMap.put(Integer.class, "int");
+	xmlRpcTypeMap.put(String.class,"string");
+        xmlRpcTypeMap.put(Vector.class, "array");
+        xmlRpcTypeMap.put(Hashtable.class, "struct");
+        xmlRpcTypeMap.put(Boolean.TYPE, "boolean");
+        xmlRpcTypeMap.put(Boolean.class, "boolean");
+        xmlRpcTypeMap.put(Double.TYPE, "double");
+        xmlRpcTypeMap.put(Double.class, "double");
+        xmlRpcTypeMap.put(Date.class, "dateTime.iso8601");
+	try
+	{
+	    xmlRpcTypeMap.put(Class.forName("byte[]"), "base64");
+	}
+	catch (ClassNotFoundException cnf_e) {} // won't actually happen
+    }
+
+    public IntrospectiveInvoker(Object target)
+    {
+	super(target);
+    }
+
+    /**
+     * Return whether a method's signature is XML-RPC compatible.
+     */
+    private boolean isXmlRpcCompatible(Method method)
+    {
+	if (!Modifier.isPublic(method.getModifiers()))
+	{
+	    return false;
+	}
+
+	if (method.getDeclaringClass() == Object.class)
+	{
+	    return false;
+	}
+	
+	if (!xmlRpcTypeMap.containsKey(method.getReturnType()))
+	{
+	    return false;
+	}
+	
+	Class[] parameterTypes = method.getParameterTypes();
+	for (int i = 0; i < parameterTypes.length; i++) {
+	    if (!xmlRpcTypeMap.containsKey(parameterTypes[i]))
+	    {
+		return false;
+	    }
+	}
+	return true;
+    }
+
+    /**
+     * Return whether any method with the given name is XML-RPC compatible.
+     */
+    private boolean isXmlRpcCompatible(String methodName)
+    {
+        Method[] methodObjects = getTargetClass().getMethods();
+
+        for (int i = 0; i < methodObjects.length; i++) {
+            if (methodObjects[i].getName().equals(methodName)
+                && isXmlRpcCompatible(methodObjects[i]))
+            {
+		return true;
+            }
+        }
+
+	return false;
+    }
+
+    /** 
+     * Return a vector of strings listing the unique method names.
+     */
+    public Vector listMethods()
+    {
+	Method[] methodObjects = getTargetClass().getMethods();
+
+        // Find the unique method names exported by this class.
+        Hashtable methodNameTable = new Hashtable();
+        for (int i = 0; i < methodObjects.length; i++)
+	{
+            if (isXmlRpcCompatible(methodObjects[i]))
+	    {
+                methodNameTable.put(methodObjects[i].getName(), "");
+            }
+        }
+
+        // Build and return a vector.
+        Vector names = new Vector();
+        Enumeration keys = methodNameTable.keys();
+        while (keys.hasMoreElements())
+	{
+            String methodName = (String) keys.nextElement();
+            names.addElement(methodName);
+        }
+        return names;
+    }
+ 
+    /** 
+     * Find the introspection name for a type.
+     */
+    private static String findTypeName(Class type) throws XmlRpcException
+    {
+	String xmlRpcType = (String)xmlRpcTypeMap.get(type);
+	if (xmlRpcType != null)
+	{
+	    return xmlRpcType;
+	}
+
+	throw new XmlRpcException(-32602, "Type \"" + type + "\" not representable in XML-RPC.");
+    }
+
+    /**
+     * Return a vector of vectors of strings containing method signatures.
+     */
+    public Vector methodSignature(String methodName) throws XmlRpcException
+    {
+        Method[] methodObjects = getTargetClass().getMethods();
+        Vector signature_set = new Vector();
+
+        // Find signatures for all matching methods.
+        for (int i = 0; i < methodObjects.length; i++)
+	{
+            Method methodObject = methodObjects[i];
+            if (methodObject.getName().equals(methodName)
+                && isXmlRpcCompatible(methodObject))
+            {
+                Vector signature = new Vector();
+                Class returnType = methodObject.getReturnType();
+                Class[] parameterTypes = methodObject.getParameterTypes();
+                signature.addElement(findTypeName(returnType));
+                for (int j = 0; j < parameterTypes.length; j++)
+		{
+                    Class parameterType = parameterTypes[j];
+                    signature.addElement(findTypeName(parameterType));
+                }
+                signature_set.addElement(signature);
+            }
+        }
+
+        // Raise an error if we don't find any matching methods.
+        if (signature_set.size() == 0)
+            throw new XmlRpcException(0, "Unknown method: " + methodName);
+
+        return signature_set;
+    }
+
+    /** Return a help string for the specified message. */
+    public String methodHelp(String methodName) throws XmlRpcException {
+	if (!isXmlRpcCompatible(methodName))
+	{
+	    throw new XmlRpcException(-32601, "Method not found");
+	}
+	
+        String help = "";
+        try
+	{
+            String helpFieldName = methodName.concat("_help");
+            Field helpField = getTargetClass().getField(helpFieldName);
+            help = (String) helpField.get(getInvokeTarget());
+        } catch (Exception e) {
+            /* Use the default value for 'help'. */
+        }
+        return help;
+    }
+
+}
+
Index: IntrospectionHandler.java
===================================================================
--- IntrospectionHandler.java	(revision 0)
+++ IntrospectionHandler.java	(revision 0)
@@ -0,0 +1,184 @@
+/*
+ * Copyright 1999,2005 The Apache Software Foundation.
+ * 
+ * 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.xmlrpc;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+/**
+ * This handler provides access to the XML-RPC introspection API.
+ *
+ * @author <a href="mailto:Walter.Mundt@coleengineering.com">Walter Mundt</a>
+ * @version $Id$
+ */
+public class IntrospectionHandler
+implements ContextXmlRpcHandler, IntrospectiveXmlRpcHandler
+{
+    static final Vector myMethods = new Vector(3);
+    static final Hashtable mySignatures = new Hashtable();
+    static {
+	myMethods.addElement("listMethods");
+	myMethods.addElement("methodSignature");
+	myMethods.addElement("methodHelp");
+
+	Vector listMethodsSignatures = new Vector(1);
+	Vector listMethodsSignature = new Vector(1);
+	listMethodsSignature.addElement("array");
+	listMethodsSignatures.addElement(listMethodsSignature);
+	mySignatures.put("listMethods", listMethodsSignatures);
+	
+	Vector methodHelpSignatures = new Vector(1);
+	Vector methodHelpSignature = new Vector(2);
+	methodHelpSignature.addElement("string");
+	methodHelpSignature.addElement("string");
+	methodHelpSignatures.addElement(methodHelpSignature);
+	mySignatures.put("methodHelp", methodHelpSignatures);
+	
+	Vector methodSignatureSignatures = new Vector(1);
+	Vector methodSignatureSignature = new Vector(2);
+	methodSignatureSignature.addElement("array");
+	methodSignatureSignature.addElement("string");
+	methodSignatureSignatures.addElement(methodSignatureSignature);
+	mySignatures.put("methodSignature", methodSignatureSignatures);
+    }
+    
+    private IntrospectiveXmlRpcHandler getHandler(String name, XmlRpcContext context) throws XmlRpcException
+    {
+	Object handler;
+	try
+	{
+	    handler = context.getHandlerMapping().getHandler(name);
+	}
+	catch (XmlRpcException xr_e)
+	{
+	    throw xr_e;
+	}
+	catch (Exception e)
+	{
+	    throw new XmlRpcException(-32603, "Unknown exception occurred", e);
+	}
+	if (!(handler instanceof IntrospectiveXmlRpcHandler))
+	{
+	    throw new XmlRpcException(-32603, "Introspection not supported on handler \"" + name + "\".");
+	}
+	return (IntrospectiveXmlRpcHandler)handler;
+    }
+
+    public Object execute(String method, Vector params, XmlRpcContext context) throws XmlRpcException
+    {
+        if ("listMethods".equals(method))
+        {
+            return listMethods(params, context);
+        }
+	else if ("methodSignature".equals(method) || "methodHelp".equals(method))
+	{
+	    if ((params.size() != 1) || !(params.elementAt(0) instanceof String))
+	    {
+		throw new XmlRpcException(-32602, "Invalid parameters to " + method + " call.");
+	    }
+	    
+	    String handlerName = "$default";
+	    String methodName = (String)params.get(0);
+	    int dotPosition = methodName.lastIndexOf('.');
+	    if (dotPosition >= 0)
+	    {
+		handlerName = methodName.substring(0, dotPosition);
+		methodName = methodName.substring(dotPosition+1);
+	    }
+	    
+	    IntrospectiveXmlRpcHandler handler = getHandler(handlerName + ".", context);
+
+	    if ("methodSignature".equals(method))
+	    {
+		return handler.methodSignature(methodName);
+	    }
+	    else // "methodHelp".equals(method)
+	    {
+		return handler.methodHelp(methodName);
+	    }
+	}
+
+        throw new XmlRpcException(-32601, "No method '" + method + "' in " + this.getClass().getName());
+    }
+
+    public Vector listMethods()
+    {
+	return myMethods;
+    }
+
+    public Vector methodSignature(String methodName) throws XmlRpcException
+    {
+	Vector sigs = (Vector)mySignatures.get(methodName);
+	if (sigs == null)
+	{
+	    throw new XmlRpcException(-32601, "Method not found");
+	}
+	return sigs;
+    }
+
+    public String methodHelp(String methodName)
+    {
+	return "methodHelp not supported";
+    }
+
+    public Vector listMethods(Vector params, XmlRpcContext context) throws XmlRpcException
+    {
+	if (params.size() > 0)
+	{
+	    throw new XmlRpcException(-32602, "listMethods takes no parameters.");
+	}
+
+	XmlRpcHandlerMapping handlerMapping = context.getHandlerMapping();
+
+	if (!(handlerMapping instanceof XmlRpcListableHandlerMapping))
+	{
+	    throw new XmlRpcException(-32603, "listMethods not supported with non-listable handler mappings");
+	}
+	XmlRpcListableHandlerMapping listableMapping = (XmlRpcListableHandlerMapping)handlerMapping;
+
+	Vector methodList = new Vector();
+	Enumeration registeredHandlers = listableMapping.getRegisteredHandlers();
+	while (registeredHandlers.hasMoreElements()) {
+	    String handlerName = (String)registeredHandlers.nextElement();
+	    Object handler;
+	    try
+	    {
+		handler = listableMapping.getHandler(handlerName + ".");
+	    }
+	    catch (XmlRpcException xr_e)
+	    {
+		throw xr_e;
+	    }
+	    catch (Exception e)
+	    {
+		throw new XmlRpcException(-32603, "Unknown exception occurred", e);
+	    }
+	    
+	    if (handler instanceof IntrospectiveXmlRpcHandler) {
+		IntrospectiveXmlRpcHandler introspective = (IntrospectiveXmlRpcHandler)handler;
+		Vector handlerMethodList = introspective.listMethods();
+		for (int i = 0; i < handlerMethodList.size(); i++) {
+		    methodList.add(handlerName + "." + handlerMethodList.get(i));
+		}
+	    }
+	}
+
+	return methodList;
+    }
+}
+
Index: DefaultHandlerMapping.java
===================================================================
--- DefaultHandlerMapping.java	(revision 359919)
+++ DefaultHandlerMapping.java	(working copy)
@@ -32,9 +32,10 @@
  * @since 1.2
  */
 public class DefaultHandlerMapping
-    implements XmlRpcHandlerMapping
+    implements XmlRpcListableHandlerMapping
 {
     private Hashtable handlers;
+    private boolean useInvokerIntrospection;
 
     /**
      * Create a new mapping.
@@ -42,9 +43,29 @@
     public DefaultHandlerMapping()
     {
         handlers = new Hashtable();
+	useInvokerIntrospection = false;
     }
 
     /**
+     * Create a new mapping.
+     *
+     * @param useInvokerIntrospection Support XML-RPC introspection of public methods on handlers not implementing the XmlRpcHandler interface.
+     */
+    public DefaultHandlerMapping(boolean useInvokerIntrospection)
+    {
+	this();
+	this.useInvokerIntrospection = useInvokerIntrospection;
+    }
+
+    /**
+     * Changes whether handlers not implementing the XmlRpcHandler interface which are added in the future will support XML-RPC introspection.
+     */
+    public void setUseInvokerIntrospection(boolean useInvokerIntrospection)
+    {
+	this.useInvokerIntrospection = useInvokerIntrospection;
+    }
+
+    /**
      * Register a handler object with this name. Methods of this
      * objects will be callable over XML-RPC as
      * "handlername.methodname". For more information about XML-RPC
@@ -64,7 +85,14 @@
         }
         else if (handler != null)
         {
-            handlers.put(handlerName, new Invoker(handler));
+	    if (useInvokerIntrospection)
+	    {
+		handlers.put(handlerName, new IntrospectiveInvoker(handler));
+	    }
+	    else
+	    {
+		handlers.put(handlerName, new Invoker(handler));
+	    }
         }
     }
 
@@ -110,19 +138,32 @@
             {
                 if (dot > -1)
                 {
-                    throw new Exception("RPC handler object \""
-                                        + handlerName + "\" not found and no "
-                                        + "default handler registered");
+                    throw new XmlRpcException(-32601, "RPC handler object \""
+					      + handlerName + "\" not found and no "
+					      + "default handler registered");
                 }
                 else
                 {
-                    throw new Exception("RPC handler object not found for \""
-                                        + methodName
-                                        + "\": No default handler registered");
+                    throw new XmlRpcException(-32601, "RPC handler object not found for \""
+					      + methodName
+					      + "\": No default handler registered");
                 }
             }
         }
 
         return handler;
     }
+
+    /**
+     * List registered handlers, if any.
+     * Implements the <code>XmlRpcListableHandlerMapping</code> interface.
+     *
+     * @return java.util.Enumeration an Enumeration of handler names
+     * @see org.apache.xmlrpc.XmlRpcListableHandlerMapping#getRegisteredHandlers()
+     */
+    public java.util.Enumeration getRegisteredHandlers()
+    {
+	return handlers.keys();
+    }
 }
+
Index: Invoker.java
===================================================================
--- Invoker.java	(revision 359919)
+++ Invoker.java	(working copy)
@@ -45,6 +45,16 @@
         }
     }
 
+    protected Object getInvokeTarget()
+    {
+	return invokeTarget;
+    }
+
+    protected Class getTargetClass()
+    {
+	return targetClass;
+    }
+
     /**
      * main method, sucht methode in object, wenn gefunden dann aufrufen.
      */
Index: SystemHandler.java
===================================================================
--- SystemHandler.java	(revision 359919)
+++ SystemHandler.java	(working copy)
@@ -17,6 +17,7 @@
 
 package org.apache.xmlrpc;
 
+import java.util.Enumeration;
 import java.util.Vector;
 
 /**
@@ -29,9 +30,10 @@
  * @since 1.2
  */
 public class SystemHandler
-implements ContextXmlRpcHandler
+implements ContextXmlRpcHandler, IntrospectiveXmlRpcHandler
 {
     private DefaultHandlerMapping systemMapping = null;
+    private boolean allowIntrospection;
 
     /**
      * Creates a new instance. This instance contains no system calls. Use the
@@ -89,6 +91,25 @@
     }
 
     /**
+     * Add the introspection system handlers.  These are:
+     * <dl>
+     *  <dt>system.listMethods</dt>
+     *  <dd>Return an array of method names supported by the server.  Only methods on handlers supporting introspection are included.</dd>
+     *  <dt>system.methodHelp</dt>
+     *  <dd>Get "help text" for a given method. Only methods on handlers supporting introspection are supported.</dd>
+     *  <dt>system.methodSignature</dt>
+     *  <dd>Return an array of potential signatures for a given method. Only methods on handlers supporting introspection are supported.</dd>
+     * </dl>
+     */
+    public void addIntrospectionSystemHandlers()
+    {
+	IntrospectionHandler ih = new IntrospectionHandler();
+	addSystemHandler("listMethods", ih);
+	addSystemHandler("methodHelp", ih);
+	addSystemHandler("methodSignature", ih);
+    }
+
+    /**
      * @see org.apache.xmlrpc.DefaultHandlerMapping#addHandler(String, Object)
      */
     public void addSystemHandler(String handlerName, ContextXmlRpcHandler handler)
@@ -130,4 +151,54 @@
 
         throw new NoSuchMethodException("No method '" + method + "' registered.");
     }
+    
+    public Vector listMethods()
+    {
+	Vector methodList = new Vector();
+	Enumeration methodEnum = systemMapping.getRegisteredHandlers();
+	
+	while (methodEnum.hasMoreElements())
+	{
+	    String methodName = (String)methodEnum.nextElement();
+	    methodList.addElement(methodName);
+	}
+	return methodList;
+    }
+
+    private IntrospectiveXmlRpcHandler getIntrospectionHandler(String methodName) throws XmlRpcException
+    {
+	Object handler = null;
+	try
+	{
+	    handler = systemMapping.getHandler(methodName + ".");
+	}
+	catch (XmlRpcException xr_e)
+	{
+	    throw xr_e;
+	}
+	catch (Exception e)
+	{
+	    throw new XmlRpcException(-32603, "Unknown exception occurred: " + e.getMessage(), e);
+	}
+	if (handler == null)
+	{
+	    throw new XmlRpcException(-32601, "Method \"system ." + methodName + "\" does not exist.");
+	}
+	if (!(handler instanceof IntrospectiveXmlRpcHandler))
+	{
+	    throw new XmlRpcException(-32603, "Method \"system." + methodName + "\" does not support detailed introspection.");
+	}
+	return (IntrospectiveXmlRpcHandler)handler;
+    }
+    
+    public Vector methodSignature(String methodName) throws XmlRpcException
+    {
+	return getIntrospectionHandler(methodName).methodSignature(methodName);
+    }
+
+    public String methodHelp(String methodName) throws XmlRpcException
+    {
+	return getIntrospectionHandler(methodName).methodHelp(methodName);
+    }
 }
+
