public override void ExecuteBuild()
        {
            DLCName = ParseParamValue("Plugin", "");
            DLCDir = CombinePaths(CmdEnv.LocalRoot, "UnrealTournament", "Plugins", DLCName);
            PluginsDir = CombinePaths(CmdEnv.LocalRoot, "UnrealTournament", "Plugins");
            PublishDir = CombinePaths(DLCDir, "Releases");

            // Right now all platform asset registries seem to be the exact same, this may change in the future
            AssetRegistry = ParseParamValue("ReleaseVersion", "UTVersion0");
            VersionString = ParseParamValue("Version", "NOVERSION");

            FileVersionName = VERSION_NAME;

            // prevent processing automation process for the wrong plugin (if mutliple PluginPackageZip commands exist)
            if (!DLCName.Equals(PLUGIN_NAME, StringComparison.InvariantCultureIgnoreCase))
            {
                // no Expception as other plugins need to be processed
                return;
            }

            // Check parms
            if (!DirectoryExists(DLCDir))
            {
                throw new AutomationException("Plugin folder '{0}' does not exist. Verify that '-plugin={1}' is set up properly.", DLCDir, DLCName);
            }
            if (new DirectoryInfo(PluginsDir).FullName.Equals(new DirectoryInfo(DLCDir).FullName, StringComparison.InvariantCultureIgnoreCase))
            {
                throw new AutomationException("No Plugin given. Verify that '-plugin=PLUGINNAME' is set.");
            }

            // Check for changed files in the git repo and abort
            if (!ParseParam("NoGitCheck"))
            {
                string GitFolder = CombinePaths(DLCDir, GIT_FOLDER_NAME);
                if (DirectoryExists(GitFolder))
                {
                    using (var repo = new LibGit2Sharp.Repository(GitFolder))
                    {
                        LibGit2Sharp.StatusOptions check = new LibGit2Sharp.StatusOptions();
                        check.ExcludeSubmodules = true;

                        LibGit2Sharp.RepositoryStatus status = repo.RetrieveStatus(check);
                        if (status.IsDirty)
                        {
                            throw new AutomationException("Git code repository has uncommited changes.");
                        }

                        foreach (LibGit2Sharp.Submodule submodule in repo.Submodules)
                        {
                            LibGit2Sharp.SubmoduleStatus substatus = submodule.RetrieveStatus();
                            if (!substatus.HasFlag(LibGit2Sharp.SubmoduleStatus.Unmodified))
                            {
                                throw new AutomationException("Git sub module '{0}' has uncommited changes.", submodule.Name);
                            }
                        }
                    }
                }
            }

            // Check if binaries exist
            {
                string BinariesFolder = CombinePaths(DLCDir, "Binaries");
                if (!DirectoryExists(BinariesFolder))
                {
                    throw new AutomationException("No Binaries folder. Please, recompile the plugin from source files");
                }

                // TODO: Check for specific files (SO for linux and DLL for windows)
                if (FindFiles("*", true, BinariesFolder).Length == 0)
                {
                    throw new AutomationException("No binary files. Please, recompile the plugin from source files");
                }
            }

            //
            // Create filter list to exclude folder/files from zip
            //

            FileFilter Filter = new FileFilter();
            Filter.ExcludeConfidentialFolders();
            Filter.ExcludeConfidentialPlatforms();

            // read git ignore file and add these to the filder
            var FilterInclude = new List<string>();
            var FilterExclude = new List<string>();
            {
                string GitFolder = CombinePaths(DLCDir, GIT_FOLDER_NAME);
                if (DirectoryExists(GitFolder))
                {
                    using (var repo = new LibGit2Sharp.Repository(GitFolder))
                    {
                        var subrepos = new List<LibGit2Sharp.Repository>();
                        foreach (LibGit2Sharp.Submodule submodule in repo.Submodules)
                        {
                            string SubFolder = CombinePaths(DLCDir, submodule.Path);
                            if (DirectoryExists(SubFolder))
                            {
                                string relpath = SubFolder.Substring(DLCDir.Length).Replace("\\", "/").Trim('/');
                                FilterExclude.Add("/" + relpath + "/**");
                                subrepos.Add(new LibGit2Sharp.Repository(SubFolder));
                            }
                        }

                        foreach (var file in FindFiles("*", true, DLCDir))
                        {
                            bool subuntracked = false;
                            foreach (var subrepo in subrepos)
                            {
                                if (file.StartsWith(subrepo.Info.WorkingDirectory))
                                {
                                    LibGit2Sharp.FileStatus substatus = subrepo.RetrieveStatus(file);
                                    if (substatus == LibGit2Sharp.FileStatus.Untracked)
                                    {
                                        subuntracked = true;
                                        string relpath = file.Substring(DLCDir.Length).Replace("\\", "/").TrimStart('/');
                                        FilterInclude.Add(relpath);
                                        break;
                                    }
                                }
                            }

                            if (!subuntracked)
                            {
                                LibGit2Sharp.FileStatus status = repo.RetrieveStatus(file);

                                if (status == LibGit2Sharp.FileStatus.Untracked)
                                {
                                    string relpath = file.Substring(DLCDir.Length).Replace("\\", "/").TrimStart('/');
                                    FilterInclude.Add(relpath);
                                }
                            }
                        }

                        foreach (var subrepo in subrepos)
                        {
                            subrepo.Dispose();
                        }
                        subrepos.Clear();
                    }
                }

                string GitIgnoreFile = CombinePaths(DLCDir, GIT_IGNORE_FILE);
                if (FileExists(GitIgnoreFile))
                {
                    //HasGitIgnore = true;
                    var GitIgnores = GitIgnoreParser.ReadFromFile(GitIgnoreFile);

                    foreach (var entry in GitIgnores.Entries)
                    {
                        string pattern = entry.Pattern;
                        if (entry.Pattern.EndsWith("/")) pattern += "**";
                        if (entry.Type == GitIgnoreParser.GitIgnoreTypInfo.Include)
                        {
                            FilterInclude.Add(pattern);
                        }
                        else if (entry.Type == GitIgnoreParser.GitIgnoreTypInfo.Exclude)
                        {
                            FilterExclude.Add(pattern);
                        }
                    }
                }
            }

            // TODO: Add build file for includes

            // include bin and plugin content but only valid editor files
            foreach (var f in FilterExclude)
            {
                Filter.Include(f.Replace("**", "..."));
            }

            if (FilterInclude.Count == 0)
            {
                Filter.Include("Readme*");
                Filter.Include("*.txt");
                Filter.Include("*.md");
                Filter.Include("*.pod");
            }
            else
            {
                Filter.Include("/*.*");
            }

            // Add source if required
            if (ParseParam("source"))
            {
                Filter.Include("/Source/...");
                Filter.Include("/Build/...");
                Filter.Exclude("/Build/.../Obj/...");
            }
            else
            {
                Filter.Exclude("/Build/...");
            }

            foreach (var f in FilterInclude)
            {
                Filter.Exclude(f.Replace("**", "..."));
            }

            Filter.Include("/Binaries/...");

            // ignore debug symbols
            Filter.Exclude("/Binaries/.../*.pdb");

            // ignore git files
            Filter.Exclude(".git*");
            Filter.Exclude(".git/...");

            // always include plugin descriptor file
            Filter.Include("*.uplugin");

            // exclude releaes foldre
            Filter.Exclude("/Releases/...");
            Filter.Exclude("/Releases/.../...");

            // read current version info from file
            CreateVersionInfo();

            // create meta info which is stored in BuildMeta
            CreateMetaInfo();

            // create file name
            string ZipFileName = GenerateFileName() + ".zip";
            string ZipFile = CombinePaths(PublishDir, ZipFileName);
            string ZipDir = CombinePaths(CmdEnv.LocalRoot, "UnrealTournament", "Plugins", DLCName);

            // check if file exists and abort...
            if (FileExists(ZipFile) && !ParseParam("overwrite"))
            {
                throw new AutomationException("Release file {0} already exists.", ZipFileName);
            }

            string zipfolder = Packager.CopyFilesToZip(PublishDir, ZipDir, DLCName, Filter, NoConversion: HasParam("source"), ParseTextOnly: HasParam("ParseTextOnly"));
            ZipFiles(ZipFile, zipfolder, new FileFilter(FileFilterType.Include));

            if (ParseParam("publish") && BuildVersion.IsValid())
            {
                bool IsInternal = false;
                if (ParseParam("release"))
                {
                    // remove internal build (public release) ... just in case
                    DataWriteToFile(FileVersionName, BuildVersion.ToData(true));
                }
                else
                {
                    IsInternal = true;

                    // increase internal build
                    BuildVersion.BuildAsNumber += 1;
                    DataWriteToFile(FileVersionName, BuildVersion.ToData());
                }

                string GitFolder = CombinePaths(DLCDir, GIT_FOLDER_NAME);
                if (ParseParam("commit") && DirectoryExists(GitFolder))
                {
                    using (var repo = new LibGit2Sharp.Repository(GitFolder))
                    {
                        string commmessage;
                        if (IsInternal)
                            commmessage = string.Format(COMMIT_TITLE_VERSION_INTERNAL, BuildVersion.ToString());
                        else
                            commmessage = string.Format(COMMIT_TITLE_VERSION_PUBLISH, BuildVersion.ToShortVersion());

                        commmessage += Environment.NewLine;
                        commmessage += Environment.NewLine;

                        commmessage += BuildMeta.ToExtendedString();

                        // Stage the file
                        LibGit2Sharp.StageOptions stageoptions = new LibGit2Sharp.StageOptions();
                        repo.Stage(FileVersionName, stageoptions);

                        // Create the committer's signature and commit
                        LibGit2Sharp.Signature author = repo.Config.BuildSignature(DateTime.Now);
                        LibGit2Sharp.Signature committer = author;

                        // Commit to the repository
                        LibGit2Sharp.CommitOptions options = new LibGit2Sharp.CommitOptions();
                        LibGit2Sharp.Commit commit = repo.Commit(commmessage, author, committer, options);

                        // Commit new tag
                        LibGit2Sharp.Tag t = repo.Tags.Add(string.Format("v{0}", BuildVersion.ToShortVersion()), repo.Head.Tip);
                    }
                }
            }
        }