private void HandleEventDeclaration(
            DoshikParser.TypeTypeOrVoidContext eventReturnTypeCtx,
            string eventCodeName,
            DoshikParser.FormalParametersContext eventParametersCtx,
            DoshikParser.BlockContext eventBodyCtx
            )
        {
            var eventDeclaration = new EventDeclaration(_compilationContext.CompilationUnit);

            eventDeclaration.Parameters = new MethodDeclarationParameters(eventDeclaration, _compilationContext.CompilationUnit.Scope);

            _currentMethodDeclaration = eventDeclaration;

            eventDeclaration.Name = eventCodeName;

            var foundType = GetTypeNameVisitor.Apply(_compilationContext, eventReturnTypeCtx);

            foundType.ThrowIfNotFound(_compilationContext);
            eventDeclaration.ReturnTypeOrVoid = foundType.DataType;

            eventDeclaration.ExternalEvent = _compilationContext.FindExternalApiEventByCodeName(eventDeclaration.Name);

            if (_compilationContext.CompilationUnit.Events.ContainsKey(eventDeclaration.Name))
            {
                throw _compilationContext.ThrowCompilationError($"event handler { eventDeclaration.Name } is already defined");
            }

            eventDeclaration.Parameters.Parameters.AddRange((List <MethodDeclarationParameter>)Visit(eventParametersCtx));

            eventDeclaration.AntlrBody = eventBodyCtx;

            if (eventDeclaration.IsCustom)
            {
                ValidateCustomEvent(eventDeclaration);
            }
            else
            {
                ValidateBuiltInEvent(eventDeclaration);
            }

            _compilationContext.CompilationUnit.Events[eventDeclaration.Name] = eventDeclaration;
        }