public override void visit(assign assignment)
        {
            var to   = assignment.to as ident;
            var from = assignment.from;

            if (to != null &&
                assignment.operator_type == Operators.Assignment &&
                to.name.ToLower() == RESULT_KEY_WORD)
            {
                var converted = syntaxTreeVisitor.convert_strong(from);
                if (converted is typed_expression)
                {
                    delegated_methods dm = converted.type as delegated_methods;
                    if (dm.empty_param_method != null)
                    {
                        converted = syntaxTreeVisitor.convert_typed_expression_to_function_call(converted as typed_expression);
                    }
                }
                resultExpressionsTypes.Add(new Tuple <type_node, expression, expression_node>(converted.type, from, converted));
            }
        }
        public override void visit(ident id)
        {
            var idName = id.name.ToLower();

            SymbolInfo si = _visitor.context.find_first(idName);

            if (si == null)
            {
                if (InLambdaContext)
                {
                    _visitor.AddError(new ThisTypeOfVariablesCannotBeCaptured(_visitor.get_location(id)));
                    return;
                }
                return;
            }

            if (si.sym_info.semantic_node_type == semantic_node_type.namespace_variable ||
                si.sym_info.semantic_node_type == semantic_node_type.common_namespace_function_node ||
                si.sym_info.semantic_node_type == semantic_node_type.namespace_constant_definition ||
                si.sym_info.semantic_node_type == semantic_node_type.compiled_function_node ||
                si.sym_info.semantic_node_type == semantic_node_type.common_method_node || // SSM bug fix  #167
                si.sym_info.semantic_node_type == semantic_node_type.compiled_namespace_node ||
                si.sym_info.semantic_node_type == semantic_node_type.compiled_variable_definition ||
                si.sym_info.semantic_node_type == semantic_node_type.common_type_node ||
                si.sym_info.semantic_node_type == semantic_node_type.compiled_type_node ||
                si.sym_info.semantic_node_type == semantic_node_type.basic_interface_node ||
                si.sym_info.semantic_node_type == semantic_node_type.common_unit_node ||
                si.sym_info.semantic_node_type == semantic_node_type.compiled_unit_node ||
                si.sym_info.semantic_node_type == semantic_node_type.template_type ||
                si.sym_info.semantic_node_type == semantic_node_type.basic_function_node && idName == "exit")
            {
                return;
            }

            var acceptableVarType = si.sym_info.semantic_node_type == semantic_node_type.local_variable ||
                                    si.sym_info.semantic_node_type == semantic_node_type.local_block_variable ||
                                    si.sym_info.semantic_node_type == semantic_node_type.common_parameter ||
                                    si.sym_info.semantic_node_type == semantic_node_type.class_field
            ;

            if (!(acceptableVarType) && InLambdaContext)
            {
                _visitor.AddError(new ThisTypeOfVariablesCannotBeCaptured(_visitor.get_location(id)));
                return;
            }

            /*if (si.sym_info.semantic_node_type == semantic_node_type.class_field && InLambdaContext)
             * {
             *  var semClassField = (class_field)si.sym_info;
             *  if (semClassField.polymorphic_state != polymorphic_state.ps_common)
             *  {
             *      _visitor.AddError(new ThisTypeOfVariablesCannotBeCaptured(_visitor.get_location(id)));
             *      return;
             *  }
             * }*/

            if (si.scope == null)
            {
                return;
            }

            var scopeIndex      = si.scope.ScopeNum;
            var selfWordInClass = false;

            CapturedVariablesTreeNode scope;

            if (_scopesCapturedVarsNodesDictionary.TryGetValue(scopeIndex, out scope))
            {
                var prScope = scope as CapturedVariablesTreeNodeProcedureScope;
                if (prScope != null && acceptableVarType)
                {
                    if (si.sym_info.semantic_node_type == semantic_node_type.local_variable)
                    {
                        if (!(idName == compiler_string_consts.self_word && si.scope is PascalSharp.Internal.TreeConverter.SymbolTable.ClassMethodScope && _classScope != null) && InLambdaContext)
                        {
                            _visitor.AddError(new ThisTypeOfVariablesCannotBeCaptured(_visitor.get_location(id)));
                        }
                    }
                    if (si.sym_info.semantic_node_type == semantic_node_type.common_parameter && prScope.FunctionNode.parameters.First(v => v.name.ToLower() == idName).parameter_type != parameter_type.value && InLambdaContext)
                    {
                        _visitor.AddError(new CannotCaptureNonValueParameters(_visitor.get_location(id)));
                    }

                    if (idName == compiler_string_consts.self_word && si.scope is PascalSharp.Internal.TreeConverter.SymbolTable.ClassMethodScope &&
                        _classScope != null)
                    {
                        var selfField = _classScope.VariablesDefinedInScope.Find(var => var.SymbolInfo == si);

                        if (selfField == null)
                        {
                            _classScope.VariablesDefinedInScope.Add(
                                new CapturedVariablesTreeNode.CapturedSymbolInfo(null, si));
                        }

                        selfWordInClass = true;
                    }
                    else
                    {
                        var field = prScope.VariablesDefinedInScope.Find(var => var.SymbolInfo == si);

                        if (field == null)
                        {
                            prScope.VariablesDefinedInScope.Add(new CapturedVariablesTreeNode.CapturedSymbolInfo(null,
                                                                                                                 si));
                        }
                    }
                }

                var clScope = scope as CapturedVariablesTreeNodeClassScope;
                if (clScope != null && acceptableVarType)
                {
                    var field = clScope.VariablesDefinedInScope.Find(var => var.SymbolInfo == si);

                    if (field == null)
                    {
                        clScope.VariablesDefinedInScope.Add(new CapturedVariablesTreeNode.CapturedSymbolInfo(null, si));
                    }

                    if (si.access_level != access_level.al_public)
                    {
                        if (!clScope.NonPublicMembersNamesMapping.ContainsKey(idName))
                        {
                            var name          = LambdaHelper.GetNameForNonPublicMember(idName);
                            var semClassField = (class_field)si.sym_info;
                            var pn            = new common_property_node(name, _visitor.context._ctn, null, field_access_level.fal_public, semClassField.polymorphic_state);
                            pn.internal_property_type = _visitor.convert_strong(id).type;
                            clScope.NonPublicMembersNamesMapping.Add(idName, new Tuple <string, class_field, semantic_node>(name, semClassField, pn));
                        }
                    }
                }

                var idRef = (selfWordInClass ? _classScope : scope)
                            .VariablesDefinedInScope
                            .Find(var => var.SymbolInfo == si);

                if (idRef == null)                                     //TODO: Осторожнее переделать
                {
                    {
                        return;
                    }
                }

                if (_currentTreeNode.CorrespondingSyntaxTreeNode != null)
                {
                    var varName  = ((IVAriableDefinitionNode)idRef.SymbolInfo.sym_info).name;                     //TODO: случай параметров и полей класса!!!!!!!!!!!!!!!!!!
                    var substKey = new SubstitutionKey(varName, idRef.SyntaxTreeNodeWithVarDeclaration, _currentTreeNode.CorrespondingSyntaxTreeNode);

                    if (!_identsReferences.ContainsKey(substKey))
                    {
                        _identsReferences.Add(substKey, new List <ident>());
                    }

                    _identsReferences[substKey].Add(id);
                }

                if (InLambdaContext && scope is CapturedVariablesTreeNodeLambdaScope &&
                    scopeIndex < _currentLambdaScopeNodeStack.Peek().ScopeIndex) //TODO: Захват параметров лямбды в другой лямбде
                {
                    _visitor.AddError(new ThisTypeOfVariablesCannotBeCaptured(_visitor.get_location(id)));
                    return;
                }

                if (!InLambdaContext ||
                    scopeIndex >= _currentLambdaScopeNodeStack.Peek().ScopeIndex)
                {
                    return;
                }

                var stackAsList = _currentLambdaScopeNodeStack.ToList();
                stackAsList.RemoveAt(0);

                if (!_currentLambdaScopeNodeStack.Peek().CapturedVarsSymbolInfo.Contains(si))
                {
                    _currentLambdaScopeNodeStack.Peek().CapturedVarsSymbolInfo.Add(si);
                    foreach (var capturedVariablesTreeNodeLambdaScope in stackAsList)
                    {
                        if (!capturedVariablesTreeNodeLambdaScope.CapturedVarsSymbolInfo.Contains(si))
                        {
                            capturedVariablesTreeNodeLambdaScope.CapturedVarsSymbolInfo.Add(si);
                        }
                    }
                }
                if (!idRef.ReferencingLambdas.Contains(_currentLambdaScopeNodeStack.Peek()))
                {
                    idRef.ReferencingLambdas.Add(_currentLambdaScopeNodeStack.Peek());
                    foreach (var capturedVariablesTreeNodeLambdaScope in stackAsList)
                    {
                        if (!idRef.ReferencingLambdas.Contains(capturedVariablesTreeNodeLambdaScope))
                        {
                            idRef.ReferencingLambdas.Add(capturedVariablesTreeNodeLambdaScope);
                        }
                    }
                }
            }
        }