diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Column.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Column.java
index 6e309600bbd2a7b4d572114e54bf02aa4b6578c6..51b0e17eb4d405d42840a49136459c17152b26bd 100644
--- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Column.java
+++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Column.java
@@ -91,7 +91,14 @@ public class Column extends ChildEntity<Table> {
     }
 
     public boolean getIndexed() {
-        return getValue(INDEXED_KEY, Boolean.class);
+        EntityProperty indexedProp = getProperty(INDEXED_KEY);
+        if (indexedProp.getType() == Boolean.class) {
+            return getValue(INDEXED_KEY, Boolean.class);
+        } else if (indexedProp.getType() == Integer.class) {
+            return getValue(INDEXED_KEY, Integer.class) == 1;
+        } else {
+            throw new RuntimeException("Indexed property cannot be an instance of " + indexedProp.getType());
+        }
     }
 
     /**
diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/ConsistencyChecks.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/ConsistencyChecks.java
index d1e9d2790cd5ddbcc6224a44223582a6570e41ed..439c348a835fdb13e2ec718adb7afa80b8dadf91 100644
--- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/ConsistencyChecks.java
+++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/ConsistencyChecks.java
@@ -40,6 +40,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
+ *
+ * TODO: Move queries into data layer classes.
  *
  * @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
  */
@@ -48,28 +50,62 @@ public class ConsistencyChecks implements Serializable {
     private static final long serialVersionUID = 4412404312756740093L;
     private final static Logger LOG = LoggerFactory.getLogger(ConsistencyChecks.class);
 
-    private static class UnexistingKeyColumn {
+    public static class UnexistingKey implements Serializable {
+
+        private static final long serialVersionUID = 7891439129072900628L;
 
         private final String keyId;
-        private final String fromColumn;
-        private final String targetColumn;
+        private final String fromTable;
+        private final String[] fromColumns;
+        private final String targetTable;
+        private final String[] targetColumns;
 
-        private UnexistingKeyColumn(String keyId, String fromColumn, String targetColumn) {
+        private UnexistingKey(String keyId, String fromTable, String[] fromColumns, String targetTable, String[] targetColumns) {
             this.keyId = keyId;
-            this.fromColumn = fromColumn;
-            this.targetColumn = targetColumn;
+            this.fromTable = fromTable;
+            this.fromColumns = fromColumns;
+            this.targetTable = targetTable;
+            this.targetColumns = targetColumns;
         }
 
         public String getKeyId() {
             return keyId;
         }
 
-        public String getFromColumn() {
-            return fromColumn;
+        public String getFromTable() {
+            return fromTable;
+        }
+
+        public String[] getFromColumns() {
+            return fromColumns;
         }
 
-        public String getTargetColumn() {
-            return targetColumn;
+        public String getTargetTable() {
+            return targetTable;
+        }
+
+        public String[] getTargetColumns() {
+            return targetColumns;
+        }
+
+        private String getColumnsString(String[] columns) {
+            StringBuilder sb = new StringBuilder();
+            boolean first = true;
+            for (String column : columns) {
+                if (!first) {
+                    sb.append(",");
+                }
+                sb.append(column);
+                first = false;
+            }
+            return sb.toString();
+        }
+
+        @Override
+        public String toString() {
+            return String.format("[%s] %s(%s) -> %s(%s)", keyId,
+                    fromTable, getColumnsString(fromColumns),
+                    targetTable, getColumnsString(targetColumns));
         }
     }
 
@@ -77,16 +113,14 @@ public class ConsistencyChecks implements Serializable {
     private final Set<String> unexisingSchemas;
     private final Set<String> unexisingTables;
     private final Map<String, String> unexisingColumns;
-    private final Set<String> unexistingKeys;
-    private final List<UnexistingKeyColumn> unexistingKeyColumns;
+    private final List<UnexistingKey> unexistingKeys;
 
     public ConsistencyChecks() {
         inconsistencies = new ArrayList<>();
         unexisingSchemas = new HashSet<>();
         unexisingTables = new HashSet<>();
         unexisingColumns = new HashMap<>();
-        unexistingKeys = new HashSet<>();
-        unexistingKeyColumns = new ArrayList<>();
+        unexistingKeys = new ArrayList<>();
     }
 
     public void addInconsistency(InconsistentValue problemDescription) {
@@ -121,21 +155,17 @@ public class ConsistencyChecks implements Serializable {
         unexisingColumns.put(completeTableName, columnName);
     }
 
-    public void addUnexistingKey(String keyId) {
+    public void addUnexistingKey(String keyId, String fromTable, String[] fromColumns, String targetTable, String[] targetColumns) {
         if (keyId == null) {
             throw new IllegalArgumentException("key_id can't be null");
         }
-        unexistingKeys.add(keyId);
+        unexistingKeys.add(new UnexistingKey(keyId, fromTable, fromColumns, targetTable, targetColumns));
     }
 
-    public Set<String> getUnexistingKeys() {
+    public List<UnexistingKey> getUnexistingKeys() {
         return unexistingKeys;
     }
 
-    public void addUnexistingKeyColumn(String keyId, String fromColumn, String targetColumn) {
-        unexistingKeyColumns.add(new UnexistingKeyColumn(keyId, fromColumn, targetColumn));
-    }
-
     private Set<String> getKeysToRemove(Connection conn, String tapSchemaNameEscaped, DatabaseType dbType, String like) throws SQLException {
         Set<String> ret = new HashSet<>();
         String query = String.format("SELECT key_id from %s.%s WHERE from_table LIKE ? OR target_table LIKE ?", tapSchemaNameEscaped, TSMUtil.escapeName("keys", dbType));
@@ -197,7 +227,9 @@ public class ConsistencyChecks implements Serializable {
                 }
             }
 
-            keysToRemoveIds.addAll(unexistingKeys);
+            for (UnexistingKey unexistingKey : unexistingKeys) {
+                keysToRemoveIds.add(unexistingKey.getKeyId());
+            }
 
             conn.setAutoCommit(false);
             LOG.debug("Starting transaction");
diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Dao.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Dao.java
deleted file mode 100644
index 42ae18d0720b346e730f60123f401776020060cb..0000000000000000000000000000000000000000
--- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Dao.java
+++ /dev/null
@@ -1,707 +0,0 @@
-/* 
- * _____________________________________________________________________________
- * 
- * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of
- * Trieste INAF - IA2 Italian Center for Astronomical Archives
- * _____________________________________________________________________________
- * 
- * Copyright (C) 2016 Istituto Nazionale di Astrofisica
- * 
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License Version 3 as published by the
- * Free Software Foundation.
- * 
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- * 
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 51
- * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package it.inaf.ia2.tsm;
-
-import it.inaf.ia2.tsm.datalayer.Credentials;
-import it.inaf.ia2.tsm.datalayer.DatabaseType;
-import it.inaf.ia2.tsm.datalayer.DBWrapper;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.List;
-import javax.sql.DataSource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Utility class that contains static methods for interacting with databases.
- *
- * @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
- */
-public class Dao {
-
-//    private static final Logger log = LoggerFactory.getLogger(Dao.class);
-//
-//    /**
-//     * Creates the TAP_SCHEMA schema and its tables.
-//     */
-//    private static void createTapSchemaStructure(DatabaseType dbType, Connection conn, TapSchema tapSchema) throws SQLException {
-//
-//        String tapSchemaName = tapSchema.getName();
-//        String version = tapSchema.getVersion();
-//
-//        if (dbType == DatabaseType.MYSQL) {
-//            try (Statement statement = conn.createStatement()) {
-//
-//                /////////////////////////////////////
-//                //         CREATE DATABASE         //
-//                /////////////////////////////////////
-//                String queryString = String.format("CREATE DATABASE IF NOT EXISTS `%s`", tapSchemaName);
-//                log.debug("Executing query {}", queryString);
-//                statement.executeUpdate(queryString);
-//
-//                StringBuilder querySb = new StringBuilder();
-//
-//                /////////////////////////////////////
-//                //      CREATE schemas TABLE       //
-//                /////////////////////////////////////
-//                querySb.append("CREATE TABLE IF NOT EXISTS `");
-//                querySb.append(tapSchemaName);
-//                querySb.append("`.`schemas` (\n");
-//                querySb.append("schema_name   varchar(64),\n");
-//                querySb.append("utype         varchar(512) NULL,\n");
-//                querySb.append("description   varchar(512) NULL,\n");
-//                if (TSMUtil.isIA2(version)) {
-//                    querySb.append("schemaID      bigint,\n");
-//                }
-//                querySb.append("PRIMARY KEY (schema_name))");
-//
-//                queryString = querySb.toString();
-//                log.debug("Creating \"schemas\" table");
-//                log.debug("Executing query {}", queryString);
-//                statement.executeUpdate(queryString);
-//
-//                /////////////////////////////////////
-//                //       CREATE tables TABLE       //
-//                /////////////////////////////////////
-//                querySb = new StringBuilder();
-//                querySb.append("CREATE TABLE IF NOT EXISTS `");
-//                querySb.append(tapSchemaName);
-//                querySb.append("`.tables (\n");
-//                querySb.append("schema_name   varchar(64),\n");
-//                querySb.append("table_name    varchar(128),\n");
-//                querySb.append("table_type    varchar(8),\n");
-//                querySb.append("utype         varchar(512) NULL,\n");
-//                querySb.append("description   varchar(512) NULL,\n");
-//                if (TSMUtil.isIA2(version)) {
-//                    querySb.append("tableID       bigint,\n");
-//                }
-//                querySb.append("PRIMARY KEY (table_name),\n");
-//                querySb.append("FOREIGN KEY (schema_name) REFERENCES `");
-//                querySb.append(tapSchemaName);
-//                querySb.append("`.`schemas` (schema_name))");
-//
-//                queryString = querySb.toString();
-//                log.debug("Creating \"tables\" table");
-//                log.debug("Executing query {}", queryString);
-//                statement.executeUpdate(queryString);
-//
-//                /////////////////////////////////////
-//                //      CREATE columns TABLE       //
-//                /////////////////////////////////////
-//                querySb = new StringBuilder();
-//                querySb.append("CREATE TABLE IF NOT EXISTS `");
-//                querySb.append(tapSchemaName);
-//                querySb.append("`.columns (\n");
-//                querySb.append("table_name    varchar(128),\n");
-//                querySb.append("column_name   varchar(64),\n");
-//                querySb.append("utype         varchar(512) NULL,\n");
-//                querySb.append("ucd           varchar(64)  NULL,\n");
-//                querySb.append("unit          varchar(64)  NULL,\n");
-//                querySb.append("description   varchar(512) NULL,\n");
-//                querySb.append("datatype      varchar(64)  NOT NULL,\n");
-//                querySb.append("size          integer      NULL,\n");
-//                querySb.append("principal     integer      NOT NULL,\n");
-//                querySb.append("indexed       integer      NOT NULL,\n");
-//                querySb.append("std           integer      NOT NULL,\n");
-//                if (TSMUtil.isIA2(version)) {
-//                    querySb.append("id      integer,\n");
-//                    querySb.append("columnID      bigint,\n");
-//                }
-//                querySb.append("PRIMARY KEY (table_name, column_name),\n");
-//                querySb.append("FOREIGN KEY (table_name) REFERENCES `");
-//                querySb.append(tapSchemaName);
-//                querySb.append("`.tables (table_name))");
-//
-//                queryString = querySb.toString();
-//                log.debug("Creating \"columns\" table");
-//                log.debug("Executing query {}", queryString);
-//                statement.executeUpdate(queryString);
-//
-//                /////////////////////////////////////
-//                //        CREATE keys TABLE        //
-//                /////////////////////////////////////
-//                querySb = new StringBuilder();
-//                querySb.append("CREATE TABLE IF NOT EXISTS `");
-//                querySb.append(tapSchemaName);
-//                querySb.append("`.keys (\n");
-//                querySb.append("key_id        varchar(64),\n");
-//                querySb.append("from_table    varchar(128) NOT NULL,\n");
-//                querySb.append("target_table  varchar(128) NOT NULL,\n");
-//                querySb.append("utype         varchar(512) NULL,\n");
-//                querySb.append("description   varchar(512) NULL,\n");
-//                if (TSMUtil.isIA2(version)) {
-//                    querySb.append("keyID         bigint,\n");
-//                }
-//                querySb.append("PRIMARY KEY (key_id),\n");
-//                querySb.append("FOREIGN KEY (from_table) REFERENCES `");
-//                querySb.append(tapSchemaName);
-//                querySb.append("`.tables (table_name),\n");
-//                querySb.append("FOREIGN KEY (target_table) REFERENCES `");
-//                querySb.append(tapSchemaName);
-//                querySb.append("`.tables (table_name))");
-//
-//                queryString = querySb.toString();
-//                log.debug("Creating \"keys\" table");
-//                log.debug("Executing query {}", queryString);
-//                statement.executeUpdate(queryString);
-//
-//                /////////////////////////////////////
-//                //    CREATE key_columns TABLE     //
-//                /////////////////////////////////////
-//                querySb = new StringBuilder();
-//                querySb.append("CREATE TABLE IF NOT EXISTS `");
-//                querySb.append(tapSchemaName);
-//                querySb.append("`.key_columns (\n");
-//                querySb.append("key_id          varchar(64),\n");
-//                querySb.append("from_column     varchar(64)   NOT NULL,\n");
-//                querySb.append("target_column   varchar(64) NOT NULL,\n");
-//                if (TSMUtil.isIA2(version)) {
-//                    querySb.append("key_columnID    bigint,\n");
-//                }
-//                querySb.append("FOREIGN KEY (key_id) REFERENCES `");
-//                querySb.append(tapSchemaName);
-//                querySb.append("`.keys (key_id))");
-//
-//                queryString = querySb.toString();
-//                log.debug("Creating \"key_columns\" table");
-//                log.debug("Executing query {}", queryString);
-//                statement.executeUpdate(queryString);
-//            }
-//        } else if (dbType == DatabaseType.POSTGRES) {
-//            try (Statement statement = conn.createStatement()) {
-//                String tapSchemaNameEscaped = TSMUtil.escapeName(tapSchemaName, dbType);
-//
-//                statement.executeUpdate("CREATE SCHEMA IF NOT EXISTS " + tapSchemaNameEscaped);
-//
-//                StringBuilder querySb = new StringBuilder();
-//
-//                /////////////////////////////////////
-//                //      CREATE schemas TABLE       //
-//                /////////////////////////////////////
-//                querySb.append("CREATE TABLE IF NOT EXISTS ");
-//                querySb.append(tapSchemaNameEscaped);
-//                querySb.append(".schemas (\n");
-//                querySb.append("schema_name character varying(64) NOT NULL,\n");
-//                querySb.append("description character varying(512),\n");
-//                if (TSMUtil.isIA2(version)) {
-//                    querySb.append("schemaid bigint,\n");
-//                }
-//                querySb.append("utype character varying(512))");
-//
-//                String queryString = querySb.toString();
-//                log.debug("Creating \"schemas\" table");
-//                log.debug("Executing query {}", queryString);
-//                int updateResult = statement.executeUpdate(queryString);
-//
-//                if (updateResult > 0) {
-//                    queryString = "ALTER TABLE ONLY schemas ADD CONSTRAINT schemas_pkey PRIMARY KEY (schema_name)";
-//                    log.debug("Adding constraints to \"schemas\" table");
-//                    log.debug("Executing query {}", queryString);
-//                    statement.executeUpdate(queryString);
-//                }
-//
-//                /////////////////////////////////////
-//                //       CREATE tables TABLE       //
-//                /////////////////////////////////////
-//                querySb = new StringBuilder();
-//
-//                querySb.append("CREATE TABLE IF NOT EXISTS ");
-//                querySb.append(tapSchemaNameEscaped);
-//                querySb.append(".tables (\n");
-//                querySb.append("table_name character varying(128) NOT NULL,\n");
-//                querySb.append("description character varying(512),\n");
-//                querySb.append("schema_name character varying(64),\n");
-//                if (TSMUtil.isIA2(version)) {
-//                    querySb.append("tableid bigint,\n");
-//                }
-//                querySb.append("table_type character varying(8),\n");
-//                querySb.append("utype character varying(512))");
-//
-//                queryString = querySb.toString();
-//                log.debug("Creating \"tables\" table");
-//                log.debug("Executing query {}", queryString);
-//                updateResult = statement.executeUpdate(queryString);
-//
-//                if (updateResult > 0) {
-//                    log.debug("Adding constraints to \"tables\" table");
-//                    queryString = "ALTER TABLE ONLY tables ADD CONSTRAINT tables_pkey PRIMARY KEY (table_name)";
-//                    log.debug("Executing query {}", queryString);
-//                    statement.executeUpdate(queryString);
-//                    queryString = "ALTER TABLE ONLY tables ADD CONSTRAINT fk_tables_schema_name FOREIGN KEY (schema_name) REFERENCES schemas(schema_name)";
-//                    log.debug("Executing query {}", queryString);
-//                    statement.executeUpdate(queryString);
-//                }
-//
-//                /////////////////////////////////////
-//                //      CREATE columns TABLE       //
-//                /////////////////////////////////////
-//                querySb = new StringBuilder();
-//
-//                querySb.append("CREATE TABLE IF NOT EXISTS ");
-//                querySb.append(tapSchemaNameEscaped);
-//                querySb.append(".columns (\n");
-//                querySb.append("table_name character varying(128) NOT NULL,\n");
-//                querySb.append("column_name character varying(64) NOT NULL,\n");
-//                if (TSMUtil.isIA2(version)) {
-//                    querySb.append("columnid bigint,\n");
-//                }
-//                querySb.append("datatype character varying(64),\n");
-//                querySb.append("description character varying(512),\n");
-//                querySb.append("id integer,\n");
-//                querySb.append("indexed boolean,\n");
-//                querySb.append("principal boolean,\n");
-//                querySb.append("size integer,\n");
-//                querySb.append("std boolean,\n");
-//                querySb.append("ucd character varying(64),\n");
-//                querySb.append("unit character varying(64),\n");
-//                querySb.append("utype character varying(512))");
-//
-//                queryString = querySb.toString();
-//                log.debug("Creating \"columns\" table");
-//                log.debug("Executing query {}", queryString);
-//                updateResult = statement.executeUpdate(queryString);
-//
-//                if (updateResult > 0) {
-//                    log.debug("Adding constraints to \"columns\" table");
-//                    queryString = "ALTER TABLE ONLY columns ADD CONSTRAINT columns_pkey PRIMARY KEY (table_name, column_name)";
-//                    log.debug("Executing query {}", queryString);
-//                    statement.executeUpdate(queryString);
-//                    queryString = "ALTER TABLE ONLY columns ADD CONSTRAINT fk_columns_table_name FOREIGN KEY (table_name) REFERENCES tables(table_name)";
-//                    log.debug("Executing query {}", queryString);
-//                    statement.executeUpdate(queryString);
-//                }
-//
-//                /////////////////////////////////////
-//                //        CREATE keys TABLE        //
-//                /////////////////////////////////////
-//                querySb = new StringBuilder();
-//
-//                querySb.append("CREATE TABLE IF NOT EXISTS ");
-//                querySb.append(tapSchemaNameEscaped);
-//                querySb.append(".keys (\n");
-//                querySb.append("key_id character varying(64) NOT NULL,\n");
-//                querySb.append("description character varying(512),\n");
-//                querySb.append("from_table character varying(128),\n");
-//                if (TSMUtil.isIA2(version)) {
-//                    querySb.append("keyid bigint,\n");
-//                }
-//                querySb.append("target_table character varying(128),\n");
-//                querySb.append("utype character varying(512))");
-//
-//                queryString = querySb.toString();
-//                log.debug("Creating \"keys\" table");
-//                log.debug("Executing query {}", queryString);
-//                updateResult = statement.executeUpdate(queryString);
-//
-//                if (updateResult > 0) {
-//                    log.debug("Adding constraints to \"keys\" table");
-//                    queryString = "ALTER TABLE ONLY keys ADD CONSTRAINT keys_pkey PRIMARY KEY (key_id)";
-//                    log.debug("Executing query {}", queryString);
-//                    statement.executeUpdate(queryString);
-//                    queryString = "ALTER TABLE ONLY keys ADD CONSTRAINT \"FK_keys_from_table\" FOREIGN KEY (from_table) REFERENCES tables(table_name)";
-//                    log.debug("Executing query {}", queryString);
-//                    statement.executeUpdate(queryString);
-//                    queryString = "ALTER TABLE ONLY keys ADD CONSTRAINT \"FK_keys_target_table\" FOREIGN KEY (target_table) REFERENCES tables(table_name)";
-//                    log.debug("Executing query {}", queryString);
-//                    statement.executeUpdate(queryString);
-//                }
-//
-//                /////////////////////////////////////
-//                //    CREATE key_columns TABLE     //
-//                /////////////////////////////////////
-//                querySb = new StringBuilder();
-//
-//                querySb.append("CREATE TABLE IF NOT EXISTS ");
-//                querySb.append(tapSchemaNameEscaped);
-//                querySb.append(".key_columns (\n");
-//                querySb.append("from_column character varying(64) NOT NULL,\n");
-//                querySb.append("target_column character varying(64) NOT NULL,\n");
-//                if (TSMUtil.isIA2(version)) {
-//                    querySb.append("key_columnid bigint,\n");
-//                }
-//                querySb.append("key_id character varying(64) NOT NULL)");
-//
-//                queryString = querySb.toString();
-//                log.debug("Creating \"key_columns\" table");
-//                log.debug("Executing query {}", queryString);
-//                updateResult = statement.executeUpdate(queryString);
-//
-//                if (updateResult > 0) {
-//                    log.debug("Adding constraints to \"key_columns\" table");
-//                    queryString = "ALTER TABLE ONLY key_columns ADD CONSTRAINT key_columns_pkey PRIMARY KEY (from_column, target_column, key_id)";
-//                    log.debug("Executing query {}", queryString);
-//                    statement.executeUpdate(queryString);
-//                    queryString = "ALTER TABLE ONLY key_columns ADD CONSTRAINT fk_key_columns_key_id FOREIGN KEY (key_id) REFERENCES keys(key_id)";
-//                    log.debug("Executing query {}", queryString);
-//                    statement.executeUpdate(queryString);
-//                }
-//            }
-//        } else {
-//            throw new UnsupportedOperationException("Database type " + dbType + " not supported");
-//        }
-//    }
-//
-//    protected static void save(DBWrapper dbWrapper, TapSchema tapSchema) throws SQLException {
-//
-//        log.debug("Saving TAP_SCHEMA");
-//
-//        DatabaseType dbType = dbWrapper.getTapSchemaDatabaseType();
-//        DataSource dataSource = dbWrapper.getTapSchemaDataSource();
-//
-//        Connection connection = null;
-//        PreparedStatement statement = null;
-//        boolean transactionStarted = false;
-//
-//        try {
-//            connection = dataSource.getConnection();
-//
-//            UpdateOperations operations = new UpdateOperations(tapSchema);
-//
-//            if (!tapSchema.exists()) {
-//                createTapSchemaStructure(dbType, connection, tapSchema);
-//            }
-//
-//            // Start update
-//            connection.setAutoCommit(false); // start transaction
-//            transactionStarted = true;
-//
-//            String tapSchemaNameEscaped = TSMUtil.escapeName(tapSchema.getName(), dbType);
-//
-//            // REMOVE ELEMENTS
-//            if (tapSchema.exists()) {
-//                for (Key key : operations.getKeysToRemove()) {
-//                    String keyId = key.getId();
-//
-//                    String query = String.format("DELETE FROM %s.%s WHERE key_id = ?", tapSchemaNameEscaped, TSMUtil.escapeName("key_columns", dbType));
-//                    statement = connection.prepareStatement(query);
-//                    statement.setString(1, keyId);
-//                    log.debug("Executing query {} [key_id={}]", query, keyId);
-//                    statement.executeUpdate();
-//
-//                    query = String.format("DELETE FROM %s.%s WHERE key_id = ?", tapSchemaNameEscaped, TSMUtil.escapeName("keys", dbType));
-//                    statement = connection.prepareStatement(query);
-//                    statement.setString(1, keyId);
-//                    log.debug("Executing query {} [key_id={}]", query, keyId);
-//                    statement.executeUpdate();
-//                }
-//
-//                for (Column column : operations.getColumnsToRemove()) {
-//                    String query = String.format("DELETE FROM %s.%s WHERE table_name = ? AND column_name = ?", tapSchemaNameEscaped, TSMUtil.escapeName("columns", dbType));
-//                    statement = connection.prepareStatement(query);
-//                    String tableName = column.getTableCompleteName();
-//                    String columnName = column.getName();
-//                    statement.setString(1, tableName);
-//                    statement.setString(2, columnName);
-//                    log.debug("Executing query {} [table_name={}, column_name={}]", query, tableName, columnName);
-//                    statement.executeUpdate();
-//                }
-//
-//                for (Table table : operations.getTablesToRemove()) {
-//                    String query = String.format("DELETE FROM %s.%s WHERE table_name = ?", tapSchemaNameEscaped, TSMUtil.escapeName("tables", dbType));
-//                    statement = connection.prepareStatement(query);
-//                    String tableCompleteName = table.getCompleteName();
-//                    statement.setString(1, tableCompleteName);
-//                    log.debug("Executing query {} [table_name={}]", query, tableCompleteName);
-//                    statement.executeUpdate();
-//                }
-//
-//                for (Schema schema : operations.getSchemasToRemove()) {
-//                    String query = String.format("DELETE FROM %s.%s WHERE schema_name = ?", tapSchemaNameEscaped, TSMUtil.escapeName("schemas", dbType));
-//                    statement = connection.prepareStatement(query);
-//                    String schemaName = schema.getName();
-//                    statement.setString(1, schemaName);
-//                    log.debug("Executing query {} [schema_name={}]", query, schemaName);
-//                    statement.executeUpdate();
-//                }
-//            }
-//
-//            // INSERT ELEMENTS
-//            if (!operations.getSchemasToAdd().isEmpty()) {
-//                log.debug("Inserting {} new schemas", operations.getSchemasToAdd().size());
-//            }
-//            for (Schema schema : operations.getSchemasToAdd()) {
-//                DaoSchema.insertNewSchema(dbType, connection, tapSchema, schema);
-//            }
-//
-//            if (!operations.getTablesToAdd().isEmpty()) {
-//                log.debug("Inserting {} new tables", operations.getTablesToAdd().size());
-//            }
-//            for (Table table : operations.getTablesToAdd()) {
-//                DaoTable.insertNewTable(dbType, connection, tapSchema, table);
-//            }
-//
-//            if (!operations.getColumnsToAdd().isEmpty()) {
-//                log.debug("Inserting {} new columns", operations.getColumnsToAdd().size());
-//            }
-//            for (Column column : operations.getColumnsToAdd()) {
-//                DaoColumn.insertNewColumn(dbType, connection, tapSchema, column);
-//            }
-//
-//            if (!operations.getKeysToAdd().isEmpty()) {
-//                log.debug("Inserting {} new keys", operations.getKeysToAdd().size());
-//            }
-//            for (Key key : operations.getKeysToAdd()) {
-//                // insert new keys and their key columns
-//                DaoKey.insertNewKey(dbType, connection, tapSchema, key);
-//            }
-//
-//            //UPDATE ELEMENTS
-//            if (tapSchema.exists()) {
-//                for (Key key : operations.getKeysToUpdate()) {
-//                    // update keys and their key columns
-//                    DaoKey.updateKey(dbType, connection, tapSchema, key);
-//                }
-//
-//                for (Schema schema : operations.getSchemasToUpdate()) {
-//                    DaoSchema.updateSchema(dbType, connection, tapSchema, schema);
-//                }
-//
-//                for (Table table : operations.getTablesToUpdate()) {
-//                    DaoTable.updateTable(dbType, connection, tapSchema, table);
-//                }
-//
-//                for (Column column : operations.getColumnsToUpdate()) {
-//                    DaoColumn.updateColumn(dbType, connection, tapSchema, column);
-//                }
-//            }
-//
-//            connection.commit();
-//
-//            // Status cleanup after commit
-//            // added
-//            for (Key key : operations.getKeysToAdd()) {
-//                key.save();
-//            }
-//            for (Schema schema : operations.getSchemasToAdd()) {
-//                schema.save();
-//            }
-//            for (Table table : operations.getTablesToAdd()) {
-//                table.save();
-//            }
-//            for (Column column : operations.getColumnsToAdd()) {
-//                column.save();
-//            }
-//
-//            // removed
-//            for (Key key : operations.getKeysToRemove()) {
-//                key.initProperty(Key.ID_KEY, null);
-//                for (KeyColumn keyColumn : key.getKeyColumns()) {
-//                    keyColumn.initProperty(KeyColumn.KEY_ID_KEY, null);
-//                }
-//            }
-//            for (Column column : operations.getColumnsToRemove()) {
-//                column.setStatus(Status.LOADED);
-//            }
-//            for (Column column : operations.getColumnsToClean()) {
-//                column.setStatus(Status.LOADED);
-//            }
-//            for (Table table : operations.getTablesToRemove()) {
-//                Schema schema = tapSchema.getChild(table.getSchemaName());
-//                if (schema != null) {
-//                    ((Schema) schema).cleanTable(table.getName());
-//                }
-//            }
-//            for (Table table : operations.getTablesToClean()) {
-//                Schema schema = tapSchema.getChild(table.getSchemaName());
-//                if (schema != null) {
-//                    ((Schema) schema).cleanTable(table.getName());
-//                }
-//            }
-//            for (Schema schema : operations.getSchemasToRemove()) {
-//                ((TapSchema) tapSchema).cleanSchema(schema.getName());
-//            }
-//            for (Schema schema : operations.getSchemasToClean()) {
-//                ((TapSchema) tapSchema).cleanSchema(schema.getName());
-//            }
-//
-//            // updated
-//            for (Key key : operations.getKeysToUpdate()) {
-//                key.save();
-//            }
-//            for (Schema schema : operations.getSchemasToUpdate()) {
-//                schema.save();
-//            }
-//            for (Table table : operations.getTablesToUpdate()) {
-//                table.save();
-//            }
-//            for (Column column : operations.getColumnsToUpdate()) {
-//                column.save();
-//            }
-//        } catch (SQLException e) {
-//            log.error("Exception caught", e);
-//            try {
-//                if (connection != null && transactionStarted) {
-//                    log.debug("Executing rollback");
-//                    connection.rollback();
-//                }
-//            } catch (SQLException e2) {
-//                log.error("Exception caught", e2);
-//            }
-//            throw e;
-//        } finally {
-//            if (connection != null) {
-//                try {
-//                    if (statement != null) {
-//                        statement.close();
-//                    }
-//                    connection.close();
-//                } catch (SQLException e2) {
-//                    log.error("Exception caught", e2);
-//                }
-//            }
-//        }
-//    }
-//
-//    public static List<String> getAllTAPSchemasNames(Credentials credentials) throws SQLException {
-//        DatabaseType dbType = credentials.getDatabaseType();
-//        DataSource ds = TSMUtil.createDataSource(credentials);
-//        List<String> allSchemas = DaoSchema.getAllSchemasNames(ds, dbType);
-//        return getAllTAPSchemasNames(ds, dbType, allSchemas);
-//    }
-//
-//    public static List<String> getAllTAPSchemasNames(DBWrapper dbs) throws SQLException {
-//        List<String> allSchemas = DaoSchema.getAllSchemasNames(dbs.getTapSchemaDataSource(), dbs.getTapSchemaDatabaseType());
-//        return getAllTAPSchemasNames(dbs, allSchemas);
-//    }
-//
-//    public static List<String> getAllTAPSchemasNames(DBWrapper dbs, List<String> allSchemas) throws SQLException {
-//        return getAllTAPSchemasNames(dbs.getTapSchemaDataSource(), dbs.getTapSchemaDatabaseType(), allSchemas);
-//    }
-//
-//    /**
-//     * Retrieve the list of all TAP_SCHEMA schemas names contained in the
-//     * TAP_SCHEMA <code>DataSource</code>.<br>
-//     * TAP_SCHEMA schemas are selected simply checking if they contains the
-//     * TAP_SCHEMA standard tables. Currently no check on columns is performed.
-//     *
-//     * @param allSchemas usually the TAP_SCHEMA schemas list is loaded together
-//     * the list of all schemas, so this list is passed by parameter to avoid
-//     * repeating the query twice.
-//     *
-//     * @return list of all TAP_SCHEMA schemas names alphabetically and case
-//     * insensitively ordered.
-//     */
-//    public static List<String> getAllTAPSchemasNames(DataSource dataSource, DatabaseType dbType, List<String> allSchemas) throws SQLException {
-//
-//        List<String> allTAPSchemas = new ArrayList<>();
-//
-//        for (String schemaName : allSchemas) {
-//
-//            boolean schemas = false,
-//                    tables = false,
-//                    columns = false,
-//                    keys = false,
-//                    keyColumns = false;
-//
-//            String query;
-//            switch (dbType) {
-//                case MYSQL:
-//                    query = "SHOW TABLES FROM `" + schemaName + "`";
-//                    break;
-//                case POSTGRES:
-//                    query = "SELECT tablename FROM pg_catalog.pg_tables where schemaname = '" + schemaName + "'";
-//                    break;
-//                default:
-//                    throw new UnsupportedOperationException("Database type " + dbType + " not supported");
-//            }
-//
-//            log.debug("Executing query {}", query);
-//
-//            try (Connection connection = dataSource.getConnection();
-//                    Statement statement = connection.createStatement();
-//                    ResultSet resultSet = statement.executeQuery(query)) {
-//                while (resultSet.next()) {
-//                    String shortTableName = resultSet.getString(1);
-//
-//                    if (null != shortTableName) {
-//                        switch (shortTableName) {
-//                            case "schemas":
-//                                schemas = true;
-//                                break;
-//                            case "tables":
-//                                tables = true;
-//                                break;
-//                            case "columns":
-//                                columns = true;
-//                                break;
-//                            case "keys":
-//                                keys = true;
-//                                break;
-//                            case "key_columns":
-//                                keyColumns = true;
-//                                break;
-//                        }
-//                    }
-//                }
-//            }
-//
-//            if (schemas && tables && columns && keys && keyColumns) {
-//                // the schema is a TAP_SCHEMA
-//                allTAPSchemas.add(schemaName);
-//            }
-//        }
-//
-//        log.debug("{} TAP_SCHEMA schemas found", allTAPSchemas.size());
-//
-//        return TSMUtil.sortStringsList(allTAPSchemas);
-//    }
-//
-//    /**
-//     * Retrieve the list of the name of the schemas exposed by the TAP_SCHEMA
-//     * specified by the <code>tapSchemaName</code> parameter.
-//     *
-//     * @return list of exposed schemas names alphabetically and case
-//     * insensitively ordered.
-//     */
-//    public static List<String> getExposedSchemas(DBWrapper dbs, String tapSchemaName) throws SQLException {
-//
-//        final List<String> exposedSchemas = new ArrayList<>();
-//
-//        DatabaseType dbType = dbs.getTapSchemaDatabaseType();
-//
-//        String query;
-//        if (dbType == DatabaseType.MYSQL) {
-//            query = "SELECT schema_name FROM `" + tapSchemaName + "`.`schemas`";
-//        } else if (dbType == DatabaseType.POSTGRES) {
-//            query = "SELECT schema_name FROM \"" + tapSchemaName + "\".\"schemas\"";
-//        } else {
-//            throw new UnsupportedOperationException("Database type " + dbType + " not supported");
-//        }
-//
-//        log.debug("Executing query " + query);
-//
-//        try (Connection connection = dbs.getTapSchemaConnection();
-//                Statement statement = connection.createStatement();
-//                ResultSet resultSet = statement.executeQuery(query)) {
-//            while (resultSet.next()) {
-//                exposedSchemas.add(resultSet.getString(1));
-//            }
-//        }
-//
-//        return exposedSchemas;
-//    }
-}
diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoColumn.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoColumn.java
deleted file mode 100644
index 6aafd03a20393456d8ef0bfadcbe0f2c712b222a..0000000000000000000000000000000000000000
--- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoColumn.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/* 
- * _____________________________________________________________________________
- * 
- * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of
- * Trieste INAF - IA2 Italian Center for Astronomical Archives
- * _____________________________________________________________________________
- * 
- * Copyright (C) 2016 Istituto Nazionale di Astrofisica
- * 
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License Version 3 as published by the
- * Free Software Foundation.
- * 
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- * 
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 51
- * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package it.inaf.ia2.tsm;
-
-import it.inaf.ia2.tsm.datalayer.DatabaseType;
-import it.inaf.ia2.tsm.datalayer.DBWrapper;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Pattern;
-import javax.sql.DataSource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Utility class that contains static methods for managing {@link Column}s into
- * the database.
- *
- * @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
- */
-public class DaoColumn {
-//
-//    private static final Logger log = LoggerFactory.getLogger(DaoColumn.class);
-//
-//    private static boolean equalsOneOf(String string, String... values) {
-//        for (String value : values) {
-//            if (string.equals(value)) {
-//                return true;
-//            }
-//        }
-//        return false;
-//    }
-//
-//    /**
-//     * Returns the list of all the columns names given a schema name and a table
-//     * name, also if these objects have never been added into the TAP_SCHEMA.
-//     * This can be useful to retrieve the source database structure.
-//     */
-//    public static List<String> getAllColumnsNames(DBWrapper dbWrapper, TapSchema tapSchema, String schemaName, String tableSimpleName) throws SQLException {
-//        final List<String> allColumns = new ArrayList<>();
-//
-//        DataSource dataSource = TSMUtil.getSchemaDataSource(dbWrapper, tapSchema, schemaName);
-//        DatabaseType dbType = TSMUtil.getSchemaDatabaseType(dbWrapper, tapSchema, schemaName);
-//
-//        String query;
-//        if (dbType == DatabaseType.MYSQL) {
-//            query = String.format("SHOW COLUMNS FROM `%s`.`%s`", schemaName, tableSimpleName);
-//        } else if (dbType == DatabaseType.POSTGRES) {
-//            query = "SELECT column_name FROM information_schema.columns WHERE table_schema = '" + schemaName + "' AND table_name = '" + tableSimpleName + "'";
-//        } else {
-//            throw new UnsupportedOperationException("Database type " + dbType + " not supported");
-//        }
-//
-//        log.debug("Executing query {}", query);
-//
-//        try (Connection connection = dataSource.getConnection();
-//                Statement statement = connection.createStatement();
-//                ResultSet resultSet = statement.executeQuery(query)) {
-//
-//            while (resultSet.next()) {
-//
-//                String columnName;
-//                if (dbType == DatabaseType.MYSQL) {
-//                    columnName = resultSet.getString("Field");
-//                } else if (dbType == DatabaseType.POSTGRES) {
-//                    columnName = resultSet.getString("column_name");
-//                } else {
-//                    throw new UnsupportedOperationException("Database type " + dbType + " not supported");
-//                }
-//
-//                allColumns.add(columnName);
-//            }
-//        }
-//
-//        return allColumns;
-//    }
-//
-//    /**
-//     * For performance reasons all columns of a {@link Table} are loaded
-//     * together using this method. Columns {@link Status} is at first set as
-//     * {@code LOADED}.
-//     */
-//    protected static List<Column> loadAllTableColumns(DBWrapper dbWrapper, TapSchema tapSchema, String schemaName, Table table) throws SQLException {
-//        String tableSimpleName = table.getName();
-//        final List<Column> allColumns = new ArrayList<>();
-//
-//        DataSource dataSource = TSMUtil.getSchemaDataSource(dbWrapper, tapSchema, schemaName);
-//        DatabaseType dbType = TSMUtil.getSchemaDatabaseType(dbWrapper, tapSchema, schemaName);
-//
-//        String query;
-//        if (dbType == DatabaseType.MYSQL) {
-//            query = String.format("SHOW COLUMNS FROM `%s`.`%s`", schemaName, tableSimpleName);
-//        } else if (dbType == DatabaseType.POSTGRES) {
-//            query = "SELECT c.column_name, c.data_type, r.contype AS column_type, c.character_maximum_length, c.numeric_precision\n" //, c.numeric_precision_radix
-//                    + "FROM information_schema.columns c\n"
-//                    + "JOIN pg_catalog.pg_tables t ON c.table_schema = t.schemaname AND c.table_name = t.tablename\n"
-//                    + "LEFT JOIN pg_catalog.pg_constraint r ON c.ordinal_position = ANY(r.conkey) AND r.conrelid = (t.schemaname || '.' || t.tablename)::regclass::oid\n"
-//                    + "WHERE t.schemaname = '" + schemaName + "' AND t.tablename = '" + tableSimpleName + "'";
-//        } else {
-//            throw new UnsupportedOperationException("Database type " + dbType + " not supported");
-//        }
-//
-//        log.debug("Executing query {}", query);
-//
-//        try (Connection connection = dataSource.getConnection();
-//                Statement statement = connection.createStatement();
-//                ResultSet resultSet = statement.executeQuery(query)) {
-//
-//            while (resultSet.next()) {
-//
-//                String columnName;
-//                if (dbType == DatabaseType.MYSQL) {
-//                    columnName = resultSet.getString("Field");
-//                } else if (dbType == DatabaseType.POSTGRES) {
-//                    columnName = resultSet.getString("column_name");
-//                } else {
-//                    throw new UnsupportedOperationException("Database type " + dbType + " not supported");
-//                }
-//
-//                boolean indexed = false, primaryKey = false;
-//
-//                // Key type
-//                if (dbType == DatabaseType.MYSQL) {
-//                    String key = resultSet.getString("Key");
-//                    primaryKey = key.equals("PRI");
-//                    indexed = equalsOneOf(key, "PRI", "UNI", "MUL");
-//                } else if (dbType == DatabaseType.POSTGRES) {
-//                    String columnType = resultSet.getString("column_type");
-//                    if (columnType != null) {
-//                        primaryKey = "p".equals(columnType);
-//                        indexed = equalsOneOf(columnType, "p", "f", "u");
-//                    }
-//                } else {
-//                    throw new UnsupportedOperationException("Database type " + dbType + " not supported");
-//                }
-//
-//                // Datatype and Size
-//                int size = 0;
-//                String datatype;
-//
-//                if (dbType == DatabaseType.MYSQL) {
-//                    String type = resultSet.getString("Type").toLowerCase();
-//
-//                    if (type.startsWith("int")) {
-//                        datatype = "adql:INTEGER";
-//                    } else if (type.startsWith("smallint")) {
-//                        datatype = "adql:SMALLINT";
-//                    } else if (type.startsWith("bigint")) {
-//                        datatype = "adql:BIGINT";
-//                    } else if (type.startsWith("float")) {
-//                        datatype = "adql:REAL";
-//                    } else if (type.startsWith("char")) {
-//                        int beginIndex = type.indexOf('(');
-//                        int endIndex = type.indexOf(')');
-//                        size = Integer.parseInt(type.substring(beginIndex + 1, endIndex));
-//                        datatype = "adql:CHAR";
-//                    } else if (type.startsWith("varchar")) {
-//                        int beginIndex = type.indexOf('(');
-//                        int endIndex = type.indexOf(')');
-//                        size = Integer.parseInt(type.substring(beginIndex + 1, endIndex));
-//                        datatype = "adql:VARCHAR";
-//                    } else if (type.contains("timestamp")) {
-//                        datatype = "adql:TIMESTAMP";
-//                    } else {
-//                        datatype = "adql:" + type.toUpperCase();
-//                    }
-//                } else if (dbType == DatabaseType.POSTGRES) {
-//                    String type = resultSet.getString("data_type");
-//
-//                    if (type.startsWith("int")) {
-//                        datatype = "adql:INTEGER";
-//                    } else if (type.startsWith("smallint")) {
-//                        datatype = "adql:SMALLINT";
-//                    } else if (type.startsWith("bigint")) {
-//                        datatype = "adql:BIGINT";
-//                    } else if (type.startsWith("double") || type.startsWith("real")) {
-//                        datatype = "adql:REAL";
-//                    } else if (type.startsWith("character varying")) {
-//                        datatype = "adql:VARCHAR";
-//                        size = resultSet.getInt("character_maximum_length");
-//                    } else if (type.startsWith("char")) {
-//                        datatype = "adql:CHAR";
-//                        size = resultSet.getInt("character_maximum_length");
-//                    } else if (type.contains("timestamp")) {
-//                        datatype = "adql:TIMESTAMP";
-//                    } else {
-//                        datatype = "adql:" + type.toUpperCase();
-//                    }
-//                } else {
-//                    throw new UnsupportedOperationException("Database type " + dbType + " not supported");
-//                }
-//
-//                Integer arraySize = null; // TODO (v 1.1)
-//
-//                Column column = new Column(dbWrapper, tapSchema, table, columnName, indexed, primaryKey, datatype, size, arraySize);
-//
-//                allColumns.add(column);
-//            }
-//        }
-//
-//        return allColumns;
-//    }
-//
-//    /**
-//     * Retrieves saved {@code Column}s from the database and add them into the
-//     * specified {@code TapSchema}.
-//     */
-//    protected static void fillSavedColumns(DBWrapper dbWrapper, final TapSchema tapSchema) throws SQLException {
-//
-//        log.debug("fillSavedColumns");
-//
-//        SelectQueryBuilder selectQueryBuilder = new SelectQueryBuilder(dbWrapper.getTapSchemaDatabaseType(), tapSchema, TapSchema.COLUMNS_TABLE) {
-//
-//            @Override
-//            protected TapSchemaEntity getEntity(ResultSet rs) throws SQLException {
-//                String tableCompleteName = rs.getString("table_name");
-//                String columnName = rs.getString("column_name");
-//
-//                String[] tableNameSplit = tableCompleteName.split(Pattern.quote("."));
-//                String schemaName = tableNameSplit[0];
-//                String tableSimpleName = tableNameSplit[1];
-//
-//                Schema schema = tapSchema.getChild(schemaName);
-//                if (schema == null) {
-//                    return null;
-//                }
-//                Table table = schema.getChild(tableSimpleName);
-//                if (table == null) {
-//                    return null;
-//                }
-//                Column column = table.addChild(columnName);
-//                if (column == null) {
-//                    return null;
-//                }
-//                column.setStatus(Status.ADDED_PERSISTED);
-//                return column;
-//            }
-//        };
-//
-//        selectQueryBuilder.executeQuery(dbWrapper.getTapSchemaConnection());
-//    }
-//
-//    /**
-//     * Save a new {@code Column} into the TAP_SCHEMA schema.
-//     */
-//    protected static void insertNewColumn(DatabaseType dbType, Connection connection, TapSchema tapSchema, Column column) throws SQLException {
-//
-//        log.debug("insertNewColumn");
-//
-//        InsertQueryBuilder insertQueryBuilder = new InsertQueryBuilder(dbType, tapSchema, column, TapSchema.COLUMNS_TABLE);
-//        insertQueryBuilder.executeQuery(connection);
-//    }
-//
-//    /**
-//     * Updates an existing {@code Column}.
-//     */
-//    protected static void updateColumn(DatabaseType dbType, Connection connection, TapSchema tapSchema, Column column) throws SQLException {
-//
-//        UpdateQueryBuilder updateQueryBuilder = new UpdateQueryBuilder(dbType, tapSchema, column, TapSchema.COLUMNS_TABLE, "column_name = ? AND table_name = ?");
-//
-//        String query = updateQueryBuilder.getQuery();
-//
-//        try (PreparedStatement statement = connection.prepareStatement(query)) {
-//
-//            log.debug("Executing query {}", query);
-//
-//            int i = updateQueryBuilder.addStatementValues(statement);
-//            statement.setString(i, column.getName());
-//            statement.setString(i + 1, column.getTableCompleteName());
-//
-//            statement.executeUpdate();
-//        }
-//    }
-}
diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoKey.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoKey.java
deleted file mode 100644
index 28599ae3cecbd2d812ef46d43fedd9f8133ccec4..0000000000000000000000000000000000000000
--- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoKey.java
+++ /dev/null
@@ -1,489 +0,0 @@
-/* 
- * _____________________________________________________________________________
- * 
- * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of
- * Trieste INAF - IA2 Italian Center for Astronomical Archives
- * _____________________________________________________________________________
- * 
- * Copyright (C) 2016 Istituto Nazionale di Astrofisica
- * 
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License Version 3 as published by the
- * Free Software Foundation.
- * 
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- * 
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 51
- * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package it.inaf.ia2.tsm;
-
-import it.inaf.ia2.tsm.datalayer.DatabaseType;
-import it.inaf.ia2.tsm.datalayer.DBWrapper;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Pattern;
-import javax.sql.DataSource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Utility class that contains static methods for managing {@link Key}s and
- * {@link KeyColumn}s into the database.
- *
- * @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
- */
-public class DaoKey {
-//
-//    private static final Logger log = LoggerFactory.getLogger(DaoKey.class);
-//
-//    /**
-//     * Generate list of KeyEntity for a given schema, specifying its
-//     * <code>DataSource</code> and its name.<br>
-//     * <strong>IMPORTANT</strong>: this keys are without id. The id has to be
-//     * set when a table is added to a schema.
-//     */
-//    protected static List<Key> getSchemaKeys(DBWrapper dbWrapper, TapSchema tapSchema, String schemaName) throws SQLException {
-//
-//        log.debug("getSchemaKeys");
-//
-//        DataSource dataSource = TSMUtil.getSchemaDataSource(dbWrapper, tapSchema, schemaName);
-//        DatabaseType dbType = TSMUtil.getSchemaDatabaseType(dbWrapper, tapSchema, schemaName);
-//
-//        if (dbType == DatabaseType.MYSQL) {
-//
-//            Map<String, Key> schemaKeys = new HashMap<>();
-//
-//            String query = "SELECT\n"
-//                    + "c.`CONSTRAINT_NAME` AS constraint_name,\n"
-//                    + "k.`TABLE_SCHEMA` AS from_schema,\n"
-//                    + "k.`TABLE_NAME` AS from_table,\n"
-//                    + "k.`COLUMN_NAME` AS from_column,\n"
-//                    + "k.`REFERENCED_TABLE_SCHEMA` AS target_schema,\n"
-//                    + "k.`REFERENCED_TABLE_NAME` AS target_table,\n"
-//                    + "k.`REFERENCED_COLUMN_NAME` AS target_column\n"
-//                    + "FROM information_schema.TABLE_CONSTRAINTS c \n"
-//                    + "LEFT JOIN information_schema.KEY_COLUMN_USAGE k \n"
-//                    + "ON c.`CONSTRAINT_NAME` = k.`CONSTRAINT_NAME` AND c.`TABLE_SCHEMA` = k.`TABLE_SCHEMA`\n"
-//                    + "WHERE c.`CONSTRAINT_TYPE` = 'FOREIGN KEY' \n"
-//                    + "AND k.`TABLE_SCHEMA` = '" + schemaName + "' OR k.`REFERENCED_TABLE_SCHEMA` = '" + schemaName + "'";
-//
-//            try (Connection connection = dataSource.getConnection();
-//                    Statement statement = connection.createStatement();
-//                    ResultSet resultSet = statement.executeQuery(query)) {
-//
-//                while (resultSet.next()) {
-//                    String constraintName = resultSet.getString("constraint_name");
-//
-//                    Key key = schemaKeys.get(constraintName);
-//                    if (key == null) {
-//                        key = new Key(
-//                                dbWrapper,
-//                                tapSchema,
-//                                resultSet.getString("from_schema"),
-//                                resultSet.getString("from_table"),
-//                                resultSet.getString("target_schema"),
-//                                resultSet.getString("target_table")
-//                        );
-//                        schemaKeys.put(constraintName, key);
-//                    }
-//
-//                    ((Key) key).addKeyColumn(resultSet.getString("from_column"), resultSet.getString("target_column"));
-//                }
-//            }
-//
-//            return new ArrayList<>(schemaKeys.values());
-//
-//        } else if (dbType == DatabaseType.POSTGRES) {
-//
-//            String databaseName
-//                    = schemaName.equals(tapSchema.getName())
-//                    ? dbWrapper.getTapSchemaCredentials().getDatabase()
-//                    : dbWrapper.getSourceCredentials().getDatabase();
-//
-//            List<Key> schemaKeys = new ArrayList<>();
-//
-//            String queryKeys = "SELECT\n"
-//                    + "conname AS constraint_name,\n"
-//                    + "conrelid::regclass AS from_table, \n"
-//                    + "confrelid::regclass AS target_table\n"
-//                    + "FROM pg_catalog.pg_constraint\n"
-//                    + "WHERE contype = 'f'\n"
-//                    + "AND ((conrelid::regclass || '' LIKE '" + schemaName + ".%')\n"
-//                    + "OR (confrelid::regclass || '' LIKE '" + schemaName + ".%'))";
-//
-//            try (Connection connection = dataSource.getConnection();
-//                    Statement statement = connection.createStatement();
-//                    ResultSet resultSet = statement.executeQuery(queryKeys)) {
-//
-//                log.debug("Executing query {}", queryKeys);
-//
-//                while (resultSet.next()) {
-//
-//                    String constraintName = resultSet.getString("constraint_name");
-//
-//                    String[] fromTableFullNameSplit = resultSet.getString("from_table").split(Pattern.quote("."));
-//                    String fromSchema = fromTableFullNameSplit[0];
-//                    String fromTable = fromTableFullNameSplit[1];
-//
-//                    String[] targetTableFullNameSplit = resultSet.getString("target_table").split(Pattern.quote("."));
-//                    String targetSchema = targetTableFullNameSplit[0];
-//                    String targetTable = targetTableFullNameSplit[1];
-//
-//                    Key key = new Key(dbWrapper, tapSchema, fromSchema, fromTable, targetSchema, targetTable);
-//                    schemaKeys.add(key);
-//
-//                    // conkey conrelid
-//                    String queryFromKC = "SELECT\n"
-//                            + "c.column_name AS key_column\n"
-//                            + "FROM information_schema.columns c\n"
-//                            + "JOIN pg_catalog.pg_constraint r ON c.ordinal_position = ANY(r.conkey)\n"
-//                            + "AND (c.table_schema || '.' || c.table_name) = (r.conrelid::regclass || '')\n"
-//                            + "WHERE r.conname = '" + constraintName + "' AND r.contype = 'f'\n"
-//                            + "AND c.table_schema = '" + fromSchema + "'\n"
-//                            + "AND table_catalog = '" + databaseName + "'";
-//
-//                    // as above, but with confkey and confrelid and different c.table_schema where condition
-//                    String queryTargetKC = "SELECT\n"
-//                            + "c.column_name AS key_column\n"
-//                            + "FROM information_schema.columns c\n"
-//                            + "JOIN pg_catalog.pg_constraint r ON c.ordinal_position = ANY(r.confkey)\n"
-//                            + "AND (c.table_schema || '.' || c.table_name) = (r.confrelid::regclass || '')\n"
-//                            + "WHERE r.conname = '" + constraintName + "' AND r.contype = 'f'\n"
-//                            + "AND c.table_schema = '" + targetSchema + "'\n"
-//                            + "AND table_catalog = '" + databaseName + "'";
-//
-//                    try (Statement statFromKC = connection.createStatement();
-//                            Statement statTargetKC = connection.createStatement()) {
-//
-//                        try (ResultSet rsFromKC = statFromKC.executeQuery(queryFromKC);
-//                                ResultSet rsTargetKC = statTargetKC.executeQuery(queryTargetKC)) {
-//
-//                            log.debug("Executing query {}", queryFromKC);
-//                            log.debug("Executing query {}", queryTargetKC);
-//
-//                            while (rsFromKC.next()) {
-//                                if (rsTargetKC.next()) {
-//                                    ((Key) key).addKeyColumn(
-//                                            rsFromKC.getString("key_column"),
-//                                            rsTargetKC.getString("key_column")
-//                                    );
-//                                }
-//                            }
-//                        }
-//                    }
-//                }
-//            }
-//
-//            return schemaKeys;
-//        } else {
-//            throw new UnsupportedOperationException("Database type " + dbType + " not supported");
-//        }
-//    }
-//
-//    /**
-//     * Retrieves saved {@code Key}s from the database and add them into the
-//     * specified {@code TapSchema}.
-//     */
-//    protected static void fillSavedKeys(DBWrapper dbWrapper, TapSchema tapSchema) throws SQLException {
-//
-//        log.debug("fillSavedKeys");
-//
-//        // We can decide to work only on from tables or target tables, because 
-//        // the same key is contained on both.
-//        // Schemas and tables have to be already added to the TAP_SCHEMA.
-//        List<Key> allVisibleKeys = new ArrayList<>();
-//
-//        // Reset to null all generated keyId.
-//        for (Key key : ((TapSchema) tapSchema).getAllKeys()) {
-//            key.initProperty(Key.ID_KEY, null);
-//
-//            // Meanwhile we add all the visible keys to this list for 
-//            // further checks
-//            if (key.isVisible()) {
-//                allVisibleKeys.add(key);
-//            }
-//        }
-//
-//        // Building query for the keys table
-//        SelectQueryBuilder keysSelect = new SelectQueryBuilder(dbWrapper.getTapSchemaDatabaseType(), tapSchema, TapSchema.KEYS_TABLE) {
-//            @Override
-//            protected TapSchemaEntity getEntity(ResultSet rs) throws SQLException {
-//                throw new UnsupportedOperationException();
-//            }
-//        };
-//        String queryKeys = keysSelect.getQuery();
-//        
-//        // Building query for the key_columns table
-//        SelectQueryBuilder keyColumnsSelect = new SelectQueryBuilder(dbWrapper.getTapSchemaDatabaseType(), tapSchema, TapSchema.KEY_COLUMNS_TABLE) {
-//            @Override
-//            protected TapSchemaEntity getEntity(ResultSet rs) throws SQLException {
-//                throw new UnsupportedOperationException();
-//            }
-//        };
-//        String queryKeyColumns = String.format("%s WHERE %s = ?",
-//                keyColumnsSelect.getQuery(),
-//                TSMUtil.escapeName(KeyColumn.KEY_ID_KEY, dbWrapper.getTapSchemaDatabaseType()));
-//
-//        boolean supportKeyID = EntityPropertyInfo.getEntityPropertyInfo(TapSchema.KEYS_TABLE, Key.KEY_ID_KEY).acceptVersion(tapSchema.getVersion());
-//        boolean supportKeyColumnID = EntityPropertyInfo.getEntityPropertyInfo(TapSchema.KEY_COLUMNS_TABLE, KeyColumn.KEY_COLUMN_ID_KEY).acceptVersion(tapSchema.getVersion());
-//
-//        try (Connection conn = dbWrapper.getTapSchemaConnection()) {
-//
-//            log.debug("Executing query {}", queryKeys);
-//
-//            // ResultSet type and concurrency are necessary for PostgreSQL
-//            try (Statement statementKeys = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
-//                    ResultSet rsKeys = statementKeys.executeQuery(queryKeys)) {
-//
-//                while (rsKeys.next()) {
-//                    // Searching the keys.
-//
-//                    String keyId = rsKeys.getString(Key.ID_KEY);
-//                    String fromTableCompleteNameSplit[] = rsKeys.getString(Key.FROM_TABLE_KEY).split(Pattern.quote("."));
-//                    String fromSchemaName = fromTableCompleteNameSplit[0];
-//                    String fromTableName = fromTableCompleteNameSplit[1];
-//
-//                    Schema fromSchema = tapSchema.getChild(fromSchemaName);
-//
-//                    if (fromSchema == null) {
-//                        tapSchema.getConsistencyChecks().addUnexistingKey(keyId);
-//                    } else {
-//                        Table fromTable = fromSchema.getChild(fromTableName);
-//                        if (fromTable == null) {
-//                            tapSchema.getConsistencyChecks().addUnexistingKey(keyId);
-//                        } else {
-//                            // ResultSet type and concurrency are necessary for PostgreSQL
-//                            try (PreparedStatement statementKeyColumns = conn.prepareStatement(queryKeyColumns, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE)) {
-//
-//                                statementKeyColumns.setString(1, keyId);
-//                                log.debug("Executing query {} [key_id={}]", queryKeyColumns, keyId);
-//
-//                                try (ResultSet rsKeyColumns = statementKeyColumns.executeQuery()) {
-//                                    for (Key fromKey : fromTable.getAllFromKeys()) {
-//
-//                                        boolean columnsFound = false;
-//
-//                                        for (KeyColumn keyColumn : fromKey.getKeyColumns()) {
-//                                            columnsFound = false;
-//
-//                                            rsKeyColumns.beforeFirst();
-//                                            while (rsKeyColumns.next()) {
-//                                                String fromColumn = rsKeyColumns.getString(KeyColumn.FROM_COLUMN_KEY);
-//                                                String targetColumn = rsKeyColumns.getString(KeyColumn.TARGET_COLUMN_KEY);
-//                                                if (keyColumn.getFromColumn().equals(fromColumn)
-//                                                        && keyColumn.getTargetColumn().equals(targetColumn)) {
-//                                                    columnsFound = true;
-//                                                    break;
-//                                                }
-//                                            }
-//                                            if (!columnsFound) {
-//                                                break;
-//                                            }
-//                                        }
-//
-//                                        if (columnsFound) {
-//                                            // all columns found --> key found!
-//
-//                                            // Updating key
-//                                            String keyDescription = rsKeys.getString(Key.DESCRIPTION_KEY);
-//                                            String keyUtype = rsKeys.getString(Key.UTYPE_KEY);
-//
-//                                            fromKey.initProperty(Key.ID_KEY, keyId);
-//                                            fromKey.initProperty(Key.DESCRIPTION_KEY, keyDescription);
-//                                            fromKey.initProperty(Key.UTYPE_KEY, keyUtype);
-//                                            if (supportKeyID) {
-//                                                fromKey.initProperty(Key.KEY_ID_KEY, TSMUtil.getObject(rsKeys, Key.KEY_ID_KEY, Long.class));
-//                                            }
-//                                            ((Key) fromKey).setVisible(true);
-//
-//                                            // Updating key columns
-//                                            for (KeyColumn keyColumn : fromKey.getKeyColumns()) {
-//                                                rsKeyColumns.beforeFirst();
-//                                                while (rsKeyColumns.next()) {
-//                                                    String fromColumn = rsKeyColumns.getString(KeyColumn.FROM_COLUMN_KEY);
-//                                                    String targetColumn = rsKeyColumns.getString(KeyColumn.TARGET_COLUMN_KEY);
-//                                                    if (keyColumn.getFromColumn().equals(fromColumn)
-//                                                            && keyColumn.getTargetColumn().equals(targetColumn)) {
-//                                                        keyColumn.initProperty(KeyColumn.KEY_ID_KEY, keyId);
-//                                                        if (supportKeyColumnID) {
-//                                                            keyColumn.initProperty(KeyColumn.KEY_COLUMN_ID_KEY, TSMUtil.getObject(rsKeyColumns, KeyColumn.KEY_COLUMN_ID_KEY, Long.class));
-//                                                        }
-//                                                        break;
-//                                                    }
-//                                                }
-//                                            }
-//
-//                                            break;
-//                                        }
-//                                    }
-//                                }
-//                            }
-//                        }
-//                    }
-//                }
-//
-//                // Check if the saved TAP_SCHEMA contains keys that aren't loaded (fictitious keys).
-//                List<Key> fictitiousKeys = new ArrayList<>();
-//
-//                rsKeys.beforeFirst();
-//                while (rsKeys.next()) {
-//                    String keyId = rsKeys.getString(Key.ID_KEY);
-//                    boolean keyIdFound = false;
-//                    for (Key key : allVisibleKeys) {
-//                        if (keyId.equals(key.getId())) {
-//                            keyIdFound = true;
-//                            break;
-//                        }
-//                    }
-//                    if (!keyIdFound && !tapSchema.getConsistencyChecks().getUnexistingKeys().contains(keyId)) {
-//                        String fromTableCompleteName = rsKeys.getString(Key.FROM_TABLE_KEY);
-//                        String targetTableCompleteName = rsKeys.getString(Key.TARGET_TABLE_KEY);
-//                        Key key = new Key(dbWrapper, tapSchema, fromTableCompleteName, targetTableCompleteName);
-//                        key.initProperty(Key.ID_KEY, keyId);
-//                        if (supportKeyID) {
-//                            key.initProperty(Key.KEY_ID_KEY, TSMUtil.getObject(rsKeys, Key.KEY_ID_KEY, Long.class));
-//                        }
-//                        key.setVisible(true);
-//                        fictitiousKeys.add(key);
-//
-//                        tapSchema.getChild(key.getFromSchemaName()).getChild(key.getFromTableSimpleName()).addFromKey(key);
-//                        tapSchema.getChild(key.getTargetSchemaName()).getChild(key.getTargetTableSimpleName()).addTargetKey(key);
-//                    }
-//                }
-//
-//                // filling fictitious keys columns
-//                for (Key key : fictitiousKeys) {
-//                    try (PreparedStatement statementKeyColumns = conn.prepareStatement(queryKeyColumns)) {
-//
-//                        String keyId = key.getId();
-//                        statementKeyColumns.setString(1, keyId);
-//                        log.debug("Executing query {} [key_id={}]", queryKeyColumns, keyId);
-//
-//                        try (ResultSet rsKeyColumns = statementKeyColumns.executeQuery()) {
-//
-//                            while (rsKeyColumns.next()) {
-//                                String fromColumn = rsKeyColumns.getString(KeyColumn.FROM_COLUMN_KEY);
-//                                String targetColumn = rsKeyColumns.getString(KeyColumn.TARGET_COLUMN_KEY);
-//
-//                                KeyColumn keyColumn = ((Key) key).addKeyColumn(fromColumn, targetColumn);
-//                                if (supportKeyColumnID) {
-//                                    keyColumn.initProperty(KeyColumn.KEY_COLUMN_ID_KEY, TSMUtil.getObject(rsKeyColumns, KeyColumn.KEY_COLUMN_ID_KEY, Long.class));
-//                                }
-//                            }
-//                        }
-//                    }
-//
-//                    // adding fictitious key to key set
-//                    ((TapSchema) tapSchema).getAllKeys().add(key);
-//                }
-//
-//                if (!fictitiousKeys.isEmpty()) {
-//                    log.debug("{} fictitious keys found", fictitiousKeys.size());
-//                    for (Key key : fictitiousKeys) {
-//                        log.debug("   {}", key);
-//                    }
-//                }
-//
-//                // Check if there are remaining keys with keyId = null (valid keys
-//                // that weren't saved into the TAP_SCHEMA).
-//                int keyId = ((TapSchema) tapSchema).getMaxKeyId() + 1;
-//                for (Key key : allVisibleKeys) {
-//                    if (key.getId() == null) {
-//                        key.setId(keyId + "");
-//                        keyId++;
-//                    }
-//                }
-//            }
-//        }
-//    }
-//
-//    /**
-//     * Save a new {@code Key} into the TAP_SCHEMA schema.
-//     */
-//    protected static void insertNewKey(DatabaseType dbType, Connection connection, TapSchema tapSchema, Key key) throws SQLException {
-//        log.debug("insertNewKey");
-//
-//        InsertQueryBuilder insertQueryBuilder = new InsertQueryBuilder(dbType, tapSchema, key, TapSchema.KEYS_TABLE);
-//        insertQueryBuilder.executeQuery(connection);
-//
-//        for (KeyColumn keyColumn : key.getKeyColumns()) {
-//            insertQueryBuilder = new InsertQueryBuilder(dbType, tapSchema, keyColumn, TapSchema.KEY_COLUMNS_TABLE);
-//            insertQueryBuilder.executeQuery(connection);
-//        }
-//    }
-//
-//    /**
-//     * Updates an existing {@code Key}.
-//     */
-//    protected static void updateKey(DatabaseType dbType, Connection connection, TapSchema tapSchema, Key key) throws SQLException {
-//        log.debug("updateKey");
-//
-//        if (key.getId() == null) {
-//            throw new IllegalStateException("Unable to update key: key_id is null");
-//        }
-//
-//        boolean keyIdChanged = key.isChanged(Key.ID_KEY);
-//
-//        if (keyIdChanged) {
-//            // Deleting key columns to avoid problem with foreign key constraint failures
-//
-//            String tapSchemaNameEscaped = TSMUtil.escapeName(tapSchema.getName(), dbType);
-//            String keyColumnsNameEscaped = TSMUtil.escapeName("key_columns", dbType);
-//
-//            String query = String.format("DELETE FROM %s.%s WHERE key_id = ?", tapSchemaNameEscaped, keyColumnsNameEscaped);
-//
-//            try (PreparedStatement statement = connection.prepareStatement(query)) {
-//                String originalKey = key.getOriginalValue(Key.ID_KEY, String.class);
-//                statement.setString(1, originalKey);
-//                log.debug("Executing query {} [key_id={}]", query, originalKey);
-//                statement.executeUpdate();
-//            }
-//        }
-//
-//        // Updating keys
-//        UpdateQueryBuilder updateQueryBuilder = new UpdateQueryBuilder(dbType, tapSchema, key, TapSchema.KEYS_TABLE, "key_id = ?");
-//        String query = updateQueryBuilder.getQuery();
-//        try (PreparedStatement statement = connection.prepareStatement(query)) {
-//            int i = updateQueryBuilder.addStatementValues(statement);
-//            String keyId = key.getId();
-//            statement.setString(i, keyId);
-//            log.debug("Executing query {} [key_id={}]", query, keyId);
-//            statement.executeUpdate();
-//        }
-//
-//        if (keyIdChanged) {
-//            // Re-insert deleted key columns
-//            for (KeyColumn keyColumn : key.getKeyColumns()) {
-//                InsertQueryBuilder insertQueryBuilder = new InsertQueryBuilder(dbType, tapSchema, keyColumn, TapSchema.KEY_COLUMNS_TABLE);
-//                insertQueryBuilder.executeQuery(connection);
-//            }
-//        } else {
-//            // Update key columns
-//            for (KeyColumn keyColumn : key.getKeyColumns()) {
-//                if (keyColumn.isChanged()) {
-//                    updateQueryBuilder = new UpdateQueryBuilder(dbType, tapSchema, keyColumn, TapSchema.KEY_COLUMNS_TABLE, "key_id = ?");
-//                    query = updateQueryBuilder.getQuery();
-//                    try (PreparedStatement statement = connection.prepareStatement(query)) {
-//                        int i = updateQueryBuilder.addStatementValues(statement);
-//                        String keyId = key.getId();
-//                        statement.setString(i, keyId);
-//                        log.debug("Executing query {} [key_id={}]", query, keyId);
-//                        statement.executeUpdate();
-//                    }
-//                }
-//            }
-//        }
-//    }
-}
diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoSchema.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoSchema.java
deleted file mode 100644
index 74429dde4750563440530033e207bdcbc9229511..0000000000000000000000000000000000000000
--- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoSchema.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/* 
- * _____________________________________________________________________________
- * 
- * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of
- * Trieste INAF - IA2 Italian Center for Astronomical Archives
- * _____________________________________________________________________________
- * 
- * Copyright (C) 2016 Istituto Nazionale di Astrofisica
- * 
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License Version 3 as published by the
- * Free Software Foundation.
- * 
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- * 
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 51
- * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package it.inaf.ia2.tsm;
-
-import it.inaf.ia2.tsm.datalayer.Credentials;
-import it.inaf.ia2.tsm.datalayer.DatabaseType;
-import it.inaf.ia2.tsm.datalayer.DBWrapper;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.List;
-import javax.sql.DataSource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Utility class that contains static methods for managing {@link Schema}s into
- * the database.
- *
- * @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
- */
-public class DaoSchema {
-//
-//    private static final Logger log = LoggerFactory.getLogger(DaoSchema.class);
-//
-//    public static List<String> getAllSchemasNames(Credentials credentials) throws SQLException {
-//        DataSource ds = TSMUtil.createDataSource(credentials);
-//        return getAllSchemasNames(ds, credentials.getDatabaseType());
-//    }
-//
-//    /**
-//     * Retrieve the list of the names of the all the schemas contained into the
-//     * database specified by the <code>DataSource</code> parameter.
-//     *
-//     * @return list of schemas names alphabetically and case insensitively
-//     * ordered.
-//     */
-//    public static List<String> getAllSchemasNames(DataSource dataSource, DatabaseType dbType) throws SQLException {
-//
-//        log.debug("getAllSchemasNames");
-//
-//        String query;
-//        if (dbType == DatabaseType.MYSQL) {
-//            query = "SHOW DATABASES";
-//        } else if (dbType == DatabaseType.POSTGRES) {
-//            query = "SELECT schema_name FROM information_schema.schemata";
-//        } else {
-//            throw new UnsupportedOperationException("Database type " + dbType + " not supported");
-//        }
-//
-//        log.debug("Executing query {}", query);
-//
-//        List<String> allSchemas = new ArrayList<>();
-//
-//        try (Connection connection = dataSource.getConnection();
-//                Statement statement = connection.createStatement();
-//                ResultSet resultSet = statement.executeQuery(query)) {
-//            while (resultSet.next()) {
-//                allSchemas.add(resultSet.getString(1));
-//            }
-//        }
-//
-//        log.debug("{} schemas found", allSchemas.size());
-//
-//        return TSMUtil.sortStringsList(allSchemas);
-//    }
-//
-//    /**
-//     * Retrieves saved {@code Schema}s from the database and add them into the
-//     * specified {@code TapSchema}.
-//     */
-//    protected static void fillSavedSchemas(DBWrapper dbWrapper, final TapSchema tapSchema) throws SQLException {
-//
-//        log.debug("fillSavedSchemas");
-//
-//        SelectQueryBuilder selectQueryBuilder = new SelectQueryBuilder(dbWrapper.getTapSchemaDatabaseType(), tapSchema, TapSchema.SCHEMAS_TABLE) {
-//
-//            @Override
-//            protected TapSchemaEntity getEntity(ResultSet rs) throws SQLException {
-//                String schemaName = rs.getString("schema_name");
-//                Schema schema = tapSchema.addChild(schemaName);
-//                if (schema == null) {
-//                    return null;
-//                }
-//                schema.setStatus(Status.ADDED_PERSISTED);
-//                return schema;
-//            }
-//        };
-//
-//        selectQueryBuilder.executeQuery(dbWrapper.getTapSchemaConnection());
-//    }
-//
-//    /**
-//     * Save a new {@code Schema} into the TAP_SCHEMA schema.
-//     */
-//    protected static void insertNewSchema(DatabaseType dbType, Connection connection, TapSchema tapSchema, Schema schema) throws SQLException {
-//
-//        log.debug("insertNewSchema");
-//
-//        InsertQueryBuilder insertQueryBuilder = new InsertQueryBuilder(dbType, tapSchema, schema, TapSchema.SCHEMAS_TABLE);
-//        insertQueryBuilder.executeQuery(connection);
-//    }
-//
-//    /**
-//     * Updates an existing {@code Schema}.
-//     */
-//    protected static void updateSchema(DatabaseType dbType, Connection connection, TapSchema tapSchema, Schema schema) throws SQLException {
-//
-//        UpdateQueryBuilder updateQueryBuilder = new UpdateQueryBuilder(dbType, tapSchema, schema, TapSchema.SCHEMAS_TABLE, "schema_name = ?");
-//
-//        String query = updateQueryBuilder.getQuery();
-//
-//        try (PreparedStatement statement = connection.prepareStatement(query)) {
-//
-//            log.debug("Executing query {}", query);
-//
-//            int i = updateQueryBuilder.addStatementValues(statement);
-//            statement.setString(i, schema.getName());
-//
-//            statement.executeUpdate();
-//        }
-//    }
-}
diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoTable.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoTable.java
deleted file mode 100644
index 4a42d7f247a8de15b0d00b581bf58d6855363a53..0000000000000000000000000000000000000000
--- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/DaoTable.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/* 
- * _____________________________________________________________________________
- * 
- * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of
- * Trieste INAF - IA2 Italian Center for Astronomical Archives
- * _____________________________________________________________________________
- * 
- * Copyright (C) 2016 Istituto Nazionale di Astrofisica
- * 
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License Version 3 as published by the
- * Free Software Foundation.
- * 
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- * 
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 51
- * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package it.inaf.ia2.tsm;
-
-import it.inaf.ia2.tsm.datalayer.DatabaseType;
-import it.inaf.ia2.tsm.datalayer.DBWrapper;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Pattern;
-import javax.sql.DataSource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Utility class that contains static methods for managing {@link Table}s into
- * the database.
- *
- * @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
- */
-public class DaoTable {
-
-//    private static final Logger log = LoggerFactory.getLogger(DaoTable.class);
-//
-//    /**
-//     * Retrieve the list of the names of all the tables contained in a schema,
-//     * given its name, also if the schema has never been added into the
-//     * TAP_SCHEMA.
-//     *
-//     * @return list of all tables names alphabetically and case insensitively
-//     * ordered.
-//     */
-//    public static List<String> getAllTablesNames(DBWrapper dbWrapper, TapSchema tapSchema, String schemaName) throws SQLException {
-//
-//        DataSource dataSource = TSMUtil.getSchemaDataSource(dbWrapper, tapSchema, schemaName);
-//        DatabaseType dbType = TSMUtil.getSchemaDatabaseType(dbWrapper, tapSchema, schemaName);
-//
-//        String query;
-//        switch (dbType) {
-//            case MYSQL:
-//                query = "SHOW TABLES FROM `" + schemaName + "`";
-//                break;
-//            case POSTGRES:
-//                query = "SELECT tablename FROM pg_catalog.pg_tables where schemaname = '" + schemaName + "'";
-//                break;
-//            default:
-//                throw new UnsupportedOperationException("Database type " + dbType + " not supported");
-//        }
-//
-//        log.debug("Executing query {}", query);
-//
-//        List<String> allTables = new ArrayList<>();
-//        try (Connection connection = dataSource.getConnection();
-//                Statement statement = connection.createStatement();
-//                ResultSet resultSet = statement.executeQuery(query)) {
-//            while (resultSet.next()) {
-//                allTables.add(resultSet.getString(1));
-//            }
-//        }
-//
-//        return TSMUtil.sortStringsList(allTables);
-//    }
-//
-//    /**
-//     * Retrieve the association between the tables names and their types
-//     * (<code>table</code> or <code>view</code>), given a
-//     * <code>DataSource</code> and a schema name.
-//     *
-//     * @return a map which has the tables names as keys and the table types as
-//     * values.
-//     */
-//    protected static Map<String, String> getTablesTypes(DBWrapper dbWrapper, TapSchema tapSchema, String schemaName) throws SQLException {
-//
-//        log.debug("getTablesTypes");
-//
-//        final Map<String, String> tablesTypes = new HashMap<>();
-//
-//        DataSource dataSource = TSMUtil.getSchemaDataSource(dbWrapper, tapSchema, schemaName);
-//        DatabaseType dbType = TSMUtil.getSchemaDatabaseType(dbWrapper, tapSchema, schemaName);
-//
-//        String query;
-//        switch (dbType) {
-//            case MYSQL:
-//                query = "SELECT table_name, table_type FROM information_schema.tables WHERE table_schema = '" + schemaName + "'";
-//                break;
-//            case POSTGRES:
-//                query = "SELECT tablename AS table_name, 'table' AS table_type\n"
-//                        + "FROM pg_catalog.pg_tables WHERE schemaname = '" + schemaName + "'\n"
-//                        + "UNION\n"
-//                        + "SELECT table_name AS table_name, 'view' AS table_type\n"
-//                        + "FROM INFORMATION_SCHEMA.views\n"
-//                        + "WHERE table_schema = '" + schemaName + "'";
-//                break;
-//            default:
-//                throw new UnsupportedOperationException("Database type " + dbType + " not supported");
-//        }
-//
-//        log.debug("Executing query {}", query);
-//
-//        try (Connection connection = dataSource.getConnection();
-//                Statement statement = connection.createStatement();
-//                ResultSet resultSet = statement.executeQuery(query)) {
-//            while (resultSet.next()) {
-//                String tableName = resultSet.getString("table_name");
-//                String tableType = resultSet.getString("table_type").equalsIgnoreCase("VIEW") ? "view" : "table";
-//                tablesTypes.put(tableName, tableType);
-//            }
-//        }
-//
-//        return tablesTypes;
-//    }
-//
-//    /**
-//     * Retrieves saved {@code Table}s from the database and add them into the
-//     * specified {@code TapSchema}.
-//     */
-//    protected static void fillSavedTables(DBWrapper dbWrapper, final TapSchema tapSchema) throws SQLException {
-//
-//        log.debug("fillSavedTables");
-//
-//        SelectQueryBuilder selectQueryBuilder = new SelectQueryBuilder(dbWrapper.getTapSchemaDatabaseType(), tapSchema, TapSchema.TABLES_TABLE) {
-//
-//            @Override
-//            protected TapSchemaEntity getEntity(ResultSet rs) throws SQLException {
-//                String schemaName = rs.getString("schema_name");
-//                String completeTableName = rs.getString("table_name");
-//
-//                Schema schema = tapSchema.getChild(schemaName);
-//
-//                if (schema != null) {
-//                    Table table = schema.addChild(completeTableName.split(Pattern.quote("."))[1]);
-//                    if (table == null) {
-//                        return null;
-//                    }
-//                    table.setStatus(Status.ADDED_PERSISTED);
-//                    return table;
-//                }
-//                // Schema was marked for removal in the ConsistencyChecks
-//                return null;
-//            }
-//        };
-//
-//        selectQueryBuilder.executeQuery(dbWrapper.getTapSchemaConnection());
-//    }
-//
-//    /**
-//     * Save a new {@code Table} into the TAP_SCHEMA schema.
-//     */
-//    protected static void insertNewTable(DatabaseType dbType, Connection connection, TapSchema tapSchema, Table table) throws SQLException {
-//
-//        log.debug("insertNewTable");
-//
-//        InsertQueryBuilder insertQueryBuilder = new InsertQueryBuilder(dbType, tapSchema, table, TapSchema.TABLES_TABLE);
-//        insertQueryBuilder.executeQuery(connection);
-//    }
-//
-//    /**
-//     * Updates an existing {@code Table}.
-//     */
-//    protected static void updateTable(DatabaseType dbType, Connection connection, TapSchema tapSchema, Table table) throws SQLException {
-//
-//        UpdateQueryBuilder updateQueryBuilder = new UpdateQueryBuilder(dbType, tapSchema, table, TapSchema.TABLES_TABLE, "table_name = ?");
-//
-//        String query = updateQueryBuilder.getQuery();
-//
-//        try (PreparedStatement statement = connection.prepareStatement(query)) {
-//
-//            log.debug("Executing query {}", query);
-//
-//            int i = updateQueryBuilder.addStatementValues(statement);
-//            statement.setString(i, table.getCompleteName());
-//
-//            statement.executeUpdate();
-//        }
-//    }
-}
diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/EntityProperty.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/EntityProperty.java
index 50744201b5ec1128ea859ac28b10396ed11ef5b7..f009cec488d19dbea0a0e6ddc813c0fb82c94eee 100644
--- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/EntityProperty.java
+++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/EntityProperty.java
@@ -77,6 +77,7 @@ public class EntityProperty<T> implements Serializable {
     }
 
     private <X> void setValue(X value, boolean checkUpdatable) {
+        assert value == null || value.getClass() == type;
         if (checkUpdatable && !propertyModel.isUpdatable()) {
             throw new UnsupportedOperationException("This EntityProperty instance (" + propertyModel.getName() + ") is not updatable");
         }
@@ -104,6 +105,9 @@ public class EntityProperty<T> implements Serializable {
      * Initialize the value.
      */
     public final <X> void init(X initialValue) {
+        if (!propertyModel.isNullable() && initialValue == null) {
+            initialValue = (X) propertyModel.getDefaultValue();
+        }
         setValue(initialValue, false);
         this.originalValue = (T) initialValue;
     }
@@ -115,4 +119,12 @@ public class EntityProperty<T> implements Serializable {
     public Class getType() {
         return type;
     }
+
+    public boolean isUpdatable() {
+        return propertyModel.isUpdatable();
+    }
+
+    public boolean isNullable() {
+        return propertyModel.isNullable();
+    }
 }
diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/InsertQueryBuilder.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/InsertQueryBuilder.java
deleted file mode 100644
index 712c16c38652354efe6ecb50dbfccdcc0eb1e0a2..0000000000000000000000000000000000000000
--- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/InsertQueryBuilder.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/* 
- * _____________________________________________________________________________
- * 
- * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of
- * Trieste INAF - IA2 Italian Center for Astronomical Archives
- * _____________________________________________________________________________
- * 
- * Copyright (C) 2016 Istituto Nazionale di Astrofisica
- * 
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License Version 3 as published by the
- * Free Software Foundation.
- * 
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- * 
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 51
- * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package it.inaf.ia2.tsm;
-
-import it.inaf.ia2.tsm.datalayer.DatabaseType;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Prepares an {@code INSERT} SQL query for a given {@link TapSchemaEntity} and
- * a given {@link TapSchema}.
- *
- * @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
- */
-public class InsertQueryBuilder {
-//
-//    private static final Logger log = LoggerFactory.getLogger(InsertQueryBuilder.class);
-//
-//    private final String query;
-//    private final List<EntityPropertyInfo> addedProperties;
-//    private final TapSchemaEntity tapSchemaEntity;
-//
-//    protected InsertQueryBuilder(DatabaseType dbType, TapSchema tapSchema, TapSchemaEntity tapSchemaEntity, String tapSchemaTableName) {
-//
-//        StringBuilder querySb = new StringBuilder("INSERT INTO ");
-//        querySb.append(TSMUtil.escapeName(tapSchema.getName(), dbType));
-//        querySb.append(".");
-//        querySb.append(TSMUtil.escapeName(tapSchemaTableName, dbType));
-//        querySb.append(" (");
-//
-//        addedProperties = new ArrayList<>();
-//        this.tapSchemaEntity = tapSchemaEntity;
-//
-//        boolean first = true;
-//        for (EntityPropertyInfo propertyInfo : EntityPropertyInfo.getEntityPropertiesInfo(tapSchemaTableName)) {
-//            if (propertyInfo.acceptVersion(tapSchema.getVersion())) {
-//
-//                if (!first) {
-//                    querySb.append(", ");
-//                }
-//                querySb.append(propertyInfo.getPropertyKey());
-//                addedProperties.add(propertyInfo);
-//                first = false;
-//            }
-//        }
-//        querySb.append(") VALUES (");
-//        for (int i = 0; i < addedProperties.size(); i++) {
-//            if (i > 0) {
-//                querySb.append(",");
-//            }
-//            querySb.append("?");
-//        }
-//        querySb.append(")");
-//
-//        query = querySb.toString();
-//    }
-//
-//    protected void executeQuery(Connection connection) throws SQLException {
-//
-//        try (PreparedStatement statement = connection.prepareStatement(query)) {
-//            log.debug("Executing query {}", query);
-//            int i = 1;
-//            for (EntityPropertyInfo property : addedProperties) {
-//                Object value = tapSchemaEntity.getValue(property.getPropertyKey(), property.getPropertyType());
-//                //log.debug("  [{}] {} ({})", i, value, property.getSqlType());
-//                statement.setObject(i, value, property.getSqlType());
-//                i++;
-//            }
-//            statement.executeUpdate();
-//        }
-//    }
-}
diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/SelectQueryBuilder.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/SelectQueryBuilder.java
deleted file mode 100644
index b3db4d2cebb5cf2087ed62a08c090172640e1480..0000000000000000000000000000000000000000
--- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/SelectQueryBuilder.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/* 
- * _____________________________________________________________________________
- * 
- * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of
- * Trieste INAF - IA2 Italian Center for Astronomical Archives
- * _____________________________________________________________________________
- * 
- * Copyright (C) 2016 Istituto Nazionale di Astrofisica
- * 
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License Version 3 as published by the
- * Free Software Foundation.
- * 
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- * 
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 51
- * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package it.inaf.ia2.tsm;
-
-import it.inaf.ia2.tsm.datalayer.DatabaseType;
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.List;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Prepares a {@code SELECT} SQL query for a given {@link TapSchemaEntity} and a
- * given {@link TapSchema}.
- *
- * @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
- */
-public abstract class SelectQueryBuilder {
-//
-//    private static final Logger log = LoggerFactory.getLogger(SelectQueryBuilder.class);
-//
-//    private final TapSchema tapSchema;
-//    private final String query;
-//    private final List<EntityPropertyInfo> addedProperties;
-//
-//    protected SelectQueryBuilder(DatabaseType dbType, TapSchema tapSchema, String tapSchemaTableName) {
-//
-//        this.tapSchema = tapSchema;
-//
-//        StringBuilder querySb = new StringBuilder("SELECT ");
-//
-//        addedProperties = new ArrayList<>();
-//
-//        boolean first = true;
-//        for (EntityPropertyInfo propertyInfo : EntityPropertyInfo.getEntityPropertiesInfo(tapSchemaTableName)) {
-//            if (propertyInfo.acceptVersion(tapSchema.getVersion())) {
-//                if (!first) {
-//                    querySb.append(", ");
-//                }
-//                querySb.append(propertyInfo.getPropertyKey());
-//                addedProperties.add(propertyInfo);
-//                first = false;
-//            }
-//        }
-//
-//        querySb.append(" FROM ");
-//
-//        querySb.append(TSMUtil.escapeName(tapSchema.getName(), dbType));
-//        querySb.append(".");
-//        querySb.append(TSMUtil.escapeName(tapSchemaTableName, dbType));
-//
-//        query = querySb.toString();
-//    }
-//
-//    protected abstract TapSchemaEntity getEntity(ResultSet rs) throws SQLException;
-//
-//    protected void executeQuery(Connection connection) throws SQLException {
-//
-//        log.debug("Executing query {}", query);
-//
-//        try (Statement statement = connection.createStatement();
-//                ResultSet rs = statement.executeQuery(query)) {
-//
-//            while (rs.next()) {
-//
-//                TapSchemaEntity entity = getEntity(rs);
-//
-//                if (entity != null) {
-//                    for (EntityPropertyInfo property : addedProperties) {
-//                        String key = property.getPropertyKey();
-//                        Class type = property.getPropertyType();
-//                        Object value = TSMUtil.getObject(rs, key, type);
-//                        if (property.isUpdatable()) {
-//                            entity.initProperty(key, value);
-//                        } else {
-//                            Object correctValue = entity.getValue(key, type);
-//                            boolean changed = (correctValue == null && value != null) || (correctValue != null && !correctValue.equals(value));
-//                            if (changed) {
-//
-//                                entity.amendProperty(key, correctValue);
-//
-//                                InconsistentValue inconsistentValue = new InconsistentValue(
-//                                        TSMUtil.getNaturalLangueName(entity),
-//                                        TSMUtil.getName(entity),
-//                                        key,
-//                                        value,
-//                                        correctValue
-//                                );
-//
-//                                tapSchema.getConsistencyChecks().addInconsistency(inconsistentValue);
-//
-//                                //throw new InconsistentTapSchemaException(debugInfo);
-//                            }
-//                        }
-//                    }
-//                }
-//            }
-//        }
-//    }
-//
-//    public String getQuery() {
-//        return query;
-//    }
-}
diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TSMUtil.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TSMUtil.java
index 418914b57c3e8d93a3f7603c1f89a5ba908ebb3f..f0639af4d5ea161f0929455f38a59871ca7c1e19 100644
--- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TSMUtil.java
+++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TSMUtil.java
@@ -145,7 +145,7 @@ public class TSMUtil {
      * </li>
      * </ul>
      */
-    protected static <T> T getObject(ResultSet rs, String key, Class<T> type) throws SQLException {
+    public static <T> T getObject(ResultSet rs, String key, Class<T> type) throws SQLException {
         T ret;
         if (type == String.class) {
             ret = (T) rs.getString(key);
@@ -168,7 +168,7 @@ public class TSMUtil {
     /**
      * Same as {@link DLUtil.getObject(ResultSet, String, Class<T>)}.
      */
-    protected static <T> T getObject(ResultSet rs, int i, Class<T> type) throws SQLException {
+    public static <T> T getObject(ResultSet rs, int i, Class<T> type) throws SQLException {
         T ret;
         if (type == String.class) {
             ret = (T) rs.getString(i);
diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Table.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Table.java
index 64461019ce77ef89e3b2b1ed85af22af9f2be2e7..83f24761313c1fee582211a371b5976226a8a703 100644
--- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Table.java
+++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/Table.java
@@ -206,10 +206,7 @@ public class Table extends ChildEntity<Schema> implements EntitiesContainer<Colu
             return false;
         }
         final Table other = (Table) obj;
-        if (!Objects.equals(this.getCompleteName(), other.getCompleteName())) {
-            return false;
-        }
-        return true;
+        return Objects.equals(this.getCompleteName(), other.getCompleteName());
     }
 
     protected void afterUpdate() {
diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TapSchema.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TapSchema.java
index e1c285ce1563b4e143230fb0c09e7f1deb7ae449..d8752dbc883ca9ba22f932fe36d03ace86ae1b32 100644
--- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TapSchema.java
+++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TapSchema.java
@@ -29,6 +29,7 @@ import it.inaf.ia2.tsm.model.PropertyModel;
 import it.inaf.ia2.tsm.model.TableModel;
 import it.inaf.ia2.tsm.model.TapSchemaModel;
 import it.inaf.ia2.tsm.model.TapSchemaModels;
+import it.inaf.ia2.tsm.model.Tasman;
 import java.io.Serializable;
 import java.sql.SQLException;
 import java.util.ArrayList;
@@ -36,6 +37,7 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.TreeMap;
 import java.util.regex.Pattern;
@@ -55,7 +57,9 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
     public static final String COLUMNS_TABLE = "columns";
     public static final String KEYS_TABLE = "keys";
     public static final String KEY_COLUMNS_TABLE = "key_columns";
+
     public static final String DESCRIPTION_KEY = "description";
+    public static final String STD_KEY = "std";
 
     private static final long serialVersionUID = 1678083091602571256L;
 
@@ -118,6 +122,30 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
         checkKeys();
     }
 
+    private void loadSavedProperties(TapSchemaEntity tapSchemaEntity, Map<String, Object> savedProperties) {
+        for (Map.Entry<String, Object> entry : savedProperties.entrySet()) {
+            String key = entry.getKey();
+            Object savedValue = entry.getValue();
+            Object currentValue = entry.getValue();
+            EntityProperty ep = tapSchemaEntity.getProperty(key);
+
+            if (!ep.isUpdatable() && !Objects.equals(savedValue, currentValue)) {
+
+                InconsistentValue inconsistentValue = new InconsistentValue(
+                        TSMUtil.getNaturalLangueName(tapSchemaEntity),
+                        TSMUtil.getName(tapSchemaEntity),
+                        key,
+                        savedValue,
+                        savedValue
+                );
+
+                consistencyChecks.addInconsistency(inconsistentValue);
+            }
+
+            tapSchemaEntity.initProperty(key, savedValue);
+        }
+    }
+
     /**
      * Loads saved TAP_SCHEMA data and performs consistency checking.
      *
@@ -133,7 +161,7 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
             if (schema == null) {
                 consistencyChecks.addUnexistingSchema(schemaName);
             } else {
-                schema.init(schemaProps);
+                loadSavedProperties(schema, schemaProps);
                 schema.setStatus(Status.ADDED_PERSISTED);
             }
         }
@@ -152,7 +180,7 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
                 if (table == null) {
                     consistencyChecks.addUnexistingTable(schemaName, tableName);
                 } else {
-                    table.init(tableProps);
+                    loadSavedProperties(table, tableProps);
                     table.setStatus(Status.ADDED_PERSISTED);
                 }
             }
@@ -177,7 +205,7 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
                     if (column == null) {
                         consistencyChecks.addUnexistingColumn(tableCompleteName, columnName);
                     } else {
-                        column.init(columnProps);
+                        loadSavedProperties(column, columnProps);
                         column.setStatus(Status.ADDED_PERSISTED);
                     }
                 }
@@ -188,19 +216,26 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
         List<Map<String, Object>> keysProps = broker.getSavedItems(getName(), getTableModel(KEYS_TABLE));
         List<Map<String, Object>> keysColumnsProps = broker.getSavedItems(getName(), getTableModel(KEY_COLUMNS_TABLE));
         for (Map<String, Object> keyProp : keysProps) {
+
+            String fromTable = (String) keyProp.get(Key.FROM_TABLE_KEY);
+            String targetTable = (String) keyProp.get(Key.TARGET_TABLE_KEY);
+            String keyId = (String) keyProp.get(Key.ID_KEY);
+            assert keyId != null;
+
+            List<Map<String, Object>> kcPropsById = new ArrayList<>();
+            for (Map<String, Object> kcp : keysColumnsProps) {
+                String keyColumnId = (String) kcp.get(KeyColumn.KEY_ID_KEY);
+                assert keyColumnId != null;
+                if (keyColumnId.equals(keyId)) {
+                    kcPropsById.add(kcp);
+                }
+            }
+
             // Searching the key
             boolean keyFound = false;
             for (Key key : allKeys) {
-                String fromTable = (String) keyProp.get(Key.FROM_TABLE_KEY);
-                String targetTable = (String) keyProp.get(Key.TARGET_TABLE_KEY);
                 if (key.getFromTableCompleteName().equals(fromTable) && key.getTargetTableCompleteName().equals(targetTable)) {
                     // Search the key columns having proper key id
-                    List<Map<String, Object>> kcPropsById = new ArrayList<>();
-                    for (Map<String, Object> kcp : keysColumnsProps) {
-                        if (kcp.get(KeyColumn.KEY_ID_KEY).equals(key.getId())) {
-                            kcPropsById.add(kcp);
-                        }
-                    }
 
                     // Verifying the matching
                     List<KeyColumn> matchedKeyColumns = new ArrayList<>();
@@ -219,21 +254,40 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
                     if (kcPropsById.size() == matchedKeyColumns.size()) {
                         keyFound = true;
                         int index = 0;
-                        key.init(keyProp);
+                        loadSavedProperties(key, keyProp);
                         for (Map<String, Object> kcp : kcPropsById) {
                             KeyColumn kc = matchedKeyColumns.get(index);
-                            kc.init(kcp);
+                            loadSavedProperties(kc, kcp);
                             index++;
                         }
                     }
                 }
             }
+
             if (!keyFound) {
-                // TODO
+                boolean setKeyToRemove = true;
+                if (Tasman.ALLOWS_FICTITIOUS_KEYS) {
+                    // TODO
+                }
+                if (setKeyToRemove) {
+                    String[] fromColumns = new String[kcPropsById.size()];
+                    String[] targetColumns = new String[kcPropsById.size()];
+                    int i = 0;
+                    for (Map<String, Object> kcp : kcPropsById) {
+                        fromColumns[i] = (String) kcp.get(KeyColumn.FROM_COLUMN_KEY);
+                        targetColumns[i] = (String) kcp.get(KeyColumn.TARGET_COLUMN_KEY);
+                        i++;
+                    }
+                    consistencyChecks.addUnexistingKey(keyId, fromTable, fromColumns, targetTable, targetColumns);
+                }
             }
         }
     }
 
+    public void addFictitiousKey(String fromTable, String[] fromColumns, String targetTable, String[] targetColumns) {
+        // TODO
+    }
+
     public DBBroker getDBBroker(String schemaName) {
         if (schemaName.equals(tapSchemaName)) {
             return getTapSchemaDBBroker();
@@ -627,14 +681,18 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
      */
     private void fillTapSchemaDescriptions() {
         TapSchemaModel tapSchemaModel = getTapSchemaModel();
+        boolean hasStd = tapSchemaModel.get(TapSchema.COLUMNS_TABLE).get(STD_KEY) != null;
         Schema tapSchema = getChild(tapSchemaName);
         tapSchema.setValue(DESCRIPTION_KEY, tapSchemaModel.getDescription());
         for (TableModel tableModel : getTapSchemaModel().getTables().values()) {
             Table table = tapSchema.getChild(tableModel.getName());
-            table.setValue(DESCRIPTION_KEY, tableModel.getDescription());
+            tapSchema.setValue(DESCRIPTION_KEY, tableModel.getDescription());
             for (PropertyModel propertyModel : tableModel.getProperties().values()) {
                 Column column = table.getChild(propertyModel.getName());
-                column.setValue(DESCRIPTION_KEY, propertyModel.getDescription());
+                tapSchema.setValue(DESCRIPTION_KEY, propertyModel.getDescription());
+                if (hasStd) {
+                    column.setValue(STD_KEY, 1);
+                }
             }
         }
     }
diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TapSchemaEntity.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TapSchemaEntity.java
index a7705dfeeb01e44934e7e8a0cb500bb5384efab4..5cb250fadbdeb54ecbd81419715808151da9e16a 100644
--- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TapSchemaEntity.java
+++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/TapSchemaEntity.java
@@ -68,6 +68,14 @@ public abstract class TapSchemaEntity implements Serializable {
             Object defaultValue = null;
             if (propModel.getLoaderKey() != null) {
                 defaultValue = metadata.get(propModel.getLoaderKey());
+                if (defaultValue != null && propModel.getType() != defaultValue.getClass()) {
+                    // Special case for boolean to integer conversion
+                    if (defaultValue.getClass() == Boolean.class && propModel.getType() == Integer.class) {
+                        defaultValue = ((Boolean) defaultValue) ? 1 : 0;
+                    } else {
+                        throw new UnsupportedOperationException("Unable to convert " + defaultValue.getClass().getCanonicalName() + " into " + propModel.getType());
+                    }
+                }
             }
             EntityProperty ep = new EntityProperty(propModel, defaultValue);
             this.properties.put(propModel.getName(), ep);
@@ -85,15 +93,6 @@ public abstract class TapSchemaEntity implements Serializable {
         properties.get(key).init(value);
     }
 
-    /**
-     * Fill saved properties.
-     */
-    public void init(Map<String, Object> props) {
-        for (Map.Entry<String, Object> entry : props.entrySet()) {
-            initProperty(entry.getKey(), entry.getValue());
-        }
-    }
-
     protected String getVersion() {
         return tapSchema.getVersion();
     }
diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/UpdateQueryBuilder.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/UpdateQueryBuilder.java
deleted file mode 100644
index 4f8bbb60373a8f2e28f82dd9313a9b5c632c04ba..0000000000000000000000000000000000000000
--- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/UpdateQueryBuilder.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/* 
- * _____________________________________________________________________________
- * 
- * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of
- * Trieste INAF - IA2 Italian Center for Astronomical Archives
- * _____________________________________________________________________________
- * 
- * Copyright (C) 2016 Istituto Nazionale di Astrofisica
- * 
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License Version 3 as published by the
- * Free Software Foundation.
- * 
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- * 
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 51
- * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package it.inaf.ia2.tsm;
-
-import it.inaf.ia2.tsm.datalayer.DatabaseType;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Prepares an {@code UPDATE } SQL query for a given {@link TapSchemaEntity} and
- * a given {@link TapSchema}.
- *
- * @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
- */
-public class UpdateQueryBuilder {
-//
-//    private static final Logger log = LoggerFactory.getLogger(UpdateQueryBuilder.class);
-//
-//    private final String query;
-//    private final List<EntityPropertyInfo> addedProperties;
-//    private final TapSchemaEntity tapSchemaEntity;
-//
-//    protected UpdateQueryBuilder(DatabaseType dbType, TapSchema tapSchema, TapSchemaEntity tapSchemaEntity, String tapSchemaTableName, String whereCondition) {
-//
-//        StringBuilder querySb = new StringBuilder("UPDATE ");
-//        querySb.append(TSMUtil.escapeName(tapSchema.getName(), dbType));
-//        querySb.append(".");
-//        querySb.append(TSMUtil.escapeName(tapSchemaTableName, dbType));
-//        querySb.append("\nSET");
-//
-//        addedProperties = new ArrayList<>();
-//        this.tapSchemaEntity = tapSchemaEntity;
-//
-//        boolean first = true;
-//        for (EntityPropertyInfo propertyInfo : EntityPropertyInfo.getEntityPropertiesInfo(tapSchemaTableName)) {
-//            if (propertyInfo.acceptVersion(tapSchema.getVersion())
-//                    && tapSchemaEntity.isChanged(propertyInfo.getPropertyKey())) {
-//
-//                if (!first) {
-//                    querySb.append(",");
-//                }
-//                querySb.append(" ");
-//                querySb.append(propertyInfo.getPropertyKey());
-//                querySb.append(" = ?");
-//                addedProperties.add(propertyInfo);
-//                first = false;
-//            }
-//        }
-//
-//        querySb.append("\nWHERE ");
-//        querySb.append(whereCondition);
-//
-//        query = querySb.toString();
-//    }
-//
-//    public String getQuery() {
-//        return query;
-//    }
-//
-//    protected int addStatementValues(PreparedStatement statement) throws SQLException {
-//        int i = 1;
-//        for (EntityPropertyInfo property : addedProperties) {
-//            Object value = tapSchemaEntity.getValue(property.getPropertyKey(), property.getPropertyType());
-//            statement.setObject(i, value, property.getSqlType());
-//            log.debug("\t[{}] {}", property.getPropertyKey(), value);
-//            i++;
-//        }
-//        return i;
-//    }
-}
diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBroker.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBroker.java
index d1870434c140f38f3549ef73cfdd92e13a06da0e..768fcaff1e6be4da7ab709ae1d9c1b05e8039c5e 100644
--- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBroker.java
+++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBroker.java
@@ -38,12 +38,12 @@ import java.util.Map;
  */
 public interface DBBroker {
 
-    Map<String, Map<String, Object>> getColumnsInfo(String schemaName, String tableName) throws SQLException;
-
     List<String> getAllSchemaNames() throws SQLException;
 
     List<String> getAllTAPSchemaNames(List<String> allSchemas) throws SQLException;
     
+    String detectVersion(String tapSchemaName) throws SQLException;
+    
     List<String> getExposedSchemas(String tapSchemaName) throws SQLException;
 
     List<String> getAllTablesNames(String schemaName) throws SQLException;
diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBrokerFactory.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBrokerFactory.java
index 7213c5632bc38be70cf680c92a1a3514bfd1805e..27a947007edc64577ce3488762628566e168d4a5 100644
--- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBrokerFactory.java
+++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBrokerFactory.java
@@ -23,6 +23,7 @@
 package it.inaf.ia2.tsm.datalayer;
 
 import it.inaf.ia2.tsm.datalayer.mysql.MySQLDBBroker;
+import it.inaf.ia2.tsm.datalayer.pgsql.PostgresDBBroker;
 
 /**
  *
@@ -35,7 +36,8 @@ public class DBBrokerFactory {
             case MYSQL:
                 return new MySQLDBBroker(dataSourceWrapper.getDataSource());
             default:
-                throw new UnsupportedOperationException(dataSourceWrapper.getDatabaseType() + " not supported yet");
+                String pgDatabase = dataSourceWrapper.getCredentials().getDatabase();
+                return new PostgresDBBroker(dataSourceWrapper.getDataSource(), pgDatabase);
         }
     }
 }
diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBrokerTemplate.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBrokerTemplate.java
index 5e42f12292c95bb53fe80a7fdd75b3aa459b31bf..685b04e05f546b5ad64f42041481ff9eac42a005 100644
--- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBrokerTemplate.java
+++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/DBBrokerTemplate.java
@@ -35,6 +35,7 @@ import it.inaf.ia2.tsm.UpdateOperations;
 import it.inaf.ia2.tsm.model.PropertyModel;
 import it.inaf.ia2.tsm.model.TableModel;
 import it.inaf.ia2.tsm.model.TapSchemaModel;
+import it.inaf.ia2.tsm.model.TapSchemaModels;
 import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
@@ -44,6 +45,7 @@ import java.sql.Types;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import javax.sql.DataSource;
@@ -106,50 +108,57 @@ public abstract class DBBrokerTemplate implements DBBroker {
 
     protected abstract void createTable(String tapSchemaName, TableModel tableModel, Connection conn) throws SQLException;
 
-    protected abstract void addPrimaryKey(String tapSchemaName, String tableName, String[] keyColumns, Connection conn) throws SQLException;
+    protected abstract String getAddPrimaryKeyQuery(String tapSchemaName, String tableName, String[] keyColumns);
 
-    protected abstract void addForeignKey(String tapSchemaName, String tableName, String[] fromKeyColumns, String targetTableName, String[] toKeyColumns, Connection conn) throws SQLException;
+    protected abstract String getAddForeignKeyQuery(String tapSchemaName, String tableName, String[] fromKeyColumns, String targetTableName, String[] toKeyColumns);
 
-    private void addPrimaryKey(String tapSchemaName, String tableName, String keyColumn, Connection conn) throws SQLException {
-        addPrimaryKey(tapSchemaName, tableName, new String[]{keyColumn}, conn);
+    private String getAddPrimaryKeyQuery(String tapSchemaName, String tableName, String keyColumn) {
+        return getAddPrimaryKeyQuery(tapSchemaName, tableName, new String[]{keyColumn});
     }
 
-    private void addForeignKey(String tapSchemaName, String tableName, String fromKeyColumn, String targetTableName, String toKeyColumn, Connection conn) throws SQLException {
-        addForeignKey(tapSchemaName, tableName, new String[]{fromKeyColumn}, targetTableName, new String[]{toKeyColumn}, conn);
+    private String getAddForeignKeyQuery(String tapSchemaName, String tableName, String fromKeyColumn, String targetTableName, String toKeyColumn) {
+        return getAddForeignKeyQuery(tapSchemaName, tableName, new String[]{fromKeyColumn}, targetTableName, new String[]{toKeyColumn});
     }
 
-    protected abstract void createDatabase(String databaseName, Connection conn) throws SQLException;
+    protected abstract String getCreateDatabaseQuery(String databaseName);
+
+    private void execute(String query, Connection conn) throws SQLException {
+        try (Statement stat = conn.createStatement()) {
+            LOG.debug("Executing query: {}", query);
+            stat.execute(query);
+        }
+    }
 
     @Override
     public void createTapSchemaStructure(String tapSchemaName, TapSchemaModel tapSchemaModel) throws SQLException {
 
         try (Connection conn = dataSource.getConnection()) {
 
-            createDatabase(tapSchemaName, conn);
+            execute(getCreateDatabaseQuery(tapSchemaName), conn);
 
             for (TableModel tableModel : tapSchemaModel.getTables().values()) {
                 createTable(tapSchemaName, tableModel, conn);
             }
 
             // schemas keys
-            addPrimaryKey(tapSchemaName, TapSchema.SCHEMAS_TABLE, Schema.SCHEMA_NAME_KEY, conn);
+            execute(getAddPrimaryKeyQuery(tapSchemaName, TapSchema.SCHEMAS_TABLE, Schema.SCHEMA_NAME_KEY), conn);
 
             // tables keys
-            addPrimaryKey(tapSchemaName, TapSchema.TABLES_TABLE, Table.TABLE_NAME_KEY, conn);
-            addForeignKey(tapSchemaName, TapSchema.TABLES_TABLE, Table.SCHEMA_NAME_KEY, TapSchema.SCHEMAS_TABLE, Schema.SCHEMA_NAME_KEY, conn);
+            execute(getAddPrimaryKeyQuery(tapSchemaName, TapSchema.TABLES_TABLE, Table.TABLE_NAME_KEY), conn);
+            execute(getAddForeignKeyQuery(tapSchemaName, TapSchema.TABLES_TABLE, Table.SCHEMA_NAME_KEY, TapSchema.SCHEMAS_TABLE, Schema.SCHEMA_NAME_KEY), conn);
 
             // columns keys
-            addPrimaryKey(tapSchemaName, TapSchema.COLUMNS_TABLE, new String[]{Column.TABLE_NAME_KEY, Column.COLUMN_NAME_KEY}, conn);
-            addForeignKey(tapSchemaName, TapSchema.COLUMNS_TABLE, Column.TABLE_NAME_KEY, TapSchema.TABLES_TABLE, Table.TABLE_NAME_KEY, conn);
+            execute(getAddPrimaryKeyQuery(tapSchemaName, TapSchema.COLUMNS_TABLE, new String[]{Column.TABLE_NAME_KEY, Column.COLUMN_NAME_KEY}), conn);
+            execute(getAddForeignKeyQuery(tapSchemaName, TapSchema.COLUMNS_TABLE, Column.TABLE_NAME_KEY, TapSchema.TABLES_TABLE, Table.TABLE_NAME_KEY), conn);
 
             // keys keys
-            addPrimaryKey(tapSchemaName, TapSchema.KEYS_TABLE, Key.ID_KEY, conn);
-            addForeignKey(tapSchemaName, TapSchema.KEYS_TABLE, Key.FROM_TABLE_KEY, TapSchema.TABLES_TABLE, Table.TABLE_NAME_KEY, conn);
-            addForeignKey(tapSchemaName, TapSchema.KEYS_TABLE, Key.TARGET_TABLE_KEY, TapSchema.TABLES_TABLE, Table.TABLE_NAME_KEY, conn);
+            execute(getAddPrimaryKeyQuery(tapSchemaName, TapSchema.KEYS_TABLE, Key.ID_KEY), conn);
+            execute(getAddForeignKeyQuery(tapSchemaName, TapSchema.KEYS_TABLE, Key.FROM_TABLE_KEY, TapSchema.TABLES_TABLE, Table.TABLE_NAME_KEY), conn);
+            execute(getAddForeignKeyQuery(tapSchemaName, TapSchema.KEYS_TABLE, Key.TARGET_TABLE_KEY, TapSchema.TABLES_TABLE, Table.TABLE_NAME_KEY), conn);
 
             // key columns key
             //addPrimaryKey(tapSchemaName, TapSchema.KEY_COLUMNS_TABLE, new String[]{KeyColumn.KEY_ID_KEY, KeyColumn.FROM_COLUMN_KEY, KeyColumn.TARGET_COLUMN_KEY}, conn);
-            addForeignKey(tapSchemaName, TapSchema.KEY_COLUMNS_TABLE, Key.ID_KEY, TapSchema.KEYS_TABLE, Key.ID_KEY, conn);
+            execute(getAddForeignKeyQuery(tapSchemaName, TapSchema.KEY_COLUMNS_TABLE, Key.ID_KEY, TapSchema.KEYS_TABLE, Key.ID_KEY), conn);
             //addForeignKey(tapSchemaName, TapSchema.KEY_COLUMNS_TABLE, KeyColumn.FROM_COLUMN_KEY, TapSchema.COLUMNS_TABLE, Column.COLUMN_NAME_KEY, conn);
             //addForeignKey(tapSchemaName, TapSchema.KEY_COLUMNS_TABLE, KeyColumn.TARGET_COLUMN_KEY, TapSchema.COLUMNS_TABLE, Column.COLUMN_NAME_KEY, conn);
         }
@@ -407,7 +416,7 @@ public abstract class DBBrokerTemplate implements DBBroker {
                     Map<String, Object> item = new HashMap<>();
 
                     for (PropertyModel pm : tableModel.getProperties().values()) {
-                        Object value = rs.getObject(pm.getName(), pm.getType());
+                        Object value = TSMUtil.getObject(rs, pm.getName(), pm.getType());
                         item.put(pm.getName(), value);
                     }
 
@@ -608,6 +617,68 @@ public abstract class DBBrokerTemplate implements DBBroker {
         return allTAPSchemas;
     }
 
+    protected abstract String getColumnNamesQuery(String tapSchemaName, String tableName);
+
+    private List<String> getColumns(String tapSchemaName, String tableName, Connection connection) throws SQLException {
+
+        List<String> columns = new ArrayList<>();
+
+        String query = getColumnNamesQuery(tapSchemaName, tableName);
+        LOG.debug("Executing query {}", query);
+
+        try (Statement statement = connection.createStatement();
+                ResultSet resultSet = statement.executeQuery(query)) {
+            while (resultSet.next()) {
+                String columnName = resultSet.getString(1);
+                columns.add(columnName);
+            }
+        }
+
+        return columns;
+    }
+
+    private boolean match(TableModel tableModel, List<String> columns) {
+        if (tableModel.getProperties().size() != columns.size()) {
+            return false;
+        }
+        for (PropertyModel propertyModel : tableModel.getProperties().values()) {
+            String columnName = propertyModel.getName();
+            if (!columns.contains(columnName)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public String detectVersion(String tapSchemaName) throws SQLException {
+
+        List<String> schemasColumns, tablesColumns, columnsColumns, keyColumns, keyColumnsColumns;
+
+        try (Connection connection = dataSource.getConnection()) {
+            schemasColumns = getColumns(tapSchemaName, TapSchema.SCHEMAS_TABLE, connection);
+            tablesColumns = getColumns(tapSchemaName, TapSchema.TABLES_TABLE, connection);
+            columnsColumns = getColumns(tapSchemaName, TapSchema.COLUMNS_TABLE, connection);
+            keyColumns = getColumns(tapSchemaName, TapSchema.KEYS_TABLE, connection);
+            keyColumnsColumns = getColumns(tapSchemaName, TapSchema.KEY_COLUMNS_TABLE, connection);
+        }
+
+        Iterator<TapSchemaModel> ite = TapSchemaModels.getIterator();
+        while (ite.hasNext()) {
+            TapSchemaModel tapSchemaModel = ite.next();
+
+            if (match(tapSchemaModel.get(TapSchema.SCHEMAS_TABLE), schemasColumns)
+                    && match(tapSchemaModel.get(TapSchema.TABLES_TABLE), tablesColumns)
+                    && match(tapSchemaModel.get(TapSchema.COLUMNS_TABLE), columnsColumns)
+                    && match(tapSchemaModel.get(TapSchema.KEYS_TABLE), keyColumns)
+                    && match(tapSchemaModel.get(TapSchema.KEY_COLUMNS_TABLE), keyColumnsColumns)) {
+                return tapSchemaModel.getVersion();
+            }
+        }
+
+        throw new RuntimeException("Unable to detect TAP_SCHEMA version for " + tapSchemaName);
+    }
+
     protected abstract String getTableTypesQuery(String schemaName);
 
     @Override
@@ -632,6 +703,7 @@ public abstract class DBBrokerTemplate implements DBBroker {
         return tablesTypes;
     }
 
+    @Override
     public List<String> getExposedSchemas(String tapSchemaName) throws SQLException {
 
         final List<String> exposedSchemas = new ArrayList<>();
@@ -650,4 +722,34 @@ public abstract class DBBrokerTemplate implements DBBroker {
 
         return exposedSchemas;
     }
+
+    protected abstract String getAllSchemaNamesQuery();
+
+    @Override
+    public List<String> getAllSchemaNames() throws SQLException {
+        String query = getAllSchemaNamesQuery();
+        LOG.debug("Executing query: {}", query);
+        List<String> allSchemas = getAllItemsNames(query);
+        LOG.debug("{} schemas found", allSchemas.size());
+        return allSchemas;
+    }
+
+    protected abstract String getAllTablesNamesQuery(String schemaName);
+
+    @Override
+    public List<String> getAllTablesNames(String schemaName) throws SQLException {
+        String query = getAllTablesNamesQuery(schemaName);
+        LOG.debug("Executing query: {}", query);
+        List<String> allTables = getAllItemsNames(query);
+        LOG.debug("{} tables found", allTables.size());
+        return allTables;
+    }
+
+    @Override
+    public List<String> getAllColumnsNames(String schemaName, String tableName) throws SQLException {
+        String query = getColumnNamesQuery(schemaName, tableName);
+        List<String> allColumns = getAllItemsNames(query);
+        LOG.debug("{} columns found", allColumns.size());
+        return allColumns;
+    }
 }
diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/mysql/MySQLDBBroker.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/mysql/MySQLDBBroker.java
index 9998aba85e14e10d372efe3408753a6b6adad830..4acabe5937d7a3065f19fbde14f921f1f3fa7bf2 100644
--- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/mysql/MySQLDBBroker.java
+++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/mysql/MySQLDBBroker.java
@@ -54,30 +54,18 @@ public class MySQLDBBroker extends DBBrokerTemplate {
     }
 
     @Override
-    public Map<String, Map<String, Object>> getColumnsInfo(String schemaName, String tableName) {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    protected String getAllSchemaNamesQuery() {
+        return "SHOW DATABASES";
     }
 
     @Override
-    public List<String> getAllSchemaNames() throws SQLException {
-        List<String> allSchemas = super.getAllItemsNames("SHOW DATABASES");
-        LOG.debug("{} schemas found", allSchemas.size());
-        return allSchemas;
-    }
-
-    @Override
-    public List<String> getAllTablesNames(String schemaName) throws SQLException {
-        List<String> allTables = super.getAllItemsNames("SHOW TABLES FROM " + escape(schemaName));
-        LOG.debug("{} tables found", allTables.size());
-        return allTables;
+    protected String getAllTablesNamesQuery(String schemaName) {
+        return "SHOW TABLES FROM " + escape(schemaName);
     }
 
     @Override
-    public List<String> getAllColumnsNames(String schemaName, String tableName) throws SQLException {
-        String query = String.format("SHOW COLUMNS FROM %s.%s", escape(schemaName), escape(tableName));
-        List<String> allColumns = super.getAllItemsNames(query);
-        LOG.debug("{} columns found", allColumns.size());
-        return allColumns;
+    protected String getColumnNamesQuery(String schemaName, String tableName) {
+        return String.format("SHOW COLUMNS FROM %s.%s", escape(schemaName), escape(tableName));
     }
 
     @Override
@@ -203,22 +191,14 @@ public class MySQLDBBroker extends DBBrokerTemplate {
     }
 
     @Override
-    protected void addPrimaryKey(String tapSchemaName, String tableName, String[] keyColumns, Connection conn) throws SQLException {
-        String query = String.format("ALTER TABLE %s.%s ADD PRIMARY KEY(%s)", escape(tapSchemaName), escape(tableName), buildColumnsList(keyColumns));
-        try (Statement stat = conn.createStatement()) {
-            LOG.debug("Executing query: {}", query);
-            stat.executeUpdate(query);
-        }
+    protected String getAddPrimaryKeyQuery(String tapSchemaName, String tableName, String[] keyColumns) {
+        return String.format("ALTER TABLE %s.%s ADD PRIMARY KEY(%s)", escape(tapSchemaName), escape(tableName), buildColumnsList(keyColumns));
     }
 
     @Override
-    protected void addForeignKey(String tapSchemaName, String tableName, String[] fromKeyColumns, String targetTableName, String[] toKeyColumns, Connection conn) throws SQLException {
-        String query = String.format("ALTER TABLE %s.%s ADD FOREIGN KEY (%s) REFERENCES %s.%s(%s)", escape(tapSchemaName), escape(tableName),
+    protected String getAddForeignKeyQuery(String tapSchemaName, String tableName, String[] fromKeyColumns, String targetTableName, String[] toKeyColumns) {
+        return String.format("ALTER TABLE %s.%s ADD FOREIGN KEY (%s) REFERENCES %s.%s(%s)", escape(tapSchemaName), escape(tableName),
                 buildColumnsList(fromKeyColumns), escape(tapSchemaName), escape(targetTableName), buildColumnsList(toKeyColumns));
-        try (Statement stat = conn.createStatement()) {
-            LOG.debug("Executing query: {}", query);
-            stat.executeUpdate(query);
-        }
     }
 
     @Override
@@ -292,12 +272,8 @@ public class MySQLDBBroker extends DBBrokerTemplate {
     }
 
     @Override
-    protected void createDatabase(String databaseName, Connection conn) throws SQLException {
-        String queryString = "CREATE DATABASE IF NOT EXISTS " + escape(databaseName);
-        LOG.debug("Executing query: {}", queryString);
-        try (Statement stat = conn.createStatement()) {
-            stat.execute(queryString);
-        }
+    protected String getCreateDatabaseQuery(String databaseName) {
+        return "CREATE DATABASE IF NOT EXISTS " + escape(databaseName);
     }
 
     @Override
diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/pgsql/PostgresDBBroker.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/pgsql/PostgresDBBroker.java
index b27016a043611eada712230b00a385fd6b33aa57..c114cd4e8caab84b57130b6152c7169b3610e7cb 100644
--- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/pgsql/PostgresDBBroker.java
+++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/datalayer/pgsql/PostgresDBBroker.java
@@ -22,15 +22,25 @@
  */
 package it.inaf.ia2.tsm.datalayer.pgsql;
 
+import it.inaf.ia2.tsm.Column;
 import it.inaf.ia2.tsm.Key;
 import it.inaf.ia2.tsm.TapSchema;
+import it.inaf.ia2.tsm.datalayer.ADQL;
 import it.inaf.ia2.tsm.datalayer.DBBrokerTemplate;
+import it.inaf.ia2.tsm.model.PropertyModel;
 import it.inaf.ia2.tsm.model.TableModel;
 import java.sql.Connection;
+import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.regex.Pattern;
 import javax.sql.DataSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  *
@@ -38,68 +48,283 @@ import javax.sql.DataSource;
  */
 public class PostgresDBBroker extends DBBrokerTemplate {
 
-    public PostgresDBBroker(DataSource dataSource) {
-        super(dataSource, '\'');
+    private final static Logger LOG = LoggerFactory.getLogger(PostgresDBBroker.class);
+
+    private final String pgDatabaseName;
+
+    public PostgresDBBroker(DataSource dataSource, String pgDatabaseName) {
+        super(dataSource, '"');
+        this.pgDatabaseName = pgDatabaseName;
     }
 
     @Override
     protected void createTable(String tapSchemaName, TableModel tableModel, Connection conn) throws SQLException {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
+        StringBuilder querySb = new StringBuilder();
 
-    @Override
-    protected void addPrimaryKey(String tapSchemaName, String tableName, String[] keyColumns, Connection conn) throws SQLException {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
+        querySb.append("CREATE TABLE IF NOT EXISTS ");
+        querySb.append(escape(tapSchemaName));
+        querySb.append(".");
+        querySb.append(escape(tableModel.getName()));
+        querySb.append(" (\n");
 
-    @Override
-    protected void addForeignKey(String tapSchemaName, String tableName, String[] fromKeyColumns, String targetTableName, String[] toKeyColumns, Connection conn) throws SQLException {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
+        boolean first = true;
+        for (PropertyModel pm : tableModel.getProperties().values()) {
+            if (!first) {
+                querySb.append(",\n");
+            }
+            first = false;
 
-    @Override
-    protected void createDatabase(String databaseName, Connection conn) throws SQLException {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
+            querySb.append(pm.getName());
+            querySb.append(" ");
 
-    @Override
-    protected String getSchemaTablesQuery(String schemaName) {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
-    }
+            Class type = pm.getType();
+            if (type == String.class) {
+                querySb.append("character varying(");
+                querySb.append(pm.getSize());
+                querySb.append(")");
+            } else if (type == Integer.class) {
+                querySb.append("integer");
+            } else if (type == Boolean.class) {
+                querySb.append("boolean");
+            } else if (type == Long.class) {
+                querySb.append("bigint");
+            } else {
+                throw new UnsupportedOperationException("Column type " + type.getCanonicalName() + " not supported yet!");
+            }
 
-    @Override
-    public Map<String, Map<String, Object>> getColumnsInfo(String schemaName, String tableName) throws SQLException {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+            if (pm.isNullable()) {
+                querySb.append(" NULL");
+            } else {
+                querySb.append(" NOT NULL");
+            }
+        }
+
+        querySb.append(")");
+
+        String query = querySb.toString();
+
+        try (Statement stat = conn.createStatement()) {
+            LOG.debug("Executing query: {}", query);
+            stat.executeUpdate(query);
+        }
     }
 
     @Override
-    public List<String> getAllSchemaNames() throws SQLException {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    protected String getAddPrimaryKeyQuery(String tapSchemaName, String tableName, String[] keyColumns) {
+        return String.format("ALTER TABLE ONLY %s.%s ADD CONSTRAINT %s_pkey PRIMARY KEY (%s)",
+                escape(tapSchemaName), escape(tableName), tableName, buildColumnsList(keyColumns));
     }
 
     @Override
-    public List<String> getAllTablesNames(String schemaName) throws SQLException {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    protected String getAddForeignKeyQuery(String tapSchemaName, String tableName, String[] fromKeyColumns, String targetTableName, String[] toKeyColumns) {
+        // Building univocal constraint name
+        StringBuilder constraintNameSb = new StringBuilder(tableName);
+        for (String fromKeyColumn : fromKeyColumns) {
+            constraintNameSb.append("_");
+            constraintNameSb.append(fromKeyColumn);
+        }
+        return String.format("ALTER TABLE ONLY %s.%s ADD CONSTRAINT fk_%s FOREIGN KEY (%s) REFERENCES %s.%s(%s)",
+                escape(tapSchemaName), escape(tableName), constraintNameSb.toString(), buildColumnsList(fromKeyColumns),
+                escape(tapSchemaName), escape(targetTableName), buildColumnsList(toKeyColumns));
     }
 
     @Override
-    public Map<String, String> getAllTableTypes(String schemaName) throws SQLException {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    protected String getCreateDatabaseQuery(String databaseName) {
+        return "CREATE SCHEMA IF NOT EXISTS " + escape(databaseName);
     }
 
     @Override
-    public List<String> getAllColumnsNames(String schemaName, String tableName) throws SQLException {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+    protected String getSchemaTablesQuery(String schemaName) {
+        return String.format("SELECT tablename FROM pg_catalog.pg_tables where schemaname = '%s'", schemaName);
     }
 
     @Override
     public Map<String, Map<String, Object>> getAllColumnsMetadata(String schemaName, String tableSimpleName) throws SQLException {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+
+        Map<String, Map<String, Object>> allColumnsMetadata = new HashMap<>();
+
+        StringBuilder querySb = new StringBuilder();
+
+        querySb.append("SELECT c.column_name, c.data_type, r.contype AS column_type, c.character_maximum_length, c.numeric_precision\n"); //, c.numeric_precision_radix
+        querySb.append("FROM information_schema.columns c\n");
+        querySb.append("JOIN pg_catalog.pg_tables t ON c.table_schema = t.schemaname AND c.table_name = t.tablename\n");
+        querySb.append("LEFT JOIN pg_catalog.pg_constraint r ON c.ordinal_position = ANY(r.conkey) AND r.conrelid = (t.schemaname || '.' || t.tablename)::regclass::oid\n");
+        querySb.append("WHERE t.schemaname = '");
+        querySb.append(schemaName);
+        querySb.append("' AND t.tablename = '");
+        querySb.append(tableSimpleName);
+        querySb.append("'");
+
+        String query = querySb.toString();
+        LOG.debug("Executing query {}", query);
+
+        try (Connection conn = dataSource.getConnection();
+                Statement statement = conn.createStatement();
+                ResultSet resultSet = statement.executeQuery(query)) {
+
+            while (resultSet.next()) {
+
+                Map<String, Object> cm = new HashMap<>();
+
+                // Column name
+                String columnName = resultSet.getString("column_name");
+                cm.put(Column.COLUMN_NAME_KEY, columnName);
+
+                // Key info
+                String columnType = resultSet.getString("column_type");
+                boolean primaryKey = false;
+                boolean indexed = false;
+                if (columnType != null) {
+                    primaryKey = "p".equals(columnType);
+                    if ("p".equals(columnType)
+                            || "f".equals(columnType)
+                            || "u".equals(columnType)) {
+                        indexed = true;
+                    }
+                }
+                cm.put(Column.PRIMARY_KEY, primaryKey);
+                cm.put(Column.INDEXED_KEY, indexed);
+
+                int size = 0;
+                String datatype;
+
+                String type = resultSet.getString("data_type");
+
+                if (type.startsWith("int")) {
+                    datatype = ADQL.INTEGER;
+                } else if (type.startsWith("smallint")) {
+                    datatype = ADQL.SMALLINT;
+                } else if (type.startsWith("bigint")) {
+                    datatype = ADQL.BIGINT;
+                } else if (type.startsWith("double") || type.startsWith("real")) {
+                    datatype = ADQL.REAL;
+                } else if (type.startsWith("character varying")) {
+                    datatype = ADQL.VARCHAR;
+                    size = resultSet.getInt("character_maximum_length");
+                } else if (type.startsWith("char")) {
+                    datatype = ADQL.CHAR;
+                    size = resultSet.getInt("character_maximum_length");
+                } else if (type.contains("timestamp")) {
+                    datatype = ADQL.TIMESTAMP;
+                } else {
+                    datatype = ADQL.getDataType(type);
+                }
+
+                cm.put(Column.DATATYPE_KEY, datatype);
+                cm.put(Column.SIZE_KEY, size);
+
+                Integer arraySize = null; // TODO (v 1.1)
+
+                allColumnsMetadata.put(columnName, cm);
+            }
+        }
+
+        return allColumnsMetadata;
     }
 
     @Override
     public List<Key> getKeys(TapSchema tapSchema, String schemaName) throws SQLException {
-        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+
+        StringBuilder queryKeysSb = new StringBuilder();
+
+        queryKeysSb.append("SELECT\n");
+        queryKeysSb.append("conname AS constraint_name,\n");
+        queryKeysSb.append("conrelid::regclass AS from_table, \n");
+        queryKeysSb.append("confrelid::regclass AS target_table\n");
+        queryKeysSb.append("FROM pg_catalog.pg_constraint\n");
+        queryKeysSb.append("WHERE contype = 'f'\n");
+        queryKeysSb.append("AND ((conrelid::regclass || '' LIKE '");
+        queryKeysSb.append(schemaName);
+        queryKeysSb.append(".%')\n");
+        queryKeysSb.append("OR (confrelid::regclass || '' LIKE '");
+        queryKeysSb.append(schemaName);
+        queryKeysSb.append(".%'))");
+
+        String queryKeys = queryKeysSb.toString();
+
+        try (Connection connection = dataSource.getConnection();
+                Statement statement = connection.createStatement();
+                ResultSet resultSet = statement.executeQuery(queryKeys)) {
+
+            LOG.debug("Executing query {}", queryKeys);
+
+            List<Key> keys = new ArrayList<>();
+            while (resultSet.next()) {
+
+                String constraintName = resultSet.getString("constraint_name");
+
+                String fromTableCompleteName = resultSet.getString("from_table");
+                String targetTableCompleteName = resultSet.getString("target_table");
+
+                String fromSchema = fromTableCompleteName.split(Pattern.quote("."))[0];
+                String targetSchema = targetTableCompleteName.split(Pattern.quote("."))[0];
+
+                Map<String, Object> keyMetadata = new HashMap<>();
+                keyMetadata.put(Key.FROM_TABLE_KEY, fromTableCompleteName);
+                keyMetadata.put(Key.TARGET_TABLE_KEY, targetTableCompleteName);
+
+                Key key = new Key(tapSchema, keyMetadata);
+                keys.add(key);
+
+                StringBuilder queryFromKCSb = new StringBuilder();
+                queryFromKCSb.append("SELECT\n");
+                queryFromKCSb.append("c.column_name AS key_column\n");
+                queryFromKCSb.append("FROM information_schema.columns c\n");
+                queryFromKCSb.append("JOIN pg_catalog.pg_constraint r ON c.ordinal_position = ANY(r.conkey)\n");
+                queryFromKCSb.append("AND (c.table_schema || '.' || c.table_name) = (r.conrelid::regclass || '')\n");
+                queryFromKCSb.append("WHERE r.conname = '");
+                queryFromKCSb.append(constraintName);
+                queryFromKCSb.append("' AND r.contype = 'f'\n");
+                queryFromKCSb.append("AND c.table_schema = '");
+                queryFromKCSb.append(fromSchema);
+                queryFromKCSb.append("'\nAND table_catalog = '");
+                queryFromKCSb.append(pgDatabaseName);
+                queryFromKCSb.append("'");
+
+                // conkey conrelid
+                String queryFromKC = queryFromKCSb.toString();
+
+                StringBuilder queryTargetKCSb = new StringBuilder();
+                queryTargetKCSb.append("SELECT\n");
+                queryTargetKCSb.append("c.column_name AS key_column\n");
+                queryTargetKCSb.append("FROM information_schema.columns c\n");
+                queryTargetKCSb.append("JOIN pg_catalog.pg_constraint r ON c.ordinal_position = ANY(r.confkey)\n");
+                queryTargetKCSb.append("AND (c.table_schema || '.' || c.table_name) = (r.confrelid::regclass || '')\n");
+                queryTargetKCSb.append("WHERE r.conname = '");
+                queryTargetKCSb.append(constraintName);
+                queryTargetKCSb.append("' AND r.contype = 'f'\n");
+                queryTargetKCSb.append("AND c.table_schema = '");
+                queryTargetKCSb.append(targetSchema);
+                queryTargetKCSb.append("'\nAND table_catalog = '");
+                queryTargetKCSb.append(pgDatabaseName);
+                queryTargetKCSb.append("'");
+
+                // as above, but with confkey and confrelid and different c.table_schema where condition
+                String queryTargetKC = queryTargetKCSb.toString();
+
+                try (Statement statFromKC = connection.createStatement();
+                        Statement statTargetKC = connection.createStatement()) {
+
+                    try (ResultSet rsFromKC = statFromKC.executeQuery(queryFromKC);
+                            ResultSet rsTargetKC = statTargetKC.executeQuery(queryTargetKC)) {
+
+                        LOG.debug("Executing query {}", queryFromKC);
+                        LOG.debug("Executing query {}", queryTargetKC);
+
+                        while (rsFromKC.next()) {
+                            if (rsTargetKC.next()) {
+                                key.addKeyColumn(
+                                        rsFromKC.getString("key_column"),
+                                        rsTargetKC.getString("key_column")
+                                );
+                            }
+                        }
+                    }
+                }
+            }
+
+            return keys;
+        }
     }
 
     @Override
@@ -117,4 +342,20 @@ public class PostgresDBBroker extends DBBrokerTemplate {
         sb.append("'");
         return sb.toString();
     }
+
+    @Override
+    protected String getColumnNamesQuery(String tapSchemaName, String tableName) {
+        return String.format("SELECT column_name FROM information_schema.columns WHERE table_schema = '%s' AND table_name = '%s'",
+                tapSchemaName, tableName);
+    }
+
+    @Override
+    protected String getAllSchemaNamesQuery() {
+        return "SELECT schema_name FROM information_schema.schemata";
+    }
+
+    @Override
+    protected String getAllTablesNamesQuery(String schemaName) {
+        return String.format("SELECT tablename FROM pg_catalog.pg_tables where schemaname = '%s'", schemaName);
+    }
 }
diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/PropertyModel.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/PropertyModel.java
index 3be665214e7e35ed400e93b4c12d8a09276c3a90..77f4ab5c90d58a3298cfefdd2bdccecf63921ea7 100644
--- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/PropertyModel.java
+++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/PropertyModel.java
@@ -39,6 +39,7 @@ public class PropertyModel implements Serializable {
     private boolean updatable;
     private boolean nullable;
     private String loaderKey;
+    private Object defaultValue;
 
     private PropertyModel() {
     }
@@ -52,6 +53,22 @@ public class PropertyModel implements Serializable {
             updatable = propertyXMLModel.isUpdatable();
             nullable = propertyXMLModel.isNullable();
             loaderKey = propertyXMLModel.getLoaderKey();
+            if (propertyXMLModel.getDefaultValue() != null) {
+                String strDefVal = propertyXMLModel.getDefaultValue();
+                if (type == String.class) {
+                    defaultValue = strDefVal;
+                } else if (type == Integer.class) {
+                    defaultValue = Integer.parseInt(strDefVal);
+                } else if (type == Double.class) {
+                    defaultValue = Double.parseDouble(strDefVal);
+                } else if (type == Long.class) {
+                    defaultValue = Long.parseLong(strDefVal);
+                } else if (type == Float.class) {
+                    defaultValue = Float.parseFloat(strDefVal);
+                } else {
+                    throw new UnsupportedOperationException("Default value for type " + type.getCanonicalName() + " not supported yet.");
+                }
+            }
         } catch (ClassNotFoundException e) {
             throw new ExceptionInInitializerError(
                     "Invalid property type for property " + propertyXMLModel.getName()
@@ -86,4 +103,8 @@ public class PropertyModel implements Serializable {
     public String getLoaderKey() {
         return loaderKey;
     }
+
+    public Object getDefaultValue() {
+        return defaultValue;
+    }
 }
diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/PropertyXMLModel.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/PropertyXMLModel.java
index 2746abfe46e238a7afa74467e15f095f132ed952..878c761efaa8bd651f44980bee799ba6cadd30d7 100644
--- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/PropertyXMLModel.java
+++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/PropertyXMLModel.java
@@ -35,6 +35,7 @@ public class PropertyXMLModel {
     private Integer size;
     private boolean updatable;
     private boolean nullable;
+    private String defaultValue;
     private String loaderKey;
     private String description;
 
@@ -89,6 +90,15 @@ public class PropertyXMLModel {
         this.nullable = nullable;
     }
 
+    @XmlElement(name = "default-value")
+    public String getDefaultValue() {
+        return defaultValue;
+    }
+
+    public void setDefaultValue(String defaultValue) {
+        this.defaultValue = defaultValue;
+    }
+
     @XmlElement(name = "key")
     public String getLoaderKey() {
         return loaderKey;
diff --git a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/TapSchemaModels.java b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/TapSchemaModels.java
index 25fc5be080fb4a2b4bed7f298c35638121a3914d..1721f6152041a229ebccb3787456a346e8f518fc 100644
--- a/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/TapSchemaModels.java
+++ b/TASMAN-core/src/main/java/it/inaf/ia2/tsm/model/TapSchemaModels.java
@@ -22,10 +22,8 @@
  */
 package it.inaf.ia2.tsm.model;
 
-import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
-import java.net.URISyntaxException;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
diff --git a/TASMAN-core/src/main/resources/tap_schema/tap_schema-1-IA2.xml b/TASMAN-core/src/main/resources/tap_schema/tap_schema-1-IA2.xml
index 70e1638b275326fccd1aaa7afdd392dd0d2ae4a2..40f909f1f3b2e9b69d90e2532bc8f97bc00fd72e 100644
--- a/TASMAN-core/src/main/resources/tap_schema/tap_schema-1-IA2.xml
+++ b/TASMAN-core/src/main/resources/tap_schema/tap_schema-1-IA2.xml
@@ -47,6 +47,11 @@ Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
                 <type>java.lang.Long</type>
                 <updatable>true</updatable>
             </property>
+            <property>
+                <name>id</name>
+                <type>java.lang.Integer</type>
+                <updatable>true</updatable>
+            </property>
         </add>
     </table>
     <table name="keys">
diff --git a/TASMAN-core/src/main/resources/tap_schema/tap_schema-1.xml b/TASMAN-core/src/main/resources/tap_schema/tap_schema-1.xml
index 26c5446c8da15b60198b0cbe55f402a39191ef67..8dbc01479ecab0a4d92c15856375888552623432 100644
--- a/TASMAN-core/src/main/resources/tap_schema/tap_schema-1.xml
+++ b/TASMAN-core/src/main/resources/tap_schema/tap_schema-1.xml
@@ -160,22 +160,27 @@ Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
             </property>
             <property>
                 <name>indexed</name>
-                <type>java.lang.Boolean</type>
+                <type>java.lang.Integer</type>
                 <updatable>false</updatable>
+                <nullable>false</nullable>
                 <key>indexed</key>
-                <description>an indexed column; 1 means 1, 0 means 0</description>
+                <description>an indexed column; 1 means true, 0 means false</description>
             </property>
             <property>
                 <name>principal</name>
-                <type>java.lang.Boolean</type>
+                <type>java.lang.Integer</type>
                 <updatable>true</updatable>
-                <description>a principal column; 1 means 1, 0 means 0</description>   
+                <nullable>false</nullable>
+                <default-value>0</default-value>
+                <description>a principal column; 1 means true, 0 means false</description>   
             </property>
             <property>
                 <name>std</name>
-                <type>java.lang.Boolean</type>
-                <updatable>true</updatable> 
-                <description>a standard column; 1 means 1, 0 means 0</description>  
+                <type>java.lang.Integer</type>
+                <updatable>true</updatable>
+                <nullable>false</nullable>
+                <default-value>0</default-value>
+                <description>a standard column; 1 means true, 0 means false</description>  
             </property>
         </add>
     </table>
diff --git a/TASMAN-core/src/test/java/it/inaf/ia2/tsm/api/TestAll.java b/TASMAN-core/src/test/java/it/inaf/ia2/tsm/TestAll.java
similarity index 98%
rename from TASMAN-core/src/test/java/it/inaf/ia2/tsm/api/TestAll.java
rename to TASMAN-core/src/test/java/it/inaf/ia2/tsm/TestAll.java
index 6b67e26b778037e8b595184cf2b8cc2313946e4b..e68aa982c6a2d2b65ebb23cd67f7a6a800461f79 100644
--- a/TASMAN-core/src/test/java/it/inaf/ia2/tsm/api/TestAll.java
+++ b/TASMAN-core/src/test/java/it/inaf/ia2/tsm/TestAll.java
@@ -20,19 +20,11 @@
  * this program; if not, write to the Free Software Foundation, Inc., 51
  * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
-package it.inaf.ia2.tsm.api;
+package it.inaf.ia2.tsm;
 
-import it.inaf.ia2.tsm.UpdateOperations;
 import it.inaf.ia2.tsm.datalayer.DBWrapper;
-import it.inaf.ia2.tsm.Table;
-import it.inaf.ia2.tsm.KeyColumn;
-import it.inaf.ia2.tsm.TapSchema;
-import it.inaf.ia2.tsm.Schema;
-import it.inaf.ia2.tsm.Column;
 import it.inaf.ia2.tsm.datalayer.DatabaseType;
 import it.inaf.ia2.tsm.datalayer.Credentials;
-import it.inaf.ia2.tsm.Status;
-import it.inaf.ia2.tsm.Key;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -95,7 +87,7 @@ public class TestAll {
 
         dbWrapper = new DBWrapper(postgresCredentials);
         dbWrapper.testConnections();
-        //dbWrappers.add(dbWrapper);
+        dbWrappers.add(dbWrapper);
 
         // Mix!
         //dbWrappers.add(new DBWrapper(mysqlCredentials, postgresCredentials));
@@ -461,6 +453,7 @@ public class TestAll {
                 // reloading
                 LOG.debug("----- Reloading saved TAP_SCHEMA -----");
                 tapSchema = new TapSchema("1.0", dbWrapper, "test_tap_schema", true);
+                assertEquals("1.0", tapSchema.getTapSchemaDBBroker().detectVersion(tapSchema.getName()));
                 LOG.debug(tapSchema.toString());
 
                 assertNotNull(sch0 = tapSchema.getChild("sch0", Status.ADDED_PERSISTED));
diff --git a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/SchemaSelectionBean.java b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/SchemaSelectionBean.java
index 1a2f6556e8122e07714368bccc2da4c9d7975e81..337614c8bb5bb068e0cb1faeb5a159192c9757c2 100644
--- a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/SchemaSelectionBean.java
+++ b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/SchemaSelectionBean.java
@@ -26,9 +26,13 @@ import it.inaf.ia2.tsm.TapSchema;
 import it.inaf.ia2.tsm.datalayer.DBBroker;
 import it.inaf.ia2.tsm.datalayer.DBBrokerFactory;
 import it.inaf.ia2.tsm.datalayer.DBWrapper;
+import it.inaf.ia2.tsm.model.TapSchemaModel;
+import it.inaf.ia2.tsm.model.TapSchemaModels;
 import java.io.Serializable;
 import java.sql.SQLException;
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
 import java.util.List;
 import javax.annotation.PostConstruct;
 import javax.faces.application.FacesMessage;
@@ -48,18 +52,18 @@ import org.slf4j.LoggerFactory;
 @Named("schemaSelection")
 @WindowScoped
 public class SchemaSelectionBean implements Serializable {
-
+    
     private static final long serialVersionUID = -5745720427701334323L;
     private static final Logger LOG = LoggerFactory.getLogger(SchemaSelectionBean.class);
-
+    
     @Inject
     TapSchemaEditingBean tapSchemaEditingBean;
-
+    
     @Inject
     ConsistencyChecksBean consistencyChecksBean;
-
+    
     private DBWrapper dbWrapper;
-
+    
     private String selectedRadioOption;
 
     // For editing
@@ -69,28 +73,37 @@ public class SchemaSelectionBean implements Serializable {
 
     // For creation
     private String tapSchemaName;
+    private List<String> versions;
+    private String version;
     private List<String> allSchemas;
     private List<String> selectedSchemas;
     private boolean loading;
     private TapSchema loadedTapSchema;
     private String loadingError;
-
+    
     @PostConstruct
     public void init() {
         selectedRadioOption = "edit";
         exposedSchemas = "";
+        versions = new ArrayList<>();
+        Iterator<TapSchemaModel> ite = TapSchemaModels.getIterator();
+        while (ite.hasNext()) {
+            TapSchemaModel model = ite.next();
+            versions.add(model.getVersion());
+        }
+        Collections.sort(versions);
     }
-
+    
     public void onPageLoad() {
         FacesContext fc = FacesContext.getCurrentInstance();
         final boolean ajaxRequest = fc.getPartialViewContext().isAjaxRequest();
         final boolean validationFailed = fc.isValidationFailed();
-
+        
         if (!ajaxRequest && !validationFailed) {
 
             // Loading all schemas of the source database
             try {
-            DBBroker broker = DBBrokerFactory.getDBBroker(dbWrapper.getSourceDataSourceWrapper());
+                DBBroker broker = DBBrokerFactory.getDBBroker(dbWrapper.getSourceDataSourceWrapper());
                 allSchemas = broker.getAllSchemaNames();
                 setSelectedSchemas(new ArrayList<String>());
             } catch (SQLException e) {
@@ -99,9 +112,9 @@ public class SchemaSelectionBean implements Serializable {
 
             // Loading all schemas of the TAP_SCHEMA database
             try {
-            DBBroker broker = DBBrokerFactory.getDBBroker(dbWrapper.getTapSchemaDataSourceWrapper());
+                DBBroker broker = DBBrokerFactory.getDBBroker(dbWrapper.getTapSchemaDataSourceWrapper());
                 allTAPSchemas = broker.getAllTAPSchemaNames(allSchemas);
-
+                
                 if (!allTAPSchemas.isEmpty()) {
                     this.selectedTAPSchema = allTAPSchemas.get(0);
                     loadExposedSchemas();
@@ -111,7 +124,7 @@ public class SchemaSelectionBean implements Serializable {
             }
         }
     }
-
+    
     private void loadExposedSchemas() throws SQLException {
         DBBroker broker = DBBrokerFactory.getDBBroker(dbWrapper.getTapSchemaDataSourceWrapper());
         List<String> schemas = broker.getExposedSchemas(selectedTAPSchema);
@@ -123,35 +136,35 @@ public class SchemaSelectionBean implements Serializable {
             }
         }
     }
-
+    
     public List<String> getAllTAPSchemas() {
         return allTAPSchemas;
     }
-
+    
     public List<String> getAllSchemas() {
         return allSchemas;
     }
-
+    
     public String getExposedSchemas() {
         return exposedSchemas;
     }
-
+    
     public String getSelectedRadioOption() {
         return selectedRadioOption;
     }
-
+    
     public void setSelectedRadioOption(String selectedRadioOption) {
         this.selectedRadioOption = selectedRadioOption;
     }
-
+    
     public String getSelectedTAPSchema() {
         return selectedTAPSchema;
     }
-
+    
     public void setSelectedTAPSchema(String selectedTAPSchema) {
         this.selectedTAPSchema = selectedTAPSchema;
     }
-
+    
     public void selectedTAPSchemaChanged() {
         try {
             loadExposedSchemas();
@@ -159,15 +172,15 @@ public class SchemaSelectionBean implements Serializable {
             throw new RuntimeException(e);
         }
     }
-
+    
     public List<String> getSelectedSchemas() {
         return selectedSchemas;
     }
-
+    
     public void setSelectedSchemas(List<String> selectedSchemas) {
         this.selectedSchemas = selectedSchemas;
     }
-
+    
     public String openLoaded() {
         if (loadedTapSchema.getConsistencyChecks().isInconsistent()) {
             consistencyChecksBean.setDbWrapper(dbWrapper);
@@ -178,18 +191,20 @@ public class SchemaSelectionBean implements Serializable {
             return "tapSchemaEditing.xhtml?faces-redirect=true";
         }
     }
-
+    
     public void edit() {
-
+        
         loadedTapSchema = null;
         loading = true;
         loadingError = null;
-
+        
         new Thread(new Runnable() {
             @Override
             public void run() {
                 try {
-                    loadedTapSchema = new TapSchema("1.0-IA2", dbWrapper, selectedTAPSchema, true);
+                    DBBroker broker = DBBrokerFactory.getDBBroker(dbWrapper.getTapSchemaDataSourceWrapper());
+                    String version = broker.detectVersion(selectedTAPSchema);
+                    loadedTapSchema = new TapSchema(version, dbWrapper, selectedTAPSchema, true);
                 } catch (Throwable e) {
                     LOG.error("Exception caught", e);
                     loadingError = e.getMessage();
@@ -201,48 +216,54 @@ public class SchemaSelectionBean implements Serializable {
             }
         }).start();
     }
-
+    
     public void create() {
-
+        
         loadedTapSchema = null;
         loading = true;
         loadingError = null;
-
+        
         new Thread(new Runnable() {
             @Override
             public void run() {
                 try {
-                    loadedTapSchema = new TapSchema("1.0-IA2", dbWrapper, tapSchemaName, false);
+                    loadedTapSchema = new TapSchema(version, dbWrapper, tapSchemaName, false);
                     for (String schemaName : selectedSchemas) {
                         loadedTapSchema.addChild(schemaName);
                     }
                 } catch (Throwable e) {
-                    loadingError = e.getMessage();
+                    LOG.error("Exception caught", e);
+                    if (e.getMessage() != null) {
+                        loadingError = e.getMessage();
+                    } else {
+                        loadingError = e.getClass().getCanonicalName();
+                        loadedTapSchema = null;
+                    }
                 }
                 loading = false;
             }
         }).start();
     }
-
+    
     public String getTapSchemaName() {
         return tapSchemaName;
     }
-
+    
     public void setTapSchemaName(String tapSchemaName) {
         this.tapSchemaName = tapSchemaName;
     }
-
+    
     public DBWrapper getDbWrapper() {
         return dbWrapper;
     }
-
+    
     public void setDbWrapper(DBWrapper dbWrapper) {
         this.dbWrapper = dbWrapper;
     }
-
+    
     public void validateTapSchemaName(FacesContext context, UIComponent inputComponent, Object value) {
         String textValue = (String) value;
-
+        
         String validatorMessage = null;
         if (textValue == null || textValue.isEmpty()) {
             validatorMessage = "TAP_SCHEMA name is required";
@@ -251,7 +272,7 @@ public class SchemaSelectionBean implements Serializable {
         } else if (allSchemas.contains(textValue)) {
             validatorMessage = "Database already contains a schema with this name. Please choose another name";
         }
-
+        
         if (validatorMessage != null) {
             throw new ValidatorException(new FacesMessage(validatorMessage));
         }
@@ -271,8 +292,20 @@ public class SchemaSelectionBean implements Serializable {
     public String getLoadingError() {
         return loadingError;
     }
-
+    
     public TapSchema getLoadedTapSchema() {
         return loadedTapSchema;
     }
+    
+    public List<String> getVersions() {
+        return versions;
+    }
+    
+    public String getVersion() {
+        return version;
+    }
+    
+    public void setVersion(String version) {
+        this.version = version;
+    }
 }
diff --git a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/TapSchemaEditingBean.java b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/TapSchemaEditingBean.java
index 5faedbe6e54d5c481e3458a830f830db2bc12ff7..66fd74860ae5cfa7acd20a0ddb565f273f88af4b 100644
--- a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/TapSchemaEditingBean.java
+++ b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/TapSchemaEditingBean.java
@@ -137,6 +137,7 @@ public class TapSchemaEditingBean implements Serializable {
                     sb.append(", ");
                 }
                 sb.append(key);
+                first = false;
             }
         }
         return sb.toString();
@@ -415,4 +416,42 @@ public class TapSchemaEditingBean implements Serializable {
             }
         }
     }
+
+    /**
+     * In TAP_SCHEMA 1.0 std column has an integer data type and use 1 for true
+     * and 0 for false, but we want to edit it using a JSF booleanCheckbox, so
+     * we need this workaround pairs of getter and setter.
+     */
+    public Boolean getStd() {
+        Column column = getSelectedColumn();
+        if (column != null && column.getProperty("std") != null) {
+            return column.getValue("std", Integer.class) == 1;
+        }
+        return null;
+    }
+
+    public void setStd(Boolean value) {
+        Column column = getSelectedColumn();
+        if (column != null) {
+            column.setValue("std", value ? 1 : 0);
+        }
+    }
+
+    /**
+     * Same of getStd().
+     */
+    public Boolean getPrincipal() {
+        Column column = getSelectedColumn();
+        if (column != null && column.getProperty("principal") != null) {
+            return column.getValue("principal", Integer.class) == 1;
+        }
+        return null;
+    }
+
+    public void setPrincipal(Boolean value) {
+        Column column = getSelectedColumn();
+        if (column != null) {
+            column.setValue("principal", value ? 1 : 0);
+        }
+    }
 }
diff --git a/TASMAN-webapp/src/main/webapp/resources/js/async-loader.js b/TASMAN-webapp/src/main/webapp/resources/js/async-loader.js
index 5409768d0148f5342ba2c6d2e5ba6c143a5ebee8..0f2e31d7a68f8ee793daa7da8947fb15b3742c50 100644
--- a/TASMAN-webapp/src/main/webapp/resources/js/async-loader.js
+++ b/TASMAN-webapp/src/main/webapp/resources/js/async-loader.js
@@ -28,7 +28,7 @@
             loading = l;
         },
         startChecking: function (event) {
-            if (event.status === 'success') {
+            if (event.status === 'success' && $('.validation-message').length === 0) {
                 periodicCheck();
             }
         }
diff --git a/TASMAN-webapp/src/main/webapp/schemaSelection.xhtml b/TASMAN-webapp/src/main/webapp/schemaSelection.xhtml
index be96e137fe0769269b665230697d3b1087d36c5a..c547e56dc7e172ecbe4f738a1d04b93f4e1ce881 100644
--- a/TASMAN-webapp/src/main/webapp/schemaSelection.xhtml
+++ b/TASMAN-webapp/src/main/webapp/schemaSelection.xhtml
@@ -73,7 +73,16 @@
                                     <div class="form-group">
                                         <h:outputLabel for="tapschemaName">Name:</h:outputLabel>
                                         <h:inputText id="tapschemaName" value="#{schemaSelection.tapSchemaName}" class="form-control" validator="#{schemaSelection.validateTapSchemaName}" />
-                                        <h:message for="tapschemaName" class="text-danger"></h:message>
+                                        <h:message for="tapschemaName" class="text-danger validation-message"></h:message>
+                                    </div>
+
+                                    <div class="form-group">
+                                        <h:outputLabel for="tapschemaVersion">Version:</h:outputLabel>
+                                        <h:selectOneMenu id="tapschemaVersion" value="#{schemaSelection.version}" class="form-control" required="true" requiredMessage="Select version">
+                                            <f:selectItem itemValue="#{null}" itemLabel="Select..." noSelectionOption="true" />
+                                            <f:selectItems value="#{schemaSelection.versions}" var="v" itemLabel="TAP_SCHEMA #{v}" itemValue="#{v}" />
+                                        </h:selectOneMenu>
+                                        <h:message for="tapschemaVersion" class="text-danger validation-message"></h:message>
                                     </div>
 
                                     <div class="form-group">
@@ -82,7 +91,7 @@
                                             <f:selectItems value="#{schemaSelection.allSchemas}"></f:selectItems>
                                             <f:validateRequired></f:validateRequired>
                                         </h:selectManyListbox>
-                                        <h:message for="selectedSchemas" class="text-danger"></h:message>
+                                        <h:message for="selectedSchemas" class="text-danger validation-message"></h:message>
                                     </div>
 
                                     <div class="form-group">
diff --git a/TASMAN-webapp/src/main/webapp/tapSchemaEditing.xhtml b/TASMAN-webapp/src/main/webapp/tapSchemaEditing.xhtml
index cb7d6c04d09d4afc1dd99d56cee3e24bfedfb362..aa37b0f285d2795a6becf8cd841ffe5b7a8a1b6f 100644
--- a/TASMAN-webapp/src/main/webapp/tapSchemaEditing.xhtml
+++ b/TASMAN-webapp/src/main/webapp/tapSchemaEditing.xhtml
@@ -276,7 +276,7 @@
                                                                 <div class="checkbox">
                                                                     <label>
                                                                         <h:selectBooleanCheckbox 
-                                                                            value="#{tapSchemaEditing.selectedColumn.getProperty('std').value}"
+                                                                            value="#{tapSchemaEditing.std}"
                                                                             class="#{tapSchemaEditing.selectedColumn.isChanged('std') ? 'changed' : ''}">
                                                                             <f:ajax execute="@form" render="@this" />
                                                                         </h:selectBooleanCheckbox>
@@ -288,7 +288,7 @@
                                                                 <div class="checkbox">
                                                                     <label>
                                                                         <h:selectBooleanCheckbox 
-                                                                            value="#{tapSchemaEditing.selectedColumn.getProperty('principal').value}"
+                                                                            value="#{tapSchemaEditing.principal}"
                                                                             class="#{tapSchemaEditing.selectedColumn.isChanged('principal') ? 'changed' : ''}">
                                                                             <f:ajax execute="@form" render="@this" />
                                                                         </h:selectBooleanCheckbox>