/**
     * @see parser.IDLParserVisitor#visit(ASTvalue_decl, Object)
     * @param data an instance of the type buildinfo specifing the scope, this value is declared in
     */
    public Object visit(ASTvalue_decl node, Object data) {
        CheckParameterForBuildInfo(data, node);
        // data contains the scope, this value type is declared in
        Scope enclosingScope = ((BuildInfo) data).GetBuildScope();
        // an IDL concrete value type
        // get the header
        ASTvalue_header header = (ASTvalue_header)node.jjtGetChild(0);
        
        Symbol forSymbol = enclosingScope.getSymbol(header.getIdent());
        // check if type is known from a previous run over a parse tree --> if so: skip
        if (m_typeManager.CheckSkip(forSymbol)) { 
            return null; 
        }
        
        // retrieve first types for the inherited
        System.Type[] inheritFrom = (System.Type[])header.jjtAccept(this, data);

        // check is custom:
        if (header.isCustom()) {    
            System.Type[] newInherit = new System.Type[inheritFrom.Length + 1];
            Array.Copy(inheritFrom, 0, newInherit, 0, inheritFrom.Length);
            newInherit[inheritFrom.Length] = typeof(ICustomMarshalled);
            inheritFrom = newInherit;
        }

        Type baseClass = ReflectionHelper.ObjectType;
        if ((inheritFrom.Length > 0) && (inheritFrom[0].IsClass)) {
            // only the first entry may be a class for a concrete value type:
            // multiple inheritance is not allowed for concrete value types, 
            // the value type from which is inherited from must be first in inheritance list,
            // 3.8.5 in CORBA 2.3.1 spec
            baseClass = inheritFrom[0];
            Type[] tmp = new Type[inheritFrom.Length-1];
            Array.Copy(inheritFrom, 1, tmp, 0, tmp.Length);
            inheritFrom = tmp;
        }
        
        TypeBuilder valueToBuild = CreateOrGetValueDcl(forSymbol, 
                                                       baseClass, inheritFrom,
                                                       false, false);
        
        // add implementation class attribute
        valueToBuild.SetCustomAttribute(new ImplClassAttribute(valueToBuild.FullName + "Impl").CreateAttributeBuilder());
        m_ilEmitHelper.AddSerializableAttribute(valueToBuild);
        
        // make sure, every value type has a default constructor
        ConstructorBuilder defConstr = 
            valueToBuild.DefineDefaultConstructor(MethodAttributes.Family);

        // generate elements
        BuildInfo buildInfo = 
            new ConcreteValTypeBuildInfo(enclosingScope.getChildScope(forSymbol.getSymbolName()),
                                         valueToBuild, forSymbol, defConstr);
        ArrayList /* FieldBuilder */ fields = new ArrayList();
        for (int i = 1; i < node.jjtGetNumChildren(); i++) { // for all value_element children
            ASTvalue_element elem = (ASTvalue_element)node.jjtGetChild(i);
            IList stateFields = (IList)
                elem.jjtAccept(this, buildInfo);
            if (stateFields != null) {
                // only state value elements return field builders
                fields.AddRange(stateFields);
            }
        }
        AddExplicitSerializationOrder(valueToBuild, fields);        

        // finally create the type
        Type resultType = m_typeManager.EndTypeDefinition(forSymbol);        
        
        // add to list of value types generated for informing the user of need for implementation class
        m_valueTypesDefined.Add(resultType);
        return null;
    }