private void make_attributes_for_declaration(SyntaxTree.unit_module un, common_unit_node cun)
        {
            if (cun.attributes != null)
            {
                Hashtable ht = new Hashtable();
                foreach (SyntaxTree.simple_attribute_list sal in un.attributes.attributes)
                    for (int j = 0; j < sal.attributes.Count; j++)
                    {
                        SyntaxTree.attribute attr = sal.attributes[j];
                        attribute_converted = true;
                        type_node tn = convert_strong(attr.type);
                        bool is_attr = false;
                        type_node tmp = tn;
                        while (tmp.base_type != null && !is_attr)
                        {
                            is_attr = tmp.base_type == SystemLibrary.SystemLibrary.attribute_type;
                            tmp = tmp.base_type;
                        }
                        if (!is_attr)
                            AddError(get_location(attr), "CLASS_{0}_NOT_ATTRIBUTE", tn.name);
                        bool allowMultiple = false;
                        AttributeTargets targets = get_usage_attrs(tn, out allowMultiple);
                        if (ht.Contains(tn) && !allowMultiple)
                        {
                            AddError(get_location(attr), "DUPLICATE_ATTRIBUTE_{0}_APPLICATION", tn.name);
                        }
                        else
                            ht[tn] = tn;
                        SemanticTree.attribute_qualifier_kind qualifier = SemanticTree.attribute_qualifier_kind.none_kind;
                        if (attr.qualifier != null)
                            if (j == 0)
                            {
                                if (string.Compare(attr.qualifier.name, "return", true) == 0)
                                {
                                    if (context.top_function == null)
                                        AddError(get_location(attr), "ATTRIBUTE_APPLICABLE_ONLY_TO_METHOD");
                                    if (context.top_function.return_value_type == null || context.top_function.return_value_type == SystemLibrary.SystemLibrary.void_type)
                                        AddError(get_location(attr), "EXPECTED_RETURN_VALUE_FOR_ATTRIBUTE");
                                    throw new NotSupportedError(get_location(attr.qualifier));
                                    qualifier = SemanticTree.attribute_qualifier_kind.return_kind;
                                }
                                else
                                    throw new NotSupportedError(get_location(attr.qualifier));
                            }
                            else
                                AddError(get_location(attr.qualifier), "ATTRIBUTE_QUALIFIER_MUST_BE_FIRST");
                        check_for_usage_attribute(cun, targets, tn.name, get_location(attr), qualifier);

                        attribute_converted = false;
                        SyntaxTree.expression_list cnstr_args = new SyntaxTree.expression_list();
                        if (attr.arguments != null)
                        {
                            foreach (SyntaxTree.expression e in attr.arguments.expressions)
                            {
                                if (e is SyntaxTree.bin_expr && (e as SyntaxTree.bin_expr).operation_type == SyntaxTree.Operators.Equal
                                    && (e as SyntaxTree.bin_expr).left is SyntaxTree.ident)
                                {
                                    break;
                                }
                                else
                                {
                                    cnstr_args.expressions.Add(e);
                                }
                            }
                        }
                        expressions_list args = new expressions_list();
                        for (int i = 0; i < cnstr_args.expressions.Count; i++)
                        {
                            constant_node cn = convert_strong_to_constant_node(cnstr_args.expressions[i]);
                            check_for_strong_constant(cn, get_location(cnstr_args.expressions[i]));
                            args.AddElement(cn);
                        }

                        base_function_call bfc = create_constructor_call(tn, args, get_location(attr));
                        attribute_node attr_node = new attribute_node(bfc.simple_function_node, tn, get_location(un));
                        foreach (expression_node en in bfc.parameters)
                        {
                            constant_node cn = convert_strong_to_constant_node(en, en.type);
                            check_for_strong_constant(cn, en.location);
                            attr_node.args.Add(cn);
                        }
                        if (attr.arguments != null)
                        {
                            for (int i = cnstr_args.expressions.Count; i < attr.arguments.expressions.Count; i++)
                            {
                                SyntaxTree.expression e = attr.arguments.expressions[i];
                                if (!(e is SyntaxTree.bin_expr && (e as SyntaxTree.bin_expr).operation_type == SyntaxTree.Operators.Equal
                                      && (e as SyntaxTree.bin_expr).left is SyntaxTree.ident))
                                {
                                    AddError(get_location(e), "EXPECTED_ATTRIBUTE_INITIALIZER");
                                }
                                else
                                {
                                    SyntaxTree.ident id = (e as SyntaxTree.bin_expr).left as SyntaxTree.ident;
                                    SymbolInfo si = tn.find(id.name);
                                    definition_node dn = context.check_name_node_type(id.name, si, get_location(id), general_node_type.property_node, general_node_type.variable_node);
                                    type_node mem_tn = null;
                                    if (dn is property_node)
                                    {
                                        property_node pn = dn as property_node;
                                        attr_node.prop_names.Add(pn);
                                        if (pn.set_function == null)
                                            AddError(new ThisPropertyCanNotBeWrited(pn, get_location(id)));
                                        if (pn.set_function.parameters.Count != 1)
                                            AddError(get_location(id), "INDEX_PROPERTY_INITIALIZING_NOT_VALID");
                                        mem_tn = pn.set_function.parameters[0].type;
                                    }
                                    else if (dn is var_definition_node)
                                    {
                                        attr_node.field_names.Add(dn as var_definition_node);
                                        mem_tn = (dn as var_definition_node).type;
                                    }
                                    else
                                    {
                                        throw new CompilerInternalError("Bad general node type for attribute initializer");
                                    }
                                    //SyntaxTree.assign tmp_ass = new SyntaxTree.assign(id,(e as SyntaxTree.bin_expr).right,SyntaxTree.Operators.Assignment);
                                    //tmp_ass.source_context = e.source_context;
                                    //basic_function_call tmp_bfc = convert_strong(tmp_ass) as basic_function_call;
                                    constant_node cn = convert_strong_to_constant_node((e as SyntaxTree.bin_expr).right, mem_tn);
                                    check_for_strong_constant(cn, get_location((e as SyntaxTree.bin_expr).right));
                                    if (dn is property_node)
                                        attr_node.prop_initializers.Add(cn);
                                    else
                                        attr_node.field_initializers.Add(cn);
                                }
                            }
                        }
                        attr_node.qualifier = qualifier;
                        cun.attributes.AddElement(attr_node);
                        if (cun.namespaces.Count > 0)
                            cun.namespaces[0].attributes.AddElement(attr_node);
                    }
            }
        }
 private void SaveAttribute(attribute_node attr)
 {
 	WriteTypeReference(attr.attribute_type);
 	WriteMethodReference(attr.attribute_constr);
 	bw.Write((byte)attr.qualifier);
 	bw.Write(attr.args.Count);
 	for (int i=0; i<attr.args.Count; i++)
 		VisitExpression(attr.args[i]);
 	bw.Write(attr.prop_names.Count);
 	for (int i=0; i<attr.prop_names.Count; i++)
 		WritePropertyReference(attr.prop_names[i]);
 	bw.Write(attr.field_names.Count);
 	for (int i=0; i<attr.field_names.Count; i++)
 		WriteFieldReference(attr.field_names[i]);
 	bw.Write(attr.prop_initializers.Count);
 	for (int i=0; i<attr.prop_initializers.Count; i++)
 		VisitExpression(attr.prop_initializers[i]);
 	bw.Write(attr.field_initializers.Count);
 	for (int i=0; i<attr.field_initializers.Count; i++)
 		VisitExpression(attr.field_initializers[i]);
 	WriteDebugInfo(attr.location);
 }
        private attribute_node GetAttribute()
        {
        	type_node tn = GetTypeReference();
        	function_node fn = GetMethodReference();
        	SemanticTree.attribute_qualifier_kind quaifier = (SemanticTree.attribute_qualifier_kind)br.ReadByte();
        	int count = br.ReadInt32();
        	List<constant_node> args = new List<constant_node>();
        	for (int i=0; i<count; i++)
        		args.Add((constant_node)CreateExpression());
        	count = br.ReadInt32();
        	List<property_node> prop_names = new List<property_node>();
        	for (int i=0; i<count; i++)
        		prop_names.Add(GetPropertyReference());
        	count = br.ReadInt32();
        	List<var_definition_node> field_names = new List<var_definition_node>();
        	for (int i=0; i<count; i++)
        		field_names.Add(GetFieldReference());
        	count = br.ReadInt32();
        	List<constant_node> prop_values = new List<constant_node>();
        	for (int i=0; i<count; i++)
        		prop_values.Add((constant_node)CreateExpression());
        	count = br.ReadInt32();
			List<constant_node> field_values = new List<constant_node>();
        	for (int i=0; i<count; i++)
        		field_values.Add((constant_node)CreateExpression());
        	location loc = ReadDebugInfo();
        	attribute_node attr = new attribute_node(fn,tn,loc);
        	attr.qualifier = quaifier;
        	attr.args.AddRange(args);
        	attr.prop_names.AddRange(prop_names);
        	attr.field_names.AddRange(field_names);
        	attr.prop_initializers.AddRange(prop_values);
        	attr.field_initializers.AddRange(field_values);
        	return attr;
        }