private void PublishPackageVersion(IPackageItemContainer folder, XmlElement parentElement, string relativePath)
        {
            var directory = Path.Combine(RootDirectory, relativePath.Replace("/", "\\"));

            if (!IsZipStreamModel && !EnsureDirectoryCreated(directory))
            {
                return;
            }

            var itemNames = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            var folders = folder.Items.OfType <PackageFolder>();

            foreach (var fd in folders)
            {
                var folderName = string.IsNullOrEmpty(fd.TransitName) ? fd.Name : fd.TransitName;
                if (itemNames.Contains(folderName))
                {
                    Errors.Add(string.Format(Lang._("The existence of items in folder \"{0}\" with the same name \"{1}\""), relativePath, folderName));
                    continue;
                }
                itemNames.Add(folderName);

                var node = parentElement.OwnerDocument.CreateElement("folder");
                node.SetAttribute("name", fd.Name);
                if (!string.IsNullOrEmpty(fd.TransitName))
                {
                    node.SetAttribute("transit_name", fd.TransitName);
                }
                parentElement.AppendChild(node);

                PublishPackageVersion(fd, node, relativePath + fd.Name + "/");
            }

            var files = folder.Items.OfType <PackageFile>();

            foreach (var file in files)
            {
                if (file == null || string.IsNullOrEmpty(file.Path))
                {
                    continue;
                }
                if (!File.Exists(file.Path))
                {
                    Errors.Add(string.Format(Lang._("File \"{0}\" not exists"), file.Path));
                    continue;
                }

                var filename = string.IsNullOrEmpty(file.TransitName) ? file.Name : file.TransitName;
                if (itemNames.Contains(filename))
                {
                    Errors.Add(string.Format(Lang._("The existence of items in folder \"{0}\" with the same name \"{1}\""), relativePath, filename));
                    continue;
                }

                itemNames.Add(filename);
                if (IsZipStreamModel)
                {
                    var entry = Zip.CreateEntry(Path.Combine(relativePath, filename));
                    using (var stream = entry.Open())
                    {
                        using (var source = new FileStream(file.Path, FileMode.Open, FileAccess.Read))
                        {
                            source.CopyTo(stream);
                        }
                    }
                }
                else
                {
                    var destFileName = Path.Combine(directory, filename);
                    if (File.Exists(destFileName))
                    {
                        try
                        {
                            File.Delete(destFileName);
                        }
                        catch (Exception ex)
                        {
                            Errors.Add(string.Format(Lang._("Delete File \"{0}\" Failed"), file.Path) + "\n" + ex.Message);
                            continue;
                        }
                    }
                    File.Copy(file.Path, destFileName);
                }

                //
                var node = parentElement.OwnerDocument.CreateElement("file");
                node.SetAttribute("name", file.Name);
                node.SetAttribute("hash", file.CreateHash());
                if (!string.IsNullOrEmpty(file.TransitName))
                {
                    node.SetAttribute("transit_name", file.TransitName);
                }
                if (!string.IsNullOrEmpty(file.Version))
                {
                    node.SetAttribute("version", file.Version);
                }
                if (file.Action != FileAction.Default)
                {
                    node.SetAttribute("action", file.Action.ToString());
                }
                if (file.CompareMode != FileCompareMode.Default)
                {
                    node.SetAttribute("compare_mode", file.CompareMode.ToString());
                }
                parentElement.AppendChild(node);

                //
                itemNames.Add(filename);
            }
        }