//TODO: Если одного из акцессоров нет?
        public override void visit(SyntaxTree.simple_property _simple_property)
        {
            if (_simple_property.accessors == null)
                AddError(get_location(_simple_property), "PROPERTYACCESSOR_{0}_OR_{1}_EXPECTED", compiler_string_consts.PascalReadAccessorName, compiler_string_consts.PascalWriteAccessorName);
            if (_simple_property.property_type == null)
                AddError(get_location(_simple_property.property_name), "TYPE_NAME_EXPECTED");
            common_property_node pn = context.add_property(_simple_property.property_name.name,
                get_location(_simple_property.property_name));
            assign_doc_info(pn, _simple_property);
            //pn.polymorphic_state=SemanticTree.polymorphic_state.ps_common;
            //pn.loc=get_location(_simple_property.property_name);
            if (_simple_property.attr == SyntaxTree.definition_attribute.Static)
            	pn.polymorphic_state = SemanticTree.polymorphic_state.ps_static;
            parameter_list pal_big = new parameter_list();
            //TODO: Спросить у Саши как получить тип параметра - var,const и т.д.
            if (_simple_property.parameter_list != null)
            {
                foreach (SyntaxTree.property_parameter pp in _simple_property.parameter_list.parameters)
                {
                    parameter_list pal_small = new parameter_list();
                    foreach (SyntaxTree.ident id in pp.names.idents)
                    {
                        common_parameter cp = new common_parameter(id.name, SemanticTree.parameter_type.value, null,
                            concrete_parameter_type.cpt_none, get_location(id));
                        pal_small.AddElement(cp);
                    }
                    type_node tn = convert_strong(pp.type);
                    foreach (parameter pr in pal_small)
                    {
                        pr.type = tn;
                    }
                    pal_big.AddRange(pal_small);
                }
            }
            pn.parameters.AddRange(pal_big);
            pn.internal_property_type = convert_strong(_simple_property.property_type);

            if (_simple_property.accessors != null)
            {

                convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors);

                SymbolInfo si = null;
                //definition_node dn = null;

                if (_simple_property.accessors.read_accessor != null)
                {
                    convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors.read_accessor);
                    if (_simple_property.accessors.read_accessor.accessor_name == null)
                    {
                        if (!context.converted_type.IsInterface)
                        {
                            AddError(get_location(_simple_property.accessors.read_accessor), "ACCESSOR_NAME_EXPECTED");
                        }
                        pn.internal_get_function = GenerateGetSetMethodForInterfaceProperty(pn, get_location(_simple_property.accessors.read_accessor), true);
                    }
                    else
                    {
                        convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors.read_accessor.accessor_name);
                        si = context.converted_type.find_in_type(_simple_property.accessors.read_accessor.accessor_name.name, context.CurrentScope);

                        location loc1 = get_location(_simple_property.accessors.read_accessor.accessor_name);

                        if (si == null)
                        {
                            AddError(new UndefinedNameReference(_simple_property.accessors.read_accessor.accessor_name.name, loc1));
                        }

                        //dn = check_name_node_type(_simple_property.accessors.read_accessor.accessor_name.name,
                        //    si, loc1, general_node_type.function_node, general_node_type.variable_node);

                        function_node read_accessor = si.sym_info as function_node;

                        if (read_accessor != null)
                        {
                            bool good_func = true;
                            bool one_func = si.Next == null;
                            while (si != null)
                            {
                                good_func = true;
                                if (read_accessor.parameters.Count != pn.parameters.Count)
                                {
                                    good_func = false;
                                    if (one_func)
                                    {
                                        AddError(new PropertyAndReadAccessorParamsCountConvergence(read_accessor, pn, loc1));
                                    }
                                }
                                //TODO: Сверять типы параметров - var, const и т.д.
                                else
                                {
                                    for (int i1 = 0; good_func && i1 < read_accessor.parameters.Count; i1++)
                                    {
                                        if (read_accessor.parameters[i1].parameter_type != pn.parameters[i1].parameter_type ||
                                            read_accessor.parameters[i1].type != pn.parameters[i1].type)
                                        {
                                            good_func = false;
                                            if (one_func)
                                            {
                                                AddError(loc1, "PROPERTY_{0}_AND_READ_ACCESSOR_{1}_PARAMS_TYPE_CONVERGENCE", pn.name, read_accessor.name);
                                            }
                                        }
                                    }
                                    if (read_accessor.return_value_type == null)
                                    {
                                        good_func = false;
                                        if (one_func)
                                        {
                                            AddError(loc1, "PROPERTY_READ_ACCESSOR_CAN_NOT_BE_PROCEDURE");
                                        }
                                    }
                                    if (read_accessor.return_value_type != pn.property_type)
                                    {
                                        good_func = false;
                                        if (one_func)
                                        {
                                            AddError(loc1, "PROPERTY_{0}_AND_READ_ACCESSOR_{1}_RETURN_VALUE_TYPE_CONVERGENCE", pn.name, read_accessor.name);
                                        }
                                    }
                                    if (read_accessor is common_method_node && (read_accessor as common_method_node).is_constructor)
                                    {
                                        AddError(loc1, "ACCESSOR_CAN_BE_FIELD_OR_METHOD_ONLY");
                                    }
                                }
                                if (good_func)
                                {
                                    break;
                                }
                                si = si.Next;
                                if (si != null)
                                {
                                    read_accessor = si.sym_info as function_node;
                                }
                            }
                            if (!good_func)
                            {
                                AddError(loc1, "NO_OVERLOAD_FUNCTION_{0}_USEFUL_FOR_ACCESSOR", read_accessor.name);
                            }
                            read_accessor = GenerateGetMethod(pn,read_accessor as common_method_node,pn.loc);
                           
                        }
                        else
                        {
                            class_field cfield = si.sym_info as class_field;
                            if (cfield == null)
                            {
                                AddError(loc1, "ACCESSOR_CAN_BE_FIELD_OR_METHOD_ONLY");
                            }
                            if (_simple_property.parameter_list != null)
                            {
                                AddError(loc1, "INDEX_PROPERTY_ACCESSOR_CAN_NOT_BE_VARIABLE");
                            }
                            if (cfield.type != pn.internal_property_type)
                            {
                                AddError(loc1, "PROPERTY_TYPE_MISMATCH_ACCESSOR_FIELD_TYPE");
                            }
                            if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state != SemanticTree.polymorphic_state.ps_static)
                        		AddError(get_location(_simple_property.accessors.read_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", cfield.name);
                    		if (pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state == SemanticTree.polymorphic_state.ps_static)
                                AddError(get_location(_simple_property.accessors.read_accessor.accessor_name), "ACCESSOR_{0}_CANNOT_BE_STATIC", cfield.name);
                            read_accessor = GenerateGetMethodForField(pn, compiler_string_consts.GetGetAccessorName(pn.name), cfield, loc1);
                        }
                       
                        //Вот здесь уже можем добавить акцессор для чтения.
                        pn.internal_get_function = read_accessor;
                    }
                    if (pn.internal_get_function != null && pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && pn.internal_get_function.polymorphic_state != SemanticTree.polymorphic_state.ps_static)
                        AddError(get_location(_simple_property.accessors.read_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", pn.internal_get_function.name);
                    if (pn.internal_get_function != null && pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && pn.internal_get_function.polymorphic_state == SemanticTree.polymorphic_state.ps_static)
                        AddError(get_location(_simple_property.accessors.read_accessor.accessor_name),  "ACCESSOR_{0}_CANNOT_BE_STATIC", pn.internal_get_function.name);
                }

                if (_simple_property.accessors.write_accessor != null)
                {
                    convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors.write_accessor);
                    if (_simple_property.accessors.write_accessor.accessor_name == null)
                    {
                        if (!context.converted_type.IsInterface)
                        {
                            AddError(get_location(_simple_property.accessors.write_accessor), "ACCESSOR_NAME_EXPECTED");
                        }
                        pn.internal_set_function = GenerateGetSetMethodForInterfaceProperty(pn, get_location(_simple_property.accessors.write_accessor), false);
                    }
                    else
                    {
                        convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors.write_accessor.accessor_name);
                        si = context.converted_type.find_in_type(_simple_property.accessors.write_accessor.accessor_name.name, context.CurrentScope);

                        location loc2 = get_location(_simple_property.accessors.write_accessor.accessor_name);

                        if (si == null)
                        {
                            AddError( new UndefinedNameReference(_simple_property.accessors.write_accessor.accessor_name.name, loc2));
                        }

                        //dn = check_name_node_type(_simple_property.accessors.write_accessor.accessor_name.name,
                        //    si, loc2, general_node_type.function_node, general_node_type.variable_node);

                        function_node write_accessor = si.sym_info as function_node;

                        if (write_accessor != null)
                        {
                            bool good_func = true;
                            bool one_func = si.Next == null;
                            while (si != null)
                            {
                                good_func = true;
                                if (write_accessor.parameters.Count != pn.parameters.Count + 1)
                                {
                                    good_func = false;
                                    if (one_func)
                                    {
                                        AddError( new PropertyAndWriteAccessorParamsCountConvergence(write_accessor, pn, loc2));
                                    }
                                }
                                else
                                {
                                    //TODO: Сверять типы параметров - var, const и т.д.
                                    for (int i2 = 0; good_func && i2 < pn.parameters.Count; i2++)
                                    {
                                        if (write_accessor.parameters[i2].parameter_type != pn.parameters[i2].parameter_type ||
                                            write_accessor.parameters[i2].type != pn.parameters[i2].type)
                                        {
                                            good_func = false;
                                            if (one_func)
                                            {
                                                AddError(loc2, "PROPERTY_{0}_AND_WRITE_ACCESSOR_{1}_PARAMS_TYPE_CONVERGENCE", pn.name ,write_accessor.name);
                                            }
                                        }
                                    }
                                    if (write_accessor.parameters[write_accessor.parameters.Count - 1].type != pn.property_type ||
                                        write_accessor.parameters[write_accessor.parameters.Count - 1].parameter_type != PascalABCCompiler.SemanticTree.parameter_type.value)
                                    {
                                        good_func = false;
                                        if (one_func)
                                        {
                                            AddError(loc2, "PROPERTY_{0}_AND_WRITE_ACCESSOR_LAST_PARAMETER_TYPE_CONVERGENCE", pn.name);
                                        }
                                    }
                                    if (write_accessor.return_value_type != null)
                                    {
                                        good_func = false;
                                        if (one_func)
                                        {
                                            AddError(loc2, "PROPERTY_WRITE_ACCESSOR_CAN_NOT_BE_FUNCTION");
                                        }
                                    }
                                }
                                if (good_func)
                                {
                                    break;
                                }
                                si = si.Next;
                                if (si != null)
                                {
                                    write_accessor = si.sym_info as function_node;
                                }
                            }
                            if (!good_func)
                            {
                                AddError(loc2, "NO_OVERLOAD_FUNCTION_{0}_USEFUL_FOR_ACCESSOR", write_accessor.name);
                            }
                            if (write_accessor is common_method_node && (write_accessor as common_method_node).is_constructor)
                            {
                                AddError(loc2, "ACCESSOR_CAN_BE_FIELD_OR_METHOD_ONLY");
                            }
                            write_accessor = GenerateSetMethod(pn, write_accessor as common_method_node, pn.loc);
                        }
                            else
                            {
                                class_field cfield = si.sym_info as class_field;
                                if (cfield == null)
                                {
                                    AddError(loc2, "ACCESSOR_CAN_BE_FIELD_OR_METHOD_ONLY");
                                }
                                if (_simple_property.parameter_list != null)
                                {
                                    AddError(loc2, "INDEX_PROPERTY_ACCESSOR_CAN_NOT_BE_VARIABLE");
                                }
                                if (cfield.type != pn.internal_property_type)
                                {
                                    AddError(loc2, "PROPERTY_TYPE_MISMATCH_ACCESSOR_FIELD_TYPE");
                                }
                                if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state != SemanticTree.polymorphic_state.ps_static)
                        			AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", cfield.name);
                    			if (pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state == SemanticTree.polymorphic_state.ps_static)
                        			AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_CANNOT_BE_STATIC", cfield.name);
                                write_accessor = GenerateSetMethodForField(pn, compiler_string_consts.GetSetAccessorName(pn.name), cfield, loc2);
                            }
                            //Вот здесь уже можем добавить акцессор для чтения.
                            pn.internal_set_function = write_accessor;
                        }
                    if (pn.internal_set_function != null && pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && pn.internal_set_function.polymorphic_state != SemanticTree.polymorphic_state.ps_static)
                        AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", pn.internal_set_function.name);
                    if (pn.internal_set_function != null && pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && pn.internal_set_function.polymorphic_state == SemanticTree.polymorphic_state.ps_static)
                        AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_CANNOT_BE_STATIC", pn.internal_set_function.name);
                }
            }
            make_attributes_for_declaration(_simple_property,pn);
            //TODO: Можно сделать множество свойств по умолчанию.
            if (_simple_property.array_default != null)
            {
                if (pn.parameters.Count == 0)
                {
                    AddError(pn.loc, "DEFAULT_PROPERTY_MUST_BE_INDEXED");
                }
                if (context.converted_type.default_property_node != null)
                {
                    AddError(pn.loc, "DUPLICATE_DEFAULT_PROPERTY_IN_CLASS");
                }
                context.converted_type.default_property = pn;
            }
        }
		public void init_delegate(common_type_node ctn, type_node return_value_type, parameter_list parameters,
		                                        location loc)
		{
			common_method_node constructor=new common_method_node(compiler_string_consts.default_constructor_name,null,loc,ctn,SemanticTree.polymorphic_state.ps_common,
			                                                      SemanticTree.field_access_level.fal_public,
			                                                      convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope));
			constructor.is_constructor = true;
			constructor.return_value_type = ctn;
			constructor.function_code=new runtime_statement(SemanticTree.runtime_statement_type.ctor_delegate,loc);

			common_method_node invoke=new common_method_node(compiler_string_consts.invoke_method_name,
			                                                 return_value_type,loc,ctn,SemanticTree.polymorphic_state.ps_virtual,
			                                                 SemanticTree.field_access_level.fal_public,
			                                                 convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope));
			ctn.add_name(compiler_string_consts.invoke_method_name,new SymbolInfo(invoke));
			for (int i=0; i<parameters.Count; i++)
			{
				if (parameters[i] is compiled_parameter)
				{
					parameters[i] = new common_parameter(parameters[i].name,parameters[i].type,parameters[i].parameter_type,invoke,concrete_parameter_type.cpt_none,null,null);
				}
			}
				
			invoke.parameters.AddRange(parameters);
			invoke.function_code = new runtime_statement(SemanticTree.runtime_statement_type.invoke_delegate, loc);

			common_method_node begin_invoke = new common_method_node(compiler_string_consts.begin_invoke_method_name,
			                                                         begin_invoke_result_type, loc, ctn, SemanticTree.polymorphic_state.ps_virtual, SemanticTree.field_access_level.fal_public,
			                                                         convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope));
			ctn.add_name(compiler_string_consts.begin_invoke_method_name,new SymbolInfo(begin_invoke));
			parameter_list begin_invoke_params=new parameter_list();
			begin_invoke_params.AddRange(parameters);
			common_parameter cp=new common_parameter(compiler_string_consts.callback_string,begin_invoke_parameter_type,
			                                         SemanticTree.parameter_type.value,begin_invoke,concrete_parameter_type.cpt_none,
			                                         null,loc);
			begin_invoke_params.AddElement(cp);
			cp = new common_parameter(compiler_string_consts.object_in_par_string, SystemLibrary.SystemLibrary.object_type,
			                          SemanticTree.parameter_type.value,begin_invoke, concrete_parameter_type.cpt_none,
			                          null, loc);
			begin_invoke_params.AddElement(cp);
			begin_invoke.parameters.AddRange(begin_invoke_params);
			begin_invoke.function_code = new runtime_statement(SemanticTree.runtime_statement_type.begin_invoke_delegate, loc);

			common_method_node end_invoke = new common_method_node(compiler_string_consts.end_invoke_method_name,
			                                                       return_value_type, loc, ctn, SemanticTree.polymorphic_state.ps_virtual, SemanticTree.field_access_level.fal_public,
			                                                       convertion_data_and_alghoritms.symbol_table.CreateScope(ctn.scope));
			ctn.add_name(compiler_string_consts.end_invoke_method_name,new SymbolInfo(end_invoke));
			cp = new common_parameter(compiler_string_consts.result_string, begin_invoke_result_type,
			                          SemanticTree.parameter_type.value, end_invoke, concrete_parameter_type.cpt_none,
			                          null, loc);
			end_invoke.parameters.AddElement(cp);
			end_invoke.function_code = new runtime_statement(SemanticTree.runtime_statement_type.end_invoke_delegate, loc);

			ctn.methods.AddElement(constructor);
			ctn.methods.AddElement(invoke);
			ctn.methods.AddElement(begin_invoke);
			ctn.methods.AddElement(end_invoke);

			SystemLibrary.SystemLibrary.init_reference_type(ctn);

			delegate_internal_interface dii = new delegate_internal_interface(return_value_type, invoke, constructor);
			dii.parameters.AddRange(parameters);

			ctn.add_internal_interface(dii);
			AddOperatorsToDelegate(ctn, loc);
		}