예제 #1
0
        static void AddShortObjectMethods(ITextBuilder builder, NpcExecutionObject executionObject)
        {
            for (int interfaceIndex = 0; interfaceIndex < executionObject.ancestorNpcInterfaces.Count; interfaceIndex++)
            {
                NpcInterfaceInfo npcInterfaceInfo = executionObject.ancestorNpcInterfaces[interfaceIndex];
                for (int methodIndex = 0; methodIndex < npcInterfaceInfo.npcMethods.Length; methodIndex++)
                {
                    NpcMethodInfo npcMethodInfo = npcInterfaceInfo.npcMethods[methodIndex];
                    builder.AppendAscii(npcMethodInfo.methodName);

                    ParameterInfo[] parameters = npcMethodInfo.parameters;
                    for (UInt16 argIndex = 0; argIndex < npcMethodInfo.parametersLength; argIndex++)
                    {
                        ParameterInfo parameterInfo = parameters[argIndex];
                        builder.AppendAscii(' ');
                        builder.AppendAscii(parameterInfo.ParameterType.SosShortTypeName());
                        builder.AppendAscii(':');
                        builder.AppendAscii(parameterInfo.Name);
                    }

                    builder.AppendAscii(" returns ");
#if WindowsCE
                    builder.AppendAscii(npcMethodInfo.methodInfo.ReturnType.SosTypeName());
#else
                    builder.AppendAscii(npcMethodInfo.methodInfo.ReturnParameter.ParameterType.SosShortTypeName());
#endif
                    builder.AppendAscii("\n");
                }
            }
        }
예제 #2
0
        public void RegressionTest()
        {
            ClassWithTestMethods testClass       = new ClassWithTestMethods();
            NpcExecutionObject   executionObject = new NpcExecutionObject(testClass);


            NpcMethodInfo[] methodArray = new NpcMethodInfo[4];

            methodArray[0] = new NpcMethodInfo(executionObject.type.GetMethod("NoArgument"));
            NpcMethodOverloadable methods = new NpcMethodOverloadable(executionObject, methodArray[0]);

            methodArray[1] = new NpcMethodInfo(executionObject.type.GetMethod("OneArgument"));
            methods.AddOverload(methodArray[1]);

            methodArray[2] = new NpcMethodInfo(executionObject.type.GetMethod("TwoArguments"));
            methods.AddOverload(methodArray[2]);

            methodArray[3] = new NpcMethodInfo(executionObject.type.GetMethod("ThreeArguments"));
            methods.AddOverload(methodArray[3]);

            Int32 index = 0;

            foreach (NpcMethodInfo method in methods)
            {
                Assert.AreSame(methodArray[index], method, String.Format("Index {0} method={1}, methodArray={2}", index, method.methodInfo, methodArray[index]));
                index++;
            }
        }
예제 #3
0
        static void AddVerboseObjectMethods(ITextBuilder builder, NpcExecutionObject executionObject)
        {
            for (int interfaceIndex = 0; interfaceIndex < executionObject.ancestorNpcInterfaces.Count; interfaceIndex++)
            {
                NpcInterfaceInfo npcInterfaceInfo = executionObject.ancestorNpcInterfaces[interfaceIndex];
                for (int methodIndex = 0; methodIndex < npcInterfaceInfo.npcMethods.Length; methodIndex++)
                {
                    NpcMethodInfo npcMethodInfo = npcInterfaceInfo.npcMethods[methodIndex];
#if WindowsCE
                    builder.AppendAscii(npcMethodInfo.methodInfo.ReturnType.SosTypeName());
#else
                    builder.AppendAscii(npcMethodInfo.methodInfo.ReturnParameter.ParameterType.SosTypeName());
#endif
                    builder.AppendAscii(' ');
                    builder.AppendAscii(npcMethodInfo.methodName);

                    builder.AppendAscii('(');

                    ParameterInfo[] parameters = npcMethodInfo.parameters;
                    for (UInt16 j = 0; j < npcMethodInfo.parametersLength; j++)
                    {
                        ParameterInfo parameterInfo = parameters[j];
                        if (j > 0)
                        {
                            builder.AppendAscii(',');
                        }
                        builder.AppendAscii(parameterInfo.ParameterType.SosTypeName());
                        builder.AppendAscii(' ');
                        builder.AppendAscii(parameterInfo.Name);
                    }
                    builder.AppendAscii(")\n");
                }
            }
        }
예제 #4
0
        public NpcReturnObjectOrException ExecuteWithObjects(String methodName, params Object[] args)
        {
            UInt16             argsLength = (args == null) ? (UInt16)0 : (UInt16)args.Length;
            NpcExecutionObject executionObject;
            NpcMethodInfo      npcMethodInfo = GetNpcMethodInfo(methodName, argsLength, out executionObject);

            return(ExecuteWithObjects(executionObject, npcMethodInfo, args));
        }
예제 #5
0
        public NpcReturnObjectOrException ExecuteWithStrings(String methodName, params String[] parameterStrings)
        {
            Int32 parameterStringsLength = (parameterStrings == null) ? 0 : parameterStrings.Length;

            NpcExecutionObject executionObject;
            NpcMethodInfo      methodInfo = GetNpcMethodInfo(methodName, (UInt16)parameterStringsLength, out executionObject);

            Object[] parameterObjects = Npc.CreateParameterObjects(methodInfo, parameterStrings);

            return(ExecuteWithObjects(executionObject, methodInfo, parameterObjects));
        }
예제 #6
0
        public override NpcMethodInfo GetNpcMethodInfo(String methodName, UInt16 parameterCount, out NpcExecutionObject executionObject)
        {
            //
            // Find method with matching name
            //
            NpcMethodOverloadable overloadableMethod;

            if (methodName.Contains("."))
            {
                if (!withObjectMethodDictionary.TryGetValue(methodName, out overloadableMethod))
                {
                    throw new NpcErrorException(NpcErrorCode.UnknownMethodName,
                                                String.Format("Method '{0}' was not found", methodName));
                }
            }
            else
            {
                List <NpcMethodOverloadable> overloadableMethodsWithSameName;
                if (!noObjectDictionary.TryGetValue(methodName, out overloadableMethodsWithSameName))
                {
                    throw new NpcErrorException(NpcErrorCode.UnknownMethodName,
                                                String.Format("Method '{0}' was not found", methodName));
                }

                if (overloadableMethodsWithSameName.Count == 1)
                {
                    overloadableMethod = overloadableMethodsWithSameName[0];
                }
                else
                {
                    throw new NpcErrorException(NpcErrorCode.AmbiguousMethodName, String.Format(
                                                    "Method '{0}' exists but there are multiple objects that have a method matching that name, use <object-name>.{0} to indicate which object you would like to call the method on", methodName));
                }
            }

            //
            // Find method with matching name that has the correct number of parameters
            //
            NpcMethodInfo npcMethodInfo = overloadableMethod.GetMethod(parameterCount);

            if (npcMethodInfo == null)
            {
                throw new InvalidOperationException(String.Format("Method '{0}' was found but it does not have {1} parameters", methodName, parameterCount));
            }
            executionObject = overloadableMethod.executionObject;
            return(npcMethodInfo);
        }
예제 #7
0
        private NpcInterfaceInfo(Type interfaceType)
        {
            this.interfaceType = interfaceType;
            this.name          = interfaceType.Name;

            // Get Methods
            MethodInfo[] methods = interfaceType.GetMethods();
            if (methods == null || methods.Length <= 0)
            {
                throw new InvalidOperationException(String.Format("NpcInterface type '{0}' has no methods", interfaceType.Name));
            }

            npcMethods = new NpcMethodInfo[methods.Length];
            for (int i = 0; i < methods.Length; i++)
            {
                MethodInfo methodInfo = methods[i];
                npcMethods[i] = new NpcMethodInfo(methodInfo);
            }
        }
예제 #8
0
        public NpcReturnObjectOrException ExecuteWithStrings(NpcExecutionObject executionObject, NpcMethodInfo methodInfo, params String[] parameterStrings)
        {
            Object[] parameterObjects = Npc.CreateParameterObjects(methodInfo, parameterStrings);

            return(ExecuteWithObjects(executionObject, methodInfo, parameterObjects));
        }
예제 #9
0
 public abstract NpcReturnObjectOrException ExecuteWithObjects(NpcExecutionObject executionObject, NpcMethodInfo npcMethodInfo, params Object[] args);
예제 #10
0
 public static Object[] CreateParameterObjects(NpcMethodInfo npcMethodInfo, params String[] parameterStrings)
 {
     return(CreateParameterObjects(npcMethodInfo.parameters, parameterStrings));
 }
예제 #11
0
        public NpcReflector(params Object [] executionObjects)
        {
            if (executionObjects == null)
            {
                throw new ArgumentNullException("executionObjects");
            }
            if (executionObjects.Length <= 0)
            {
                throw new ArgumentException("exeuctionObjects must have at least one object", "executionObjects");
            }

            this.npcExecutionObjects = new NpcExecutionObject[executionObjects.Length];

            this.interfaceSet = new NpcInterfaceInfo.Set(new Dictionary <Type, NpcInterfaceInfo>());
            this.methodList   = new List <NpcMethodOverloadable>();
            this.withObjectMethodDictionary   = new Dictionary <String, NpcMethodOverloadable>(StringComparer.OrdinalIgnoreCase);
            this.noObjectDictionary           = new Dictionary <String, List <NpcMethodOverloadable> >(StringComparer.OrdinalIgnoreCase);
            this.enumAndObjectTypesDictionary = new Dictionary <String, Type>();
            this.enumAndObjectTypesWithUniqueShortNamesDictionary = new Dictionary <String, OneOrMoreTypes>();

            //
            // Find all methods that are apart of an [NpcInterface]
            //
            SosTypeSerializationVerifier verifier = new SosTypeSerializationVerifier();

            for (int objectIndex = 0; objectIndex < executionObjects.Length; objectIndex++)
            {
                Object             executionObject    = executionObjects[objectIndex];
                NpcExecutionObject npcExecutionObject = executionObject as NpcExecutionObject;
                if (npcExecutionObject == null)
                {
                    npcExecutionObject = new NpcExecutionObject(executionObject);
                }
                npcExecutionObject.InitializeInterfaces(this.interfaceSet);
                npcExecutionObjects[objectIndex] = npcExecutionObject;

                foreach (NpcInterfaceInfo interfaceInfo in npcExecutionObject.ancestorNpcInterfaces)
                {
                    //
                    // Add all the methods
                    //
                    NpcMethodInfo[] npcMethodInfos = interfaceInfo.npcMethods;
                    for (int methodIndex = 0; methodIndex < npcMethodInfos.Length; methodIndex++)
                    {
                        NpcMethodInfo npcMethodInfo = npcMethodInfos[methodIndex];
                        //Console.WriteLine("   [NpcDebug] Registering types for method '{0}'", npcMethodInfo.methodName);

                        //
                        // Check that all parameter types can be parsed
                        //
                        for (UInt16 k = 0; k < npcMethodInfo.parametersLength; k++)
                        {
                            RegisterType(verifier, npcMethodInfo.parameters[k].ParameterType);
                        }

                        //
                        // Find the appropriate ToString method for the return type
                        //
                        RegisterType(verifier, npcMethodInfo.methodInfo.ReturnType);

                        //
                        // Add method info to dictionary
                        //
                        String objectMethodName = npcExecutionObject.objectName + "." + npcMethodInfo.methodName;
                        NpcMethodOverloadable overloadableMethod;
                        if (withObjectMethodDictionary.TryGetValue(objectMethodName, out overloadableMethod))
                        {
                            overloadableMethod.AddOverload(npcMethodInfo);
                        }
                        else
                        {
                            overloadableMethod = new NpcMethodOverloadable(npcExecutionObject, npcMethodInfo);
                            methodList.Add(overloadableMethod);
                            withObjectMethodDictionary.Add(objectMethodName, overloadableMethod);
                        }

                        List <NpcMethodOverloadable> methodsWithSameShortName;
                        if (!noObjectDictionary.TryGetValue(npcMethodInfo.methodName, out methodsWithSameShortName))
                        {
                            methodsWithSameShortName = new List <NpcMethodOverloadable>();
                            noObjectDictionary.Add(npcMethodInfo.methodName, methodsWithSameShortName);
                        }
                        methodsWithSameShortName.Add(overloadableMethod);
                    }
                }
            }
        }
예제 #12
0
        public override NpcReturnObjectOrException ExecuteWithObjects(NpcExecutionObject executionObject, NpcMethodInfo npcMethodInfo, params Object[] args)
        {
            //
            // Setup Parameter array of Objects to invoke the method
            //
            MethodInfo methodInfo = npcMethodInfo.methodInfo;

            //
            // Invoke
            //
            try
            {
                //
                // Call pre call if specified
                //
                if (executionObject.preAndPostCall != null)
                {
                    executionObject.preAndPostCall.PreCall(executionObject, npcMethodInfo, args);
                }

                Object returnObject;
                //
                // Make sure execution lock is respected if it was provided
                //
                try
                {
                    if (executionObject.executionLock == null)
                    {
                        returnObject = methodInfo.Invoke(executionObject.invokeObject, args);
                    }
                    else
                    {
                        lock (executionObject.executionLock)
                        {
                            returnObject = methodInfo.Invoke(executionObject.invokeObject, args);
                        }
                    }
                }
                finally
                {
                    //
                    // Call post call if specified
                    //
                    if (executionObject.preAndPostCall != null)
                    {
                        executionObject.preAndPostCall.PostCall(executionObject, npcMethodInfo, args);
                    }
                }

                return(new NpcReturnObjectOrException(methodInfo.ReturnType, returnObject, returnObject.SerializeObject()));
            }
            catch (TargetInvocationException e)
            {
                return(new NpcReturnObjectOrException(e.InnerException, e.SerializeObject()));
            }
        }
예제 #13
0
        void InterfaceCommandHandler(ITextBuilder responseBuilder)
        {
            //
            // Add Interface Definitions
            //
            foreach (NpcInterfaceInfo interfaceInfo in npcExecutor.Interfaces)
            {
                responseBuilder.AppendAscii(interfaceInfo.name);
                for (int i = 0; i < interfaceInfo.parentNpcInterfaces.Count; i++)
                {
                    NpcInterfaceInfo parentNpcInterface = interfaceInfo.parentNpcInterfaces[i];
                    responseBuilder.AppendAscii(' ');
                    responseBuilder.AppendAscii(parentNpcInterface.name);
                }
                responseBuilder.AppendAscii('\n');

                for (int i = 0; i < interfaceInfo.npcMethods.Length; i++)
                {
                    NpcMethodInfo npcMethodInfo = interfaceInfo.npcMethods[i];
#if WindowsCE
                    responseBuilder.Append(npcMethodInfo.methodInfo.ReturnType.SosTypeName());
#else
                    responseBuilder.AppendAscii(npcMethodInfo.methodInfo.ReturnParameter.ParameterType.SosTypeName());
#endif
                    responseBuilder.AppendAscii(' ');
                    responseBuilder.AppendAscii(npcMethodInfo.methodName);

                    responseBuilder.AppendAscii('(');

                    ParameterInfo[] parameters = npcMethodInfo.parameters;
                    for (UInt16 j = 0; j < npcMethodInfo.parametersLength; j++)
                    {
                        ParameterInfo parameterInfo = parameters[j];
                        if (j > 0)
                        {
                            responseBuilder.AppendAscii(',');
                        }
                        responseBuilder.AppendAscii(parameterInfo.ParameterType.SosTypeName());
                        responseBuilder.AppendAscii(' ');
                        responseBuilder.AppendAscii(parameterInfo.Name);
                    }
                    responseBuilder.AppendAscii(")\n");
                }
                responseBuilder.AppendAscii('\n');
            }
            responseBuilder.AppendAscii('\n'); // Add blank line to end (to mark end of interfaces)

            //
            // Add Object Names and their Interfaces
            //
            foreach (NpcExecutionObject executionObject in npcExecutor.ExecutionObjects)
            {
                responseBuilder.AppendAscii(executionObject.objectName);
                for (int i = 0; i < executionObject.parentNpcInterfaces.Count; i++)
                {
                    NpcInterfaceInfo npcInterface = executionObject.parentNpcInterfaces[i];
                    responseBuilder.AppendAscii(' ');
                    responseBuilder.AppendAscii(npcInterface.name);
                }
                responseBuilder.AppendAscii('\n');
            }
            responseBuilder.AppendAscii('\n'); // Add blank line to end (to mark end of objects
        }
예제 #14
0
        public void GenerateCallPage(ITextBuilder htmlBuilder, string call)
        {
            Int32 questionMarkIndex = call.IndexOf('?');

            String methodName;

            String[] parameters = null;
            if (questionMarkIndex < 0)
            {
                methodName = call;
            }
            else
            {
                methodName = call.Remove(questionMarkIndex);
                String parametersQueryString = (questionMarkIndex >= call.Length - 1) ? null :
                                               call.Substring(questionMarkIndex + 1);

                if (String.IsNullOrEmpty(methodName))
                {
                    throw new FormatException(String.Format("Call '{0}' is missing method name", call));
                }
                else if (!String.IsNullOrEmpty(parametersQueryString))
                {
                    parameters = parametersQueryString.Split('&');
                    for (int i = 0; i < parameters.Length; i++)
                    {
                        Int32 equalIndex = parameters[i].IndexOf('=');
                        if (equalIndex > 0)
                        {
                            parameters[i] = (equalIndex >= parameters[i].Length - 1) ? "" :
                                            parameters[i].Substring(equalIndex + 1);
                        }
                    }
                }
            }

            UInt16 parameterCount = (parameters == null) ? (UInt16)0 : (UInt16)parameters.Length;

            NpcExecutionObject executionObject;
            NpcMethodInfo      npcMethodInfo = npcExecutor.GetNpcMethodInfo(methodName, parameterCount, out executionObject);

            NpcReturnObjectOrException returnObject = npcExecutor.ExecuteWithStrings(executionObject, npcMethodInfo, parameters);

            if (returnObject.exception == null)
            {
                htmlBuilder.AppendAscii("<div style=\"background:#333;color:#0f5;padding:5px;\"><h1>Success</h1></div>");
            }
            else
            {
                htmlBuilder.AppendAscii("<div style=\"background:#333;color:#f00;padding:5px;\"><h1>Exception</h1></div>");
            }

            htmlBuilder.AppendAscii("<br/>");

            //htmlBuilder.AppendFormat("<div><div><span class=\"SectionTitle\">Function Called</span><hr/></div> {0}&nbsp;<span class=\"bold\">{1}</span>(", TypeAsHtml(npcMethodInfo.methodInfo.ReturnType), methodName);
            htmlBuilder.AppendAscii("<div><div><span class=\"SectionTitle\">Function Called</span><hr/></div> ");
            htmlBuilder.AppendAscii(TypeAsHtml(npcMethodInfo.methodInfo.ReturnType));
            htmlBuilder.AppendAscii("&nbsp;<span class=\"bold\">");
            htmlBuilder.AppendAscii(methodName);
            htmlBuilder.AppendAscii("</span>(");
            if (parameterCount > 0)
            {
                htmlBuilder.AppendAscii("<table>");
                for (int i = 0; i < parameters.Length; i++)
                {
                    ParameterInfo parameterInfo   = npcMethodInfo.parameters[i];
                    String        parameterString = parameters[i];
                    //htmlBuilder.AppendFormat("<tr><td>&nbsp;{0}</td><td>&nbsp;{1}</td><td>&nbsp;=&nbsp;</td><td>{2}</td></tr>",
                    //    TypeAsHtml(parameterInfo.ParameterType), parameterInfo.Name, parameterString);
                    htmlBuilder.AppendAscii("<tr><td>&nbsp;");
                    htmlBuilder.AppendAscii(TypeAsHtml(parameterInfo.ParameterType));
                    htmlBuilder.AppendAscii("</td><td>&nbsp;");
                    htmlBuilder.AppendAscii(parameterInfo.Name);
                    htmlBuilder.AppendAscii("</td><td>&nbsp;=&nbsp;</td><td>");
                    htmlBuilder.AppendAscii(parameterString);
                    htmlBuilder.AppendAscii("</td></tr>");
                }
                htmlBuilder.AppendAscii("</table>");
            }
            htmlBuilder.AppendAscii(")</div>");

            htmlBuilder.AppendAscii("<br/>");

            if (returnObject.exception == null)
            {
                if (returnObject.type != typeof(void))
                {
                    //htmlBuilder.AppendFormat("<div><span class=\"SectionTitle\">Return Value</span>&nbsp;{0}<hr/></div>", TypeAsHtml(returnObject.type));
                    htmlBuilder.AppendAscii("<div><span class=\"SectionTitle\">Return Value</span>&nbsp;");
                    htmlBuilder.AppendAscii(TypeAsHtml(returnObject.type));
                    htmlBuilder.AppendAscii("<hr/></div>");
                    GenerateHtmlValue(htmlBuilder, returnObject.value);
                }
            }
            else
            {
                //htmlBuilder.AppendFormat("<div><span class=\"SectionTitle\">Exception</span>&nbsp;<span class=\"cstype\">{0}</span><hr/></div>", returnObject.type.FullName);
                htmlBuilder.AppendAscii("<div><span class=\"SectionTitle\">Exception</span>&nbsp;<span class=\"cstype\">");
                htmlBuilder.AppendAscii(returnObject.type.FullName);
                htmlBuilder.AppendAscii("</span><hr/></div>");
                GenerateExceptionHtml(htmlBuilder, returnObject.exception);
            }
        }
예제 #15
0
        public void GenerateMethodsPage(ITextBuilder htmlBuilder)
        {
            htmlBuilder.AppendAscii("<div class=\"methodgroups\">");

            Int32 tabIndex = 1;

            foreach (NpcExecutionObject executionObject in npcExecutor.ExecutionObjects)
            {
                htmlBuilder.AppendAscii("<div class=\"methods\"><hr/><h2>");
                htmlBuilder.AppendAscii(executionObject.objectName);
                htmlBuilder.AppendAscii("</h2><hr/>");

                for (int interfaceIndex = 0; interfaceIndex < executionObject.ancestorNpcInterfaces.Count; interfaceIndex++)
                {
                    NpcInterfaceInfo interfaceInfo = executionObject.ancestorNpcInterfaces[interfaceIndex];
                    for (int methodIndex = 0; methodIndex < interfaceInfo.npcMethods.Length; methodIndex++)
                    {
                        NpcMethodInfo npcMethodInfo = interfaceInfo.npcMethods[methodIndex];

                        ParameterInfo[] parameters     = npcMethodInfo.parameters;
                        Int32           parameterCount = (parameters == null) ? 0 : parameters.Length;

                        //htmlBuilder.AppendFormat("<form class=\"methodform\" action=\"call/{0}.{1}\" method=\"get\">", executionObject.objectName, npcMethodInfo.methodName);
                        htmlBuilder.AppendAscii("<form class=\"methodform\" action=\"call/");
                        htmlBuilder.AppendAscii(executionObject.objectName);
                        htmlBuilder.AppendAscii(".");
                        htmlBuilder.AppendAscii(npcMethodInfo.methodName);
                        htmlBuilder.AppendAscii("\" method=\"get\">");

                        //htmlBuilder.AppendFormat("<input class=\"executebutton\" type=\"submit\" value=\"Execute\" tabindex=\"{0}\"/>", tabIndex + parameterCount);
                        htmlBuilder.AppendAscii("<input class=\"executebutton\" type=\"submit\" value=\"Execute\" tabindex=\"");
                        htmlBuilder.AppendNumber(tabIndex + parameterCount);
                        htmlBuilder.AppendAscii("\"/>");
#if WindowsCE
                        htmlBuilder.Append(TypeAsHtml(npcMethodInfo.methodInfo.ReturnType));
#else
                        htmlBuilder.AppendAscii(TypeAsHtml(npcMethodInfo.methodInfo.ReturnParameter.ParameterType));
#endif

                        //htmlBuilder.AppendFormat("&nbsp;<font class=\"bold\">{0}</font>(", npcMethodInfo.methodInfo.Name);
                        htmlBuilder.AppendAscii("&nbsp;<font class=\"bold\">");
                        htmlBuilder.AppendAscii(npcMethodInfo.methodInfo.Name);
                        htmlBuilder.AppendAscii("</font>(");
                        if (parameterCount > 0)
                        {
                            htmlBuilder.AppendAscii("<div style=\"padding-left:50px;\"><table class=\"methodtable\">");
                            for (UInt16 j = 0; j < parameterCount; j++)
                            {
                                ParameterInfo parameterInfo = parameters[j];
                                //htmlBuilder.AppendFormat("<tr><td>{0}</td><td>&nbsp;{1}</td><td>&nbsp;=&nbsp;</td><td width=\"100%\"><input style=\"width:100%;\" tabindex=\"{3}\" name=\"{2}\"/></td></tr>",
                                //    TypeAsHtml(parameterInfo.ParameterType), parameterInfo.Name, j, tabIndex++);
                                htmlBuilder.AppendAscii("<tr><td>");
                                htmlBuilder.AppendAscii(TypeAsHtml(parameterInfo.ParameterType));
                                htmlBuilder.AppendAscii("</td><td>&nbsp;");
                                htmlBuilder.AppendAscii(parameterInfo.Name);
                                htmlBuilder.AppendAscii("</td><td>&nbsp;=&nbsp;</td><td width=\"100%\"><input style=\"width:100%;\" tabindex=\"");
                                htmlBuilder.AppendNumber(tabIndex++);
                                htmlBuilder.AppendAscii("\" name=\"");
                                htmlBuilder.AppendNumber(j);
                                htmlBuilder.AppendAscii("\"/></td></tr>");
                            }
                            htmlBuilder.AppendAscii("</table></div>");
                        }
                        htmlBuilder.AppendAscii(")</form>");
                    }
                }
                tabIndex++;
                htmlBuilder.AppendAscii("</div>");
            }

            htmlBuilder.AppendAscii("</div>");

            htmlBuilder.AppendAscii("<div id=\"executeframe\"></div>");
        }