/// <summary>
        /// Maps a specified <see cref="Snippet"/> to the newly created <see cref="CodeSnippetElement"/>, optionally modifying serialization process.
        /// </summary>
        /// <param name="snippet">A <see cref="Snippet"/> to be serialized.</param>
        /// <param name="settings">A <see cref="SaveSettings"/> that modify serialization process.</param>
        /// <returns>Newly created <see cref="CodeSnippetElement"/>.</returns>
        public static CodeSnippetElement MapToElement(Snippet snippet, SaveSettings settings)
        {
            if (snippet == null)
                throw new ArgumentNullException(nameof(snippet));

            if (settings == null)
                throw new ArgumentNullException(nameof(settings));

            var context = new SerializationContext(snippet, settings);

            SerializeVersion(snippet.FormatVersion, context);

            context.Element.Header = CreateHeaderElement(context);
            context.Element.Snippet = CreateSnippetElement(context);

            return context.Element;
        }
        private static HeaderElement CreateHeaderElement(SerializationContext context)
        {
            var element = new HeaderElement();
            Snippet snippet = context.Snippet;

            if (!string.IsNullOrEmpty(snippet.Title))
                element.Title = snippet.Title;

            if (!string.IsNullOrEmpty(snippet.Author))
                element.Author = snippet.Author;

            if (!string.IsNullOrEmpty(snippet.Description))
                element.Description = snippet.Description;

            if (!string.IsNullOrEmpty(snippet.Shortcut))
                element.Shortcut = snippet.Shortcut;

            if (snippet.HelpUrl != null)
                element.HelpUrl = snippet.HelpUrl.ToString();

            if (snippet.SnippetTypes != SnippetTypes.None)
                element.SnippetTypes = GetSnippetTypes(snippet.SnippetTypes).ToArray();

            if (snippet.Keywords.Count > 0)
                element.Keywords = snippet.Keywords.ToArray();

            if (snippet.HasAlternativeShortcuts)
                element.AlternativeShortcuts = snippet.AlternativeShortcuts.ToArray();

            return element;
        }
        private static CodeElement CreateCodeElement(SerializationContext context)
        {
            var element = new CodeElement();
            Snippet snippet = context.Snippet;

            if (!string.IsNullOrEmpty(snippet.CodeText))
            {
                if (TextUtility.ContainsCDataEnd(snippet.CodeText))
                    throw new InvalidOperationException("Snippet code cannot contain CDATA ending sequence ']]>'.");

                element.Code = snippet.CodeText;
            }

            if (!snippet.HasDefaultDelimiter || !context.Settings.OmitDefaultDelimiter)
                element.Delimiter = new string(snippet.Delimiter, 1);

            if (snippet.ContextKind != ContextKind.None)
                element.Kind = snippet.ContextKind.ToString();

            element.Language = LanguageMapper.Instance.MapEnumToText(snippet.Language);

            return element;
        }
        private static IEnumerable<ObjectElement> CreateObjectElements(SerializationContext context)
        {
            foreach (Literal literal in context.Snippet.Literals.Where(f => !string.IsNullOrEmpty(f.TypeName)))
            {
                var element = new ObjectElement();

                if (!string.IsNullOrEmpty(literal.DefaultValue))
                    element.Default = literal.DefaultValue;

                if (!string.IsNullOrEmpty(literal.Identifier))
                    element.ID = literal.Identifier;

                element.Editable = literal.IsEditable;
                element.Function = literal.Function;
                element.ToolTip = literal.ToolTip;
                element.Type = literal.TypeName;

                yield return element;
            }
        }
        private static DeclarationsElement CreateDeclarationsElement(SerializationContext context)
        {
            var elements = new DeclarationsElement();

            LiteralElement[] literals = CreateLiteralElements(context).ToArray();

            ObjectElement[] objects = CreateObjectElements(context).ToArray();

            if (literals.Length > 0)
                elements.Literals = literals;

            if (objects.Length > 0)
                elements.Objects = objects;

            return elements;
        }
        private static SnippetElement CreateSnippetElement(SerializationContext context)
        {
            var element = new SnippetElement();

            element.Code = CreateCodeElement(context);

            if (context.Snippet.Literals.Count > 0)
                element.Declarations = CreateDeclarationsElement(context);

            element.Imports = CreateImportsElements(context.Snippet.Namespaces);
            element.References = CreateReferenceElements(context.Snippet.AssemblyReferences);

            return element;
        }
 private static void SerializeVersion(Version version, SerializationContext context)
 {
     if (ValidationHelper.IsValidVersion(version))
         context.Element.Format = version.ToString(3);
     else if (context.Settings.SetDefaultFormat)
         context.Element.Format = Snippet.DefaultFormatVersionText;
 }