void GenerateEventHelper(List <GeneratedEventMetadata> generatedEvents)
        {
            var eventMetadataHash         = GeneratedEventMetadata.GetHash(generatedEvents);
            var eventMetadataHashHex      = HexUtil.GetHexFromBytes(eventMetadataHash);
            var eventMetadataHashHexBytes = Encoding.ASCII.GetBytes(eventMetadataHashHex);

            var outputFilePath = Path.Combine(_generatedContractsDirectory, EventHelperFile + G_CS_FILE_EXT);

            if (!_returnFullSources && FileStartsWithHash(outputFilePath, eventMetadataHashHexBytes))
            {
                _logger("Skipping writing already up-to-date source file: " + EventHelperFile);
                return;
            }

            var generator = new EventHelperGenerator(generatedEvents, _namespace);

            var(generatedCode, syntaxTree) = generator.GenerateSourceCode();
            using (var fs = new StreamWriter(outputFilePath, append: false, encoding: StringUtil.UTF8))
            {
                _logger("Writing source file: " + outputFilePath);
                fs.WriteLine("//" + eventMetadataHashHex);
                fs.WriteLine(generatedCode);

                var generatedCSharpEntry = new SolCodeGenCSharpResult(outputFilePath, generatedCode, syntaxTree);
                _genResults.GeneratedCSharpEntries.Add(generatedCSharpEntry);
            }
        }
        void GenerateSolcOutputDataFiles(
            OutputDescription solcOutput,
            Dictionary <string, string> soliditySourceContent,
            byte[] codeBaseHash)
        {
            var codeBaseHashBytes    = HexUtil.GetHexFromBytes(codeBaseHash);
            var codeBaseHashHexBytes = Encoding.ASCII.GetBytes(codeBaseHashBytes);

            var outputHelperFilePath = Path.Combine(_generatedContractsDirectory, SolcOutputDataHelperFile + G_CS_FILE_EXT);
            var outputResxFilePath   = Path.Combine(_generatedContractsDirectory, SolcOutputDataResxFile + G_RESX_FILE_EXT);

            if (!_returnFullSources && FileStartsWithHash(outputHelperFilePath, codeBaseHashHexBytes) && File.Exists(outputResxFilePath))
            {
                _logger("Skipping writing already up-to-date source file: " + SolcOutputDataHelperFile);
                _logger("Skipping writing already up-to-date source file: " + SolcOutputDataResxFile);
                return;
            }

            var solcOutputDataResxGenerator = new SolcOutputDataResxGenerator(solcOutput, soliditySourceContent, _solSourceDirectory, _solidityCompilerVersion);
            var solcOutputDataResxWriter    = solcOutputDataResxGenerator.GenerateResx();

            using (var fs = new StreamWriter(outputResxFilePath, append: false, encoding: new UTF8Encoding(false)))
            {
                solcOutputDataResxWriter.Save(fs);
                _genResults.GeneratedResxFilePath = outputResxFilePath;
            }

            var generator = new SolcOutputHelperGenerator(codeBaseHash, _namespace);

            var(generatedCode, syntaxTree) = generator.GenerateSourceCode();
            using (var fs = new StreamWriter(outputHelperFilePath, append: false, encoding: StringUtil.UTF8))
            {
                _logger("Writing source file: " + outputHelperFilePath);
                var hashHex = HexUtil.GetHexFromBytes(codeBaseHash);
                fs.WriteLine("//" + hashHex);
                fs.WriteLine(generatedCode);

                var generatedCSharpEntry = new SolCodeGenCSharpResult(outputHelperFilePath, generatedCode, syntaxTree);
                _genResults.GeneratedCSharpEntries.Add(generatedCSharpEntry);
            }

            if (_returnFullSources)
            {
                _genResults.GeneratedResxResources = solcOutputDataResxWriter.Resources;
            }
        }
        void GeneratedContractSourceFiles(
            ContractInfo[] contractInfos,
            List <GeneratedEventMetadata> generatedEvents)
        {
            int skippedAlreadyUpdated = 0;

            foreach (var contractInfo in contractInfos)
            {
                var(solFile, contractName, contract, hash, bytecode) = contractInfo;
                var hashHex          = HexUtil.GetHexFromBytes(hash);
                var hashHexBytes     = Encoding.ASCII.GetBytes(hashHex);
                var contactEventInfo = GeneratedEventMetadata.Parse(contractName, _namespace, contract).ToList();
                generatedEvents.AddRange(contactEventInfo);

                var outputFilePath = Path.Combine(_generatedContractsDirectory, contractName + G_CS_FILE_EXT);
                if (!_returnFullSources && FileStartsWithHash(outputFilePath, hashHexBytes))
                {
                    skippedAlreadyUpdated++;
                    continue;
                }

                var generator = new ContractGenerator(contractInfo, _solSourceDirectory, _namespace, contactEventInfo);
                var(generatedContractCode, syntaxTree) = generator.GenerateSourceCode();
                using (var fs = new StreamWriter(outputFilePath, append: false, encoding: StringUtil.UTF8))
                {
                    _logger("Writing source file: " + outputFilePath);
                    fs.WriteLine("//" + hashHex);
                    fs.WriteLine(generatedContractCode);

                    var generatedCSharpEntry = new SolCodeGenCSharpResult(outputFilePath, generatedContractCode, syntaxTree);
                    _genResults.GeneratedCSharpEntries.Add(generatedCSharpEntry);
                }
            }

            if (skippedAlreadyUpdated > 0)
            {
                _logger($"Detected already up-to-date generated files: {skippedAlreadyUpdated} contracts");
            }
        }