diff --git a/.gitignore b/.gitignore
index 7c8041bcc2451773e574b119d7a2584292980f25..f7db4b641de813a678b90840deee40b361228a41 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,10 +3,4 @@ __pycache__
 pages/application/DecisionTree/utils/__pycache__
 pages/application/DecisionTree/__pycache__
 pages/application/__pycache__
-decision_tree_classifier_20170212.pkl
-push_command
-adult.pkl
-adult_data_00000.inst
-iris_00000.txt
-tests
-create_pkl.py
\ No newline at end of file
+tests/push_command
\ No newline at end of file
diff --git a/assets/header.css b/assets/header.css
index 8da0dd9e4f9bb5406ea42e7415ae4b068bf29c85..3a882eae1b7fdffd40dd37f87941a5508a4f29d1 100644
--- a/assets/header.css
+++ b/assets/header.css
@@ -36,6 +36,12 @@ div.sidebar.col-3 {
     background-color:gray;
   }
 
+.sidebar .check-boxes{
+    width: 100%;
+    height: 40px;
+    text-align: center;
+}
+
 .sidebar .upload {
         width: 100%;
         height: 50px;
@@ -49,7 +55,6 @@ div.sidebar.col-3 {
 
 .sidebar .Select-control {
     width: 100%;
-    height: 30px;
     line-height: 30px;
     border-width: 1px;
     border-radius: 5px;
@@ -60,9 +65,9 @@ div.sidebar.col-3 {
     background-color: rgb(26,26,26);
 }
 
-.sidebar .sidebar-dropdown{
+.sidebar .dropdown{
     width: 100%;
-    height: 40px;
+    height: 30px;
     line-height: 30px;
     border-width: 1px;
     border-radius: 5px;
diff --git a/callbacks.py b/callbacks.py
index 04930d6d59440aa0bbf430ede63f6201dc416a65..5ef62d601526f58dbf4d39f45ca698ee867d80ad 100644
--- a/callbacks.py
+++ b/callbacks.py
@@ -54,10 +54,13 @@ def register_callbacks(page_home, page_course, page_application, app):
         if ctx.triggered:
             ihm_id = ctx.triggered[0]['prop_id'].split('.')[0]
             model_application = page_application.model
+
+            # Choice of model
             if ihm_id == 'ml_model_choice' :
-                    model_application.update_ml_model(value_ml_model)
-                    return None, None, None, None, None
+                model_application.update_ml_model(value_ml_model)
+                return None, None, None, None, None
 
+            # Choice of pkl pretrained model
             elif ihm_id == 'ml_pretrained_model_choice':
                 if model_application.ml_model is None :
                     raise PreventUpdate
@@ -69,6 +72,7 @@ def register_callbacks(page_home, page_course, page_application, app):
                 else :
                     return pretrained_model_filename, None, None, None, None
 
+            # Choice of information for the model
             elif ihm_id == 'model_info_choice':
                 if model_application.ml_model is None :
                     raise PreventUpdate
@@ -76,36 +80,38 @@ def register_callbacks(page_home, page_course, page_application, app):
                 model_application.update_pretrained_model_layout_with_info(model_info, model_info_filename)
                 return pretrained_model_filename, model_info_filename, None, model_application.component.network, None
 
+            # Choice of instance to explain
             elif ihm_id == 'ml_instance_choice' :
-                if model_application.ml_model is None or model_application.pretrained_model is None :
+                if model_application.ml_model is None or model_application.pretrained_model is None or model_application.enum<=0 or model_application.xtype is None :
                     raise PreventUpdate
                 instance = parse_contents_instance(instance_contents, instance_filename)
-                model_application.update_instance(instance, enum, xtype)
+                model_application.update_instance(instance)
                 return pretrained_model_filename, model_info_filename, instance_filename, model_application.component.network, model_application.component.explanation   
 
+            # Choice of number of expls
             elif ihm_id == 'number_explanations' :
-                if model_application.ml_model is None or model_application.pretrained_model is None or model_application.instance is None:
+                if model_application.ml_model is None or model_application.pretrained_model is None or len(model_application.instance)==0 or model_application.xtype is None:
                     raise PreventUpdate
-                instance = parse_contents_instance(model_application.instance, instance_filename)
-                model_application.update_instance(instance, enum, xtype)
+                model_application.update_enum(enum)
                 return pretrained_model_filename, model_info_filename, instance_filename, model_application.component.network, model_application.component.explanation   
 
+            # Choice of AxP or CxP
             elif ihm_id == 'explanation_type' :
-                if model_application.ml_model is None or model_application.pretrained_model is None or model_application.instance is None:
+                if model_application.ml_model is None or model_application.pretrained_model is None or len(model_application.instance)==0 or model_application.enum<=0 :
                     raise PreventUpdate
-                instance = parse_contents_instance(model_application.instance, instance_filename)
-                model_application.update_instance(instance, enum, xtype)
+                model_application.update_xtype(xtype)
                 return pretrained_model_filename, model_info_filename, instance_filename, model_application.component.network, model_application.component.explanation
             
+            # Choice of solver 
             elif ihm_id == 'solver_sat' :
-                if model_application.ml_model is None or model_application.pretrained_model is None or model_application.instance is None:
+                if model_application.ml_model is None or model_application.pretrained_model is None or len(model_application.instance)==0 or model_application.enum<=0 or len(model_application.xtype)==0:
                     raise PreventUpdate
-                instance = parse_contents_instance(model_application.instance, instance_filename)
-                model_application.update_instance(instance, enum, xtype, solver=solver)
+                model_application.update_solver(solver)
                 return pretrained_model_filename, model_info_filename, instance_filename, model_application.component.network, model_application.component.explanation             
             
+            # Choice of AxP to draw
             elif ihm_id == 'expl_choice' :
-                if instance_contents is None :
+                if model_application.ml_model is None or model_application.pretrained_model is None or len(model_application.instance)==0 or model_application.enum<=0 or len(model_application.xtype)==0:
                     raise PreventUpdate
                 model_application.update_expl(expl_choice)
                 return pretrained_model_filename, model_info_filename, instance_filename, model_application.component.network, model_application.component.explanation             
@@ -133,14 +139,14 @@ def register_callbacks(page_home, page_course, page_application, app):
             return False, False, False, options
 
     @app.callback(
-        Output('model_info_choice', 'disabled'),
-        Input('add_info_model_choice', 'value'),
+        Output('choice_info_div', 'hidden'),
+        Input('add_info_model_choice', 'on'),
         prevent_initial_call=True
     )
     def add_model_info(add_info_model_choice):
         model_application = page_application.model
         model_application.update_info_needed(add_info_model_choice)
-        if add_info_model_choice==1:
+        if add_info_model_choice:
             return False
         else :
             return True
diff --git a/callbacks_detached.py b/callbacks_detached.py
new file mode 100644
index 0000000000000000000000000000000000000000..a8db16ff713479399892471d56224bd0cd9456b2
--- /dev/null
+++ b/callbacks_detached.py
@@ -0,0 +1,172 @@
+import dash
+import pandas as pd
+from dash import Input, Output, State
+from dash.dependencies import Input, Output, State
+from dash.exceptions import PreventUpdate
+
+from utils import parse_contents_graph, parse_contents_instance, parse_contents_data
+
+
+def register_callbacks(page_home, page_course, page_application, app):
+    page_list = ['home', 'course', 'application']
+
+    @app.callback(
+        Output('page-content', 'children'),
+        Input('url', 'pathname'))
+    def display_page(pathname):
+        if pathname == '/':
+            return page_home
+        if pathname == '/application':
+            return page_application.view.layout        
+        if pathname == '/course':
+            return page_course
+
+    @app.callback(Output('home-link', 'active'),
+                Output('course-link', 'active'),
+                Output('application-link', 'active'),
+                Input('url', 'pathname'))
+    def navbar_state(pathname):
+        active_link = ([pathname == f'/{i}' for i in page_list])
+        return active_link[0], active_link[1], active_link[2]
+
+    @app.callback(
+        Output('graph', 'children'),
+        Input('ml_model_choice', 'value'),
+        prevent_initial_call=True
+    )
+    def update_ml_type(value_ml_model):
+        model_application = page_application.model
+        model_application.update_ml_model(value_ml_model)
+        return None
+
+    @app.callback(
+        Output('pretrained_model_filename', 'children'),
+        Output('graph', 'children'),
+        Input('ml_pretrained_model_choice', 'contents'),
+        State('ml_pretrained_model_choice', 'filename'),
+        prevent_initial_call=True
+    )
+    def update_ml_pretrained_model(pretrained_model_contents, pretrained_model_filename):
+        model_application = page_application.model
+        if model_application.ml_model is None :
+            raise PreventUpdate
+        graph = parse_contents_graph(pretrained_model_contents, pretrained_model_filename)
+        model_application.update_pretrained_model(graph)
+        if not model_application.add_info :
+            model_application.update_pretrained_model_layout()
+            return pretrained_model_filename, model_application.component.network
+        else :
+            return pretrained_model_filename, None
+
+    @app.callback(
+        Output('info_filename', 'children'),
+        Output('graph', 'children'),
+        Input('model_info_choice', 'contents'),
+        State('model_info_choice', 'filename'),
+        prevent_initial_call=True
+    )
+    def update_info_model(model_info, model_info_filename):
+        model_application = page_application.model
+        if model_application.ml_model is None :
+            raise PreventUpdate
+        model_info = parse_contents_data(model_info, model_info_filename)
+        model_application.update_pretrained_model_layout_with_info(model_info, model_info_filename)
+        return model_info_filename, model_application.component.network
+
+    @app.callback(
+        Output('instance_filename', 'children'),
+        Output('graph', 'children'),
+        Output('explanation', 'children'),
+        Input('ml_instance_choice', 'contents'),
+        State('ml_instance_choice', 'filename'),
+        prevent_initial_call=True
+    )
+    def update_instance(instance_contents, instance_filename):
+        model_application = page_application.model
+        if model_application.ml_model is None or model_application.pretrained_model is None or model_application.enum<=0 or model_application.xtype is None :
+            raise PreventUpdate
+        instance = parse_contents_instance(instance_contents, instance_filename)
+        model_application.update_instance(instance)
+        return instance_filename, model_application.component.network, model_application.component.explanation   
+
+    @app.callback(
+        Output('explanation', 'children'),
+        Input('number_explanations', 'value'),
+        prevent_initial_call=True
+    )
+    def update_enum(enum):
+        model_application = page_application.model
+        if model_application.ml_model is None or model_application.pretrained_model is None or len(model_application.instance)==0 or model_application.xtype is None:
+            raise PreventUpdate
+        model_application.update_enum(enum)
+        return model_application.component.explanation   
+
+    @app.callback(
+        Output('explanation', 'children'),
+        Input('explanation_type', 'value'),
+        prevent_initial_call=True
+    )
+    def update_xtype(xtype):
+        model_application = page_application.model
+        if model_application.ml_model is None or model_application.pretrained_model is None or len(model_application.instance)==0 or model_application.enum<=0 :
+            raise PreventUpdate
+        model_application.update_xtype(xtype)
+        return  model_application.component.explanation
+    
+    @app.callback(
+    Output('explanation', 'children'),
+    Input('solver_sat', 'value'),
+    prevent_initial_call=True
+)
+    def update_solver(solver):
+        model_application = page_application.model
+        if model_application.ml_model is None or model_application.pretrained_model is None or len(model_application.instance)==0 or model_application.enum<=0 or len(model_application.xtype)==0:
+            raise PreventUpdate
+        model_application.update_solver(solver)
+        return model_application.component.explanation             
+    
+    @app.callback(
+        Output('graph', 'children'),
+        Input('expl_choice', 'value'),
+        prevent_initial_call=True
+    )
+    def update_expl_choice( expl_choice):
+        model_application = page_application.model
+        if model_application.ml_model is None or model_application.pretrained_model is None or len(model_application.instance)==0 or model_application.enum<=0 or len(model_application.xtype)==0:
+            raise PreventUpdate
+        model_application.update_expl(expl_choice)
+        return model_application.component.network            
+
+    @app.callback(
+        Output('explanation', 'hidden'),
+        Output('navigate_label', 'hidden'),    
+        Output('navigate_dropdown', 'hidden'),
+        Output('expl_choice', 'options'),
+        Input('explanation', 'children'),
+        Input('explanation_type', 'value'),
+        prevent_initial_call=True
+    )
+    def layout_buttons_navigate_expls(explanation, explanation_type):
+        if explanation is None or len(explanation_type)==0:
+            return True, True, True, {}
+        elif "AXp" not in explanation_type and "CXp" in explanation_type:
+            return False, True, True, {}
+        else : 
+            options = {}
+            model_application = page_application.model
+            for i in range (len(model_application.list_expls)):
+                options[str(model_application.list_expls[i])] = model_application.list_expls[i]
+            return False, False, False, options
+
+    @app.callback(
+        Output('choice_info_div', 'hidden'),
+        Input('add_info_model_choice', 'on'),
+        prevent_initial_call=True
+    )
+    def add_model_info(add_info_model_choice):
+        model_application = page_application.model
+        model_application.update_info_needed(add_info_model_choice)
+        if add_info_model_choice:
+            return False
+        else :
+            return True
diff --git a/pages/application/DecisionTree/DecisionTreeComponent.py b/pages/application/DecisionTree/DecisionTreeComponent.py
index a1e23631c496156e327ce9903751131fa919c4c4..8a56c32349fced19e8c03889bb26fdc176b79973 100644
--- a/pages/application/DecisionTree/DecisionTreeComponent.py
+++ b/pages/application/DecisionTree/DecisionTreeComponent.py
@@ -15,27 +15,32 @@ from pages.application.DecisionTree.utils.dtviz import (visualize,
 
 class DecisionTreeComponent():
 
-    def __init__(self, tree, info=None, type_info=''):
-
+    def __init__(self, tree, type_tree='SKL', info=None, type_info=''):
 
         if info is not None and '.csv' in type_info: 
             self.categorical = True
             data = Data(info)
             fvmap = data.mapping_features()
             feature_names = data.names[:-1]
-
-            self.uploaded_dt = UploadedDecisionTree(tree, 'SKL', maxdepth=tree.get_depth(), feature_names=feature_names, nb_classes=tree.n_classes_)
+            self.uploaded_dt = UploadedDecisionTree(tree, type_tree, maxdepth=tree.get_depth(), feature_names=feature_names, nb_classes=tree.n_classes_)
             self.dt_format, self.map, features_names_mapping = self.uploaded_dt.dump(fvmap, feat_names=feature_names)
-            self.mapping_instance = self.create_fvmap_inverse_with_info(features_names_mapping)
-
 
         elif info is not None and '.txt' in type_info :
             self.categorical = True
             fvmap = {}
-
-            self.uploaded_dt = UploadedDecisionTree(tree, 'SKL', maxdepth=tree.get_depth(), feature_names=feature_names, nb_classes=tree.n_classes_)
+            feature_names = []
+            for i,line in enumerate(info.split('\n')):
+                fid, TYPE = line.split(',')[:2]
+                dom = line.split(',')[2:]
+                assert (fid not in feature_names)
+                feature_names.append(fid)
+                assert (TYPE in ['Binary', 'Categorical'])
+                fvmap[f'f{i}'] = dict()
+                dom = sorted(dom)
+                for j,v in enumerate(dom):
+                    fvmap[f'f{i}'][j] = (fid, True, v)
+            self.uploaded_dt = UploadedDecisionTree(tree, type_tree, maxdepth=tree.get_depth(), feature_names=feature_names, nb_classes=tree.n_classes_)
             self.dt_format, self.map, features_names_mapping = self.uploaded_dt.dump(fvmap, feat_names=feature_names)
-            self.mapping_instance = self.create_fvmap_inverse_with_info(features_names_mapping)
 
         else : 
             self.categorical = False
@@ -43,42 +48,46 @@ class DecisionTreeComponent():
                 feature_names = tree.feature_names_in_
             except:
                 feature_names = [f'f{i}' for i in range(tree.n_features_in_)]
-
-            self.uploaded_dt = UploadedDecisionTree(tree, 'SKL', maxdepth=tree.get_depth(), feature_names=feature_names, nb_classes=tree.n_classes_)
+            self.uploaded_dt = UploadedDecisionTree(tree, type_tree, maxdepth=tree.get_depth(), feature_names=feature_names, nb_classes=tree.n_classes_)
             self.dt_format, self.map, features_names_mapping = self.uploaded_dt.convert_dt(feat_names=feature_names)
-            self.mapping_instance = self.create_fvmap_inverse_threashold(features_names_mapping)
-
-        self.dt = DecisionTree(from_dt=self.dt_format, mapfile = self.map)
+        
+        self.mapping_instance = self.create_fvmap_inverse(features_names_mapping)
+        self.dt = DecisionTree(from_dt=self.dt_format, mapfile = self.map, feature_names = feature_names)
         dot_source = visualize(self.dt)
-        self.network = [dbc.Row(dash_interactive_graphviz.DashInteractiveGraphviz(dot_source=dot_source, style = {"width": "60%",
+        self.network = html.Div([dash_interactive_graphviz.DashInteractiveGraphviz(dot_source=dot_source, style = {"width": "60%",
                                                                                                                 "height": "90%",
-                                                                                                                "background-color": "transparent"}))]
+                                                                                                                "background-color": "transparent"})])
         self.explanation = []
 
 
-    def create_fvmap_inverse_with_info(self, features_names_mapping) :
-        mapping_instance = {}
-        for feat in features_names_mapping :
-            feat_dic = {}
-            feature_description = feat.split(',')
-            name_feat, id_feat =  feature_description[1].split(':')
+    def create_fvmap_inverse(self, instance):
+        def create_fvmap_inverse_with_info(features_names_mapping) :
+            mapping_instance = {}
+            for feat in features_names_mapping :
+                feat_dic = {}
+                feature_description = feat.split(',')
+                name_feat, id_feat =  feature_description[1].split(':')
 
-            for mapping in feature_description[2:]:
-                real_value, mapped_value = mapping.split(':')
-                feat_dic[np.float32(real_value)] = int(mapped_value)
-            mapping_instance[name_feat] = feat_dic
+                for mapping in feature_description[2:]:
+                    real_value, mapped_value = mapping.split(':')
+                    feat_dic[np.float32(real_value)] = int(mapped_value)
+                mapping_instance[name_feat] = feat_dic
 
-        return mapping_instance
+            return mapping_instance
 
+        def create_fvmap_inverse_threashold(features_names_mapping) :
+            mapping_instance = {}
+            for feat in features_names_mapping :
+                feature_description = feat.split(',')
+                name_feat, id_feat =  feature_description[1].split(':')
+                mapping_instance[name_feat] = float(feature_description[2].split(':')[0])
 
-    def create_fvmap_inverse_threashold(self, features_names_mapping) :
-        mapping_instance = {}
-        for feat in features_names_mapping :
-            feature_description = feat.split(',')
-            name_feat, id_feat =  feature_description[1].split(':')
-            mapping_instance[name_feat] = float(feature_description[2].split(':')[0])
+            return mapping_instance
 
-        return mapping_instance
+        if self.categorical :
+            return create_fvmap_inverse_with_info(instance)
+        else : 
+            return create_fvmap_inverse_threashold(instance)
 
 
     def translate_instance(self, instance):
@@ -114,14 +123,17 @@ class DecisionTreeComponent():
         explanation = self.dt.explain(instance_translated, enum=enum, xtype = xtype, solver=solver)
 
         dot_source = visualize_instance(self.dt, instance_translated)
-        self.network = [dbc.Row(dash_interactive_graphviz.DashInteractiveGraphviz(
+        self.network = html.Div([dash_interactive_graphviz.DashInteractiveGraphviz(
             dot_source=dot_source, style = {"width": "50%",
                                              "height": "80%",
                                             "background-color": "transparent"}
-        ))]
+        )])
 
 
         #Creating a clean and nice text component
+        #instance plotting
+        self.explanation.append(html.H4("Instance : \n"))
+        self.explanation.append(html.P(str([str(instance[i]) for i in range (len(instance))])))
         for k in explanation.keys() :
             if k != "List of path explanation(s)":
                 if k in ["List of abductive explanation(s)","List of contrastive explanation(s)"] :
@@ -140,8 +152,8 @@ class DecisionTreeComponent():
     def draw_explanation(self, instance, expl) :
         instance = self.translate_instance(instance)
         dot_source = visualize_expl(self.dt, instance, expl)
-        self.network = [dbc.Row(dash_interactive_graphviz.DashInteractiveGraphviz(
+        self.network = html.Div([dash_interactive_graphviz.DashInteractiveGraphviz(
                                 dot_source=dot_source, 
                                 style = {"width": "50%",
                                         "height": "80%",
-                                        "background-color": "transparent"}))]
+                                        "background-color": "transparent"})])
diff --git a/pages/application/DecisionTree/utils/data.py b/pages/application/DecisionTree/utils/data.py
index d23ddb6108683ad08e41d5da10f889f163b67ad5..91aded54aaa39c6239d3a0696beafb217dc9a8a4 100644
--- a/pages/application/DecisionTree/utils/data.py
+++ b/pages/application/DecisionTree/utils/data.py
@@ -13,17 +13,13 @@
 from __future__ import print_function
 import collections
 import itertools
-import os, pickle
+import pickle
 import six
 import gzip
 from six.moves import range
 import numpy as np
 import pandas as pd
 
-#from  sklearn.preprocessing import OneHotEncoder
-from sklearn.model_selection import train_test_split
-
-
 #
 #==============================================================================
 class Data(object):
diff --git a/pages/application/DecisionTree/utils/dtree.py b/pages/application/DecisionTree/utils/dtree.py
index 1e7e270cc6a24a743dac1d33e9c870dda318933b..1eb9de3978b04b026de42c81dc3b600eb8b35345 100644
--- a/pages/application/DecisionTree/utils/dtree.py
+++ b/pages/application/DecisionTree/utils/dtree.py
@@ -45,7 +45,7 @@ class DecisionTree():
         Simple decision tree class.
     """
 
-    def __init__(self, from_dt=None, mapfile=None, verbose=0):
+    def __init__(self, from_dt=None, mapfile=None, feature_names=None, verbose=0):
         """
             Constructor.
         """
@@ -62,6 +62,7 @@ class DecisionTree():
         self.feids = {}
         self.fdoms = {}
         self.fvmap = {}
+        self.feature_names = {f'f{i}' : feature_names[i] for i, f in enumerate(feature_names)}
 
         # OHE mapping
         OHEMap = collections.namedtuple('OHEMap', ['dir', 'opp'])
@@ -145,7 +146,6 @@ class DecisionTree():
         """
             Parse feature-value mapping from a file.
         """
-
         self.fvmap = {}
 
         lines = mapfile.split('\n')
@@ -184,7 +184,6 @@ class DecisionTree():
         """
             Convert ITI trees with '!=' edges to multi-edges.
         """
-
         # new feature domains
         fdoms = collections.defaultdict(lambda: [])
 
@@ -227,7 +226,6 @@ class DecisionTree():
         """
             Traverse the tree and extract explicit paths.
         """
-
         if root in self.terms:
             # store the path
             term = self.terms[root]
@@ -242,7 +240,6 @@ class DecisionTree():
         """
             Run the tree and obtain the prediction given an input instance.
         """
-
         root = self.root_node
         depth = 0
         path = []
@@ -297,7 +294,6 @@ class DecisionTree():
             Hitting set based encoding of the problem.
             (currently not incremental -- should be fixed later)
         """
-
         sets = []
         for t, paths in self.paths.items():
             # ignoring the right class
@@ -334,12 +330,9 @@ class DecisionTree():
         """
         #contaiins all the elements for explanation
         explanation_dic = {}
-        #instance plotting
-        explanation_dic["Instance : "] = str([str(inst[i]) for i in range (len(inst))])
 
         self.feids = {f'f{i}': i for i, f in enumerate(inst)}
         inst = [(f'f{i}', int(inst[i][1])) for i,f in enumerate(inst)]
-
         path, term, depth = self.execute(inst, pathlits)
 
         #decision path
@@ -347,10 +340,8 @@ class DecisionTree():
         explanation_dic["Decision path of instance : "] = decision_path_str
         explanation_dic["Decision path length : "] = 'Path length is :'+ str(depth)
 
-
         if self.ohmap.dir:
             f2v = {fv[0]: fv[1] for fv in inst}
-
             # updating fvmap for printing ohe features
             for fo, fis in self.ohmap.dir.items():
                 self.fvmap[tuple([fo, None])] = '(' + ' AND '.join([self.fvmap[tuple([fi, f2v[fi]])] for fi in fis]) + ')'
@@ -394,7 +385,6 @@ class DecisionTree():
         """
             Enumerate contrastive explanations.
         """
-
         def process_set(done, target):
             for s in done:
                 if s <= target:
diff --git a/pages/application/DecisionTree/utils/dtviz.py b/pages/application/DecisionTree/utils/dtviz.py
index 0c940c64d0a7e57336db3ba9bb00e0fd5171239c..21ea63920338159b71e45c44a1cd2b772084bc9f 100755
--- a/pages/application/DecisionTree/utils/dtviz.py
+++ b/pages/application/DecisionTree/utils/dtviz.py
@@ -10,16 +10,14 @@
 
 #
 #==============================================================================
-from pages.application.DecisionTree.utils.dtree import DecisionTree
 import getopt
-import os
 import pygraphviz
-import sys
 
 #
 #==============================================================================
 def create_legend(g):
     legend = g.subgraphs()[-1]
+    legend.graph_attr.update(size="2,2")    
     legend.add_node("a", style = "invis")
     legend.add_node("b", style = "invis")
     legend.add_node("c", style = "invis")
@@ -50,7 +48,7 @@ def visualize(dt):
 
     # non-terminal nodes
     for n in dt.nodes:
-        g.add_node(n, label=dt.nodes[n].feat)
+        g.add_node(n, label=dt.feature_names[dt.nodes[n].feat])
         node = g.get_node(n)
         node.attr['shape'] = 'circle'
         node.attr['fontsize'] = 13
@@ -98,7 +96,7 @@ def visualize_instance(dt, instance):
 
     # non-terminal nodes
     for n in dt.nodes:
-        g.add_node(n, label=dt.nodes[n].feat)
+        g.add_node(n, label=dt.feature_names[dt.nodes[n].feat])
         node = g.get_node(n)
         node.attr['shape'] = 'circle'
         node.attr['fontsize'] = 13
@@ -156,7 +154,7 @@ def visualize_expl(dt, instance, expl):
 
     # non-terminal nodes
     for n in dt.nodes:
-        g.add_node(n, label=dt.nodes[n].feat)
+        g.add_node(n, label=dt.feature_names[dt.nodes[n].feat])
         node = g.get_node(n)
         node.attr['shape'] = 'circle'
         node.attr['fontsize'] = 13
diff --git a/pages/application/DecisionTree/utils/upload_tree.py b/pages/application/DecisionTree/utils/upload_tree.py
index b3e1297783ae503d4ee22ae7e024aa02b4c2f7f7..98bf190cfc588cae331fff2caeeb85df06b87645 100644
--- a/pages/application/DecisionTree/utils/upload_tree.py
+++ b/pages/application/DecisionTree/utils/upload_tree.py
@@ -14,7 +14,6 @@ from anytree import Node, RenderTree,AsciiStyle
 import json
 import numpy as np
 import math
-import os
 import six
 
 
@@ -297,8 +296,8 @@ class UploadedDecisionTree:
         map += f"{len(self.intvs)}"
         for f in self.intvs:
             for j,t in enumerate(self.intvs[f][:-1]):
-                map += f"\n{f} {j} <={t}"
-            map += f"\n{f} {j+1} >{t}"  
+                map += f"\n{f} {j} <={np.round(float(t),4)}"
+            map += f"\n{f} {j+1} >{np.round(float(t),4)}"  
 
 
         if feat_names is not None:
diff --git a/pages/application/application.py b/pages/application/application.py
index 925a1b7307bc9567b8df55cbd6623da1f075f717..db54577aa48a31e87069afd59ebf34ed6a346ea0 100644
--- a/pages/application/application.py
+++ b/pages/application/application.py
@@ -1,5 +1,6 @@
 from dash import dcc, html
 import dash_bootstrap_components as dbc
+import dash_daq as daq
 
 from pages.application.DecisionTree.DecisionTreeComponent import DecisionTreeComponent
 
@@ -23,6 +24,10 @@ class Model():
         self.add_info = False
         self.model_info = ''
 
+        self.enum=1
+        self.xtype = ['AXp', 'CXp']
+        self.solver="g3"
+
         self.instance = ''
 
         self.list_expls = []
@@ -47,12 +52,24 @@ class Model():
 
     def update_pretrained_model_layout_with_info(self, model_info, model_info_filename):
         self.model_info = model_info
-        self.component = self.component_class(self.pretrained_model, self.model_info, model_info_filename)
+        self.component = self.component_class(self.pretrained_model, info=self.model_info, type_info=model_info_filename)
 
-    def update_instance(self, instance, enum, xtype, solver="g3"):
+    def update_instance(self, instance):
         self.instance = instance
-        self.list_expls = self.component.update_with_explicability(self.instance, enum, xtype, solver)    
+        self.list_expls = self.component.update_with_explicability(self.instance, self.enum, self.xtype, self.solver)    
+        
+    def update_enum(self, enum):
+        self.enum = enum
+        self.list_expls = self.component.update_with_explicability(self.instance, self.enum, self.xtype, self.solver)    
         
+    def update_xtype(self, xtype):
+        self.xtype = xtype
+        self.list_expls = self.component.update_with_explicability(self.instance, self.enum, self.xtype, self.solver)    
+
+    def update_solver(self, solver):
+        self.solver = solver
+        self.list_expls = self.component.update_with_explicability(self.instance, self.enum, self.xtype, self.solver)    
+              
     def update_expl(self, expl):
         self.expl = expl
         self.component.draw_explanation(self.instance, expl)
@@ -62,17 +79,18 @@ class View():
     def __init__(self, model):
         self.model = model
 
-        self.ml_menu_models = dcc.Dropdown(self.model.ml_models, 
+        self.ml_menu_models = html.Div([                                    
+                                    html.Br(),                                
+                                    html.Label("Choose the Machine Learning algorithm :"),
+                                    html.Br(),
+                                    dcc.Dropdown(self.model.ml_models, 
                                             id='ml_model_choice',
-                                            className="sidebar-dropdown")
-
-        self.ml_library_used = dcc.Dropdown(options = [{'label': 'Scikit-learn ', 'value': "SKL"},
-                                                        {'label': 'ITI', 'value': "ITI"},
-                                                        {'label': 'IAI', 'value': "IAI"}], 
-                                            id='ml_library_choice',
-                                            className="sidebar-dropdown")
+                                            className="dropdown")])
 
         self.pretrained_model_upload = html.Div([
+                                    html.Hr(),
+                                    html.Label("Choose the pretrained model : "),
+                                    html.Br(),
                                     dcc.Upload(        
                                         id='ml_pretrained_model_choice',
                                         children=html.Div([
@@ -83,15 +101,20 @@ class View():
                                     ),
                                     html.Div(id='pretrained_model_filename')])
 
-        self.add_model_info_choice = dcc.RadioItems(id="add_info_model_choice", 
-                                                    options = [{'label': 'Yes ', 'value': 1},
-                                                               {'label': 'No', 'value': 0}], 
-                                                    value=0, className="sidebar-dropdown")
+        self.add_model_info_choice = html.Div([
+                                    html.Hr(),
+                                    html.Label("Do you wish to upload more info for your model ? : "),
+                                    html.Br(),
+                                    daq.BooleanSwitch(id='add_info_model_choice', on=False, color="#000000",)])
 
-        self.model_info = html.Div([
+        self.model_info = html.Div(id="choice_info_div",
+                                    hidden=True,
+                                    children=[
+                                    html.Hr(),
+                                    html.Label("Choose the pretrained model dataset (csv) or feature definition file (txt): "),
+                                    html.Br(),
                                     dcc.Upload(        
                                         id='model_info_choice',
-                                        disabled=True,
                                         children=html.Div([
                                             'Drag and Drop or ',
                                             html.A('Select File')
@@ -101,6 +124,9 @@ class View():
                                     html.Div(id='info_filename')])
 
         self.instance_upload = html.Div([
+                                    html.Hr(),
+                                    html.Label("Choose the instance to explain : "),
+                                    html.Br(),
                                     dcc.Upload(        
                                         id='ml_instance_choice',
                                         children=html.Div([
@@ -111,34 +137,7 @@ class View():
                                     ),
                                     html.Div(id='instance_filename')])
 
-        self.sidebar = dcc.Tabs(children=[
-                                dcc.Tab(label='Basic Parameters', children = [    
-                                    html.Br(),                                
-                                    html.Label("Choose the Machine Learning algorithm :"),
-                                    html.Br(),
-                                    self.ml_menu_models,
-                                    html.Hr(),
-                                    html.Label("Choose the Machine Learning library used :"),
-                                    html.Br(),
-                                    self.ml_library_used,
-                                    html.Hr(),
-                                    html.Label("Choose the pretrained model : "),
-                                    html.Br(),
-                                    self.pretrained_model_upload, 
-                                    html.Hr(),
-                                    html.Label("Do you wish to upload more info for your model ? : "),
-                                    html.Br(),
-                                    self.add_model_info_choice,
-                                    html.Hr(),
-                                    html.Label("Choose the pretrained model dataset (csv) or feature definition file (txt): "),
-                                    html.Br(),
-                                    self.model_info,
-                                    html.Hr(),
-                                    html.Label("Choose the instance to explain : "),
-                                    html.Br(),
-                                    self.instance_upload], className="sidebar"),
-                                dcc.Tab(label='Advanced Parameters', children = [ 
-                                    html.Br(),
+        self.num_explanation = html.Div([
                                     html.Label("Choose the number of explanations : "),
                                     html.Br(),
                                     dcc.Input(
@@ -146,29 +145,48 @@ class View():
                                         value=1,
                                         type="number",
                                         placeholder="How many explanations ?",
-                                        className="sidebar-dropdown"),
-                                    html.Hr(),
+                                        className="dropdown"),
+                                    html.Hr()])
+
+        self.type_explanation = html.Div([
                                     html.Label("Choose the kind of explanation : "),
                                     html.Br(),
                                     dcc.Checklist(
                                         id="explanation_type",
                                         options={'AXp' : "Abductive Explanation", 'CXp': "Contrastive explanation"},
                                         value = ['AXp', 'CXp'],
-                                        className="sidebar-dropdown",
+                                        className="check-boxes",
                                         inline=True),
-                                    html.Hr(),
-                                    html.Label("Choose the SAT solver : "),
+                                    html.Hr()])
+
+        self.solver = html.Div([    html.Label("Choose the SAT solver : "),
+                                    html.Br(),
+                                    dcc.Dropdown(['g3', 'g4', 'lgl', 'mcb', 'mcm', 'mpl', 'm22', 'mc', 'mgh'], 'g3', id='solver_sat') ])
+                                    
+        self.sidebar = dcc.Tabs(children=[
+                                dcc.Tab(label='Basic Parameters', children = [    
+                                    self.ml_menu_models,
+                                    self.pretrained_model_upload, 
+                                    self.add_model_info_choice,
+                                    self.model_info,
+                                    self.instance_upload], className="sidebar"),
+                                dcc.Tab(label='Advanced Parameters', children = [ 
                                     html.Br(),
-                                    dcc.Dropdown(['g3', 'g4', 'lgl', 'mcb', 'mcm', 'mpl', 'm22', 'mc', 'mgh'], 'g3', id='solver_sat') 
+                                    self.num_explanation,
+                                    self.type_explanation,
+                                    self.solver
                                 ], className="sidebar")])
                             
  
-        self.expl_choice = dcc.Dropdown(self.model.list_expls,
+        self.expl_choice = html.Div([html.H5(id = "navigate_label", hidden=True, children="Navigate through the explanations and plot them on the tree : "),
+                                    html.Div(id='navigate_dropdown', hidden=True,
+                                    children = [dcc.Dropdown(self.model.list_expls,
                                         id='expl_choice',  
-                                        className="dropdown")
+                                        className="dropdown")])])
                                             
-        self.layout = dbc.Row([ dbc.Col([self.sidebar], width=3, class_name="sidebar"), 
+        self.layout = dbc.Row([ dbc.Col([self.sidebar], 
+                                        width=3, class_name="sidebar"), 
                                 dbc.Col([dbc.Row(id = "graph", children=[]),
-                                         dbc.Row(html.Div([html.H5(id = "navigate_label", hidden=True, children="Navigate through the explanations and plot them on the tree : "),
-                                                          html.Div(self.expl_choice, id='navigate_dropdown', hidden=True)]))], width=5, class_name="column_graph"), 
+                                         dbc.Row(self.expl_choice)], 
+                                         width=5, class_name="column_graph"), 
                                 dbc.Col(html.Main(id = "explanation", children=[], hidden=True), width=4)])
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index aab2fcaf8910657e4d1cd96b58230fefca5b5dbc..4f70ae69cdd7f78304ed576c0745589b7d79e127 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -11,5 +11,6 @@ scipy>=1.2.1
 dash_bootstrap_components
 dash_interactive_graphviz
 python-sat[pblib,aiger]
-pygraphviz
-anytree
\ No newline at end of file
+pygraphviz==1.9
+anytree==2.8.0
+dash_daq==0.5.0
\ No newline at end of file
diff --git a/tests/adult/adult.pkl b/tests/adult/adult.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..b18b4d6e77cfc501320ebd5650158dd268530d1d
Binary files /dev/null and b/tests/adult/adult.pkl differ
diff --git a/tests/adult/adult_2.pkl b/tests/adult/adult_2.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..5221943e347e0a7b2b83e0ee33e5c603396536a3
Binary files /dev/null and b/tests/adult/adult_2.pkl differ
diff --git a/tests/adult/adult_3.pkl b/tests/adult/adult_3.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..b17bc94372fe8d7b6db981e73bf34d6f37b1d07b
Binary files /dev/null and b/tests/adult/adult_3.pkl differ
diff --git a/tests/adult/adult_data_00000.inst b/tests/adult/adult_data_00000.inst
new file mode 100644
index 0000000000000000000000000000000000000000..c72f4e9e0aec1da4c12fdaa3b585d6d96054a30a
--- /dev/null
+++ b/tests/adult/adult_data_00000.inst
@@ -0,0 +1 @@
+f0=1,f1=9,f2=9,f3=7,f4=9,f5=5,f6=7,f7=0,f8=5,f9=3,f10=0,f11=15
\ No newline at end of file
diff --git a/tests/iris/decision_tree_classifier_20170212.pkl b/tests/iris/decision_tree_classifier_20170212.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..006ccc214168eed2a37f7201ccca66648f1112f7
Binary files /dev/null and b/tests/iris/decision_tree_classifier_20170212.pkl differ
diff --git a/tests/iris/iris.csv b/tests/iris/iris.csv
new file mode 100644
index 0000000000000000000000000000000000000000..1b9d0294d6d589f667daf28efecbd0cb0276c352
--- /dev/null
+++ b/tests/iris/iris.csv
@@ -0,0 +1,151 @@
+"sepal.length","sepal.width","petal.length","petal.width","variety"
+5.1,3.5,1.4,.2,"Setosa"
+4.9,3,1.4,.2,"Setosa"
+4.7,3.2,1.3,.2,"Setosa"
+4.6,3.1,1.5,.2,"Setosa"
+5,3.6,1.4,.2,"Setosa"
+5.4,3.9,1.7,.4,"Setosa"
+4.6,3.4,1.4,.3,"Setosa"
+5,3.4,1.5,.2,"Setosa"
+4.4,2.9,1.4,.2,"Setosa"
+4.9,3.1,1.5,.1,"Setosa"
+5.4,3.7,1.5,.2,"Setosa"
+4.8,3.4,1.6,.2,"Setosa"
+4.8,3,1.4,.1,"Setosa"
+4.3,3,1.1,.1,"Setosa"
+5.8,4,1.2,.2,"Setosa"
+5.7,4.4,1.5,.4,"Setosa"
+5.4,3.9,1.3,.4,"Setosa"
+5.1,3.5,1.4,.3,"Setosa"
+5.7,3.8,1.7,.3,"Setosa"
+5.1,3.8,1.5,.3,"Setosa"
+5.4,3.4,1.7,.2,"Setosa"
+5.1,3.7,1.5,.4,"Setosa"
+4.6,3.6,1,.2,"Setosa"
+5.1,3.3,1.7,.5,"Setosa"
+4.8,3.4,1.9,.2,"Setosa"
+5,3,1.6,.2,"Setosa"
+5,3.4,1.6,.4,"Setosa"
+5.2,3.5,1.5,.2,"Setosa"
+5.2,3.4,1.4,.2,"Setosa"
+4.7,3.2,1.6,.2,"Setosa"
+4.8,3.1,1.6,.2,"Setosa"
+5.4,3.4,1.5,.4,"Setosa"
+5.2,4.1,1.5,.1,"Setosa"
+5.5,4.2,1.4,.2,"Setosa"
+4.9,3.1,1.5,.2,"Setosa"
+5,3.2,1.2,.2,"Setosa"
+5.5,3.5,1.3,.2,"Setosa"
+4.9,3.6,1.4,.1,"Setosa"
+4.4,3,1.3,.2,"Setosa"
+5.1,3.4,1.5,.2,"Setosa"
+5,3.5,1.3,.3,"Setosa"
+4.5,2.3,1.3,.3,"Setosa"
+4.4,3.2,1.3,.2,"Setosa"
+5,3.5,1.6,.6,"Setosa"
+5.1,3.8,1.9,.4,"Setosa"
+4.8,3,1.4,.3,"Setosa"
+5.1,3.8,1.6,.2,"Setosa"
+4.6,3.2,1.4,.2,"Setosa"
+5.3,3.7,1.5,.2,"Setosa"
+5,3.3,1.4,.2,"Setosa"
+7,3.2,4.7,1.4,"Versicolor"
+6.4,3.2,4.5,1.5,"Versicolor"
+6.9,3.1,4.9,1.5,"Versicolor"
+5.5,2.3,4,1.3,"Versicolor"
+6.5,2.8,4.6,1.5,"Versicolor"
+5.7,2.8,4.5,1.3,"Versicolor"
+6.3,3.3,4.7,1.6,"Versicolor"
+4.9,2.4,3.3,1,"Versicolor"
+6.6,2.9,4.6,1.3,"Versicolor"
+5.2,2.7,3.9,1.4,"Versicolor"
+5,2,3.5,1,"Versicolor"
+5.9,3,4.2,1.5,"Versicolor"
+6,2.2,4,1,"Versicolor"
+6.1,2.9,4.7,1.4,"Versicolor"
+5.6,2.9,3.6,1.3,"Versicolor"
+6.7,3.1,4.4,1.4,"Versicolor"
+5.6,3,4.5,1.5,"Versicolor"
+5.8,2.7,4.1,1,"Versicolor"
+6.2,2.2,4.5,1.5,"Versicolor"
+5.6,2.5,3.9,1.1,"Versicolor"
+5.9,3.2,4.8,1.8,"Versicolor"
+6.1,2.8,4,1.3,"Versicolor"
+6.3,2.5,4.9,1.5,"Versicolor"
+6.1,2.8,4.7,1.2,"Versicolor"
+6.4,2.9,4.3,1.3,"Versicolor"
+6.6,3,4.4,1.4,"Versicolor"
+6.8,2.8,4.8,1.4,"Versicolor"
+6.7,3,5,1.7,"Versicolor"
+6,2.9,4.5,1.5,"Versicolor"
+5.7,2.6,3.5,1,"Versicolor"
+5.5,2.4,3.8,1.1,"Versicolor"
+5.5,2.4,3.7,1,"Versicolor"
+5.8,2.7,3.9,1.2,"Versicolor"
+6,2.7,5.1,1.6,"Versicolor"
+5.4,3,4.5,1.5,"Versicolor"
+6,3.4,4.5,1.6,"Versicolor"
+6.7,3.1,4.7,1.5,"Versicolor"
+6.3,2.3,4.4,1.3,"Versicolor"
+5.6,3,4.1,1.3,"Versicolor"
+5.5,2.5,4,1.3,"Versicolor"
+5.5,2.6,4.4,1.2,"Versicolor"
+6.1,3,4.6,1.4,"Versicolor"
+5.8,2.6,4,1.2,"Versicolor"
+5,2.3,3.3,1,"Versicolor"
+5.6,2.7,4.2,1.3,"Versicolor"
+5.7,3,4.2,1.2,"Versicolor"
+5.7,2.9,4.2,1.3,"Versicolor"
+6.2,2.9,4.3,1.3,"Versicolor"
+5.1,2.5,3,1.1,"Versicolor"
+5.7,2.8,4.1,1.3,"Versicolor"
+6.3,3.3,6,2.5,"Virginica"
+5.8,2.7,5.1,1.9,"Virginica"
+7.1,3,5.9,2.1,"Virginica"
+6.3,2.9,5.6,1.8,"Virginica"
+6.5,3,5.8,2.2,"Virginica"
+7.6,3,6.6,2.1,"Virginica"
+4.9,2.5,4.5,1.7,"Virginica"
+7.3,2.9,6.3,1.8,"Virginica"
+6.7,2.5,5.8,1.8,"Virginica"
+7.2,3.6,6.1,2.5,"Virginica"
+6.5,3.2,5.1,2,"Virginica"
+6.4,2.7,5.3,1.9,"Virginica"
+6.8,3,5.5,2.1,"Virginica"
+5.7,2.5,5,2,"Virginica"
+5.8,2.8,5.1,2.4,"Virginica"
+6.4,3.2,5.3,2.3,"Virginica"
+6.5,3,5.5,1.8,"Virginica"
+7.7,3.8,6.7,2.2,"Virginica"
+7.7,2.6,6.9,2.3,"Virginica"
+6,2.2,5,1.5,"Virginica"
+6.9,3.2,5.7,2.3,"Virginica"
+5.6,2.8,4.9,2,"Virginica"
+7.7,2.8,6.7,2,"Virginica"
+6.3,2.7,4.9,1.8,"Virginica"
+6.7,3.3,5.7,2.1,"Virginica"
+7.2,3.2,6,1.8,"Virginica"
+6.2,2.8,4.8,1.8,"Virginica"
+6.1,3,4.9,1.8,"Virginica"
+6.4,2.8,5.6,2.1,"Virginica"
+7.2,3,5.8,1.6,"Virginica"
+7.4,2.8,6.1,1.9,"Virginica"
+7.9,3.8,6.4,2,"Virginica"
+6.4,2.8,5.6,2.2,"Virginica"
+6.3,2.8,5.1,1.5,"Virginica"
+6.1,2.6,5.6,1.4,"Virginica"
+7.7,3,6.1,2.3,"Virginica"
+6.3,3.4,5.6,2.4,"Virginica"
+6.4,3.1,5.5,1.8,"Virginica"
+6,3,4.8,1.8,"Virginica"
+6.9,3.1,5.4,2.1,"Virginica"
+6.7,3.1,5.6,2.4,"Virginica"
+6.9,3.1,5.1,2.3,"Virginica"
+5.8,2.7,5.1,1.9,"Virginica"
+6.8,3.2,5.9,2.3,"Virginica"
+6.7,3.3,5.7,2.5,"Virginica"
+6.7,3,5.2,2.3,"Virginica"
+6.3,2.5,5,1.9,"Virginica"
+6.5,3,5.2,2,"Virginica"
+6.2,3.4,5.4,2.3,"Virginica"
+5.9,3,5.1,1.8,"Virginica"
\ No newline at end of file
diff --git a/tests/iris/iris.pkl b/tests/iris/iris.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..cf2d521581ec57be284bb87b75316940c16fdcb7
Binary files /dev/null and b/tests/iris/iris.pkl differ
diff --git a/tests/iris/iris.txt b/tests/iris/iris.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d356f5d1d011df170da9dacee5ac4b2d6bfc844b
--- /dev/null
+++ b/tests/iris/iris.txt
@@ -0,0 +1,4 @@
+sepal.length,Categorical,7.6,6.8,7.1,4.9,4.4,6.2,6,7.3,5.9,7.4,5.2,5.6,4.8,6.5,5.5,4.6,6.6,6.4,7,4.5,7.2,5.1,5.8,5.3,6.9,6.1,6.7,4.7,7.7,6.3,5.7,7.9,5.4,4.3,5
+sepal.width,Categorical,4.2,4.4,3.1,2.4,2.9,2,3.8,4.1,4,3.2,2.7,3.3,2.2,2.5,2.3,3.6,3.5,3.9,2.8,2.6,3.7,3,3.4
+petal.length,Categorical,4.2,4.9,4.4,6,5.9,5.2,5.6,4.8,1,5.5,4.6,6.6,1.1,3.8,1.5,6.4,4.1,4,4.5,1.6,3.3,1.4,5.1,1.7,5.8,3.5,3.6,5.3,1.9,6.9,6.1,6.7,4.7,3.9,1.2,1.3,6.3,5.7,3.7,5.4,3,4.3,5
+petal.width,Categorical,2.4,.2,1,2,1.1,1.5,.6,.5,2.2,.3,1.6,1.4,2.5,1.7,2.3,1.8,2.1,1.9,1.2,1.3,.1,.4
\ No newline at end of file
diff --git a/tests/iris/iris01.json b/tests/iris/iris01.json
new file mode 100644
index 0000000000000000000000000000000000000000..59c0840b5597ccb4347c3c2041707f0ae1d11aa0
--- /dev/null
+++ b/tests/iris/iris01.json
@@ -0,0 +1,4 @@
+{"sepal.length":4.9,
+"sepal.width":3,
+"petal.length":1.4,
+"petal.width":0.2}
diff --git a/tests/iris/iris2.pkl b/tests/iris/iris2.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..cf2d521581ec57be284bb87b75316940c16fdcb7
Binary files /dev/null and b/tests/iris/iris2.pkl differ
diff --git a/tests/iris/iris_00000.txt b/tests/iris/iris_00000.txt
new file mode 100644
index 0000000000000000000000000000000000000000..108004d0deba35123ce4bdbcb9fa37930d6164ba
--- /dev/null
+++ b/tests/iris/iris_00000.txt
@@ -0,0 +1 @@
+sepal.length=4.3,sepal.width=2.0,petal.length=1.0,petal.width=0.1
\ No newline at end of file
diff --git a/tests/zoo/inst/zoo_00.inst b/tests/zoo/inst/zoo_00.inst
new file mode 100644
index 0000000000000000000000000000000000000000..8d6abc5618927fb2ddf49400932809448ebef26c
--- /dev/null
+++ b/tests/zoo/inst/zoo_00.inst
@@ -0,0 +1 @@
+f0=1,f1=0,f1=0,f1=1,f1=0,f1=0,f1=1,f1=1,f1=1,f1=1,f1=0,f1=0,f1=4,f1=0,f1=0,f1=1
\ No newline at end of file
diff --git a/tests/zoo/inst/zoo_01.inst b/tests/zoo/inst/zoo_01.inst
new file mode 100644
index 0000000000000000000000000000000000000000..4a6df5103d348fbf79e75654cb20f9594d47e842
--- /dev/null
+++ b/tests/zoo/inst/zoo_01.inst
@@ -0,0 +1 @@
+1,0,0,1,0,0,0,1,1,1,0,0,4,1,0,1
\ No newline at end of file
diff --git a/tests/zoo/inst/zoo_02.inst b/tests/zoo/inst/zoo_02.inst
new file mode 100644
index 0000000000000000000000000000000000000000..d72c0ae09ad51c4f6ec073b66e773beb18515be4
--- /dev/null
+++ b/tests/zoo/inst/zoo_02.inst
@@ -0,0 +1 @@
+0,0,1,0,0,1,1,1,1,0,0,1,0,1,0,0
\ No newline at end of file
diff --git a/tests/zoo/inst/zoo_11.inst b/tests/zoo/inst/zoo_11.inst
new file mode 100644
index 0000000000000000000000000000000000000000..0fa9d7c8a871929cbe518a7be16966fc2f7b9a6d
--- /dev/null
+++ b/tests/zoo/inst/zoo_11.inst
@@ -0,0 +1 @@
+0,1,1,0,1,0,0,0,1,1,0,0,2,1,1,0
\ No newline at end of file
diff --git a/tests/zoo/zoo.csv b/tests/zoo/zoo.csv
new file mode 100644
index 0000000000000000000000000000000000000000..7eb9774cdc5f452baac8ed8d4ea0efe83a466386
--- /dev/null
+++ b/tests/zoo/zoo.csv
@@ -0,0 +1,102 @@
+hair,feathers,eggs,milk,airborne,aquatic,predator,toothed,backbone,breathes,venomous,fins,legs,tail,domestic,catsize,class_type
+1,0,0,1,0,0,1,1,1,1,0,0,4,0,0,1,mammal
+1,0,0,1,0,0,0,1,1,1,0,0,4,1,0,1,mammal
+0,0,1,0,0,1,1,1,1,0,0,1,0,1,0,0,fish
+1,0,0,1,0,0,1,1,1,1,0,0,4,0,0,1,mammal
+1,0,0,1,0,0,1,1,1,1,0,0,4,1,0,1,mammal
+1,0,0,1,0,0,0,1,1,1,0,0,4,1,0,1,mammal
+1,0,0,1,0,0,0,1,1,1,0,0,4,1,1,1,mammal
+0,0,1,0,0,1,0,1,1,0,0,1,0,1,1,0,fish
+0,0,1,0,0,1,1,1,1,0,0,1,0,1,0,0,fish
+1,0,0,1,0,0,0,1,1,1,0,0,4,0,1,0,mammal
+1,0,0,1,0,0,1,1,1,1,0,0,4,1,0,1,mammal
+0,1,1,0,1,0,0,0,1,1,0,0,2,1,1,0,bird
+0,0,1,0,0,1,1,1,1,0,0,1,0,1,0,0,fish
+0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,invertebrate
+0,0,1,0,0,1,1,0,0,0,0,0,4,0,0,0,invertebrate
+0,0,1,0,0,1,1,0,0,0,0,0,6,0,0,0,invertebrate
+0,1,1,0,1,0,1,0,1,1,0,0,2,1,0,0,bird
+1,0,0,1,0,0,0,1,1,1,0,0,4,1,0,1,mammal
+0,0,1,0,0,1,1,1,1,0,0,1,0,1,0,1,fish
+0,0,0,1,0,1,1,1,1,1,0,1,0,1,0,1,mammal
+0,1,1,0,1,0,0,0,1,1,0,0,2,1,1,0,bird
+0,1,1,0,1,1,0,0,1,1,0,0,2,1,0,0,bird
+1,0,0,1,0,0,0,1,1,1,0,0,4,1,0,1,mammal
+0,1,1,0,1,0,0,0,1,1,0,0,2,1,0,1,bird
+0,0,1,0,0,0,0,0,0,1,0,0,6,0,0,0,bug
+0,0,1,0,0,1,1,1,1,1,0,0,4,0,0,0,amphibian
+0,0,1,0,0,1,1,1,1,1,1,0,4,0,0,0,amphibian
+1,0,0,1,1,0,0,1,1,1,0,0,2,1,0,0,mammal
+1,0,0,1,0,0,0,1,1,1,0,0,4,1,0,1,mammal
+1,0,0,1,0,0,1,1,1,1,0,0,2,0,1,1,mammal
+0,0,1,0,1,0,0,0,0,1,0,0,6,0,0,0,bug
+1,0,0,1,0,0,0,1,1,1,0,0,4,1,1,1,mammal
+1,0,0,1,0,0,0,1,1,1,0,0,2,0,0,1,mammal
+0,1,1,0,1,1,1,0,1,1,0,0,2,1,0,0,bird
+0,0,1,0,0,1,0,1,1,0,0,1,0,1,0,0,fish
+1,0,0,1,0,0,0,1,1,1,0,0,4,1,1,0,mammal
+1,0,0,1,0,0,0,1,1,1,0,0,4,1,0,0,mammal
+0,1,1,0,1,0,1,0,1,1,0,0,2,1,0,0,bird
+0,0,1,0,0,1,1,1,1,0,0,1,0,1,0,0,fish
+1,0,1,0,1,0,0,0,0,1,1,0,6,0,1,0,bug
+1,0,1,0,1,0,0,0,0,1,0,0,6,0,0,0,bug
+0,1,1,0,0,0,1,0,1,1,0,0,2,1,0,0,bird
+0,0,1,0,1,0,1,0,0,1,0,0,6,0,0,0,bug
+0,1,1,0,1,0,0,0,1,1,0,0,2,1,0,0,bird
+1,0,0,1,0,0,1,1,1,1,0,0,4,1,0,1,mammal
+1,0,0,1,0,0,1,1,1,1,0,0,4,1,0,1,mammal
+0,0,1,0,0,1,1,0,0,0,0,0,6,0,0,0,invertebrate
+1,0,0,1,0,0,1,1,1,1,0,0,4,1,0,1,mammal
+1,0,0,1,0,1,1,1,1,1,0,0,4,1,0,1,mammal
+1,0,0,1,0,0,1,1,1,1,0,0,4,1,0,0,mammal
+1,0,0,1,0,0,1,1,1,1,0,0,4,1,0,1,mammal
+1,0,1,0,1,0,0,0,0,1,0,0,6,0,0,0,bug
+0,0,1,0,0,1,1,1,1,1,0,0,4,1,0,0,amphibian
+0,0,1,0,0,1,1,0,0,0,0,0,8,0,0,1,invertebrate
+1,0,0,1,0,0,1,1,1,1,0,0,4,1,0,0,mammal
+1,0,0,1,0,0,0,1,1,1,0,0,4,1,0,1,mammal
+0,1,1,0,0,0,0,0,1,1,0,0,2,1,0,1,bird
+0,1,1,0,1,0,0,0,1,1,0,0,2,1,1,0,bird
+0,1,1,0,0,1,1,0,1,1,0,0,2,1,0,1,bird
+0,1,1,0,1,0,0,0,1,1,0,0,2,1,0,0,bird
+0,0,1,0,0,1,1,1,1,0,0,1,0,1,0,1,fish
+0,0,1,0,0,1,1,1,1,0,0,1,0,1,0,0,fish
+0,0,1,0,0,0,1,1,1,1,1,0,0,1,0,0,reptile
+1,0,1,1,0,1,1,0,1,1,0,0,4,1,0,1,mammal
+1,0,0,1,0,0,1,1,1,1,0,0,4,1,0,1,mammal
+1,0,0,1,0,0,0,1,1,1,0,0,4,1,1,1,mammal
+0,0,0,1,0,1,1,1,1,1,0,1,0,1,0,1,mammal
+1,0,0,1,0,0,1,1,1,1,0,0,4,1,0,1,mammal
+1,0,0,1,0,0,1,1,1,1,0,0,4,1,1,1,mammal
+1,0,0,1,0,0,1,1,1,1,0,0,4,1,0,1,mammal
+1,0,0,1,0,0,0,1,1,1,0,0,4,1,1,1,mammal
+0,1,1,0,0,0,1,0,1,1,0,0,2,1,0,1,bird
+0,0,0,0,0,0,1,0,0,1,1,0,8,1,0,0,invertebrate
+0,0,1,0,0,1,0,1,1,0,0,1,0,1,0,0,fish
+1,0,0,1,0,1,1,1,1,1,0,1,0,0,0,1,mammal
+1,0,0,1,0,1,1,1,1,1,0,1,2,1,0,1,mammal
+0,0,0,0,0,1,1,1,1,0,1,0,0,1,0,0,reptile
+0,0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,invertebrate
+0,1,1,0,1,1,1,0,1,1,0,0,2,1,0,0,bird
+0,1,1,0,1,1,1,0,1,1,0,0,2,1,0,0,bird
+0,0,1,0,0,0,1,1,1,1,0,0,0,1,0,0,reptile
+0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,invertebrate
+0,0,1,0,0,1,0,1,1,0,0,1,0,1,0,0,fish
+0,1,1,0,1,0,0,0,1,1,0,0,2,1,0,0,bird
+1,0,0,1,0,0,0,1,1,1,0,0,2,1,0,0,mammal
+0,0,1,0,0,1,1,0,0,0,0,0,5,0,0,0,invertebrate
+0,0,1,0,0,1,1,1,1,0,1,1,0,1,0,1,fish
+0,1,1,0,1,1,0,0,1,1,0,0,2,1,0,1,bird
+0,0,1,0,0,0,0,0,0,1,0,0,6,0,0,0,bug
+0,0,1,0,0,1,0,1,1,1,0,0,4,0,0,0,amphibian
+0,0,1,0,0,0,0,0,1,1,0,0,4,1,0,1,reptile
+0,0,1,0,0,0,1,1,1,1,0,0,4,1,0,0,reptile
+0,0,1,0,0,1,1,1,1,0,0,1,0,1,0,1,fish
+1,0,0,1,1,0,0,1,1,1,0,0,2,1,0,0,mammal
+1,0,0,1,0,0,0,1,1,1,0,0,4,1,0,0,mammal
+0,1,1,0,1,0,1,0,1,1,0,0,2,1,0,1,bird
+1,0,0,1,0,0,0,1,1,1,0,0,2,1,0,1,mammal
+1,0,1,0,1,0,0,0,0,1,1,0,6,0,0,0,bug
+1,0,0,1,0,0,1,1,1,1,0,0,4,1,0,1,mammal
+0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,invertebrate
+0,1,1,0,1,0,0,0,1,1,0,0,2,1,0,0,bird
\ No newline at end of file
diff --git a/tests/zoo/zoo.dt b/tests/zoo/zoo.dt
new file mode 100644
index 0000000000000000000000000000000000000000..a1ee6427913de0385b71077c93d9889e0479c78d
--- /dev/null
+++ b/tests/zoo/zoo.dt
@@ -0,0 +1,85 @@
+41
+1
+I 1 2 3 6 9 10 12 14 17 18 20 21 22 24 28 30 33 35 37 38
+T 4 5 7 8 11 13 15 16 19 23 25 26 27 29 31 32 34 36 39 40 41
+4 T bug
+5 T mammal
+7 T bird
+8 T bug
+11 T mammal
+13 T fish
+15 T bird
+16 T reptile
+19 T mammal
+23 T reptile
+25 T reptile
+26 T bird
+27 T fish
+29 T amphibian
+31 T amphibian
+32 T reptile
+34 T invertebrate
+36 T invertebrate
+39 T invertebrate
+40 T bug
+41 T invertebrate
+1 f4 0 2
+1 f4 1 9
+2 f0 0 3
+2 f0 1 6
+3 f10 0 4
+3 f10 1 5
+6 f12 1 7
+6 f12 5 7
+6 f12 9 7
+6 f12 11 7
+6 f12 3 8
+6 f12 7 8
+9 f15 0 10
+9 f15 1 17
+10 f3 0 11
+10 f3 1 12
+12 f11 0 13
+12 f11 1 14
+14 f12 1 15
+14 f12 9 15
+14 f12 3 16
+14 f12 5 16
+14 f12 7 16
+14 f12 11 16
+17 f8 0 18
+17 f8 1 33
+18 f0 0 19
+18 f0 1 20
+20 f12 1 21
+20 f12 9 21
+20 f12 3 28
+20 f12 5 28
+20 f12 7 28
+20 f12 11 28
+21 f6 0 22
+21 f6 1 27
+22 f10 0 23
+22 f10 1 24
+24 f12 9 25
+24 f12 1 26
+24 f12 3 26
+24 f12 5 26
+24 f12 7 26
+24 f12 11 26
+28 f10 0 29
+28 f10 1 30
+30 f5 0 31
+30 f5 1 32
+33 f5 0 34
+33 f5 1 35
+35 f13 0 36
+35 f13 1 37
+37 f9 0 38
+37 f9 1 41
+38 f12 1 39
+38 f12 5 39
+38 f12 9 39
+38 f12 11 39
+38 f12 3 40
+38 f12 7 40
diff --git a/tests/zoo/zoo.json b/tests/zoo/zoo.json
new file mode 100644
index 0000000000000000000000000000000000000000..506568b6a24d9f5066f1673d69e24a45d1109299
--- /dev/null
+++ b/tests/zoo/zoo.json
@@ -0,0 +1,18 @@
+{
+"hair":1,
+"feathers":0,
+"eggs":0,
+"milk":1,
+"airborne":0,
+"aquatic":0,
+"predator":0,
+"toothed":1,
+"backbone":1,
+"breathes":1,
+"venomous":0,
+"fins":0,
+"legs":6,
+"tail":1,
+"domestic":0,
+"catsize":1
+}
diff --git a/tests/zoo/zoo.map b/tests/zoo/zoo.map
new file mode 100644
index 0000000000000000000000000000000000000000..89838b19a6ef9d3425d66ce4c6ec27f5c3981fdd
--- /dev/null
+++ b/tests/zoo/zoo.map
@@ -0,0 +1,38 @@
+Categorical
+16
+f0 0 =1
+f0 1 =0
+f1 0 =1
+f1 1 =0
+f2 0 =1
+f2 1 =0
+f3 0 =1
+f3 1 =0
+f4 0 =1
+f4 1 =0
+f5 0 =1
+f5 1 =0
+f6 0 =1
+f6 1 =0
+f7 0 =1
+f7 1 =0
+f8 0 =1
+f8 1 =0
+f9 0 =1
+f9 1 =0
+f10 0 =1
+f10 1 =0
+f11 0 =1
+f11 1 =0
+f12 1 =2
+f12 3 =6
+f12 5 =5
+f12 7 =8
+f12 9 =0
+f12 11 =4
+f13 0 =1
+f13 1 =0
+f14 0 =1
+f14 1 =0
+f15 0 =1
+f15 1 =0
diff --git a/tests/zoo/zoo.pkl b/tests/zoo/zoo.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..edfd6540dd861d1260292b0bce1efe6d6a809461
Binary files /dev/null and b/tests/zoo/zoo.pkl differ
diff --git a/utils.py b/utils.py
index b3429106341c7d07009843c22547057ee72e2ab5..42b30c99af3af1b8463b3aa8e29f1834e974e0b3 100644
--- a/utils.py
+++ b/utils.py
@@ -2,6 +2,7 @@ import base64
 import io
 import pickle
 import joblib
+import json
 
 import numpy as np
 from dash import html
@@ -43,14 +44,16 @@ def parse_contents_instance(contents, filename):
     try:
         if '.csv' in filename:
             data = decoded.decode('utf-8')
+            data = str(data).strip().split(',')
+            data = list(map(lambda i: tuple([i[0], np.float32(i[1])]), [i.split('=') for i in data]))
         elif '.txt' in filename:
-            data = decoded.decode('utf-8')       
-        elif '.json' in filename:
             data = decoded.decode('utf-8')
-        else : 
+            data = str(data).strip().split(',')
+            data = list(map(lambda i: tuple([i[0], np.float32(i[1])]), [i.split('=') for i in data]))       
+        elif '.json' in filename:
             data = decoded.decode('utf-8')
-        data = str(data).strip().split(',')
-        data = list(map(lambda i: tuple([i[0], np.float32(i[1])]), [i.split('=') for i in data]))
+            data = json.loads(data)
+            data = list(tuple(data.items()))
     except Exception as e:
         print(e)
         return html.Div([