/// <summary>
        /// Converts the specified grammatic tag collection into string format according to loaded specification
        /// </summary>
        /// <param name="tag">The tag.</param>
        /// <returns></returns>
        public string ConvertToString(grammaticTagCollection tag)
        {
            var sb   = new StringBuilder();
            var tags = tag.GetTags();

            var pos_t = tags.getFirstOfType <pos_type>(false, pos_type.none, true);

            if (pos_t == pos_type.none)
            {
                sb.Append("-");
            }
            else
            {
                var typePattern = posTypeVsPattern[pos_t];


                sb.Append(posEnumVsString.GetOfTypeByKey(pos_t));

                foreach (Type t in typePattern)
                {
                    var pos = tag.Get(t);
                    if (pos == null)
                    {
                        sb.Append("-");
                    }
                    else
                    {
                        String p = posEnumVsString.GetOfTypeByKey(pos);
                        if (p.isNullOrEmpty())
                        {
                            sb.Append("-");
                        }
                        else
                        {
                            sb.Append(p);
                        }
                    }
                }
            }
            return(sb.ToString());
        }
        /// <summary>
        /// Builds <see cref="grammaticTagCollection"/> instance from string form
        /// </summary>
        /// <param name="tag">The string encoding that is to be interpreted into grammatic tag</param>
        /// <returns>Instance of grammaticTagCollection built from the string input</returns>
        /// <exception cref="ArgumentOutOfRangeException">Tag flag [" + s+ "] not resolved in [" +t.Name + "] - tag</exception>
        public grammaticTagCollection ConvertFromString(string tag)
        {
            grammaticTagCollection output = new grammaticTagCollection();

            if (cachedTags.ContainsKey(tag))
            {
                cachedTags[tag].ForEach(x => output.Add(x));
                return(output);
            }

            if (tag.isNullOrEmpty())
            {
                return(output);
            }

            string pos_type_str = tag[0].ToString();

            object        pt    = posEnumVsString.GetOfTypeByValue(pos_type_str, typeof(pos_type));
            List <Object> flags = new List <object>();

            try
            {
                if (pt != null)
                {
                    pos_type pos_t = (pos_type)pt; //.GetByValue(pos_type_str);
                    flags.Add(pos_t);

                    List <Type> typeList = posTypeVsPattern[pos_t];
                    for (int i = 1; i < tag.Length; i++)
                    {
                        string s = tag[i].toStringSafe("");

                        if (s != "-")
                        {
                            Type t = typeList[i - 1];

                            object f = posEnumVsString.GetOfTypeByValue(s, t);

                            if (f == null)
                            {
                                List <Object> values = posEnumVsString.GetByValue(s);
                                foreach (object vl in values)
                                {
                                    if (!flags.Any(x => x.GetType() == vl.GetType()))
                                    {
                                        flags.Add(vl);
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                flags.Add(f);
                            }

                            //if (f == null)
                            //{
                            //    throw new ArgumentOutOfRangeException("Tag flag [" + s + "] not resolved in [" + t.Name + "]", nameof(tag));
                            //}
                        }
                    }

                    flags.ForEach(x => output.Add(x));
                    cachedTags.TryAdd(tag, flags);
                }
            }
            catch (Exception ex)
            {
                String msg = "[" + ex.Message + "] ---> [" + ex.GetType().Name + "] ";
                output.comment = msg;
                aceLog.log(msg);
            }

            return(output);
        }