/** Set the value for the key in this context. */
  public <T> void put(Key<T> key, T data) {
    DEBUG.P(this, "put(Key<T> key, T data)");
    if (data != null) DEBUG.P("data=" + data.getClass().getName());
    else DEBUG.P("data=" + data);
    // DEBUG.P("context前="+toString());

    /*例如:
       Context context = new Context();
       Context.Key<Context.Factory> factoryKey =new Context.Key<Context.Factory>();
    context.put(factoryKey,new Context.Factory<String>(){public String make() {return "";}});

       出现如下类似异常:
       Exception in thread "main" java.lang.AssertionError: T extends Context.Factory

       因为Context.Key<T>的参数化类型不允许是Context.Key<Context.Factory>
       */
    if (data instanceof Factory) throw new AssertionError("T extends Context.Factory");
    checkState(ht);
    Object old = ht.put(key, data);
    if (old != null && !(old instanceof Factory) && old != data && data != null)
      throw new AssertionError("duplicate context value");

    DEBUG.P("context后=" + toString());
    DEBUG.P(0, this, "put(Key<T> key, T data)");
  }
    protected Enter(Context context) {
		DEBUG.P(this,"Enter(1)");
		context.put(enterKey, this);

		log = Log.instance(context);
		reader = ClassReader.instance(context);
		make = TreeMaker.instance(context);
		syms = Symtab.instance(context);
		chk = Check.instance(context);
		memberEnter = MemberEnter.instance(context);
		annotate = Annotate.instance(context);
		lint = Lint.instance(context);

		predefClassDef = make.ClassDef(
			make.Modifiers(PUBLIC),
			syms.predefClass.name, null, null, null, null);
		//predefClass是一个ClassSymbol(PUBLIC|ACYCLIC, names.empty, rootPackage)
		//且它的Scope members_field已有成员(几个基本类型符号(symbols for basic types)及其他操作符)
		//请参考Systab类的predefClass字段说明
		predefClassDef.sym = syms.predefClass;

		todo = Todo.instance(context);
		fileManager = context.get(JavaFileManager.class);
		
		names = Name.Table.instance(context);    //我加上的
		DEBUG.P(0,this,"Enter(1)");
    }
  private TypeHandler resolveTypeHandler(
      TypeHandlerFactory typeHandlerFactory,
      Class clazz,
      String propertyName,
      String javaType,
      String jdbcType) {
    try { // 我加上的
      DEBUG.P(this, "resolveTypeHandler(5)");

      TypeHandler handler = null;
      if (clazz == null) {
        // Unknown
        handler = typeHandlerFactory.getUnkownTypeHandler();
      } else if (DomTypeMarker.class.isAssignableFrom(clazz)) {
        // DOM
        handler = typeHandlerFactory.getTypeHandler(String.class, jdbcType);
      } else if (java.util.Map.class.isAssignableFrom(clazz)) {
        // Map
        if (javaType == null) {
          handler =
              typeHandlerFactory
                  .getUnkownTypeHandler(); // BUG 1012591 -
                                           // typeHandlerFactory.getTypeHandler(java.lang.Object.class, jdbcType);
        } else {
          try {
            javaType = typeHandlerFactory.resolveAlias(javaType);
            Class javaClass = Resources.classForName(javaType);
            handler = typeHandlerFactory.getTypeHandler(javaClass, jdbcType);
          } catch (Exception e) {
            throw new SqlMapException("Error.  Could not set TypeHandler.  Cause: " + e, e);
          }
        }
      } else if (typeHandlerFactory.getTypeHandler(clazz, jdbcType) != null) {
        // Primitive
        handler = typeHandlerFactory.getTypeHandler(clazz, jdbcType);
      } else {
        // JavaBean
        if (javaType == null) {

          Class type = PROBE.getPropertyTypeForGetter(clazz, propertyName);
          handler = typeHandlerFactory.getTypeHandler(type, jdbcType);

        } else {
          try {
            javaType = typeHandlerFactory.resolveAlias(javaType);
            Class javaClass = Resources.classForName(javaType);
            handler = typeHandlerFactory.getTypeHandler(javaClass, jdbcType);
          } catch (Exception e) {
            throw new SqlMapException("Error.  Could not set TypeHandler.  Cause: " + e, e);
          }
        }
      }
      return handler;

    } finally { // 我加上的
      DEBUG.P(0, this, "resolveTypeHandler(5)");
    }
  }
  public <T> void put(Class<T> clazz, Factory<T> fac) {
    DEBUG.P(this, "put(Class<T> clazz, Factory<T> fac)");
    if (fac != null) DEBUG.P("fac=" + fac.getClass().getName());
    else DEBUG.P("fac=" + fac);
    // DEBUG.P("context前="+toString());

    put(key(clazz), fac);

    // DEBUG.P("context后="+toString());
    DEBUG.P(0, this, "put(Class<T> clazz, Factory<T> fac)");
  }
  public <T> void put(Class<T> clazz, T data) {
    DEBUG.P(this, "put(Class<T> clazz, T data)");
    if (data != null) DEBUG.P("data=" + data.getClass().getName());
    else DEBUG.P("data=" + data);
    // DEBUG.P("context前="+toString());

    put(key(clazz), data);

    // DEBUG.P("context后="+toString());
    DEBUG.P(0, this, "put(Class<T> clazz, T data)");
  }
  public SqlText parseInlineParameterMap(
      TypeHandlerFactory typeHandlerFactory, String sqlStatement) {
    try { // 我加上的
      DEBUG.P(this, "parseInlineParameterMap(2)");

      return parseInlineParameterMap(typeHandlerFactory, sqlStatement, null);

    } finally { // 我加上的
      DEBUG.P(0, this, "parseInlineParameterMap(2)");
    }
  }
  public <T> T get(Class<T> clazz) {
    try {
      DEBUG.P(this, "get(Class<T> clazz)");
      if (clazz != null) DEBUG.P("clazz=" + clazz.getName());
      else DEBUG.P("clazz=" + clazz);

      return get(key(clazz));

    } finally {
      DEBUG.P(0, this, "get(Class<T> clazz)");
    }
  }
  /** Set the factory for the key in this context. */
  public <T> void put(Key<T> key, Factory<T> fac) {
    DEBUG.P(this, "put(Key<T> key, Factory<T> fac)");
    // DEBUG.P("context前="+toString())
    if (fac != null) DEBUG.P("fac=" + fac.getClass().getName());
    else DEBUG.P("fac=" + fac);

    checkState(ht);
    Object old = ht.put(key, fac);
    if (old != null) throw new AssertionError("duplicate context value");

    DEBUG.P("context后=" + toString());
    DEBUG.P(0, this, "put(Key<T> key, Factory<T> fac)");
  }
  /** Default constructor */
  public SessionScope() {
    try { // 我加上的
      DEBUG.P(this, "SessionScope()");

      this.preparedStatements = new HashMap();
      this.inBatch = false;
      this.requestStackDepth = 0;
      this.id = getNextId();

      DEBUG.P("this.id=" + this.id);

    } finally { // 我加上的
      DEBUG.P(0, this, "SessionScope()");
    }
  }
  public ServerErrorMessage(String p_serverError, int verbosity) {
    try { // 我加上的
      DEBUG.P(this, "ServerErrorMessage(2)");
      DEBUG.P("p_serverError=" + p_serverError);
      DEBUG.P("verbosity=" + verbosity);

      this.verbosity = verbosity;

      char[] l_chars = p_serverError.toCharArray();
      int l_pos = 0;
      int l_length = l_chars.length;
      while (l_pos < l_length) {
        char l_mesgType = l_chars[l_pos];
        if (l_mesgType != '\0') {
          l_pos++;
          int l_startString = l_pos;
          while (l_chars[l_pos] != '\0' && l_pos < l_length) {
            l_pos++;
          }
          String l_mesgPart = new String(l_chars, l_startString, l_pos - l_startString);
          m_mesgParts.put(new Character(l_mesgType), l_mesgPart);

          DEBUG.P("l_mesgPart=" + l_mesgPart);
          DEBUG.P("m_mesgParts=" + m_mesgParts);
        }
        l_pos++;
      }

      DEBUG.P("m_mesgParts=" + m_mesgParts);

    } finally { // 我加上的
      DEBUG.P(0, this, "ServerErrorMessage(2)");
    }
  }
  private <T> Key<T> key(Class<T> clss) {
    DEBUG.P(this, "key(Class<T> clss)");
    if (clss != null) DEBUG.P("clss=" + clss.getName());
    else DEBUG.P("clss=" + clss);

    checkState(kt);
    // 等价于Key<T> k = Context.<Key<T>>uncheckedCast(kt.get(clss));
    // 因为kt.get(clss)返回的类型是Key<T>,刚好与等式左边的类型一样
    Key<T> k = uncheckedCast(kt.get(clss));

    DEBUG.P("k=" + k);

    if (k == null) {
      k = new Key<T>();
      kt.put(clss, k);
    }

    DEBUG.P(0, this, "key(Class<T> clss)");
    return k;
  }
  /** Get the value for the key in this context. */
  public <T> T get(Key<T> key) {
    try {
      DEBUG.P(this, "get(Key<T> key)");
      // if(key!=null) DEBUG.P("key="+key.getClass().getName());
      // else DEBUG.P("key="+key);
      DEBUG.P("key=" + key);

      checkState(ht);
      Object o = ht.get(key);

      if (o != null) DEBUG.P("o=" + o.getClass().getName());
      else DEBUG.P("o=" + o);

      DEBUG.P("(o instanceof Factory)=" + (o instanceof Factory));

      if (o instanceof Factory) {
        Factory fac = (Factory) o;
        o = fac.make();
        if (o instanceof Factory) throw new AssertionError("T extends Context.Factory");
        // 也就是说在调用make()时已把make()返回的结果放入ht(例子见:JavacFileManager.preRegister())
        assert ht.get(key) == o;
      }

      /* The following cast can't fail unless there was
       * cheating elsewhere, because of the invariant on ht.
       * Since we found a key of type Key<T>, the value must
       * be of type T.
       */
      return Context.<T>uncheckedCast(o);

    } finally {
      DEBUG.P(0, this, "get(Key<T> key)");
    }
    /*
    注意这里的“<T>”与 “private static <T> T uncheckedCast(Object o)”中
    的“<T>”的差别,前者表示的是get(Key<T> key)方法中的“T”的实际类型,
    假设最开始:
    -------------------------------------
    Context context = new Context();
    Context.Key<Number> numberKey = new Context.Key<Number>();
    Number number=new Number();
    context.put(numberKey,number);

    number=context.get(numberKey);
    ------------------------------------
    这时把“numberKey”传进“get(Key<T> key)”方法,
    因为参数“numberKey”是“Context.Key<Number>”类型,
    所以get(Key<T> key)中的“T”的实际类型是“Number”。

    但是“get(Key<T> key)”方法里的“Object o = ht.get(key)”,
    变量“o”是Object类型的,必需调用“Context.<T>uncheckedCast(o)”将
    变量“o”引用的Object实例转换成“Number”类型,
    这样“number=context.get(numberKey)”得到的结果才正确。
    “Context.<T>uncheckedCast(o)”相当于把“Object o”转换成“<T>”(这里就是Number)

    像“Context.<T>uncheckedCast(o)”这种语法确实很古怪,
    这主要是由于“private static <T> T uncheckedCast(Object o)”方法的定义
    造成的,这个方法是一个静态泛型方法,而且只有返回类型与泛型变量“<T>”相关,
    方法参数只有( Object o ),并且不与泛型变量“<T>”相关,
    当要调用uncheckedCast方法时,可以用下面的格式调用它:
    Context.<返回值类型>uncheckedCast(参数Object o)

    返回值类型可以是泛型变量
    (泛型变量的实际类型在编译期间只能推断它的上限绑定,
    具体是什么类型只能在运行期间确定)


    假设最开始:
    Object o=new String("str");
    那么可以这样调用它:
    String str=Context.<String>uncheckedCast(o);(等价于: String str=(String)o)

    把“return Context.<T>uncheckedCast(o);”与uncheckedCast方法的调用格式对照
    “<T>”对应“<返回值类型>”,“(o)”对应“(参数Object o)”

    另外“uncheckedCast”方法的定义如下:
    --------------------------------------
    @SuppressWarnings("unchecked")
       private static <T> T uncheckedCast(Object o) {
           return (T)o;
       }
       --------------------------------------
       注释“@SuppressWarnings("unchecked")”间接指出了uncheckedCast方法会在
       运行时有可能产生转换异常(java.lang.ClassCastException),
       因为(T)的类型是未确定的,
       比如(T)的类型可能是“Number”,当参数(Object o)实际是String的实例引用时,
       这时“(T)o”就等价于“(Number)String”,显然是不对的。
    */
  }
  public SqlText parseInlineParameterMap(
      TypeHandlerFactory typeHandlerFactory, String sqlStatement, Class parameterClass) {
    try { // 我加上的
      DEBUG.P(this, "parseInlineParameterMap(3)");
      DEBUG.P("sqlStatement=" + sqlStatement);
      DEBUG.P("parameterClass=" + parameterClass);

      String newSql = sqlStatement;

      List mappingList = new ArrayList();

      // 第三个参数为true,表示把分隔符PARAMETER_TOKEN("#")也返回
      StringTokenizer parser = new StringTokenizer(sqlStatement, PARAMETER_TOKEN, true);
      StringBuffer newSqlBuffer = new StringBuffer();

      String token = null;
      String lastToken = null;
      while (parser.hasMoreTokens()) {
        token = parser.nextToken();

        DEBUG.P("lastToken=" + lastToken);
        DEBUG.P("token=" + token);

        if (PARAMETER_TOKEN.equals(lastToken)) {
          if (PARAMETER_TOKEN.equals(token)) {
            // 连续的两个#代表一个"#"字符
            // 如:select * from ACCOUNT where ACC_FIRST_NAME = "##"
            // 实际是: select * from ACCOUNT where ACC_FIRST_NAME = "#"
            newSqlBuffer.append(PARAMETER_TOKEN);
            token = null;
          } else {
            ParameterMapping mapping = null;
            if (token.indexOf(PARAM_DELIM) > -1) {
              mapping = oldParseMapping(token, parameterClass, typeHandlerFactory);
            } else {
              mapping = newParseMapping(token, parameterClass, typeHandlerFactory);
            }

            mappingList.add(mapping);
            newSqlBuffer.append("?");
            token = parser.nextToken();

            DEBUG.P("token2=" + token);
            if (!PARAMETER_TOKEN.equals(token)) {
              throw new SqlMapException(
                  "Unterminated inline parameter in mapped statement ("
                      + "statement.getId()"
                      + ").");
            }
            token = null;
          }
        } else {
          if (!PARAMETER_TOKEN.equals(token)) {
            newSqlBuffer.append(token);
          }
        }

        lastToken = token;
      }

      newSql = newSqlBuffer.toString();

      DEBUG.P(1);

      DEBUG.P("newSql=" + newSql);

      ParameterMapping[] mappingArray =
          (ParameterMapping[]) mappingList.toArray(new ParameterMapping[mappingList.size()]);

      DEBUG.PA("mappingArray", mappingArray);

      SqlText sqlText = new SqlText();
      sqlText.setText(newSql);
      sqlText.setParameterMappings(mappingArray);
      return sqlText;

    } finally { // 我加上的
      DEBUG.P(0, this, "parseInlineParameterMap(3)");
    }
  }
  private ParameterMapping oldParseMapping(
      String token, Class parameterClass, TypeHandlerFactory typeHandlerFactory) {
    try { // 我加上的
      DEBUG.P(this, "oldParseMapping(3)");

      ParameterMapping mapping = new ParameterMapping();
      if (token.indexOf(PARAM_DELIM) > -1) {
        StringTokenizer paramParser = new StringTokenizer(token, PARAM_DELIM, true);
        int n1 = paramParser.countTokens();
        if (n1 == 3) {
          String name = paramParser.nextToken();
          paramParser.nextToken(); // ignore ":"
          String type = paramParser.nextToken();
          mapping.setPropertyName(name);
          mapping.setJdbcTypeName(type);
          TypeHandler handler;
          if (parameterClass == null) {
            handler = typeHandlerFactory.getUnkownTypeHandler();
          } else {
            handler = resolveTypeHandler(typeHandlerFactory, parameterClass, name, null, type);
          }
          mapping.setTypeHandler(handler);
          return mapping;
        } else if (n1 >= 5) {
          String name = paramParser.nextToken();
          paramParser.nextToken(); // ignore ":"
          String type = paramParser.nextToken();
          paramParser.nextToken(); // ignore ":"
          String nullValue = paramParser.nextToken();
          while (paramParser.hasMoreTokens()) {
            nullValue = nullValue + paramParser.nextToken();
          }
          mapping.setPropertyName(name);
          mapping.setJdbcTypeName(type);
          mapping.setNullValue(nullValue);
          TypeHandler handler;
          if (parameterClass == null) {
            handler = typeHandlerFactory.getUnkownTypeHandler();
          } else {
            handler = resolveTypeHandler(typeHandlerFactory, parameterClass, name, null, type);
          }
          mapping.setTypeHandler(handler);
          return mapping;
        } else {
          throw new SqlMapException("Incorrect inline parameter map format: " + token);
        }
      } else {
        mapping.setPropertyName(token);
        TypeHandler handler;
        if (parameterClass == null) {
          handler = typeHandlerFactory.getUnkownTypeHandler();
        } else {
          handler = resolveTypeHandler(typeHandlerFactory, parameterClass, token, null, null);
        }
        mapping.setTypeHandler(handler);
        return mapping;
      }

    } finally { // 我加上的
      DEBUG.P(0, this, "oldParseMapping(3)");
    }
  }
  private ParameterMapping newParseMapping(
      String token, Class parameterClass, TypeHandlerFactory typeHandlerFactory) {
    try { // 我加上的
      DEBUG.P(this, "newParseMapping(3)");
      DEBUG.P("token=" + token);
      DEBUG.P("parameterClass=" + parameterClass);

      ParameterMapping mapping = new ParameterMapping();

      // #propertyName,javaType=string,jdbcType=VARCHAR,mode=IN,nullValue=N/A,handler=string,numericScale=2#

      StringTokenizer paramParser = new StringTokenizer(token, "=,", false);
      mapping.setPropertyName(paramParser.nextToken());

      while (paramParser.hasMoreTokens()) {
        String field = paramParser.nextToken();
        if (paramParser.hasMoreTokens()) {
          String value = paramParser.nextToken();
          if ("javaType".equals(field)) {
            value = typeHandlerFactory.resolveAlias(value);
            mapping.setJavaTypeName(value);
          } else if ("jdbcType".equals(field)) {
            mapping.setJdbcTypeName(value);
          } else if ("mode".equals(field)) {
            mapping.setMode(value);
          } else if ("nullValue".equals(field)) {
            mapping.setNullValue(value);
          } else if ("handler".equals(field)) {
            try {
              value = typeHandlerFactory.resolveAlias(value);
              Object impl = Resources.instantiate(value);
              if (impl instanceof TypeHandlerCallback) {
                mapping.setTypeHandler(new CustomTypeHandler((TypeHandlerCallback) impl));
              } else if (impl instanceof TypeHandler) {
                mapping.setTypeHandler((TypeHandler) impl);
              } else {
                throw new SqlMapException(
                    "The class "
                        + value
                        + " is not a valid implementation of TypeHandler or TypeHandlerCallback");
              }
            } catch (Exception e) {
              throw new SqlMapException(
                  "Error loading class specified by handler field in " + token + ".  Cause: " + e,
                  e);
            }
          } else if ("numericScale".equals(field)) {
            try {
              Integer numericScale = Integer.valueOf(value);
              if (numericScale.intValue() < 0) {
                throw new SqlMapException(
                    "Value specified for numericScale must be greater than or equal to zero");
              }
              mapping.setNumericScale(numericScale);
            } catch (NumberFormatException e) {
              throw new SqlMapException("Value specified for numericScale is not a valid Integer");
            }
          } else {
            throw new SqlMapException(
                "Unrecognized parameter mapping field: '" + field + "' in " + token);
          }
        } else {
          throw new SqlMapException(
              "Incorrect inline parameter map format (missmatched name=value pairs): " + token);
        }
      }

      if (mapping.getTypeHandler() == null) {
        TypeHandler handler;
        if (parameterClass == null) {
          handler = typeHandlerFactory.getUnkownTypeHandler();
        } else {
          handler =
              resolveTypeHandler(
                  typeHandlerFactory,
                  parameterClass,
                  mapping.getPropertyName(),
                  mapping.getJavaTypeName(),
                  mapping.getJdbcTypeName());
        }
        mapping.setTypeHandler(handler);
      }

      return mapping;

    } finally { // 我加上的
      DEBUG.P(0, this, "newParseMapping(3)");
    }
  }