protected internal virtual void Populate(Env env, IDictionary <string, string> attributes, Func <Pair <Env, string>, K> getKey)
        {
            Edu.Stanford.Nlp.Ling.Tokensregex.ComplexNodePattern <M, K> p = this;
            foreach (string attr in attributes.Keys)
            {
                string value = attributes[attr];
                K      c     = getKey.Apply(Pair.MakePair(env, attr));
                if (c != null)
                {
                    if (value.StartsWith("\"") && value.EndsWith("\""))
                    {
                        value = Sharpen.Runtime.Substring(value, 1, value.Length - 1);
                        value = value.ReplaceAll("\\\\\"", "\"");
                        // Unescape quotes...
                        p.Add(c, new ComplexNodePattern.StringAnnotationPattern(value, env.defaultStringMatchFlags));
                    }
                    else
                    {
                        if (value.StartsWith("/") && value.EndsWith("/"))
                        {
                            value = Sharpen.Runtime.Substring(value, 1, value.Length - 1);
                            value = value.ReplaceAll("\\\\/", "/");
                            // Unescape forward slash
                            string regex = (env != null) ? env.ExpandStringRegex(value) : value;
                            int    flags = (env != null) ? env.defaultStringPatternFlags : 0;
                            p.Add(c, NewStringRegexPattern(regex, flags));
                        }
                        else
                        {
                            if (value.StartsWith("::"))
                            {
                                switch (value)
                                {
                                case "::IS_NIL":
                                case "::NOT_EXISTS":
                                {
                                    p.Add(c, new ComplexNodePattern.NilAnnotationPattern());
                                    break;
                                }

                                case "::EXISTS":
                                case "::NOT_NIL":
                                {
                                    p.Add(c, new ComplexNodePattern.NotNilAnnotationPattern());
                                    break;
                                }

                                case "::IS_NUM":
                                {
                                    p.Add(c, new ComplexNodePattern.NumericAnnotationPattern(0, ComplexNodePattern.NumericAnnotationPattern.CmpType.IsNum));
                                    break;
                                }

                                default:
                                {
                                    bool ok = false;
                                    if (env != null)
                                    {
                                        object custom = env.Get(value);
                                        if (custom != null)
                                        {
                                            p.Add(c, (NodePattern)custom);
                                            ok = true;
                                        }
                                    }
                                    if (!ok)
                                    {
                                        throw new ArgumentException("Invalid value " + value + " for key: " + attr);
                                    }
                                    break;
                                }
                                }
                            }
                            else
                            {
                                if (value.StartsWith("<="))
                                {
                                    double v = double.Parse(Sharpen.Runtime.Substring(value, 2));
                                    p.Add(c, new ComplexNodePattern.NumericAnnotationPattern(v, ComplexNodePattern.NumericAnnotationPattern.CmpType.Le));
                                }
                                else
                                {
                                    if (value.StartsWith(">="))
                                    {
                                        double v = double.Parse(Sharpen.Runtime.Substring(value, 2));
                                        p.Add(c, new ComplexNodePattern.NumericAnnotationPattern(v, ComplexNodePattern.NumericAnnotationPattern.CmpType.Ge));
                                    }
                                    else
                                    {
                                        if (value.StartsWith("=="))
                                        {
                                            double v = double.Parse(Sharpen.Runtime.Substring(value, 2));
                                            p.Add(c, new ComplexNodePattern.NumericAnnotationPattern(v, ComplexNodePattern.NumericAnnotationPattern.CmpType.Eq));
                                        }
                                        else
                                        {
                                            if (value.StartsWith("!="))
                                            {
                                                double v = double.Parse(Sharpen.Runtime.Substring(value, 2));
                                                p.Add(c, new ComplexNodePattern.NumericAnnotationPattern(v, ComplexNodePattern.NumericAnnotationPattern.CmpType.Ne));
                                            }
                                            else
                                            {
                                                if (value.StartsWith(">"))
                                                {
                                                    double v = double.Parse(Sharpen.Runtime.Substring(value, 1));
                                                    p.Add(c, new ComplexNodePattern.NumericAnnotationPattern(v, ComplexNodePattern.NumericAnnotationPattern.CmpType.Gt));
                                                }
                                                else
                                                {
                                                    if (value.StartsWith("<"))
                                                    {
                                                        double v = double.Parse(Sharpen.Runtime.Substring(value, 1));
                                                        p.Add(c, new ComplexNodePattern.NumericAnnotationPattern(v, ComplexNodePattern.NumericAnnotationPattern.CmpType.Lt));
                                                    }
                                                    else
                                                    {
                                                        if (value.Matches("[A-Za-z0-9_+-.]+"))
                                                        {
                                                            p.Add(c, new ComplexNodePattern.StringAnnotationPattern(value, env.defaultStringMatchFlags));
                                                        }
                                                        else
                                                        {
                                                            throw new ArgumentException("Invalid value " + value + " for key: " + attr);
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    throw new ArgumentException("Unknown annotation key: " + attr);
                }
            }
        }
 public static Edu.Stanford.Nlp.Ling.Tokensregex.ComplexNodePattern ValueOf <M, K>(Env env, IDictionary <string, string> attributes, IBiFunction <M, K, object> getter, Func <Pair <Env, string>, K> getKey)
 {
     Edu.Stanford.Nlp.Ling.Tokensregex.ComplexNodePattern <M, K> p = new Edu.Stanford.Nlp.Ling.Tokensregex.ComplexNodePattern <M, K>(getter, new List <Pair <K, NodePattern> >(attributes.Count));
     p.Populate(env, attributes, getKey);
     return(p);
 }