/**
         * Resolve a simple or qualified rule name as a full rule name.
         *
         * @param ruleName
         *            the name of the rule.
         */
        public JSGFRuleName Resolve(JSGFRuleName ruleName)
        {
            // System.out.println ("Resolving " + ruleName);
            JSGFRuleName rn = new JSGFRuleName(ruleName.GetRuleName());

            String simpleName      = rn.GetSimpleRuleName();
            String grammarName     = rn.GetSimpleGrammarName();
            String packageName     = rn.GetPackageName();
            String fullGrammarName = rn.GetFullGrammarName();

            // Check for badly formed RuleName
            if (packageName != null && grammarName == null)
            {
                throw new JSGFGrammarException("Error: badly formed rulename " + rn);
            }

            if (ruleName.GetSimpleRuleName().Equals("NULL"))
            {
                return(JSGFRuleName.Null);
            }

            if (ruleName.GetSimpleRuleName().Equals("VOID"))
            {
                return(JSGFRuleName.Void);
            }

            // Check simple case: a local rule reference
            if (fullGrammarName == null && GetRule(simpleName) != null)
            {
                return(new JSGFRuleName(_name + '.' + simpleName));
            }

            // Check for fully-qualified reference
            if (fullGrammarName != null)
            {
                JSGFRuleGrammar g = _manager.RetrieveGrammar(fullGrammarName);
                if (g != null)
                {
                    if (g.GetRule(simpleName) != null)
                    {
                        // we have a successful resolution
                        return(new JSGFRuleName(fullGrammarName + '.' + simpleName));
                    }
                }
            }

            // Collect all matching imports into a list. After trying to
            // match rn to each import statement the vec will have
            // size()=0 if rn is unresolvable
            // size()=1 if rn is properly resolvable
            // size()>1 if rn is an ambiguous reference
            List <JSGFRuleName> matches = new List <JSGFRuleName>();

            // Get list of imports
            // Add local grammar to simply the case of checking for
            // a qualified or fully-qualified local reference.
            List <JSGFRuleName> imports = new List <JSGFRuleName>(this.Imports);

            imports.Add(new JSGFRuleName(_name + ".*"));

            // Check each import statement for a possible match
            foreach (JSGFRuleName importName in imports)
            {
                // TO-DO: update for JSAPI 1.0
                String importSimpleName      = importName.GetSimpleRuleName();
                String importGrammarName     = importName.GetSimpleGrammarName();
                String importFullGrammarName = importName.GetFullGrammarName();

                // Check for badly formed import name
                if (importFullGrammarName == null)
                {
                    throw new JSGFGrammarException("Error: badly formed import " + ruleName);
                }

                // Get the imported grammar
                JSGFRuleGrammar gref = _manager.RetrieveGrammar(importFullGrammarName);
                if (gref == null)
                {
                    Console.WriteLine("Warning: import of unknown grammar " + ruleName + " in " + _name);
                    continue;
                }

                // If import includes simpleName, test that it really exists
                if (!importSimpleName.Equals("*") && gref.GetRule(importSimpleName) == null)
                {
                    Console.WriteLine("Warning: import of undefined rule " + ruleName + " in " + _name);
                    continue;
                }

                // Check for fully-qualified or qualified reference
                if (importFullGrammarName.Equals(fullGrammarName) || importGrammarName.Equals(fullGrammarName))
                {
                    // Know that either
                    // import <ipkg.igram.???> matches <pkg.gram.???>
                    // OR
                    // import <ipkg.igram.???> matches <gram.???>
                    // (ipkg may be null)

                    if (importSimpleName.Equals("*"))
                    {
                        if (gref.GetRule(simpleName) != null)
                        {
                            // import <pkg.gram.*> matches <pkg.gram.rulename>
                            matches.Add(new JSGFRuleName(importFullGrammarName + '.' + simpleName));
                        }
                        continue;
                    }
                    else
                    {
                        // Now testing
                        // import <ipkg.igram.iRuleName> against <??.gram.ruleName>
                        //
                        if (importSimpleName.Equals(simpleName))
                        {
                            // import <pkg.gram.rulename> exact match for
                            // <???.gram.rulename>
                            matches.Add(new JSGFRuleName(importFullGrammarName + '.' + simpleName));
                        }
                        continue;
                    }
                }

                // If we get here and rulename is qualified or fully-qualified
                // then the match failed - try the next import statement
                if (fullGrammarName != null)
                {
                    continue;
                }

                // Now test
                // import <ipkg.igram.*> against <simpleName>

                if (importSimpleName.Equals("*"))
                {
                    if (gref.GetRule(simpleName) != null)
                    {
                        // import <pkg.gram.*> matches <simpleName>
                        matches.Add(new JSGFRuleName(importFullGrammarName + '.' + simpleName));
                    }
                    continue;
                }

                // Finally test
                // import <ipkg.igram.iSimpleName> against <simpleName>

                if (importSimpleName.Equals(simpleName))
                {
                    matches.Add(new JSGFRuleName(importFullGrammarName + '.' + simpleName));
                    continue;
                }
            }

            // The return behavior depends upon number of matches
            switch (matches.Count)
            {
            case 0:     // Return null if rulename is unresolvable
                return(null);

            case 1:     // Return successfully
                return(matches[0]);

            default:     // Throw exception if ambiguous reference
                StringBuilder b = new StringBuilder();
                b.Append("Warning: ambiguous reference ").Append(rn).Append(" in ").Append(_name).Append(" to ");
                foreach (JSGFRuleName tmp in matches)
                {
                    b.Append(tmp).Append(" and ");
                }
                b.Length = (b.Length - 5);
                throw new JSGFGrammarException(b.ToString());
            }
        }