// Path: analyzer/src/main/java/com/novoda/sqlite/impl/TableCreateStatementParser.java
// public class TableCreateStatementParser {
//     private final static Pattern p = Pattern.compile("(JOIN|FROM)\\W+(\\w+)");
// 
//     public List<String> parseUsedTables(String sqlCreateStatement) {
//         ArrayList<String> baseTables = new ArrayList<String>();
//         Matcher m = p.matcher(sqlCreateStatement.toUpperCase());
//         while (m.find()) {
//             baseTables.add(m.group(2));
//         }
//         return baseTables;
//     }
// }
// 
// Path: analyzer/src/main/java/com/novoda/sqlite/model/Column.java
// public final class Column {
//     private final String name;
//     private final String type;
//     private final boolean nullable;
//     private final DataAffinity affinity;
// 
//     public Column(String name, String type, boolean nullable) {
//         this.name = name;
//         this.type = type;
//         this.nullable = nullable;
//         this.affinity = DataAffinity.fromType(type);
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public String getType() {
//         return type;
//     }
// 
//     public boolean isNullable() {
//         return nullable;
//     }
// 
//     public DataAffinity getAffinity() {
//         return affinity;
//     }
// 
//     public boolean isBoolean() {
//         return affinity == DataAffinity.NUMERIC && type.toLowerCase(Locale.US).contains("bool");
//     }
// 
// 
// }
// 
// Path: analyzer/src/main/java/com/novoda/sqlite/model/Database.java
// public final class Database {
// 	private final List<Table> tables = new ArrayList<Table>();
// 
// 	public void addTable(Table table) {
// 		tables.add(table);
// 	}
// 
// 	public Collection<Table> getTables() {
// 		return Collections.unmodifiableCollection(tables);
// 	}
// 
//     public Table findTableByName(String tableName) {
//         for (Table table : tables)
//             if (table.getName().equalsIgnoreCase(tableName)) {
//                 return table;
//             }
//         return null;
//     }
// 
// }
// 
// Path: analyzer/src/main/java/com/novoda/sqlite/model/Table.java
// public final class Table {
//     private final String name;
//     private final List<Column> columns = new ArrayList<Column>();
//     private final String sql;
//     private final boolean isView;
//     private final List<Table> dependents = new ArrayList<Table>();
// 
//     public Table(String name, String sql, boolean isView) {
//         this.name = name;
//         this.sql = sql;
//         this.isView = isView;
//     }
// 
//     public boolean isView() {
//         return isView;
//     }
// 
//     public void addColumn(Column column) {
//         columns.add(column);
//     }
// 
//     public Column findColumnByName(String name) {
//         for (Column column : columns) {
//             if (column.getName().equalsIgnoreCase(name))
//                 return column;
//         }
//         return null;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public String getSql() {
//         return sql;
//     }
// 
//     public Collection<Column> getColumns() {
//         return Collections.unmodifiableCollection(columns);
//     }
// 
//     public void addDependent(Table table) {
//         dependents.add(table);
//     }
// 
//     public Collection<Table> getDependents() {
//         return Collections.unmodifiableCollection(dependents);
//     }
// 
//     @Override
//     public String toString() {
//         return "Table{" +
//                 "name='" + name + '\'' +
//                 '}';
//     }
// }


import com.novoda.sqlite.impl.TableCreateStatementParser;
import com.novoda.sqlite.model.Column;
import com.novoda.sqlite.model.Database;
import com.novoda.sqlite.model.Table;
import java.sql.*;
import java.util.Arrays;
import java.util.List;
package com.novoda.sqlite;



public final class Analyzer {
    private Statement statement;
    private final Connection connection;

    public Analyzer(Connection connection) throws SQLException {
        this.connection = connection;
    }

    public Database analyze() throws SQLException {
        statement = connection.createStatement();
        Database database = new Database();
        readTableAndViewNames(database);
        for (Table name : database.getTables()) {
            readTableInfo(name);
        }
        addTableDependencies(database);
        statement.close();
        return database;
    }

    private void addTableDependencies(Database database) {
// Path: analyzer/src/main/java/com/novoda/sqlite/impl/TableCreateStatementParser.java
// public class TableCreateStatementParser {
//     private final static Pattern p = Pattern.compile("(JOIN|FROM)\\W+(\\w+)");
// 
//     public List<String> parseUsedTables(String sqlCreateStatement) {
//         ArrayList<String> baseTables = new ArrayList<String>();
//         Matcher m = p.matcher(sqlCreateStatement.toUpperCase());
//         while (m.find()) {
//             baseTables.add(m.group(2));
//         }
//         return baseTables;
//     }
// }
// 
// Path: analyzer/src/main/java/com/novoda/sqlite/model/Column.java
// public final class Column {
//     private final String name;
//     private final String type;
//     private final boolean nullable;
//     private final DataAffinity affinity;
// 
//     public Column(String name, String type, boolean nullable) {
//         this.name = name;
//         this.type = type;
//         this.nullable = nullable;
//         this.affinity = DataAffinity.fromType(type);
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public String getType() {
//         return type;
//     }
// 
//     public boolean isNullable() {
//         return nullable;
//     }
// 
//     public DataAffinity getAffinity() {
//         return affinity;
//     }
// 
//     public boolean isBoolean() {
//         return affinity == DataAffinity.NUMERIC && type.toLowerCase(Locale.US).contains("bool");
//     }
// 
// 
// }
// 
// Path: analyzer/src/main/java/com/novoda/sqlite/model/Database.java
// public final class Database {
// 	private final List<Table> tables = new ArrayList<Table>();
// 
// 	public void addTable(Table table) {
// 		tables.add(table);
// 	}
// 
// 	public Collection<Table> getTables() {
// 		return Collections.unmodifiableCollection(tables);
// 	}
// 
//     public Table findTableByName(String tableName) {
//         for (Table table : tables)
//             if (table.getName().equalsIgnoreCase(tableName)) {
//                 return table;
//             }
//         return null;
//     }
// 
// }
// 
// Path: analyzer/src/main/java/com/novoda/sqlite/model/Table.java
// public final class Table {
//     private final String name;
//     private final List<Column> columns = new ArrayList<Column>();
//     private final String sql;
//     private final boolean isView;
//     private final List<Table> dependents = new ArrayList<Table>();
// 
//     public Table(String name, String sql, boolean isView) {
//         this.name = name;
//         this.sql = sql;
//         this.isView = isView;
//     }
// 
//     public boolean isView() {
//         return isView;
//     }
// 
//     public void addColumn(Column column) {
//         columns.add(column);
//     }
// 
//     public Column findColumnByName(String name) {
//         for (Column column : columns) {
//             if (column.getName().equalsIgnoreCase(name))
//                 return column;
//         }
//         return null;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public String getSql() {
//         return sql;
//     }
// 
//     public Collection<Column> getColumns() {
//         return Collections.unmodifiableCollection(columns);
//     }
// 
//     public void addDependent(Table table) {
//         dependents.add(table);
//     }
// 
//     public Collection<Table> getDependents() {
//         return Collections.unmodifiableCollection(dependents);
//     }
// 
//     @Override
//     public String toString() {
//         return "Table{" +
//                 "name='" + name + '\'' +
//                 '}';
//     }
// }


// Path: analyzer/src/main/java/com/novoda/sqlite/Analyzer.java
import com.novoda.sqlite.impl.TableCreateStatementParser;
import com.novoda.sqlite.model.Column;
import com.novoda.sqlite.model.Database;
import com.novoda.sqlite.model.Table;
import java.sql.*;
import java.util.Arrays;
import java.util.List;

package com.novoda.sqlite;



public final class Analyzer {
    private Statement statement;
    private final Connection connection;

    public Analyzer(Connection connection) throws SQLException {
        this.connection = connection;
    }

    public Database analyze() throws SQLException {
        statement = connection.createStatement();
        Database database = new Database();
        readTableAndViewNames(database);
        for (Table name : database.getTables()) {
            readTableInfo(name);
        }
        addTableDependencies(database);
        statement.close();
        return database;
    }

    private void addTableDependencies(Database database) {
        TableCreateStatementParser parser = new TableCreateStatementParser();