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 f0639af4d5ea161f0929455f38a59871ca7c1e19..abde2e34f44a4a14840f8b79da4e868928972ca3 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
@@ -306,4 +306,38 @@ public class TSMUtil {
 
         return sb.toString();
     }
+
+    /**
+     * Utility class for joining a collection of object properties.
+     */
+    public static class StringJoiner<T> {
+
+        private final Iterable<T> values;
+        private final String separator;
+
+        public StringJoiner(Iterable<T> values, String separator) {
+            this.values = values;
+            this.separator = separator;
+        }
+
+        public final String getString() {
+            StringBuilder sb = new StringBuilder();
+            boolean first = true;
+            for (T value : values) {
+                if (!first) {
+                    sb.append(separator);
+                }
+                sb.append(getStringValue(value));
+                first = false;
+            }
+            return sb.toString();
+        }
+
+        public String getStringValue(T value) {
+            if (value instanceof String) {
+                return (String) value;
+            }
+            return null;
+        }
+    }
 }
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 54574983c673265ef74e5ab91d504f581ec07995..e4385711c77d278f5540820743bdbd0fd132c1c7 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
@@ -463,7 +463,8 @@ public class TapSchema implements EntitiesContainer<Schema>, Serializable {
             if (obscore) {
                 SchemaModel ivoaSchemaModel = getIvoaSchemaModel();
 
-                broker.createIvoaSchemaStructure(ivoaSchemaModel);
+                // ivoa schema has to be created into source database
+                getSourceDBBroker().createIvoaSchemaStructure(ivoaSchemaModel);
                 // Initializing ivoa schema slot in schemata maps
                 schemas.put(ivoaSchemaModel.getName(), null);
 
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 b7d4cbd7b9f0c839d3434567c5e8848bc330168e..f3b8475b490a605e83cabf016c60a583ce5638fd 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
@@ -74,7 +74,11 @@ public class MySQLDBBroker extends DBBrokerTemplate {
         if (beginIndex != -1) {
             int endIndex = typeWithSize.indexOf(')');
             if (endIndex != -1) {
-                return Integer.parseInt(typeWithSize.substring(beginIndex + 1, endIndex));
+                try {
+                    return Integer.parseInt(typeWithSize.substring(beginIndex + 1, endIndex));
+                } catch (NumberFormatException e) {
+                    return null;
+                }
             }
         }
         return null;
diff --git a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/SearchUCDDialog.java b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/SearchUCDDialog.java
index f42170632062ff77b20d528c48e672b65b2ea51b..55039c5fb0180141a8d58c94966ed5a2dd0ba261 100644
--- a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/SearchUCDDialog.java
+++ b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/SearchUCDDialog.java
@@ -107,6 +107,9 @@ public class SearchUCDDialog implements Serializable {
             String assignResponse = SearchUCD.assign(description);
             if (assignResponse == null) {
                 UCDnotFound = true;
+                selectedUCD = null;
+                suggestedUCD = null;
+                suggestedUCDs.clear();
             } else {
                 selectedUCD = assignResponse;
                 suggestedUCD = assignResponse;
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 bedc26fd1a9ecf0486186f81be8f672fd7bc16ad..0bbac7f52aaf8d16bf140343223d1f5cdbcfa4e8 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
@@ -30,6 +30,7 @@ import it.inaf.ia2.tsm.Key;
 import it.inaf.ia2.tsm.KeyColumn;
 import it.inaf.ia2.tsm.Schema;
 import it.inaf.ia2.tsm.Status;
+import it.inaf.ia2.tsm.TSMUtil;
 import it.inaf.ia2.tsm.Table;
 import it.inaf.ia2.tsm.TapSchema;
 import it.inaf.ia2.tsm.TapSchemaEntity;
@@ -67,6 +68,7 @@ public class TapSchemaEditingBean implements Serializable {
 
     private EntitiesContainer currentAddingContainer;
     private List<AddableItem> currentAddables;
+    private boolean addAlsoAllChildren;
     private VOUnitValidator voUnitValidator;
 
     @Inject
@@ -259,6 +261,7 @@ public class TapSchemaEditingBean implements Serializable {
     }
 
     public void openAddablesModal(EntitiesContainer<?> currentAddingContainer) {
+        this.addAlsoAllChildren = false;
         this.currentAddingContainer = currentAddingContainer;
         this.currentAddables = new ArrayList<>();
         for (String name : currentAddingContainer.getAddableChildrenNames()) {
@@ -277,11 +280,30 @@ public class TapSchemaEditingBean implements Serializable {
         }
     }
 
+    private void addAllChildren(TapSchemaEntity childEntity) throws SQLException {
+        if (childEntity instanceof Schema) {
+            Schema schema = (Schema) childEntity;
+            for (String tableName : schema.getAddableChildrenNames()) {
+                Table table = schema.addChild(tableName);
+                addAllChildren(table);
+            }
+        } else if (childEntity instanceof Table) {
+            Table table = (Table) childEntity;
+            for (String column : table.getAddableChildrenNames()) {
+                table.addChild(column);
+            }
+        }
+    }
+
     public void addSelected() throws SQLException {
         TapSchemaEntity lastAddedEntity = null;
+        boolean canAddChildren = isCanAddChildren();
         for (AddableItem item : currentAddables) {
             if (item.isSelected()) {
                 lastAddedEntity = currentAddingContainer.addChild(item.getName());
+                if (lastAddedEntity != null && canAddChildren) {
+                    addAllChildren(lastAddedEntity);
+                }
             }
         }
         if (lastAddedEntity != null) {
@@ -299,6 +321,22 @@ public class TapSchemaEditingBean implements Serializable {
         return currentAddables;
     }
 
+    public boolean isCanAddChildren() {
+        if (currentAddingContainer == null) {
+            return false;
+        }
+        return currentAddingContainer instanceof TapSchema
+                || currentAddingContainer instanceof Schema;
+    }
+
+    public boolean isAddAlsoAllChildren() {
+        return addAlsoAllChildren;
+    }
+
+    public void setAddAlsoAllChildren(boolean addAlsoAllChildren) {
+        this.addAlsoAllChildren = addAlsoAllChildren;
+    }
+
     public void saveUCD() {
         if (!FacesContext.getCurrentInstance().isValidationFailed()) {
 
@@ -402,4 +440,32 @@ public class TapSchemaEditingBean implements Serializable {
             column.setValue("principal", value ? 1 : 0);
         }
     }
+
+    public List<Key> getVisibleKeys() {
+        List<Key> keys = new ArrayList<>();
+        for (Key key : tapSchema.getAllKeys()) {
+            if (key.isVisible()) {
+                keys.add(key);
+            }
+        }
+        return keys;
+    }
+
+    public String formatFromColumns(Key key) {
+        return (new TSMUtil.StringJoiner<KeyColumn>(key.getKeyColumns(), ", ") {
+            @Override
+            public String getStringValue(KeyColumn kc) {
+                return kc.getFromColumn();
+            }
+        }).getString();
+    }
+
+    public String formatTargetColumns(Key key) {
+        return (new TSMUtil.StringJoiner<KeyColumn>(key.getKeyColumns(), ", ") {
+            @Override
+            public String getStringValue(KeyColumn kc) {
+                return kc.getTargetColumn();
+            }
+        }).getString();
+    }
 }
diff --git a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/UCDEditor.java b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/UCDEditor.java
index 1e1555a06f53f35a8c314c761f78a4e3b072ffa7..6a36cfd42b74278c3200670f70b7c331b3a27dae 100644
--- a/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/UCDEditor.java
+++ b/TASMAN-webapp/src/main/java/it/inaf/ia2/tsm/webapp/UCDEditor.java
@@ -6,7 +6,6 @@ import it.inaf.ia2.tsm.webapp.xmlconfig.UCDConfiguration;
 import java.io.IOException;
 import java.io.Serializable;
 import java.util.List;
-import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 import javax.inject.Named;
 import org.apache.deltaspike.core.api.scope.WindowScoped;
@@ -30,7 +29,7 @@ public class UCDEditor implements Serializable {
     private boolean viewExisting;
     private UCDConfiguration newUCDConfiguration;
     private String invalidUCDMessage;
-    
+
     public void openDialog() {
         viewExisting = true;
         newUCDConfiguration = new UCDConfiguration(user.getUsername());
@@ -76,11 +75,20 @@ public class UCDEditor implements Serializable {
             invalidUCDMessage = "Invalid UCD word syntax";
             return;
         }
-//
-//        newUCDConfiguration = new UCDConfiguration(user.getUsername());
-//        if(config.addUCD(newUCDConfiguration)) {
-//            ne
-//        }
+
+        if (!newUCDConfiguration.getWord().contains(":")) {
+            invalidUCDMessage = "Custom UCDs must have a namespace";
+            return;
+        }
+
+        boolean inserted = config.addUCD(newUCDConfiguration);
+        if (!inserted) {
+            invalidUCDMessage = "Specified UCD already exists";
+            return;
+        }
+
+        newUCDConfiguration = new UCDConfiguration(user.getUsername());
+        invalidUCDMessage = null;
     }
 
     public void removeUCD(UCDConfiguration ucd) {
diff --git a/TASMAN-webapp/src/main/webapp/resources/js/edit-tapschema.js b/TASMAN-webapp/src/main/webapp/resources/js/edit-tapschema.js
index 34cdd9c3a1e586c8baf8b0512c4db1ae0398def9..0146318691ec33efa70c1c4a78b39a00b7f79f20 100644
--- a/TASMAN-webapp/src/main/webapp/resources/js/edit-tapschema.js
+++ b/TASMAN-webapp/src/main/webapp/resources/js/edit-tapschema.js
@@ -4,6 +4,10 @@
         $('#updateOperationsModal').modal('show');
     });
 
+    TSM.displayKeysModal = TSM.eventHandlerFactory(function (srcElement, jsupdate) {
+        $('#keysModal').modal('show');
+    });
+
     TSM.saveUCDCalled = TSM.eventHandlerFactory(function (srcElement, jsupdate) {
         if (jsupdate !== null) {
             $('#searchUCDModal').modal('hide');
diff --git a/TASMAN-webapp/src/main/webapp/resources/tsm_components/ucd_editor.xhtml b/TASMAN-webapp/src/main/webapp/resources/tsm_components/ucd_editor.xhtml
index 9ed13bd898dd6a12f8bd1260a7314fbd42367d72..d65ef2837ab0c7e44d828363905f04cca0878b61 100644
--- a/TASMAN-webapp/src/main/webapp/resources/tsm_components/ucd_editor.xhtml
+++ b/TASMAN-webapp/src/main/webapp/resources/tsm_components/ucd_editor.xhtml
@@ -31,12 +31,12 @@
                                 <ul>
                                     <ui:repeat value="#{ucdEditor.customUCDs}" var="ucd" varStatus="loop">
                                         <li>
-                                            <h:commandLink class="text-danger" action="#{ucdEditor.removeUCD(ucd)}">
+                                            <h:commandLink class="text-danger" action="#{ucdEditor.removeUCD(ucd)}" rendered="#{ucdEditor.isEditable(ucd)}">
                                                 &#215;
                                                 <ui:remove>
                                                     <!-- Note: due to a strange JSF bug following render attribute needs complete component id reference -->
                                                 </ui:remove>
-                                                <f:ajax execute="ucd-editor-body" render="main:ucd-editor:ucd-editor-body" />
+                                                <f:ajax execute="ucd-editor-body" render=":main:ucd-editor:ucd-editor-body" />
                                             </h:commandLink>
                                             [#{ucd.code}] <span title="#{ucd.description}">#{ucd.word}</span>
                                         </li>
diff --git a/TASMAN-webapp/src/main/webapp/tapSchemaEditing.xhtml b/TASMAN-webapp/src/main/webapp/tapSchemaEditing.xhtml
index bfe98e778e9e8a62a31e98e387cf199e183b2d01..b7a428bfd230bbe90e99e1df0fbff689fdb6433b 100644
--- a/TASMAN-webapp/src/main/webapp/tapSchemaEditing.xhtml
+++ b/TASMAN-webapp/src/main/webapp/tapSchemaEditing.xhtml
@@ -25,11 +25,31 @@
             </h1>
 
             <div class="col-sm-6 vpadding text-center">
-                <h:commandLink class="btn btn-info" action="#{tapSchemaEditing.displayUpdateOperations()}">
-                    <span class="glyphicon glyphicon-info-sign"></span>
-                    Display update operations
-                    <f:ajax execute="@form" render="update-operations-form" onevent="TSM.displayUpdateOperations"/>
-                </h:commandLink>
+                <div class="btn-group">
+                    <button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+                        <span class="glyphicon glyphicon-info-sign"></span>
+                        Show <span class="caret"></span>
+                    </button>
+                    <ul class="dropdown-menu">
+                        <li>
+                            <h:commandLink action="#{tapSchemaEditing.displayUpdateOperations()}">
+                                <span class="glyphicon glyphicon-cog"></span>
+                                Update operations
+                                <f:ajax execute="@form" render="update-operations-form" onevent="TSM.displayUpdateOperations"/>
+                            </h:commandLink>
+                        </li>
+                        <li>
+                            <h:commandLink>
+                                <span class="icon-key"></span>
+                                Keys
+                                <ui:remove>
+                                    <!-- Very important: execute="@this", otherwise wrong values will be updated -->
+                                </ui:remove>
+                                <f:ajax execute="@this" render="keys-panel" onevent="TSM.displayKeysModal"/>                                
+                            </h:commandLink>
+                        </li>
+                    </ul>
+                </div>
                 &#160;
                 <h:commandLink class="btn btn-success" action="#{tapSchemaEditing.update()}" id="update-btn">
                     <span class="icon-save"></span>
@@ -366,6 +386,16 @@
                                                                 <f:ajax event="keyup" execute="@form" listener="#{tapSchemaEditing.textInputChanged(tapSchemaEditing.selectedColumn, 'description')}" onevent="TSM.textInputChanged" />
                                                             </h:inputText>
                                                         </div>
+                                                        <h:panelGroup class="form-group" layout="block" rendered="#{tapSchemaEditing.selectedColumn.getProperty('xtype') ne null}">
+                                                            <h:outputLabel for="column_xtype" class="control-label">Xtype:</h:outputLabel>
+                                                            <h:inputText 
+                                                                id="column_xtype"
+                                                                class="form-control #{tapSchemaEditing.selectedColumn.isChanged('xtype') ? 'changed' : ''}"
+                                                                value="#{tapSchemaEditing.selectedColumn.getProperty('xtype').value}">
+                                                                <f:converter converterId="it.inaf.ia2.NullOrEmptyConverter" />
+                                                                <f:ajax event="keyup" execute="@form" listener="#{tapSchemaEditing.textInputChanged(tapSchemaEditing.selectedColumn, 'xtype')}" onevent="TSM.textInputChanged" />
+                                                            </h:inputText>
+                                                        </h:panelGroup>
                                                     </h:panelGroup>
                                                 </h:panelGroup>
                                             </h:panelGroup>
@@ -380,7 +410,7 @@
 
             <div class="modal fade" tabindex="-1" role="dialog" id="addablesModal">
                 <div class="modal-dialog modal-lg">
-                    <div class="modal-content">
+                    <h:panelGroup class="modal-content" id="addables_modal_content" layout="block">
                         <div class="modal-header">
                             <div class="pull-right">
                                 <h:commandLink class="btn btn-default btn-sm" action="#{tapSchemaEditing.checkAllEntities(false)}">
@@ -400,27 +430,85 @@
                         </div>
                         <div class="modal-body">
                             <div class="addables">
-                                <h:panelGroup id="addables_modal_content">
-                                    <h:panelGroup rendered="#{tapSchemaEditing.currentAddingContainer ne null}">
-                                        <ui:repeat value="#{tapSchemaEditing.currentAddables}" var="item">
-                                            <div class="checkbox">
-                                                <label>
-                                                    <h:selectBooleanCheckbox value="#{item.selected}"/>
-                                                    #{item.name}
-                                                </label>
-                                            </div>
-                                        </ui:repeat>
-                                    </h:panelGroup>
+                                <h:panelGroup rendered="#{tapSchemaEditing.currentAddingContainer ne null}">
+                                    <ui:repeat value="#{tapSchemaEditing.currentAddables}" var="item">
+                                        <div class="checkbox">
+                                            <label>
+                                                <h:selectBooleanCheckbox value="#{item.selected}"/>
+                                                #{item.name}
+                                            </label>
+                                        </div>
+                                    </ui:repeat>
                                 </h:panelGroup>
                             </div>
                         </div>
                         <div class="modal-footer">
+                            <h:panelGroup class="checkbox pull-left" layout="block" rendered="#{tapSchemaEditing.canAddChildren}">
+                                <label>
+                                    <h:selectBooleanCheckbox value="#{tapSchemaEditing.addAlsoAllChildren}" /> Add also all children
+                                </label>
+                            </h:panelGroup>
                             <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                             <h:commandLink class="btn btn-primary" action="#{tapSchemaEditing.addSelected}">
                                 Add
                                 <f:ajax execute="@form" render=":main:main_panel" onevent="TSM.entitiesAdded" />
                             </h:commandLink>
                         </div>
+                    </h:panelGroup>
+                </div>
+            </div>
+
+            <div class="modal fade" tabindex="-1" role="dialog" id="keysModal">
+                <div class="modal-dialog modal-lg" 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">Keys</h4>
+                        </div>
+                        <h:panelGroup class="modal-body" layout="block" id="keys-panel">
+                            <table class="table table-striped">
+                                <thead>
+                                    <tr>
+                                        <th>Id</th>
+                                        <th>From table</th>
+                                        <th>From columns</th>
+                                        <th>Target table</th>
+                                        <th>Target columns</th>
+                                        <th>Utype</th>
+                                        <th>Description</th>
+                                    </tr>
+                                </thead>
+                                <tbody>
+                                    <ui:repeat value="#{tapSchemaEditing.visibleKeys}" var="key">
+                                        <tr>
+                                            <td>#{key.id}</td>
+                                            <td>#{key.fromTableCompleteName}</td>
+                                            <td>#{tapSchemaEditing.formatFromColumns(key)}</td>
+                                            <td>#{key.targetTableCompleteName}</td>
+                                            <td>#{tapSchemaEditing.formatTargetColumns(key)}</td>
+                                            <td>
+                                                <h:inputText 
+                                                    id="key_utype"
+                                                    class="form-control #{key.isChanged('utype') ? 'changed' : ''}"
+                                                    value="#{key.getProperty('utype').value}">
+                                                    <f:converter converterId="it.inaf.ia2.NullOrEmptyConverter" />
+                                                    <f:ajax event="keyup" execute="@form" listener="#{tapSchemaEditing.textInputChanged(key, 'utype')}" onevent="TSM.textInputChanged" />
+                                                </h:inputText>
+                                            </td>
+                                            <td>
+                                                <h:inputText 
+                                                    id="key_description"
+                                                    class="form-control #{key.isChanged('description') ? 'changed' : ''}"
+                                                    value="#{key.getProperty('description').value}">
+                                                    <f:converter converterId="it.inaf.ia2.NullOrEmptyConverter" />
+                                                    <f:ajax event="keyup" execute="@form" listener="#{tapSchemaEditing.textInputChanged(key, 'description')}" onevent="TSM.textInputChanged" />
+                                                </h:inputText>
+                                            </td>
+                                        </tr>
+                                    </ui:repeat>
+                                </tbody>
+                            </table>
+                        </h:panelGroup>
                     </div>
                 </div>
             </div>