public override MorphoFeatures FromTagString(string str)
            {
                string[]       feats  = str.Split("\\-");
                MorphoFeatures mFeats = new ArabicMorphoFeatureSpecification.ArabicMorphoFeatures();

                // First element is the base POS
                //      String baseTag = feats[0];
                for (int i = 1; i < feats.Length; i++)
                {
                    string[] keyValue = feats[i].Split(KeyValDelim);
                    if (keyValue.Length != 2)
                    {
                        continue;
                    }
                    MorphoFeatureSpecification.MorphoFeatureType fName = MorphoFeatureSpecification.MorphoFeatureType.ValueOf(keyValue[0].Trim());
                    mFeats.AddFeature(fName, keyValue[1].Trim());
                }
                return(mFeats);
            }
        /// <summary>Hand-written rules to convert SAMA analyses to feature structures.</summary>
        public override MorphoFeatures StrToFeatures(string spec)
        {
            MorphoFeatures features = new ArabicMorphoFeatureSpecification.ArabicMorphoFeatures();

            // Check for the boundary symbol
            if (spec == null || spec.Equals(string.Empty))
            {
                return(features);
            }
            //Possessiveness
            if (IsActive(MorphoFeatureSpecification.MorphoFeatureType.Poss) && spec.Contains("POSS"))
            {
                features.AddFeature(MorphoFeatureSpecification.MorphoFeatureType.Poss, possVals[0]);
            }
            //Nominals and pronominals. Mona ignores Pronominals in ERTS, but they seem to help...
            // NSUFF -- declinable nominals
            // VSUFF -- enclitic pronominals
            // PRON -- ordinary pronominals
            if (spec.Contains("NSUFF") || spec.Contains("NOUN") || spec.Contains("ADJ"))
            {
                // Nominal phi feature indicators are different than the indicators
                // that we process with processInflectionalFeatures()
                if (IsActive(MorphoFeatureSpecification.MorphoFeatureType.Ngen))
                {
                    if (spec.Contains("FEM"))
                    {
                        features.AddFeature(MorphoFeatureSpecification.MorphoFeatureType.Ngen, genVals[1]);
                    }
                    else
                    {
                        if (spec.Contains("MASC") || !pNounNoMorph.Matcher(spec).Find())
                        {
                            features.AddFeature(MorphoFeatureSpecification.MorphoFeatureType.Ngen, genVals[0]);
                        }
                    }
                }
                // WSGDEBUG -- Number for nominals only
                if (IsActive(MorphoFeatureSpecification.MorphoFeatureType.Nnum))
                {
                    if (spec.Contains("DU"))
                    {
                        features.AddFeature(MorphoFeatureSpecification.MorphoFeatureType.Nnum, numVals[1]);
                    }
                    else
                    {
                        if (spec.Contains("PL"))
                        {
                            features.AddFeature(MorphoFeatureSpecification.MorphoFeatureType.Nnum, numVals[2]);
                        }
                        else
                        {
                            if (!pNounNoMorph.Matcher(spec).Find())
                            {
                                // (spec.contains("SG"))
                                features.AddFeature(MorphoFeatureSpecification.MorphoFeatureType.Nnum, numVals[0]);
                            }
                        }
                    }
                }
                //Definiteness
                if (IsActive(MorphoFeatureSpecification.MorphoFeatureType.Def))
                {
                    if (spec.Contains("DET"))
                    {
                        features.AddFeature(MorphoFeatureSpecification.MorphoFeatureType.Def, defVals[1]);
                    }
                    else
                    {
                        if (!pNounNoMorph.Matcher(spec).Find())
                        {
                            features.AddFeature(MorphoFeatureSpecification.MorphoFeatureType.Def, defVals[0]);
                        }
                    }
                }
                // Proper nouns (probably a stupid feature)
                if (IsActive(MorphoFeatureSpecification.MorphoFeatureType.Prop))
                {
                    if (spec.Contains("PROP"))
                    {
                        features.AddFeature(MorphoFeatureSpecification.MorphoFeatureType.Prop, string.Empty);
                    }
                }
            }
            else
            {
                if (spec.Contains("PRON") || (spec.Contains("VSUFF_DO") && !pVerbMood.Matcher(spec).Find()))
                {
                    if (spec.Contains("DEM_PRON"))
                    {
                        features.AddFeature(MorphoFeatureSpecification.MorphoFeatureType.Def, defVals[0]);
                        Matcher m = pDemPronounFeatures.Matcher(spec);
                        if (m.Find())
                        {
                            spec = m.Group(1);
                            ProcessInflectionalFeaturesHelper(features, spec);
                        }
                    }
                    else
                    {
                        ProcessInflectionalFeatures(features, spec);
                    }
                }
                else
                {
                    // Verbs (marked for tense)
                    if (pVerbTenseMarker.Matcher(spec).Find())
                    {
                        // Tense feature
                        if (IsActive(MorphoFeatureSpecification.MorphoFeatureType.Tense))
                        {
                            if (spec.Contains("PV"))
                            {
                                features.AddFeature(MorphoFeatureSpecification.MorphoFeatureType.Tense, tenseVals[0]);
                            }
                            else
                            {
                                if (spec.Contains("IV"))
                                {
                                    features.AddFeature(MorphoFeatureSpecification.MorphoFeatureType.Tense, tenseVals[1]);
                                }
                                else
                                {
                                    if (spec.Contains("CV"))
                                    {
                                        features.AddFeature(MorphoFeatureSpecification.MorphoFeatureType.Tense, tenseVals[2]);
                                    }
                                }
                            }
                        }
                        // Inflectional features
                        ProcessInflectionalFeatures(features, spec);
                        if (IsActive(MorphoFeatureSpecification.MorphoFeatureType.Mood))
                        {
                            Matcher moodMatcher = pMood.Matcher(spec);
                            if (moodMatcher.Find())
                            {
                                string moodStr = moodMatcher.Group(1);
                                switch (moodStr)
                                {
                                case "I":
                                {
                                    features.AddFeature(MorphoFeatureSpecification.MorphoFeatureType.Mood, moodVals[0]);
                                    break;
                                }

                                case "S":
                                {
                                    features.AddFeature(MorphoFeatureSpecification.MorphoFeatureType.Mood, moodVals[1]);
                                    break;
                                }

                                case "J":
                                {
                                    features.AddFeature(MorphoFeatureSpecification.MorphoFeatureType.Mood, moodVals[2]);
                                    break;
                                }
                                }
                            }
                        }
                        if (IsActive(MorphoFeatureSpecification.MorphoFeatureType.Voice))
                        {
                            if (spec.Contains("PASS"))
                            {
                                features.AddFeature(MorphoFeatureSpecification.MorphoFeatureType.Voice, voiceVals[1]);
                            }
                            else
                            {
                                features.AddFeature(MorphoFeatureSpecification.MorphoFeatureType.Voice, voiceVals[0]);
                            }
                        }
                    }
                }
            }
            return(features);
        }