boolean isOperator(Name name) {
                int i = 0;
                while (i < name.len &&
                       "+-~!*/%&|^<>=".indexOf(name.byteAt(i)) >= 0) i++;
                return i > 0 && i == name.len;
            }
    }

    /** Resolve error class indicating that a symbol is not accessible.
     */
    class AccessError extends ResolveError {

        AccessError(Symbol sym) {
            this(null, null, sym);
        }

        AccessError(Env<AttrContext> env, Type site, Symbol sym) {
            super(HIDDEN, sym, "access error");
            this.env = env;
            this.site = site;
            if (debugResolve)
                log.error("proc.messager", sym + " @ " + site + " is inaccessible.");
        }

        private Env<AttrContext> env;
        private Type site;

        /** Report error.
         *  @param log       The error log to be used for error reporting.
         *  @param pos       The position to be used for error reporting.
         *  @param site      The original type from where the selection took place.
         *  @param name      The name of the symbol to be resolved.
         *  @param argtypes  The invocation's value arguments,
         *                   if we looked for a method.
         *  @param typeargtypes  The invocation's type arguments,
         *                   if we looked for a method.
         */
        void report(Log log, DiagnosticPosition pos, Type site, Name name,
                    List<Type> argtypes, List<Type> typeargtypes) {
            if (sym.owner.type.tag != ERROR) {
                if (sym.name == sym.name.table.init && sym.owner != site.tsym)
                    new ResolveError(ABSENT_MTH, sym.owner, "absent method " + sym).report(
                        log, pos, site, name, argtypes, typeargtypes);
                if ((sym.flags() & PUBLIC) != 0
                    || (env != null && this.site != null
                        && !isAccessible(env, this.site)))
                    log.error(pos, "not.def.access.class.intf.cant.access",
                        sym, sym.location());
                else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0)
                    log.error(pos, "report.access", sym,
                              TreeInfo.flagNames(sym.flags() & (PRIVATE | PROTECTED)),
                              sym.location());
                else
                    log.error(pos, "not.def.public.cant.access",
                              sym, sym.location());
            }
        }
    }

    /** Resolve error class indicating that an instance member was accessed
     *  from a static context.
     */
    class StaticError extends ResolveError {
        StaticError(Symbol sym) {
            super(STATICERR, sym, "static error");
        }

        /** Report error.
         *  @param log       The error log to be used for error reporting.
         *  @param pos       The position to be used for error reporting.
         *  @param site      The original type from where the selection took place.
         *  @param name      The name of the symbol to be resolved.
         *  @param argtypes  The invocation's value arguments,
         *                   if we looked for a method.
         *  @param typeargtypes  The invocation's type arguments,
         *                   if we looked for a method.
         */
        void report(Log log,
                    DiagnosticPosition pos,
                    Type site,
                    Name name,
                    List<Type> argtypes,
                    List<Type> typeargtypes) {
            String symstr = ((sym.kind == TYP && sym.type.tag == CLASS)
                ? types.erasure(sym.type)
                : sym).toString();
            log.error(pos, "non-static.cant.be.ref",
                      kindName(sym), symstr);
        }
    }

    /** Resolve error class indicating an ambiguous reference.
     */
    class AmbiguityError extends ResolveError {
        Symbol sym1;
        Symbol sym2;

        AmbiguityError(Symbol sym1, Symbol sym2) {
            super(AMBIGUOUS, sym1, "ambiguity error");
            this.sym1 = sym1;
            this.sym2 = sym2;
        }

        /** Report error.
         *  @param log       The error log to be used for error reporting.
         *  @param pos       The position to be used for error reporting.
         *  @param site      The original type from where the selection took place.
         *  @param name      The name of the symbol to be resolved.
         *  @param argtypes  The invocation's value arguments,
         *                   if we looked for a method.
         *  @param typeargtypes  The invocation's type arguments,
         *                   if we looked for a method.
         */
        void report(Log log, DiagnosticPosition pos, Type site, Name name,
                    List<Type> argtypes, List<Type> typeargtypes) {
            AmbiguityError pair = this;
            while (true) {
                if (pair.sym1.kind == AMBIGUOUS)
                    pair = (AmbiguityError)pair.sym1;
                else if (pair.sym2.kind == AMBIGUOUS)
                    pair = (AmbiguityError)pair.sym2;
                else break;
            }
            Name sname = pair.sym1.name;
            if (sname == sname.table.init) sname = pair.sym1.owner.name;
            log.error(pos, "ref.ambiguous", sname,
                      kindName(pair.sym1),
                      pair.sym1,
                      pair.sym1.location(site, types),
                      kindName(pair.sym2),
                      pair.sym2,
                      pair.sym2.location(site, types));
        }