// parses a list of MappingCharFilter style rules into a custom byte[] type table
        private sbyte[] parseTypes(IList <string> rules)
        {
            SortedMap <char?, sbyte?> typeMap = new SortedDictionary <char?, sbyte?>();

            foreach (string rule in rules)
            {
                Matcher m = typePattern.matcher(rule);
                if (!m.find())
                {
                    throw new System.ArgumentException("Invalid Mapping Rule : [" + rule + "]");
                }
                string lhs = parseString(m.group(1).Trim());
                sbyte? rhs = parseType(m.group(2).Trim());
                if (lhs.Length != 1)
                {
                    throw new System.ArgumentException("Invalid Mapping Rule : [" + rule + "]. Only a single character is allowed.");
                }
                if (rhs == null)
                {
                    throw new System.ArgumentException("Invalid Mapping Rule : [" + rule + "]. Illegal type.");
                }
                typeMap.put(lhs[0], rhs);
            }

            // ensure the table is always at least as big as DEFAULT_WORD_DELIM_TABLE for performance
            sbyte[] types = new sbyte[Math.Max(typeMap.LastKey() + 1, WordDelimiterIterator.DEFAULT_WORD_DELIM_TABLE.Length)];
            for (int i = 0; i < types.Length; i++)
            {
                types[i] = WordDelimiterIterator.getType(i);
            }
            foreach (KeyValuePair <char?, sbyte?> mapping in typeMap.EntrySet())
            {
                types[mapping.Key] = mapping.Value;
            }
            return(types);
        }