/// <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);
        }