From 59b4b3dc53dcc4c642bf7ff98a13764eab69cee0 Mon Sep 17 00:00:00 2001
From: Sonia Zorba <zorba@oats.inaf.it>
Date: Wed, 26 Jul 2017 00:07:11 +0200
Subject: [PATCH] Credentials insertion and management changes

---
 .../main/java/it/inaf/ia2/tsm/TapSchema.java  |   3 -
 .../it/inaf/ia2/tsm/datalayer/DBBroker.java   |   4 +-
 .../ia2/tsm/webapp/ConfigurationManager.java  |  56 +++-
 .../ia2/tsm/webapp/ConsistencyChecksBean.java |   2 +-
 .../ia2/tsm/webapp/CredentialsEditing.java    | 143 ++++----
 .../ia2/tsm/webapp/SchemaSelectionBean.java   | 311 ------------------
 .../ia2/tsm/webapp/TapSchemaEditingBean.java  |  34 +-
 .../inaf/ia2/tsm/webapp/TapSchemaLoader.java  | 172 ++++++++++
 .../tsm/webapp/TapSchemaLoaderResource.java   |   8 +-
 .../it/inaf/ia2/tsm/webapp/UsersEditing.java  |   9 +-
 .../env/CustomPartialResponseWriter.java      |  14 +-
 .../ia2/tsm/webapp/env/JSUpdateHandler.java   |  32 --
 .../it/inaf/ia2/tsm/webapp/env/UIModal.java   |  71 ----
 .../src/main/webapp/credentialsEditing.xhtml  | 171 ++++++----
 .../main/webapp/resources/js/async-loader.js  |  14 +-
 .../src/main/webapp/resources/js/common.js    |   3 +-
 .../main/webapp/resources/js/credentials.js   |  28 +-
 .../tsm_components/print_credentials.xhtml    |  12 +
 .../src/main/webapp/schemaSelection.xhtml     | 127 -------
 .../src/main/webapp/tapSchemaEditing.xhtml    |   4 +-
 20 files changed, 447 insertions(+), 771 deletions(-)
 delete mode 100644 TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/SchemaSelectionBean.java
 create mode 100644 TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/TapSchemaLoader.java
 delete mode 100644 TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/env/JSUpdateHandler.java
 delete mode 100644 TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/env/UIModal.java
 create mode 100644 TASMAN-webapp/src/main/webapp/resources/tsm_components/print_credentials.xhtml
 delete mode 100644 TASMAN-webapp/src/main/webapp/schemaSelection.xhtml

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 f3d6ade..36a4e77 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,7 +29,6 @@ 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;
@@ -45,8 +44,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * The main implementation of {@link TapSchema}.
- *
  * @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
  */
 public class TapSchema implements EntitiesContainer<Schema>, Serializable {
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 768fcaf..0ead895 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
@@ -41,9 +41,9 @@ public interface DBBroker {
     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-webapp/src/main/java/it/inaf/ia2/tsm/webapp/ConfigurationManager.java b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/ConfigurationManager.java
index 8a11d97..7e3a8f9 100644
--- a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/ConfigurationManager.java
+++ b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/ConfigurationManager.java
@@ -101,6 +101,15 @@ public class ConfigurationManager {
         return Collections.unmodifiableList(usersConfig.getUsers());
     }
 
+    public UserConfiguration getUserConfiguration(String username) {
+        for (UserConfiguration user : usersConfig.getUsers()) {
+            if (username.equals(user.getUsername())) {
+                return user;
+            }
+        }
+        return null;
+    }
+
     public List<UCDConfiguration> getUCDConfiguration() {
         return Collections.unmodifiableList(ucdListConfig.getUCDList());
     }
@@ -197,9 +206,17 @@ public class ConfigurationManager {
     }
 
     public List<TapCredentials> getCredentials(String username) {
+        List<TapCredentials> credentials = getUserCredentials(username);
+        if (credentials == null) {
+            return null;
+        }
+        return Collections.unmodifiableList(credentials);
+    }
+
+    private List<TapCredentials> getUserCredentials(String username) {
         for (UserConfiguration user : usersConfig.getUsers()) {
             if (user.getUsername().equals(username)) {
-                return Collections.unmodifiableList(user.getCredentialsInfo());
+                return user.getCredentialsInfo();
             }
         }
         return null;
@@ -213,18 +230,11 @@ public class ConfigurationManager {
      * otherwise.
      */
     public synchronized boolean addCredentials(String username, TapCredentials credentials) {
-        for (UserConfiguration user : usersConfig.getUsers()) {
-            if (user.getUsername().equals(username)) {
-                for (TapCredentials tapCredentials : user.getCredentialsInfo()) {
-                    if (tapCredentials.equals(credentials)) {
-                        return false;
-                    }
-                }
-
-                user.getCredentialsInfo().add(credentials);
-                updateUsersConfigurationFile();
-                return false;
-            }
+        List<TapCredentials> userCredentials = getUserCredentials(username);
+        if (userCredentials != null) {
+            userCredentials.add(credentials);
+            updateUsersConfigurationFile();
+            return true;
         }
         return false;
     }
@@ -234,11 +244,21 @@ public class ConfigurationManager {
      * otherwise.
      */
     public synchronized boolean deleteCredentials(String username, int credentialsIndex) {
-        for (UserConfiguration user : usersConfig.getUsers()) {
-            if (user.getUsername().equals(username)) {
-                user.getCredentialsInfo().remove(credentialsIndex);
-                return true;
-            }
+        List<TapCredentials> userCredentials = getUserCredentials(username);
+        if (userCredentials != null && userCredentials.size() > credentialsIndex) {
+            userCredentials.remove(credentialsIndex);
+            updateUsersConfigurationFile();
+            return true;
+        }
+        return false;
+    }
+
+    public synchronized boolean updateCredentials(String username, TapCredentials updatedCredentials, int index) {
+        List<TapCredentials> userCredentials = getUserCredentials(username);
+        if (userCredentials != null && userCredentials.size() > index) {
+            userCredentials.set(index, updatedCredentials);
+            updateUsersConfigurationFile();
+            return true;
         }
         return false;
     }
diff --git a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/ConsistencyChecksBean.java b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/ConsistencyChecksBean.java
index 81b1423..f44f84d 100644
--- a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/ConsistencyChecksBean.java
+++ b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/ConsistencyChecksBean.java
@@ -71,6 +71,6 @@ public class ConsistencyChecksBean implements Serializable {
     }
 
     public String back() {
-        return "schemaSelection.xhtml?faces-redirect=true";
+        return "credentialsEditing.xhtml?faces-redirect=true";
     }
 }
diff --git a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/CredentialsEditing.java b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/CredentialsEditing.java
index 5bb68a6..3ce133c 100644
--- a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/CredentialsEditing.java
+++ b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/CredentialsEditing.java
@@ -24,9 +24,7 @@ package it.inaf.ia2.tsm.webapp;
 
 import it.inaf.ia2.tsm.webapp.xmlconfig.SeparatedCredentials;
 import it.inaf.ia2.tsm.datalayer.Credentials;
-import it.inaf.ia2.tsm.datalayer.DBWrapper;
 import it.inaf.ia2.tsm.model.TapSchemaModels;
-import it.inaf.ia2.tsm.webapp.env.UIModal;
 import it.inaf.ia2.tsm.webapp.xmlconfig.JoinedCredentials;
 import it.inaf.ia2.tsm.webapp.xmlconfig.TapCredentials;
 import java.io.IOException;
@@ -60,12 +58,11 @@ public class CredentialsEditing implements Serializable {
     private ConfigurationManager config;
 
     @Inject
-    private SchemaSelectionBean schemaSelectionBean;
+    private TapSchemaLoader tapSchemaLoader;
 
     private Integer credentialsInEditing;
     private Integer credentialsToRemove;
 
-    private UIModal.StatusObserver credentialsDialogStatusObserver;
     private boolean credentialsDialogOpened;
 
     private List<String> tapSchemaVersions;
@@ -79,12 +76,6 @@ public class CredentialsEditing implements Serializable {
 
     @PostConstruct
     public void init() {
-        this.credentialsDialogStatusObserver = new UIModal.StatusObserver() {
-            @Override
-            public void statusChanged(boolean isOpen) {
-                credentialsDialogOpened = isOpen;
-            }
-        };
         this.tapSchemaVersions = TapSchemaModels.getAvailableVersions();
     }
 
@@ -117,7 +108,8 @@ public class CredentialsEditing implements Serializable {
         hasObscore = credentials.isHasObscore();
     }
 
-    public void addNewCredentials() {
+    public void addNewCredentialsInEditing() {
+        credentialsInEditing = null;
         separateCredentials = false;
         sourceCredentials = new Credentials();
         tapSchemaCredentials = new Credentials();
@@ -126,63 +118,73 @@ public class CredentialsEditing implements Serializable {
         hasObscore = false;
     }
 
-//    public void editCredentials(Credentials credentials, int index) {
-//        this.sourceCredentials = credentials;
-//        separateCredentials = false;
-//        currentEditingRow = index;
-//    }
-//
-//    public void editSeparateCredentials(SeparatedCredentials sc, int index) {
-//        this.sourceCredentials = sc.getSourceCredentials();
-//        this.tapSchemaCredentials = sc.getTapSchemaCredentials();
-//        currentEditingRow = index;
-//        separateCredentials = true;
-//    }
-    public String loginWithJoinedCredentials(JoinedCredentials credentials) {
-        return loginWithDBWrapper(new DBWrapper(credentials.getCredentials()));
+    public void loadTapSchema(TapCredentials tapCredentials) throws SQLException {
+        tapSchemaLoader.tryLoadingTapSchema(tapCredentials);
     }
 
-    public String loginWithSeparatedCredentials(Credentials sourceCredentials, Credentials tapSchemaCredentials) {
-        return loginWithDBWrapper(new DBWrapper(sourceCredentials, tapSchemaCredentials));
+    public void openDeleteCredentialsConfirmation(int index) throws IOException {
+        credentialsToRemove = index;
     }
 
-    private String loginWithDBWrapper(DBWrapper dbWrapper) {
-
-        try {
-            dbWrapper.testConnections();
-            schemaSelectionBean.setDbWrapper(dbWrapper);
-            return "schemaSelection.xhtml?faces-redirect=true";
-        } catch (SQLException e) {
-            LOG.error("Exception caught", e);
-            FacesContext.getCurrentInstance().addMessage("main", new FacesMessage("Connection error: " + e.getMessage()));
-            return null;
+    public void confirmCredentialsDeletion() {
+        if (credentialsToRemove != null) {
+            config.deleteCredentials(user.getUsername(), credentialsToRemove);
         }
+        credentialsToRemove = null;
     }
 
-    public void removeCredentials(int index) throws IOException {
-//        getSavedCredentials().remove(index);
-//        config.updateUsersConfigurationFile();
+    public boolean validateNotNull(FacesContext ctx, String value, String componentId, String errorMessage) {
+        if (value == null || value.isEmpty()) {
+            ctx.addMessage(componentId, new FacesMessage(errorMessage));
+            return false;
+        }
+        return true;
     }
 
     public void saveCredentialsEdited() throws IOException {
-//
-//        // If is editing existing, remove old for creating a new one
-//        if (currentEditingRow < getSavedCredentials().size()) {
-//            getSavedCredentials().remove(currentEditingRow);
-//        }
-//
-//        if (separateCredentials) {
-//            SeparatedCredentials sc = new SeparatedCredentials(sourceCredentials, tapSchemaCredentials);
-//            getSavedCredentials().add(currentEditingRow, sc);
-//        } else {
-//            getSavedCredentials().add(currentEditingRow, sourceCredentials);
-//        }
-//
-//        config.updateUsersConfigurationFile();
-    }
 
-    public UIModal.StatusObserver getCredentialsDialogStatus() {
-        return credentialsDialogStatusObserver;
+        /**
+         * We need to validate manually to avoid problem with JSF AJAX partial
+         * updates.
+         */
+        FacesContext ctx = FacesContext.getCurrentInstance();
+
+        /**
+         * Single & operator used to perform all validation.
+         */
+        boolean validationOk
+                = validateNotNull(ctx, sourceCredentials.getHostname(), "main:source_hostname", "Hostname is required")
+                & validateNotNull(ctx, sourceCredentials.getUsername(), "main:source_username", "Username is required")
+                & validateNotNull(ctx, tapSchemaName, "main:tap_schema_name", "TAP_SCHEMA name is required");
+
+        if (separateCredentials) {
+            validationOk = validationOk
+                    & validateNotNull(ctx, tapSchemaCredentials.getHostname(), "main:tap_schema_hostname", "Hostname is required")
+                    & validateNotNull(ctx, tapSchemaCredentials.getHostname(), "main:tap_schema_username", "Username is required");
+        }
+
+        if (!validationOk) {
+            return;
+        }
+
+        TapCredentials editedCredentials;
+        if (separateCredentials) {
+            editedCredentials = new SeparatedCredentials(sourceCredentials, tapSchemaCredentials);
+        } else {
+            editedCredentials = new JoinedCredentials(sourceCredentials);
+        }
+
+        editedCredentials.setHasObscore(hasObscore);
+        editedCredentials.setTapSchemaName(tapSchemaName);
+        editedCredentials.setTapSchemaVersion(tapSchemaVersion);
+
+        if (credentialsInEditing == null) {
+            // New credentials
+            config.addCredentials(user.getUsername(), editedCredentials);
+        } else {
+            // Existing credentials
+            config.updateCredentials(user.getUsername(), editedCredentials, credentialsInEditing);
+        }
     }
 
     public List<String> getTapSchemaVersions() {
@@ -201,33 +203,6 @@ public class CredentialsEditing implements Serializable {
         this.separateCredentials = separateCredentials;
     }
 
-//    public void separateCredentialsChanged() {
-//        if (separateCredentials) {
-//            Credentials credentials = getJoinedCredentialsInEditing().getCredentials();
-//            SeparatedCredentials separatedCredentials = new SeparatedCredentials();
-//            separatedCredentials.setSourceCredentials(credentials);
-//            credentialsInEditing = separatedCredentials;
-//        } else {
-//            Credentials credentials = getSeparatedCredentialsInEditing().getSourceCredentials();
-//            JoinedCredentials joinedCredentials = new JoinedCredentials();
-//            joinedCredentials.setCredentials(credentials);
-//            credentialsInEditing = joinedCredentials;
-//        }
-//    }
-//
-//    public JoinedCredentials getJoinedCredentialsInEditing() {
-//        if (credentialsInEditing instanceof JoinedCredentials) {
-//            return (JoinedCredentials) credentialsInEditing;
-//        }
-//        return null;
-//    }
-//
-//    public SeparatedCredentials getSeparatedCredentialsInEditing() {
-//        if (credentialsInEditing instanceof SeparatedCredentials) {
-//            return (SeparatedCredentials) credentialsInEditing;
-//        }
-//        return null;
-//    }
     public boolean isCredentialsDialogOpened() {
         return credentialsDialogOpened;
     }
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
deleted file mode 100644
index 337614c..0000000
--- a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/SchemaSelectionBean.java
+++ /dev/null
@@ -1,311 +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.webapp;
-
-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;
-import javax.faces.component.UIComponent;
-import javax.faces.context.FacesContext;
-import javax.faces.validator.ValidatorException;
-import javax.inject.Inject;
-import javax.inject.Named;
-import org.apache.deltaspike.core.api.scope.WindowScoped;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- *
- * @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
- */
-@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
-    private List<String> allTAPSchemas;
-    private String selectedTAPSchema;
-    private String exposedSchemas;
-
-    // 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());
-                allSchemas = broker.getAllSchemaNames();
-                setSelectedSchemas(new ArrayList<String>());
-            } catch (SQLException e) {
-                throw new RuntimeException(e);
-            }
-
-            // Loading all schemas of the TAP_SCHEMA database
-            try {
-                DBBroker broker = DBBrokerFactory.getDBBroker(dbWrapper.getTapSchemaDataSourceWrapper());
-                allTAPSchemas = broker.getAllTAPSchemaNames(allSchemas);
-                
-                if (!allTAPSchemas.isEmpty()) {
-                    this.selectedTAPSchema = allTAPSchemas.get(0);
-                    loadExposedSchemas();
-                }
-            } catch (SQLException e) {
-                throw new RuntimeException(e);
-            }
-        }
-    }
-    
-    private void loadExposedSchemas() throws SQLException {
-        DBBroker broker = DBBrokerFactory.getDBBroker(dbWrapper.getTapSchemaDataSourceWrapper());
-        List<String> schemas = broker.getExposedSchemas(selectedTAPSchema);
-        exposedSchemas = "";
-        for (int i = 0; i < schemas.size(); i++) {
-            exposedSchemas += schemas.get(i);
-            if (i < schemas.size() - 1) {
-                exposedSchemas += ", ";
-            }
-        }
-    }
-    
-    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();
-        } catch (SQLException e) {
-            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);
-            consistencyChecksBean.setTapSchema(loadedTapSchema);
-            return "consistencyChecks.xhtml?faces-redirect=true";
-        } else {
-            tapSchemaEditingBean.setTapSchema(loadedTapSchema);
-            return "tapSchemaEditing.xhtml?faces-redirect=true";
-        }
-    }
-    
-    public void edit() {
-        
-        loadedTapSchema = null;
-        loading = true;
-        loadingError = null;
-        
-        new Thread(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    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();
-                    if (loadingError == null) {
-                        loadingError = e.getClass().getCanonicalName();
-                    }
-                }
-                loading = false;
-            }
-        }).start();
-    }
-    
-    public void create() {
-        
-        loadedTapSchema = null;
-        loading = true;
-        loadingError = null;
-        
-        new Thread(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    loadedTapSchema = new TapSchema(version, dbWrapper, tapSchemaName, false);
-                    for (String schemaName : selectedSchemas) {
-                        loadedTapSchema.addChild(schemaName);
-                    }
-                } catch (Throwable e) {
-                    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";
-        } else if (!textValue.matches("^[a-zA-Z0-9_[-]]*$")) {
-            validatorMessage = "TAP_SCHEMA name has to be a valid table name";
-        } 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));
-        }
-    }
-
-    /**
-     * This boolean is true when a TapSchema instance is loading.
-     */
-    public boolean isLoading() {
-        return loading;
-    }
-
-    /**
-     * This String is not null when an error happens while a TapSchema is
-     * loading.
-     */
-    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 c5f3612..bedc26f 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
@@ -25,7 +25,6 @@ package it.inaf.ia2.tsm.webapp;
 import it.inaf.ia2.tsm.ChildEntity;
 import it.inaf.ia2.tsm.Column;
 import it.inaf.ia2.tsm.webapp.env.CustomPartialResponseWriter;
-import it.inaf.ia2.tsm.webapp.env.JSUpdateHandler;
 import it.inaf.ia2.tsm.EntitiesContainer;
 import it.inaf.ia2.tsm.Key;
 import it.inaf.ia2.tsm.KeyColumn;
@@ -58,7 +57,7 @@ public class TapSchemaEditingBean implements Serializable {
     private static final Logger LOG = LoggerFactory.getLogger(TapSchemaEditingBean.class);
 
     @Inject
-    SchemaSelectionBean schemaSelection;
+    private TapSchemaLoader tapSchemaLoader;
 
     private TapSchema tapSchema;
     private Schema selectedSchema;
@@ -247,7 +246,7 @@ public class TapSchemaEditingBean implements Serializable {
     }
 
     public String back() {
-        return "schemaSelection.xhtml?faces-redirect=true";
+        return "credentialsEditing.xhtml?faces-redirect=true";
     }
 
     public void undoRemove(ChildEntity entity) throws SQLException {
@@ -310,13 +309,7 @@ public class TapSchemaEditingBean implements Serializable {
             }
 
             // New UCD is set and we can notify the client to close the UCD Search modal dialog.
-            CustomPartialResponseWriter.getCurrentInstance().addCustomJSUpdate(new JSUpdateHandler() {
-
-                @Override
-                public String getUpdate() {
-                    return "true";
-                }
-            });
+            CustomPartialResponseWriter.getCurrentInstance().addCustomJSUpdate(String.valueOf(true));
         }
     }
 
@@ -338,13 +331,7 @@ public class TapSchemaEditingBean implements Serializable {
         if (key.equals("unit")) {
             voUnitValidator = new VOUnitValidator(entity.getValue(key, String.class));
         }
-        CustomPartialResponseWriter.getCurrentInstance().addCustomJSUpdate(new JSUpdateHandler() {
-
-            @Override
-            public String getUpdate() {
-                return isChanged + "";
-            }
-        });
+        CustomPartialResponseWriter.getCurrentInstance().addCustomJSUpdate(String.valueOf(isChanged));
     }
 
     public void removeColumn(String name) {
@@ -371,17 +358,10 @@ public class TapSchemaEditingBean implements Serializable {
 
     public void reload() {
 
-        if (schemaSelection.getSelectedRadioOption().equals("edit")) {
-            schemaSelection.edit();
+        if (tapSchema.exists()) {
+            tapSchemaLoader.edit();
         } else {
-            if (tapSchema.exists()) {
-                schemaSelection.setSelectedRadioOption("edit");
-                schemaSelection.setSelectedTAPSchema(tapSchema.getName());
-                schemaSelection.selectedTAPSchemaChanged();
-                schemaSelection.edit();
-            } else {
-                schemaSelection.create();
-            }
+            tapSchemaLoader.create();
         }
     }
 
diff --git a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/TapSchemaLoader.java b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/TapSchemaLoader.java
new file mode 100644
index 0000000..ff5951b
--- /dev/null
+++ b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/TapSchemaLoader.java
@@ -0,0 +1,172 @@
+/*
+ * _____________________________________________________________________________
+ * 
+ * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of
+ * Trieste INAF - IA2 Italian Center for Astronomical Archives
+ * _____________________________________________________________________________
+ * 
+ * Copyright (C) 2017 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.webapp;
+
+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.webapp.env.CustomPartialResponseWriter;
+import it.inaf.ia2.tsm.webapp.xmlconfig.JoinedCredentials;
+import it.inaf.ia2.tsm.webapp.xmlconfig.SeparatedCredentials;
+import it.inaf.ia2.tsm.webapp.xmlconfig.TapCredentials;
+import java.io.Serializable;
+import java.sql.SQLException;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.apache.deltaspike.core.api.scope.WindowScoped;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
+ */
+@Named("tapSchemaLoader")
+@WindowScoped
+public class TapSchemaLoader implements Serializable {
+
+    private static final long serialVersionUID = 3203810003976020854L;
+
+    private static final Logger LOG = LoggerFactory.getLogger(TapSchemaLoader.class);
+
+    @Inject
+    private ConsistencyChecksBean consistencyChecksBean;
+
+    @Inject
+    TapSchemaEditingBean tapSchemaEditingBean;
+
+    private TapCredentials tapCredentials;
+    private DBWrapper dbWrapper;
+
+    private boolean loading;
+    private TapSchema loadedTapSchema;
+    private String loadingError;
+
+    public void tryLoadingTapSchema(TapCredentials tapCredentials) throws SQLException {
+        this.tapCredentials = tapCredentials;
+
+        if (tapCredentials instanceof JoinedCredentials) {
+            JoinedCredentials joinedCredentials = (JoinedCredentials) tapCredentials;
+            dbWrapper = new DBWrapper(joinedCredentials.getCredentials());
+        } else {
+            SeparatedCredentials separatedCredentials = (SeparatedCredentials) tapCredentials;
+            dbWrapper = new DBWrapper(separatedCredentials.getSourceCredentials(), separatedCredentials.getTapSchemaCredentials());
+        }
+
+        // Testing connections
+        dbWrapper.testConnections();
+
+        // Searching for TAP_SCHEMA name
+        DBBroker broker = DBBrokerFactory.getDBBroker(dbWrapper.getTapSchemaDataSourceWrapper());
+        boolean tapSchemaExists = false;
+        for (String schemaName : broker.getAllSchemaNames()) {
+            if (schemaName.equals(tapCredentials.getTapSchemaName())) {
+                tapSchemaExists = true;
+                break;
+            }
+        }
+
+        CustomPartialResponseWriter.getCurrentInstance().addCustomJSUpdate("tap_schema_existence", String.valueOf(tapSchemaExists));
+
+        if (tapSchemaExists) {
+            edit();
+        }
+        // Otherwise create TAP_SCHEMA only if user press Ok on confirmation dialog
+    }
+
+    public void edit() {
+
+        loadedTapSchema = null;
+        loading = true;
+        loadingError = null;
+
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    loadedTapSchema = new TapSchema(tapCredentials.getTapSchemaVersion(), dbWrapper, tapCredentials.getTapSchemaName(), true);
+                } catch (Throwable e) {
+                    LOG.error("Exception caught", e);
+                    loadingError = e.getMessage();
+                    if (loadingError == null) {
+                        loadingError = e.getClass().getCanonicalName();
+                    }
+                }
+                loading = false;
+            }
+        }).start();
+    }
+
+    public void create() {
+
+        loadedTapSchema = null;
+        loading = true;
+        loadingError = null;
+
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    loadedTapSchema = new TapSchema(tapCredentials.getTapSchemaVersion(), dbWrapper, tapCredentials.getTapSchemaName(), false);
+                } catch (Throwable e) {
+                    LOG.error("Exception caught", e);
+                    if (e.getMessage() != null) {
+                        loadingError = e.getMessage();
+                    } else {
+                        loadingError = e.getClass().getCanonicalName();
+                        loadedTapSchema = null;
+                    }
+                }
+                loading = false;
+            }
+        }).start();
+    }
+
+    public TapCredentials getTapCredentials() {
+        return tapCredentials;
+    }
+
+    public boolean isLoading() {
+        return loading;
+    }
+
+    public TapSchema getLoadedTapSchema() {
+        return loadedTapSchema;
+    }
+
+    public String getLoadingError() {
+        return loadingError;
+    }
+
+    public String openLoaded() {
+        if (loadedTapSchema.getConsistencyChecks().isInconsistent()) {
+            consistencyChecksBean.setDbWrapper(dbWrapper);
+            consistencyChecksBean.setTapSchema(loadedTapSchema);
+            return "consistencyChecks.xhtml?faces-redirect=true";
+        } else {
+            tapSchemaEditingBean.setTapSchema(loadedTapSchema);
+            return "tapSchemaEditing.xhtml?faces-redirect=true";
+        }
+    }
+}
diff --git a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/TapSchemaLoaderResource.java b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/TapSchemaLoaderResource.java
index 7a7b0c9..77bd7c7 100644
--- a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/TapSchemaLoaderResource.java
+++ b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/TapSchemaLoaderResource.java
@@ -39,15 +39,15 @@ import javax.json.JsonObjectBuilder;
 public class TapSchemaLoaderResource {
 
     @Inject
-    private SchemaSelectionBean schemaSelection;
+    private TapSchemaLoader loader;
 
     @GET
     @Path("status")
     public String getStatus() {
         JsonObjectBuilder job = Json.createObjectBuilder();
-        job.add("loading", schemaSelection.isLoading());
-        if (schemaSelection.getLoadingError() != null) {
-            job.add("error", schemaSelection.getLoadingError());
+        job.add("loading", loader.isLoading());
+        if (loader.getLoadingError() != null) {
+            job.add("error", loader.getLoadingError());
         }
         return job.build().toString();
     }
diff --git a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/UsersEditing.java b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/UsersEditing.java
index e2e9053..9a578e8 100644
--- a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/UsersEditing.java
+++ b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/UsersEditing.java
@@ -23,7 +23,6 @@
 package it.inaf.ia2.tsm.webapp;
 
 import it.inaf.ia2.tsm.webapp.env.CustomPartialResponseWriter;
-import it.inaf.ia2.tsm.webapp.env.JSUpdateHandler;
 import it.inaf.ia2.tsm.webapp.xmlconfig.UserConfiguration;
 import java.io.Serializable;
 import java.util.List;
@@ -142,13 +141,7 @@ public class UsersEditing implements Serializable {
             canSave = false;
         }
 
-        final String jsUpdate = String.valueOf(canSave);
-        CustomPartialResponseWriter.getCurrentInstance().addCustomJSUpdate(new JSUpdateHandler() {
-            @Override
-            public String getUpdate() {
-                return jsUpdate;
-            }
-        });
+        CustomPartialResponseWriter.getCurrentInstance().addCustomJSUpdate(String.valueOf(canSave));
 
         if (canSave) {
             if (newUser) {
diff --git a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/env/CustomPartialResponseWriter.java b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/env/CustomPartialResponseWriter.java
index 431d503..9164274 100644
--- a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/env/CustomPartialResponseWriter.java
+++ b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/env/CustomPartialResponseWriter.java
@@ -36,7 +36,7 @@ import javax.faces.context.ResponseWriter;
  */
 public class CustomPartialResponseWriter extends PartialResponseWriter {
 
-    private final Map<String, JSUpdateHandler> customJSUpdates;
+    private final Map<String, String> customJSUpdates;
 
     public CustomPartialResponseWriter(ResponseWriter wrapped) {
         super(wrapped);
@@ -47,11 +47,11 @@ public class CustomPartialResponseWriter extends PartialResponseWriter {
     public void endDocument() throws IOException {
         if (!customJSUpdates.isEmpty()) {
             startExtension(Collections.singletonMap("id", "jsupdates"));
-            for (Map.Entry<String, JSUpdateHandler> entry : customJSUpdates.entrySet()) {
+            for (Map.Entry<String, String> entry : customJSUpdates.entrySet()) {
                 String componentId = entry.getKey();
                 startElement("jsupdate", null);
                 writeAttribute("src", componentId, null);
-                write(entry.getValue().getUpdate());
+                write(entry.getValue());
                 endElement("jsupdate");
             }
             endExtension();
@@ -60,13 +60,13 @@ public class CustomPartialResponseWriter extends PartialResponseWriter {
         super.endDocument();
     }
 
-    public void addCustomJSUpdate(String componentId, JSUpdateHandler updateHandler) {
-        customJSUpdates.put(componentId, updateHandler);
+    public void addCustomJSUpdate(String key, String jsUpdate) {
+        customJSUpdates.put(key, jsUpdate);
     }
 
-    public void addCustomJSUpdate(JSUpdateHandler updateHandler) {
+    public void addCustomJSUpdate(String jsUpdate) {
         String sourceComponentId = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("javax.faces.source");
-        addCustomJSUpdate(sourceComponentId, updateHandler);
+        addCustomJSUpdate(sourceComponentId, jsUpdate);
     }
 
     public static CustomPartialResponseWriter getCurrentInstance() {
diff --git a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/env/JSUpdateHandler.java b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/env/JSUpdateHandler.java
deleted file mode 100644
index dc63045..0000000
--- a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/env/JSUpdateHandler.java
+++ /dev/null
@@ -1,32 +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.webapp.env;
-
-/**
- *
- * @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
- */
-public abstract class JSUpdateHandler {
-
-    public abstract String getUpdate();
-}
diff --git a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/env/UIModal.java b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/env/UIModal.java
deleted file mode 100644
index 5444db3..0000000
--- a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/env/UIModal.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * _____________________________________________________________________________
- * 
- * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of
- * Trieste INAF - IA2 Italian Center for Astronomical Archives
- * _____________________________________________________________________________
- * 
- * Copyright (C) 2017 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.webapp.env;
-
-import java.io.IOException;
-import javax.faces.component.FacesComponent;
-import javax.faces.component.UIComponentBase;
-import javax.faces.context.FacesContext;
-import javax.faces.context.ResponseWriter;
-
-/**
- *
- * @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
- */
-@FacesComponent(tagName = "modal", namespace = "http://ia2.inaf.it/component", createTag = true)
-public class UIModal extends UIComponentBase {
-
-    public static abstract class StatusObserver {
-
-        public abstract void statusChanged(boolean isOpen);
-    }
-
-    @Override
-    public void decode(FacesContext context) {
-
-        if (getAttributes().containsKey("status-observer")) {
-            StatusObserver status = (StatusObserver) getAttributes().get("status-observer");
-            boolean open = Boolean.parseBoolean((String) getAttributes().get("open"));
-            status.statusChanged(open);
-        }
-    }
-
-    @Override
-    public String getFamily() {
-        return "modal";
-    }
-
-    @Override
-    public void encodeBegin(FacesContext context) throws IOException {
-        ResponseWriter writer = context.getResponseWriter();
-        writer.write("<div class=\"modal fade\" tabindex=\"-1\" role=\"dialog\" id=\"");
-        writer.write(getClientId());
-        writer.write("\">");
-    }
-
-    @Override
-    public void encodeEnd(FacesContext context) throws IOException {
-        ResponseWriter writer = context.getResponseWriter();
-        writer.write("</div>");
-    }
-}
diff --git a/TASMAN-webapp/src/main/webapp/credentialsEditing.xhtml b/TASMAN-webapp/src/main/webapp/credentialsEditing.xhtml
index fe29f2c..ab1f7da 100644
--- a/TASMAN-webapp/src/main/webapp/credentialsEditing.xhtml
+++ b/TASMAN-webapp/src/main/webapp/credentialsEditing.xhtml
@@ -10,6 +10,8 @@
     <ui:define name="scripts">
         <h:outputScript library="js" name="credentials.js"></h:outputScript>
         <h:outputScript library="js" name="ucd-editor.js"></h:outputScript>
+        <h:outputScript library="js" name="async-loader.js"></h:outputScript>
+        <script>TSM.asyncLoader.init(#{tapSchemaLoader.loading});</script>
     </ui:define>
     <ui:define name="content">
         <f:event listener="#{loggedInChecker.checkFromNonIndex()}" type="preRenderView" />
@@ -26,57 +28,62 @@
                 </div>
 
                 <h:panelGroup id="saved-credentials">
-                    <ui:repeat value="#{credentialsInsertion.savedCredentials}" var="c" varStatus="loop">
-                        <div class="panel panel-default">
-                            <div class="panel-body">
-                                <h:panelGroup rendered="#{c.class.simpleName eq 'Credentials'}">
-                                    <div class="col-xs-10">
-                                        <h:commandLink action="#{credentialsInsertion.removeCredentials(loop.index)}" title="Delete">
-                                            <span class="glyphicon glyphicon-trash"></span>
-                                            <f:ajax execute="@this" render="@form" />
-                                        </h:commandLink>
-                                        <h:commandLink action="#{credentialsInsertion.editCredentials(c, loop.index)}" title="Edit">
-                                            <span class="glyphicon glyphicon-pencil"></span>
-                                            <f:ajax execute="@this" render=":main:credentials-modal-body" onevent="credentials.editClicked" />
-                                        </h:commandLink>
-                                        (${c.databaseType eq 'MYSQL' ? 'MySQL' : 'Postgres'}) ${c.hostname}:${c.port} ${c.username}
-                                    </div>
-                                    <div class="col-xs-2 text-right">
-                                        <h:commandLink action="#{credentialsInsertion.loginWithJoinedCredentials(c)}" title="Login" immediate="true">
-                                            <span class="glyphicon glyphicon-log-in"></span>
-                                        </h:commandLink>
-                                    </div>
-                                </h:panelGroup>
-                                <h:panelGroup rendered="#{c.class.simpleName eq 'SeparateCredentials'}">
-                                    <div class="col-xs-10">
-                                        <h:commandLink action="#{credentialsInsertion.removeCredentials(loop.index)}" title="Delete">
-                                            <span class="glyphicon glyphicon-trash"></span>
-                                            <f:ajax execute="@this" render="@form" />
-                                        </h:commandLink>
-                                        <h:commandLink action="#{credentialsInsertion.editSeparateCredentials(c, loop.index)}" title="Edit">
-                                            <span class="glyphicon glyphicon-pencil"></span>
-                                            <f:ajax execute="@this" render=":main:credentials-modal-body" onevent="credentials.editClicked" />
-                                        </h:commandLink>
-                                        <strong>Source</strong>
-                                        (${c.sourceCredentials.databaseType eq 'MYSQL' ? 'MySQL' : 'Postgres'}) ${c.sourceCredentials.hostname}:${c.sourceCredentials.port} ${c.sourceCredentials.username}
-                                        <strong>TAP_SCHEMA</strong>
-                                        (${c.tapSchemaCredentials.databaseType eq 'MYSQL' ? 'MySQL' : 'Postgres'}) ${c.tapSchemaCredentials.hostname}:${c.tapSchemaCredentials.port} ${c.tapSchemaCredentials.username}
-                                    </div>
-                                    <div class="col-xs-2 text-right">
-                                        <h:commandLink  action="#{credentialsInsertion.loginWithSeparatedCredentials(c.sourceCredentials, c.tapSchemaCredentials)}" title="Login" immediate="true">
-                                            <span class="glyphicon glyphicon-log-in"></span>
-                                        </h:commandLink>
-                                    </div>
-                                </h:panelGroup>
-                            </div>
-                        </div>
-                    </ui:repeat>
+
+                    <h:panelGroup rendered="#{credentialsInsertion.savedCredentials.size() gt 0}">
+                        <table class="table table-striped"> 
+                            <thead>
+                                <tr>
+                                    <th></th>
+                                    <th>Credentials</th>
+                                    <th>TAP_SCHEMA name</th>
+                                    <th>Version</th>
+                                    <th>Obscore</th>
+                                    <th>Login</th>
+                                </tr>
+                            </thead>
+                            <tbody>
+                                <ui:repeat value="#{credentialsInsertion.savedCredentials}" var="c" varStatus="loop">
+                                    <tr>
+                                        <td>
+                                            <h:commandLink action="#{credentialsInsertion.openDeleteCredentialsConfirmation(loop.index)}" title="Delete" class="text-danger">
+                                                <span class="glyphicon glyphicon-trash"></span>
+                                                <f:ajax execute="@this" render="@form" onevent="credentials.openConfirmDeleteModal" />
+                                            </h:commandLink>
+                                            <h:commandLink action="#{credentialsInsertion.editCredentials(loop.index)}" title="Edit">
+                                                <span class="glyphicon glyphicon-pencil"></span>
+                                                <f:ajax execute="@this" render=":main:credentials-modal-body" onevent="credentials.editClicked" />
+                                            </h:commandLink>
+                                        </td>
+                                        <td>
+                                            <h:panelGroup rendered="#{c.class.simpleName eq 'JoinedCredentials'}">
+                                                <tsm_components:print_credentials credentials="#{c.credentials}" />
+                                            </h:panelGroup>
+                                            <h:panelGroup rendered="#{c.class.simpleName eq 'SeparatedCredentials'}">
+                                                <tsm_components:print_credentials credentials="#{c.sourceCredentials}" />
+                                                <span class="glyphicon glyphicon-arrow-right"></span>
+                                                <tsm_components:print_credentials credentials="#{c.tapSchemaCredentials}" />
+                                            </h:panelGroup>
+                                        </td>
+                                        <td>#{c.tapSchemaName}</td>
+                                        <td>#{c.tapSchemaVersion}</td>
+                                        <td><span class="glyphicon glyphicon-#{c.hasObscore ? 'ok':'remove'}"></span></td>
+                                        <td>
+                                            <h:commandLink  action="#{credentialsInsertion.loadTapSchema(c)}" title="Login" immediate="true">
+                                                <span class="glyphicon glyphicon-log-in"></span>
+                                                <f:ajax execute="@form" render="@form" onevent="TSM.asyncLoader.openTapSchemaClicked" />
+                                            </h:commandLink>
+                                        </td>
+                                    </tr>
+                                </ui:repeat>
+                            </tbody>
+                        </table>
+                    </h:panelGroup>
 
                     <p class="text-danger text-center"><strong><h:message for="main" /></strong></p>
 
                     <div class="text-center">
                         <br/><br/>
-                        <h:commandLink class="btn btn-success" action="#{credentialsInsertion.addNewCredentials()}">
+                        <h:commandLink class="btn btn-success" action="#{credentialsInsertion.addNewCredentialsInEditing()}">
                             <span class="glyphicon glyphicon-plus"></span>
                             Add new database credentials
                             <f:ajax execute="@this" render="credentials-modal-body" onevent="credentials.editClicked" />
@@ -84,7 +91,7 @@
                     </div>
                 </h:panelGroup>
 
-                <ia2:modal id="credentials-modal" visibility-status="#{credentialsInsertion.credentialsDialogStatus}">
+                <div class="modal fade" tabindex="-1" role="dialog" id="credentials-modal">
                     <div class="modal-dialog">
                         <div class="modal-content">
                             <div class="modal-header">
@@ -100,7 +107,7 @@
                                                 <h3 class="panel-title">Source credentials</h3>
                                             </div>
                                             <div class="panel-body">
-                                                <h:panelGroup layout="block" class="form-horizontal" id="source_credentials">
+                                                <h:panelGroup layout="block" class="form-horizontal" id="source_credentials" rendered="#{credentialsInsertion.sourceCredentials ne null}">
                                                     <div class="form-group">
                                                         <h:outputLabel for="source_dbtype" class="#{credentialsInsertion.separateCredentials ? 'col-xs-4': 'col-xs-3'} control-label">Database type</h:outputLabel>
                                                         <div class="#{credentialsInsertion.separateCredentials ? 'col-xs-8': 'col-xs-9'}">
@@ -114,21 +121,21 @@
                                                     <div class="form-group">
                                                         <h:outputLabel for="source_hostname" class="#{credentialsInsertion.separateCredentials ? 'col-xs-4': 'col-xs-3'} control-label">Hostname</h:outputLabel>
                                                         <div class="#{credentialsInsertion.separateCredentials ? 'col-xs-8': 'col-xs-9'}">
-                                                            <h:inputText id="source_hostname" value="#{credentialsInsertion.sourceCredentials.hostname}" class="form-control" required="#{credentialsInsertion.credentialsDialogOpened}" requiredMessage="Hostname is required"/>
+                                                            <h:inputText id="source_hostname" value="#{credentialsInsertion.sourceCredentials.hostname}" class="form-control" />
                                                             <h:message for="source_hostname" class="text-danger" /> 
                                                         </div>
                                                     </div>
                                                     <div class="form-group">
                                                         <h:outputLabel for="source_port" class="#{credentialsInsertion.separateCredentials ? 'col-xs-4': 'col-xs-3'} control-label">Port</h:outputLabel>
                                                         <div class="#{credentialsInsertion.separateCredentials ? 'col-xs-8': 'col-xs-9'}">
-                                                            <h:inputText id="source_port" value="#{credentialsInsertion.sourceCredentials.port}" class="form-control" required="#{credentialsInsertion.credentialsDialogOpened}" requiredMessage="Port is required"/>
+                                                            <h:inputText id="source_port" value="#{credentialsInsertion.sourceCredentials.port}" class="form-control" />
                                                             <h:message for="source_port" class="text-danger" /> 
                                                         </div>
                                                     </div>
                                                     <div class="form-group">
                                                         <h:outputLabel for="source_username" class="#{credentialsInsertion.separateCredentials ? 'col-xs-4': 'col-xs-3'} control-label">Username</h:outputLabel>
                                                         <div class="#{credentialsInsertion.separateCredentials ? 'col-xs-8': 'col-xs-9'}">
-                                                            <h:inputText id="source_username" value="#{credentialsInsertion.sourceCredentials.username}" required="#{credentialsInsertion.credentialsDialogOpened}" class="form-control" requiredMessage="Username is required"/>
+                                                            <h:inputText id="source_username" value="#{credentialsInsertion.sourceCredentials.username}" class="form-control" />
                                                             <h:message for="source_username" class="text-danger" /> 
                                                         </div>
                                                     </div>
@@ -151,7 +158,7 @@
                                         </div>
                                     </div>
                                     <div class="#{credentialsInsertion.separateCredentials ? 'col-xs-6':'col-xs-12'}">
-                                        <h:panelGroup layout="block" class="panel panel-primary" rendered="#{credentialsInsertion.separateCredentials}">
+                                        <h:panelGroup layout="block" class="panel panel-primary" rendered="#{credentialsInsertion.separateCredentials and credentialsInsertion.tapSchemaCredentials ne null}">
                                             <h:panelGroup layout="block" class="panel-heading" rendered="#{credentialsInsertion.separateCredentials}">
                                                 <h3 class="panel-title">TAP_SCHEMA credentials</h3>
                                             </h:panelGroup>
@@ -170,21 +177,21 @@
                                                     <div class="form-group">
                                                         <h:outputLabel for="tap_schema_hostname" class="#{credentialsInsertion.separateCredentials ? 'col-xs-4': 'col-xs-3'} control-label">Hostname</h:outputLabel>
                                                         <div class="#{credentialsInsertion.separateCredentials ? 'col-xs-8': 'col-xs-9'}">
-                                                            <h:inputText id="tap_schema_hostname" value="#{credentialsInsertion.tapSchemaCredentials.hostname}" required="#{credentialsInsertion.credentialsDialogOpened}" class="form-control" requiredMessage="Hostname is required"/>
+                                                            <h:inputText id="tap_schema_hostname" value="#{credentialsInsertion.tapSchemaCredentials.hostname}" class="form-control" />
                                                             <h:message for="tap_schema_hostname" class="text-danger" /> 
                                                         </div>
                                                     </div>
                                                     <div class="form-group">
                                                         <h:outputLabel for="tap_schema_port" class="#{credentialsInsertion.separateCredentials ? 'col-xs-4': 'col-xs-3'} control-label">Port</h:outputLabel>
                                                         <div class="#{credentialsInsertion.separateCredentials ? 'col-xs-8': 'col-xs-9'}">
-                                                            <h:inputText id="tap_schema_port" value="#{credentialsInsertion.tapSchemaCredentials.port}" required="#{credentialsInsertion.credentialsDialogOpened}" class="form-control" requiredMessage="Port is required"/>
+                                                            <h:inputText id="tap_schema_port" value="#{credentialsInsertion.tapSchemaCredentials.port}" class="form-control" />
                                                             <h:message for="tap_schema_port" class="text-danger" /> 
                                                         </div>
                                                     </div>
                                                     <div class="form-group">
                                                         <h:outputLabel for="tap_schema_username" class="#{credentialsInsertion.separateCredentials ? 'col-xs-4': 'col-xs-3'} control-label">Username</h:outputLabel>
                                                         <div class="#{credentialsInsertion.separateCredentials ? 'col-xs-8': 'col-xs-9'}">
-                                                            <h:inputText id="tap_schema_username" value="#{credentialsInsertion.tapSchemaCredentials.username}" required="#{credentialsInsertion.credentialsDialogOpened}" class="form-control" requiredMessage="Username is required"/>
+                                                            <h:inputText id="tap_schema_username" value="#{credentialsInsertion.tapSchemaCredentials.username}" class="form-control" />
                                                             <h:message for="tap_schema_username" class="text-danger" /> 
                                                         </div>
                                                     </div>
@@ -212,7 +219,7 @@
                                     <div class="form-group">
                                         <label class="col-xs-6 col-xs-offset-4">
                                             <h:selectBooleanCheckbox value="#{credentialsInsertion.separateCredentials}" id="separate-credentials">
-                                                <f:ajax render="credentials_panels_wrapper" execute="@this" onevent="credentials.separateCredentialsChanged" />
+                                                <f:ajax render="credentials_panels_wrapper" execute="@form" onevent="credentials.separateCredentialsChanged" />
                                             </h:selectBooleanCheckbox>
                                             Separate credentials
                                         </label>
@@ -220,14 +227,15 @@
                                     <div class="form-group">
                                         <h:outputLabel for="tap_schema_name" class="control-label col-xs-4">TAP_SCHEMA name</h:outputLabel>
                                         <div class="col-xs-6">
-                                            <h:inputText value="#{credentialsInsertion.tapSchemaName}" class="form-control" />
+                                            <h:inputText value="#{credentialsInsertion.tapSchemaName}" id="tap_schema_name" class="form-control" />
+                                            <h:message for="tap_schema_name" class="text-danger" />
                                         </div>
                                     </div>
                                     <div class="form-group">
-                                        <h:outputLabel for="tap_schema_name" class="control-label col-xs-4">TAP_SCHEMA version</h:outputLabel>
+                                        <h:outputLabel for="tap_schema_version" class="control-label col-xs-4">TAP_SCHEMA version</h:outputLabel>
                                         <div class="col-xs-6">
                                             <h:selectOneMenu value="#{credentialsInsertion.tapSchemaVersion}" class="form-control">
-                                                <f:selectItems value="#{credentialsInsertion.tapSchemaVersions}" var="version" itemLabel="#{version}" itemDescription="#{version}" />
+                                                <f:selectItems value="#{credentialsInsertion.tapSchemaVersions}" var="version" itemLabel="#{version}" itemDescription="#{version}" id="tap_schema_version" />
                                             </h:selectOneMenu>
                                         </div>
                                     </div>
@@ -248,10 +256,53 @@
                             </div>
                         </div>
                     </div>
-                </ia2:modal>
+                </div>
+
+                <div class="modal fade" tabindex="-1" role="dialog" id="modal-confirm-credentials-deletion">
+                    <div class="modal-dialog" role="document">
+                        <div class="modal-content">
+                            <div class="modal-header">
+                                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&#215;</span></button>
+                                <h4 class="modal-title">Confirm deletion</h4>
+                            </div>
+                            <div class="modal-body">
+                                <p>Do you really want to delete this credentials?</p>
+                            </div>
+                            <div class="modal-footer">
+                                <h:commandButton class="btn btn-danger" value="Confirm" action="#{credentialsInsertion.confirmCredentialsDeletion()}">
+                                    <f:ajax execute="@form" render=":main:saved-credentials" onevent="credentials.closeConfirmDeleteModal" />
+                                </h:commandButton>
+                            </div>
+                        </div>
+                    </div>
+                </div>
 
                 <tsm_components:ucd_editor id="ucd-editor" />
             </div>
+
+            <div class="modal fade" tabindex="-1" role="dialog" id="modal-confirm-ts-creation">
+                <div class="modal-dialog" role="document">
+                    <div class="modal-content">
+                        <div class="modal-header">
+                            <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&#215;</span></button>
+                            <h4 class="modal-title">Create TAP_SCHEMA</h4>
+                        </div>
+                        <div class="modal-body">
+                            The TAP_SCHEMA <strong>#{tapSchemaLoader.tapCredentials.tapSchemaName}</strong> doesn't exists. Do you want to create it?
+                        </div>
+                        <div class="modal-footer">
+                            <h:commandButton class="btn btn-success" value="Yes" action="#{tapSchemaLoader.create()}">
+                                <f:ajax execute="@this" render="@none" onevent="TSM.asyncLoader.tapSchemaCreationConfirmed" />
+                            </h:commandButton>
+                            <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </h:form>
+
+        <h:form id="async-loader" class="hide">
+            <h:commandButton action="#{tapSchemaLoader.openLoaded()}" id="open-loaded" />
         </h:form>
     </ui:define>
 </ui:composition>
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 0f2e31d..d3eda57 100644
--- a/TASMAN-webapp/src/main/webapp/resources/js/async-loader.js
+++ b/TASMAN-webapp/src/main/webapp/resources/js/async-loader.js
@@ -27,8 +27,20 @@
         init: function (l) {
             loading = l;
         },
-        startChecking: function (event) {
+        openTapSchemaClicked: function (event) {
             if (event.status === 'success' && $('.validation-message').length === 0) {
+                var $tsExistenceEl = $(event.responseXML).find('jsupdate[src="tap_schema_existence"]');
+                if ($tsExistenceEl.length === 1) {
+                    if ($tsExistenceEl.text() === 'true') {
+                        periodicCheck();
+                    } else {
+                        $('#modal-confirm-ts-creation').modal('show');
+                    }
+                }
+            }
+        },
+        tapSchemaCreationConfirmed: function (event) {
+            if (event.status === 'success') {
                 periodicCheck();
             }
         }
diff --git a/TASMAN-webapp/src/main/webapp/resources/js/common.js b/TASMAN-webapp/src/main/webapp/resources/js/common.js
index c525d2d..1ca96ad 100644
--- a/TASMAN-webapp/src/main/webapp/resources/js/common.js
+++ b/TASMAN-webapp/src/main/webapp/resources/js/common.js
@@ -89,7 +89,8 @@
 
             // Setup loading animation
             jsf.ajax.addOnEvent(function (data) {
-                if ($(data.source).is('input[type="text"]')) {
+                if ($(data.source).is('input[type="text"]') ||
+                        $(data.source).is('[data-jsf-modal]')) {
                     return; // special case
                 }
                 switch (data.status) {
diff --git a/TASMAN-webapp/src/main/webapp/resources/js/credentials.js b/TASMAN-webapp/src/main/webapp/resources/js/credentials.js
index 5fb483c..bd8ce12 100644
--- a/TASMAN-webapp/src/main/webapp/resources/js/credentials.js
+++ b/TASMAN-webapp/src/main/webapp/resources/js/credentials.js
@@ -2,19 +2,19 @@
 
     function checkSeparateCredentials() {
         var separateCredentials = $('#main\\:separate-credentials').is(':checked');
-        $('#main\\:credentials-modal .modal-dialog').toggleClass('modal-lg', separateCredentials);
+        $('#credentials-modal .modal-dialog').toggleClass('modal-lg', separateCredentials);
     }
 
     window.credentials = {
         editClicked: function (event) {
             if (event.status === 'success') {
-                $('#main\\:credentials-modal').modal('show');
+                $('#credentials-modal').modal('show');
             }
         },
         credentialsSaved: function (event) {
             if (event.status === 'success') {
-                if ($('#main\\:credentials-modal .text-danger').length === 0) {
-                    $('#main\\:credentials-modal').modal('hide');
+                if ($('#credentials-modal .text-danger').length === 0) {
+                    $('#credentials-modal').modal('hide');
                 }
             }
         },
@@ -22,21 +22,25 @@
             if (event.status === 'success') {
                 checkSeparateCredentials();
             }
+        },
+        openConfirmDeleteModal: function (event) {
+            if (event.status === 'success') {
+                $('#modal-confirm-credentials-deletion').modal('show');
+            }
+        },
+        closeConfirmDeleteModal: function (event) {
+            if (event.status === 'success') {
+                $('#modal-confirm-credentials-deletion').modal('hide');
+            }
         }
     };
 
     $(document).ready(function () {
-        $('body').on('show.bs.modal', '#main\\:credentials-modal', function ( ) {
+        $('body').on('show.bs.modal', '#credentials-modal', function ( ) {
             checkSeparateCredentials();
         });
-//        $('body').on('shown.bs.modal', '#main\\:credentials-modal', function ( ) {
-//            $.post(TSM.getRestPath("credentialsDialog?opened=true"));
-//        });
-//        $('body').on('hidden.bs.modal', '#main\\:credentials-modal', function ( ) {
-//            $.post(TSM.getRestPath("credentialsDialog?opened=false"));
-//        });
 
-        $('body').on('keyup', '#main\\:credentials-modal input', function (event) {
+        $('body').on('keyup', '#credentials-modal input', function (event) {
             if (event.keyCode === 13) {
                 $('#main\\:save-credentials').click();
                 event.preventDefault();
diff --git a/TASMAN-webapp/src/main/webapp/resources/tsm_components/print_credentials.xhtml b/TASMAN-webapp/src/main/webapp/resources/tsm_components/print_credentials.xhtml
new file mode 100644
index 0000000..cbcf1a9
--- /dev/null
+++ b/TASMAN-webapp/src/main/webapp/resources/tsm_components/print_credentials.xhtml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:composite="http://java.sun.com/jsf/composite">
+
+    <composite:interface>
+        <composite:attribute name="credentials" type="it.inaf.ia2.tsm.datalayer.Credentials" required="true" />
+    </composite:interface>
+
+    <composite:implementation>
+        (${cc.attrs.credentials.databaseType eq 'MYSQL' ? 'MySQL' : 'Postgres'}) ${cc.attrs.credentials.hostname}:${cc.attrs.credentials.port} ${cc.attrs.credentials.username}
+    </composite:implementation>
+</html>
diff --git a/TASMAN-webapp/src/main/webapp/schemaSelection.xhtml b/TASMAN-webapp/src/main/webapp/schemaSelection.xhtml
deleted file mode 100644
index c547e56..0000000
--- a/TASMAN-webapp/src/main/webapp/schemaSelection.xhtml
+++ /dev/null
@@ -1,127 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<ui:composition template="/WEB-INF/templates/master.xhtml"
-                xmlns="http://www.w3.org/1999/xhtml"
-                xmlns:f="http://java.sun.com/jsf/core"
-                xmlns:h="http://java.sun.com/jsf/html"
-                xmlns:ui="http://java.sun.com/jsf/facelets" 
-                xmlns:tsm_components="http://xmlns.jcp.org/jsf/composite/tsm_components">
-    <ui:define name="title">TASMAN - Schemata selection page</ui:define>
-    <ui:define name="scripts">
-        <h:outputScript library="js" name="ucd-editor.js"></h:outputScript>
-        <h:outputScript library="js" name="async-loader.js"></h:outputScript>
-        <script>TSM.asyncLoader.init(#{schemaSelection.loading});</script>
-    </ui:define>
-    <ui:define name="content">
-
-        <f:event listener="#{loggedInChecker.checkFromNonIndex()}" type="preRenderView" />
-        <f:event listener="#{schemaSelection.onPageLoad()}" type="preRenderView" />
-
-        <h:form id="main">
-
-            <tsm_components:user_navbar />
-
-            <div class="container">
-                <h1 class="text-center">Schemata selection page</h1>
-                <br/>
-
-                <f:passThroughAttribute name="autocomplete" value="off" />
-                <div class="panel panel-default col-sm-10 col-sm-offset-1">
-                    <div class="panel-body">
-                        <div class="row">
-                            <div class="col-sm-2 text-right">
-                                <strong>Action:</strong>
-                            </div>
-                            <div class="form-inline col-sm-10">
-                                <h:selectOneRadio value="#{schemaSelection.selectedRadioOption}">
-                                    <f:selectItem itemValue="edit" itemLabel="Edit existing" />
-                                    <f:selectItem itemValue="create" itemLabel="Create new" />
-                                    <f:ajax event="click" render="main:radioPanels"></f:ajax>
-                                </h:selectOneRadio>
-                            </div>
-                        </div>
-                        <br/>
-
-                        <h:panelGroup id="radioPanels">
-                            <!-- Edit -->
-                            <h:panelGroup rendered="#{schemaSelection.selectedRadioOption eq 'edit'}">
-                                <div id="editContainer">
-                                    <div class="form-group">
-                                        <h:outputLabel for="selectedTAPSchema">Tap Schema:</h:outputLabel>
-                                        <h:selectOneMenu value="#{schemaSelection.selectedTAPSchema}" id="selectedTAPSchema" class="form-control">
-                                            <f:selectItems value="#{schemaSelection.allTAPSchemas}"></f:selectItems>
-                                            <f:ajax event="change" render="main:exposedSchemas" listener="#{schemaSelection.selectedTAPSchemaChanged}"></f:ajax>
-                                        </h:selectOneMenu>
-                                    </div>
-                                    <div class="form-group" id="exposedDatabasesWrapper">
-                                        <label class="control-label">Exposed databases:</label>
-
-                                        <p class="form-control-static" id="exposed-schemas">
-                                            <h:panelGroup id="exposedSchemas">#{schemaSelection.exposedSchemas}</h:panelGroup>
-                                        </p>
-                                    </div>
-                                    <div class="form-group">
-                                        <h:commandButton value="Edit Tapschema" class="btn btn-primary" action="#{schemaSelection.edit()}">
-                                            <f:ajax execute="@form" render="@form" onevent="TSM.asyncLoader.startChecking" />
-                                        </h:commandButton>
-                                    </div>
-                                </div>
-                            </h:panelGroup>
-
-                            <!-- Create -->
-                            <h:panelGroup rendered="#{schemaSelection.selectedRadioOption eq 'create'}">
-                                <div id="createContainer">
-                                    <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 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">
-                                        <h:outputLabel for="selectedSchemas">Databases to expose:</h:outputLabel>
-                                        <h:selectManyListbox value="#{schemaSelection.selectedSchemas}" id="selectedSchemas" class="form-control" size="7" validatorMessage="Select at least one schema">
-                                            <f:selectItems value="#{schemaSelection.allSchemas}"></f:selectItems>
-                                            <f:validateRequired></f:validateRequired>
-                                        </h:selectManyListbox>
-                                        <h:message for="selectedSchemas" class="text-danger validation-message"></h:message>
-                                    </div>
-
-                                    <div class="form-group">
-                                        <h:commandButton value="Create TAP_SCHEMA" class="btn btn-primary" action="#{schemaSelection.create()}">
-                                            <f:ajax execute="@form" render="@form" onevent="TSM.asyncLoader.startChecking" />
-                                        </h:commandButton>
-                                    </div>
-                                </div>
-                            </h:panelGroup>
-                        </h:panelGroup>
-                    </div>
-                </div>
-
-                <ui:remove>
-                    <div class="row">
-                        <div class="col-sm-10 col-sm-offset-1">
-                            <h:commandLink action="#{schemaSelection.logout()}" class="btn btn-danger pull-right" immediate="true">
-                                <span class="glyphicon glyphicon-log-out"></span>
-                                Close session
-                            </h:commandLink>
-                        </div>
-                    </div>
-                </ui:remove>
-            </div>
-
-            <tsm_components:ucd_editor id="ucd-editor" />
-        </h:form>
-
-        <h:form id="async-loader" class="hide">
-            <h:commandButton action="#{schemaSelection.openLoaded()}" id="open-loaded" />
-        </h:form>
-    </ui:define>
-</ui:composition>
\ No newline at end of file
diff --git a/TASMAN-webapp/src/main/webapp/tapSchemaEditing.xhtml b/TASMAN-webapp/src/main/webapp/tapSchemaEditing.xhtml
index aa37b0f..d36e1df 100644
--- a/TASMAN-webapp/src/main/webapp/tapSchemaEditing.xhtml
+++ b/TASMAN-webapp/src/main/webapp/tapSchemaEditing.xhtml
@@ -11,7 +11,7 @@
         <h:outputScript library="js" name="edit-tapschema.js"></h:outputScript>
         <h:outputScript library="js" name="ucd-editor.js"></h:outputScript>
         <h:outputScript library="js" name="async-loader.js"></h:outputScript>
-        <script>TSM.asyncLoader.init(#{schemaSelection.loading});</script>
+        <script>TSM.asyncLoader.init(#{tapSchemaLoader.loading});</script>
     </ui:define>
     <ui:define name="content">
         <f:event listener="#{loggedInChecker.checkFromNonIndex()}" type="preRenderView" />
@@ -852,7 +852,7 @@
         </div>
 
         <h:form id="async-loader" class="hide">
-            <h:commandButton action="#{schemaSelection.openLoaded()}" id="open-loaded" />
+            <h:commandButton action="#{tapSchemaLoader.openLoaded()}" id="open-loaded" />
         </h:form>
     </ui:define>
 </ui:composition>
\ No newline at end of file
-- 
GitLab