public Table addTable(Class<?> clazz) {
    if(Modifier.isAbstract(clazz.getModifiers())){
      return null;
    }
    Table table = new Table();
    ClassInfo info = ClassInfo.getClassInfo(clazz);
    table.setName(info.tableName);
    table.setType("MyISAM");
    database.addTable(table);
    
    Map<String, UniqueIndex> uniques = new HashMap<String, UniqueIndex>();
    Map<String, NonUniqueIndex> indexes = new HashMap<String, NonUniqueIndex>();
    
    /* columns */
    for (Field field : info.allFields) {
      String[] columns = ClassInfo.getColumnNames(field);
      boolean notNull = field.getAnnotation(NotNull.class) != null;
      
      Class<?> type = field.getType();
      if(!ClassInfo.isModel(type) || (ClassInfo.isModel(type) && ClassInfo.isEmbedded(field))) {
        Column column = createColumn(clazz, field, columns[0]);
        
        if(notNull || type.isPrimitive()) {
          column.setRequired(true);
          
          if(type.isPrimitive() && !ClassInfo.isId(field)) { // TODO: add also Boolean, Long, Double,... ?
            if(type == Boolean.TYPE) {
              column.setDefaultValue("false");
            } else {
              column.setDefaultValue("0");
            }
          }
        }
        
        Id id = field.getAnnotation(Id.class);
        if(id != null) {
          column.setPrimaryKey(true);
          column.setRequired(true);
          
          // auto_increments managed ONLY for long
          if(id.value() == Generator.AUTO_INCREMENT 
              && (Long.TYPE == type || Long.class.isAssignableFrom(type)))
            column.setAutoIncrement(true);
          
          // adds index on primary key
          /*UniqueIndex i = uniques.get(columns[0]);
          if(i == null) {
            i = new UniqueIndex();
            i.setName(columns[0]);
            uniques.put(columns[0], i);
            table.addIndex(i);
          }
          fillIndex(i, field);*/
        }
        
        table.addColumn(column);
      } else {
        List<Field> keys = ClassInfo.getClassInfo(type).keys;
        
        for (int i = 0; i < columns.length; i++) {
          Field f = keys.get(i);
          Column column = createColumn(clazz, f, columns[i]);
          if(notNull)
            column.setRequired(true);
          
          table.addColumn(column);
        }
      }
    }
    /* indexes */
    for (Field field : info.updateFields) {
      Index index = field.getAnnotation(Index.class);
      if(index != null) {
        String[] names = index.value();
        for (String name : names) {
          NonUniqueIndex i = indexes.get(name);
          if(i == null) {
            i = new NonUniqueIndex();
            i.setName(name);
            indexes.put(name, i);
            table.addIndex(i);
          }
          fillIndex(i, field);
        }
      }
      
      Unique unique = field.getAnnotation(Unique.class);
      if(unique != null) {
        String[] names = unique.value();
        for (String name : names) {
          UniqueIndex i = uniques.get(name);
          if(i == null) {
            i = new UniqueIndex();
            i.setName(name);
            uniques.put(name, i);
            table.addIndex(i);
          }
          fillIndex(i, field);
        }
      }
    }
    
    tables.put(table.getName(), table);
    return table;
  }