internal JsonRpcServiceClass(JsonRpcServiceClassBuilder classBuilder)
        {
            Debug.Assert(classBuilder != null);
            
            _serviceName = classBuilder.Name;
            _description = classBuilder.Description;

            JsonRpcMethodBuilder[] methodBuilders = classBuilder.GetMethods();
            
            _methods = new JsonRpcMethod[methodBuilders.Length];
            _methodByName = new Hashtable(methodBuilders.Length);
            int methodIndex = 0;

            foreach (JsonRpcMethodBuilder methodBuilder in methodBuilders)
            {
                JsonRpcMethod method = new JsonRpcMethod(methodBuilder, this);

                //
                // Check for duplicates.
                //

                if (_methodByName.ContainsKey(method.Name))
                    throw new DuplicateMethodException(string.Format("The method '{0}' cannot be exported as '{1}' because this name has already been used by another method on the '{2}' service.", method.Name, method.InternalName, _serviceName));

                //
                // Add the method to the class and index it by its name.
                //

                _methods[methodIndex++] = method;
                _methodByName.Add(method.Name, method);
            }
        }
        private static void BuildMethod(JsonRpcMethod.Builder builder, MethodInfo method)
        {
            Debug.Assert(method != null);
            Debug.Assert(builder != null);

            builder.InternalName = method.Name;
            builder.ResultType = method.ReturnType;
            builder.Dispatcher = new Dispatcher(method);
            
            //
            // Build via attributes.
            //
            
            object[] attributes = method.GetCustomAttributes(typeof(IMethodReflector), true);
            foreach (IMethodReflector reflector in attributes)
                reflector.Build(builder, method);
            
            //
            // Fault in the method name if still without name.
            //
            
            if (builder.Name.Length == 0)
                builder.Name = method.Name;

            //
            // Build the method parameters.
            //

            foreach (ParameterInfo parameter in method.GetParameters())
                BuildParameter(builder.DefineParameter(), parameter);
        }
 internal JsonRpcParameter(JsonRpcParameterBuilder builder, JsonRpcMethod method)
 {
     Debug.Assert(builder != null);
     Debug.Assert(builder.Position >= 0);
     Debug.Assert(method != null);
     
     _name = builder.Name;
     _parameterType = builder.ParameterType;
     _position = builder.Position;
     _isParamArray = builder.IsParamArray;
     _method = method;
 }
        internal JsonRpcServiceClass(JsonRpcServiceClassBuilder classBuilder)
        {
            Debug.Assert(classBuilder != null);
            
            _serviceName = classBuilder.Name;
            _description = classBuilder.Description;

            //
            // Set up methods and their names.
            //

            ICollection methodBuilders = classBuilder.Methods;
            _methods = new JsonRpcMethod[methodBuilders.Count];
            _methodNames = new string[methodBuilders.Count];
            int methodIndex = 0;

            foreach (JsonRpcMethodBuilder methodBuilder in methodBuilders)
            {
                JsonRpcMethod method = new JsonRpcMethod(methodBuilder, this);

                //
                // Check for duplicates.
                //

                if (Array.IndexOf(_methodNames, method.Name) >= 0)
                    throw new DuplicateMethodException(string.Format("The method '{0}' cannot be exported as '{1}' because this name has already been used by another method on the '{2}' service.", method.Name, method.InternalName, _serviceName));

                //
                // Add the method to the class and index it by its name.
                //

                _methods[methodIndex] = method;
                _methodNames[methodIndex++] = method.Name;
            }

            //
            // Keep a sorted list of parameters and their names so we can
            // do fast look ups using binary search.
            //
            
            _sortedMethods = (JsonRpcMethod[]) _methods.Clone();
            Array.Sort(_methodNames, _sortedMethods, Comparer.DefaultInvariant);
        }
 void IMethodReflector.Build(JsonRpcMethod.Builder builder, MethodInfo method)
 {
     builder.IsObsolete = true;
     builder.ObsoletionMessage = Message;
 }
        private static object ReadParameters(JsonRpcMethod method, JsonReader reader)
        {
            Debug.Assert(method != null);
            Debug.Assert(reader != null);
            
            reader.MoveToContent();
            
            JsonRpcParameter[] parameters = method.GetParameters();
                            
            if (reader.TokenClass == JsonTokenClass.Array)
            {
                reader.Read();
                ArrayList argList = new ArrayList(parameters.Length);
                                
                // TODO: This loop could bomb when more args are supplied that parameters available.
                                                        
                for (int i = 0; i < parameters.Length && reader.TokenClass != JsonTokenClass.EndArray; i++)
                    argList.Add(reader.ReadValue(parameters[i].ParameterType));

                reader.StepOut();
                return argList.ToArray();
            }
            else if (reader.TokenClass == JsonTokenClass.Object)
            {
                reader.Read();
                JsonObject argByName = new JsonObject();
                                
                while (reader.TokenClass != JsonTokenClass.EndObject)
                {
                    // TODO: Imporve this lookup.
                    // FIXME: Does not work when argument is positional.
                                    
                    Type parameterType = null;
                    string name = reader.ReadMember();

                    foreach (JsonRpcParameter parameter in parameters)
                    {
                        if (parameter.Name.Equals(name))
                        {
                            parameterType = parameter.ParameterType;
                            break;
                        }
                    }
                                    
                    argByName.Put(name, reader.ReadValue(parameterType));
                }
                                
                reader.Read();
                return argByName;
            }
            else
            {
                return reader.ReadValue();
            }
        }
 void IMethodReflector.Build(JsonRpcMethod.Builder builder, MethodInfo method)
 {
     builder.Description = Text;
 }
 void IMethodReflector.Build(JsonRpcMethod.Builder builder, MethodInfo method)
 {
     builder.Name = Name;
 }
 internal Builder(JsonRpcMethod.Builder method)
 {
     Debug.Assert(method != null);
     
     _method = method;
 }