protected void throwTableRelatedPrimaryKeyNotFoundException(
     String entityName, DfCustomizeEntityInfo entityInfo, String tableName, String columnName) {
   final ExceptionMessageBuilder br = new ExceptionMessageBuilder();
   br.addNotice("The table name related to the primary key is not found.");
   br.addItem("OutsideSql");
   br.addElement(entityInfo.getOutsideSqlFile());
   br.addItem("Entity");
   br.addElement(entityName);
   br.addItem("Table Name");
   br.addElement(tableName);
   br.addItem("Primary Key");
   br.addElement(columnName);
   final String msg = br.buildExceptionMessage();
   throw new IllegalOutsideSqlOperationException(msg);
 }
 protected void throwUnknownClassificationSpecifiedInHintException(
     String entityName, DfCustomizeEntityInfo entityInfo, Column column, String classification) {
   final ExceptionMessageBuilder br = new ExceptionMessageBuilder();
   br.addNotice("Unknown classification specified in the hint.");
   br.addItem("OutsideSql");
   br.addElement(entityInfo.getOutsideSqlFile());
   br.addItem("Entity");
   br.addElement(entityName);
   br.addItem("Column");
   br.addElement(column.getName());
   br.addItem("Comment");
   br.addElement(column.getComment());
   br.addItem("Unknown Classification");
   br.addElement(classification);
   final String msg = br.buildExceptionMessage();
   throw new IllegalOutsideSqlOperationException(msg);
 }
  // ===================================================================================
  //                                                                  Prepare Generation
  //                                                                  ==================
  @Override
  public Context initControlContext() throws Exception {
    _log.info("");
    _log.info("...Preparing generation of customize-entities and parameter-beans");
    _log.info("* * * * * * * * * *");
    _log.info("* CustomizeEntity *");
    _log.info("* * * * * * * * * *");
    final StringBuilder logSb = new StringBuilder();

    final Database database = _database;
    database.setSql2EntitySchemaData(_schemaData);
    database.setPmbMetaDataMap(_sql2entityMeta.getPmbMetaDataMap());
    database.setSkipDeleteOldClass(isSkipDeleteOldClass());

    final Map<String, DfCustomizeEntityInfo> entityInfoMap = _sql2entityMeta.getEntityInfoMap();
    final Set<String> entityNameSet = entityInfoMap.keySet();
    for (String entityName : entityNameSet) {
      final DfCustomizeEntityInfo entityInfo = entityInfoMap.get(entityName);
      final Map<String, DfColumnMeta> metaMap = entityInfo.getColumnMap();
      final DfOutsideSqlFile outsideSqlFile = entityInfo.getOutsideSqlFile();

      final Table tbl = new Table();
      tbl.setSql2EntityCustomize(true);
      if (outsideSqlFile != null) { // basically true but checked just in case
        tbl.setSql2EntitySqlFile(outsideSqlFile);
      }
      tbl.setName(entityInfo.getTableDbName());
      if (!entityInfo.needsJavaNameConvert()) {
        tbl.suppressJavaNameConvert(); // basically here (except STRUCT type)
      }
      if (entityInfo.hasNestedCustomizeEntity()) {
        tbl.setSql2EntityCustomizeHasNested(true); // basically when STRUCT type
      }
      if (entityInfo.isAdditionalSchema()) {
        tbl.setUnifiedSchema(entityInfo.getAdditionalSchema()); // basically when STRUCT type
      }
      tbl.setSql2EntityTypeSafeCursor(entityInfo.isCursorHandling());
      buildCustomizeEntityTitle(logSb, entityName, entityInfo);

      final StringKeyMap<String> pkMap = getPrimaryKeyMap(entityInfo);
      final boolean allCommonColumn = hasAllCommonColumn(metaMap);
      final Set<String> columnNameSet = metaMap.keySet();
      for (String columnName : columnNameSet) {
        final Column column = new Column();
        setupColumnName(columnName, column);

        // an element removed from pkMap if true
        // and a table name related to primary key is returned
        final String pkRelatedTableName = setupPrimaryKey(pkMap, entityName, columnName, column);

        setupTorqueType(metaMap, columnName, column, allCommonColumn);
        setupDbType(metaMap, columnName, column);
        setupNotNull(metaMap, columnName, column);
        setupColumnSizeContainsDigit(metaMap, columnName, column);
        setupColumnComment(metaMap, columnName, column);
        setupSql2EntityElement(
            entityName, entityInfo, metaMap, columnName, column, pkRelatedTableName, logSb);
        tbl.addColumn(column);
      }
      if (!pkMap.isEmpty()) { // if not-removed columns exist
        throwPrimaryKeyNotFoundException(entityName, pkMap, columnNameSet);
      }

      if (entityInfo.isScalarHandling()) {
        // it does not generate an only-one-column entity
        tbl.setDatabase(database); // one-way love for utility (just in case)
        processScalarHandling(entityInfo, tbl);
      } else if (entityInfo.isDomainHandling()) {
        // it does not generate an customize-entity
        tbl.setDatabase(database); // one-way love for utility (just in case)
        processDomainHandling(entityInfo, tbl);
      } else {
        // initialize a class name of the entity for typed parameter-bean
        database.addTable(tbl); // should be before getting names
        entityInfo.setEntityClassName(tbl.getExtendedEntityClassName());
        entityInfo.setImmutableClassName(tbl.getImmutableExtendedEntityClassName());
      }
      logSb.append(ln());
    }
    final String databaseType = getDatabaseTypeFacadeProp().getTargetDatabase();
    final AppData appData = new AppData(databaseType);
    appData.addDatabase(database);

    showCustomizeEntity(logSb);
    showParameterBean();

    final VelocityContext context = createVelocityContext(appData);
    return context;
  }