private static void ParseSubHierarchy(INode parent, ClassHierarchyProto.Node n)
        {
            INode parsed;

            if (n.package_node != null)
            {
                parsed = new PackageNodeImpl(parent, n.name, n.full_name);
            }
            else if (n.named_parameter_node != null)
            {
                ClassHierarchyProto.NamedParameterNode np = n.named_parameter_node;
                parsed = new NamedParameterNodeImpl(parent, n.name,
                                                    n.full_name, np.full_arg_class_name, np.simple_arg_class_name,
                                                    np.is_set, np.documentation, np.short_name,
                                                    np.instance_default.ToArray());
            }
            else if (n.class_node != null)
            {
                ClassHierarchyProto.ClassNode cn = n.class_node;
                IList <IConstructorDef>       injectableConstructors = new List <IConstructorDef>();
                IList <IConstructorDef>       allConstructors        = new List <IConstructorDef>();

                foreach (ClassHierarchyProto.ConstructorDef injectable in cn.InjectableConstructors)
                {
                    IConstructorDef def = ParseConstructorDef(injectable, true);
                    injectableConstructors.Add(def);
                    allConstructors.Add(def);
                }
                foreach (ClassHierarchyProto.ConstructorDef other in cn.OtherConstructors)
                {
                    IConstructorDef def = ParseConstructorDef(other, false);
                    allConstructors.Add(def);
                }

                IConstructorDef[] dummy = new ConstructorDefImpl[0];
                parsed = new ClassNodeImpl(parent, n.name, n.full_name,
                                           cn.is_unit, cn.is_injection_candidate,
                                           cn.is_external_constructor, injectableConstructors,
                                           allConstructors, cn.default_implementation);
            }

            else
            {
                throw new IllegalStateException("Bad protocol buffer: got abstract node" + n);
            }

            foreach (ClassHierarchyProto.Node child in n.children)
            {
                ParseSubHierarchy(parsed, child);
            }
        }
        private static ClassHierarchyProto.Node NewNamedParameterNode(string name,
                                                                      string fullName, string simpleArgClassName, string fullArgClassName,
                                                                      bool isSet, bool isList, string documentation, // can be null
                                                                      string shortName,                              // can be null
                                                                      string[] instanceDefault,                      // can be null
                                                                      IList <ClassHierarchyProto.Node> children)
        {
            ClassHierarchyProto.NamedParameterNode namedParameterNode = new ClassHierarchyProto.NamedParameterNode();
            namedParameterNode.simple_arg_class_name = simpleArgClassName;
            namedParameterNode.full_arg_class_name   = fullArgClassName;
            namedParameterNode.is_set  = isSet;
            namedParameterNode.is_list = isList;

            if (documentation != null)
            {
                namedParameterNode.documentation = documentation;
            }

            if (shortName != null)
            {
                namedParameterNode.short_name = shortName;
            }

            foreach (var id in instanceDefault)
            {
                namedParameterNode.instance_default.Add(id);
            }

            ClassHierarchyProto.Node n = new ClassHierarchyProto.Node();
            n.name                 = name;
            n.full_name            = fullName;
            n.named_parameter_node = namedParameterNode;

            foreach (var c in children)
            {
                n.children.Add(c);
            }

            return(n);
        }
        private static ClassHierarchyProto.Node NewNamedParameterNode(string name,
            string fullName, string simpleArgClassName, string fullArgClassName,
            bool isSet, string documentation, // can be null
            string shortName, // can be null
            string[] instanceDefault, // can be null
            IList<ClassHierarchyProto.Node> children)
        {
            ClassHierarchyProto.NamedParameterNode namedParameterNode = new ClassHierarchyProto.NamedParameterNode();
            namedParameterNode.simple_arg_class_name = simpleArgClassName;
            namedParameterNode.full_arg_class_name = fullArgClassName;
            namedParameterNode.is_set = isSet;

            if (documentation != null)
            {
                namedParameterNode.documentation = documentation;
            }

            if (shortName != null)
            {
                namedParameterNode.short_name = shortName;
            }

            foreach (var id in instanceDefault)
            {
                namedParameterNode.instance_default.Add(id);
            }

            ClassHierarchyProto.Node n = new ClassHierarchyProto.Node();
            n.name = name;
            n.full_name = fullName;
            n.named_parameter_node = namedParameterNode;

            foreach (var c in children)
            {
                n.children.Add(c);
            }

            return n;
        }