diff --git a/.gitignore b/.gitignore
index 1412f3b8b77cfb067d6cc3bdbcdfeaa6465e817c..c6169d23442ed264fecf043ac1b88614a75858a5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,6 +16,9 @@
 /Tst/tst/install-sh
 /Tst/tst/missing
 /Tst/tst/tst.desktop
+/Tst/confignator/confignator/confignator.log
+/Tst/test_specs/
+/Tst/logs_test_runs/
 
 ### Example user template
 !.gitkeep
diff --git a/Ccs/editor.py b/Ccs/editor.py
index 6b3af4c828a614bb9d8931f6b95a1a08cca64e8c..586f48be7b2413fe1cdaaeb5919ef56621f59720 100644
--- a/Ccs/editor.py
+++ b/Ccs/editor.py
@@ -1015,6 +1015,7 @@ class CcsEditor(Gtk.Window):
     def _check_unsaved_buffers(self):
         for page in self.editor_notebook:
             label = self.editor_notebook.get_tab_label(page).get_children()[0]
+            save_as = False
             if label.get_text()[0] == '*':
                 ask = UnsavedBufferDialog(parent=self, msg='Unsaved changes in {}. Save?'.format(label.get_text()[1:]))
                 response = ask.run()
@@ -1022,13 +1023,19 @@ class CcsEditor(Gtk.Window):
                 if response == Gtk.ResponseType.YES:
                     buf = page.get_child().get_buffer()
                     text = buf.get_text(*buf.get_bounds(), True)
-                    with open(label.get_tooltip_text(), 'w') as fdesc:
-                        fdesc.write(text)
+                    if label.get_tooltip_text():
+                        with open(label.get_tooltip_text(), 'w') as fdesc:
+                            fdesc.write(text)
+                    else:
+                        save_as = True
                 elif response == Gtk.ResponseType.CANCEL:
                     ask.destroy()
                     return False
 
                 ask.destroy()
+                if save_as:
+                    self.on_menu_file_saveas(label=label)
+
         return True
 
     """ save the buffer and reconnect the "changed" signal signal """
diff --git a/Ccs/getting_started.py b/Ccs/getting_started.py
index e840c1a1ec5e0b46cfa97fcc51f48e274a7b8a6a..b0c15007b3fa97d007b97cf9d3ab4b7340799f93 100644
--- a/Ccs/getting_started.py
+++ b/Ccs/getting_started.py
@@ -1,4 +1,3 @@
-
 # This File gives a basic overview on the most important Functions to use the CCS
 
 # If it is not already running start the ccs.py file, this file will appear there automatically
diff --git a/Tst/json_to_barescript.py b/Tst/json_to_barescript.py
index 48cb0e2ae8b8d1571d81e81d8b007e1a1387d921..7ca49e2a6bc9bb08a575589fc40c4a6cb25d7179 100755
--- a/Tst/json_to_barescript.py
+++ b/Tst/json_to_barescript.py
@@ -1,40 +1,67 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
+"""
+Generates a small Test Script from an existing json Test Specification, mostly used during internal testing and
+debugging Process, For the real tests the more extensive Test Scripts are generated by the TST (included logging,
+step id, run id,...)
+author: Marko Mecina
+date: 01.08.2021
+edited: Dominik Möslinger
+"""
 
 import datetime
+import os
 import json
 import sys
 
-jfile = sys.argv[1]
-# = 'IASW-FFT-1-TS-1.csv.json'
 
-data = json.load(open(jfile, 'r'))
-date = datetime.datetime.now().strftime('%Y-%m-%d')
+def run(jfile, outfile):
+    data = json.load(open(jfile, 'r'))
+    date = datetime.datetime.now().strftime('%Y-%m-%d')
 
-script = ''
+    script = ''
 
-script += '#--------------------------------------------\n'
-script += '# ' + data['_name'] + '\n'
-script += '# ' + data['_description'] + '\n'
-script += '# Version: ' + data['_version'] + '\n'
-script += '# Author: UVIE\n# Date: {}\n'.format(date)
-script += '#--------------------------------------------\n\n\n'
+    script += '#--------------------------------------------\n'
+    script += '# ' + data['_name'] + '\n'
+    script += '# ' + data['_description'] + '\n'
+    script += '# Specification Version: ' + data['_spec_version'] + '\n'
+    script += '# Software Version: ' + data['sw_version'] + '\n'
+    script += '# Author: UVIE\n# Date: {}\n'.format(date)
+    script += '#--------------------------------------------\n\n\n'
 
-script += '# Precond.\n# {}\n\n\n'.format(data['_precon_descr'])
+    script += '# Precond.\n# {}\n'.format(data['_precon_descr'])
+    # script += '{}\n\n\n'.format(data['_precon_code'].strip())  # Add the precondition code
 
-for step in data['sequences'][0]['steps']:
-    comment = '# COMMENT: {}\n'.format(step['_step_comment'].strip()) if step['_step_comment'] != '' else ''
+    for step in data['sequences'][0]['steps']:
+        comment = '# COMMENT: {}\n'.format(step['_step_comment'].strip()) if step['_step_comment'] != '' else ''
 
-    txt = '# STEP {}\n' \
-          '# {}\n' \
-          '{}\n' \
-          '# VERIFICATION: {}\n{}\n\n'.format(step['_step_number'], step['_description'].strip(), step['_command_code'].strip(), step['_verification_description'].strip(), comment)
+        txt = '# STEP {}\n' \
+              '# {}\n' \
+              '{}\n' \
+              '# VERIFICATION: {}\n{}\n\n'.format(step['_step_number'], step['_description'].strip(),
+                                                  step['_command_code'].strip(),
+                                                  step['_verification_description'].strip(),
+                                                  # step['_verification_code'].strip(), # Add verification code
+                                                  comment)
 
-    script += txt
+        script += txt
 
-script += '# Postcond.\n# {}\n'.format(data['_postcon_descr'])
+    script += '# Postcond.\n# {}\n'.format(data['_postcon_descr'])
+    # script += data['_postcon_code'].strip()  # Add the postcondition code
 
-outpath = '/'.join(jfile.split('/')[:-1]) + '/'
-outfile = outpath + data['_name'] + '-' + '-'.join(data['_version'].split('-')[-2:]) + '.py'
+    if outfile[-1] == '/':  # If path is given not the actual filename
+        outfile = outfile + data['_name'] + '-TS' + '-'.join(data['_spec_version']) + '.py'
 
-with open(outfile, 'w') as fd:
-    fd.write(script)
+    with open(outfile, 'w') as fd:
+        fd.write(script)
+
+
+if __name__ == '__main__':
+    json_file_path = sys.argv[1]
+
+    if len(sys.argv) > 1:  # If filename is given
+        outputfile = sys.argv[2]
+    else:  # If no filename is given take the working directory path, filename is used from the json file
+        outputfile = os.getcwd() + '/'
+        #outputfile = '/'.join(json_file_path[:-len(json_file_path.split('/')[-1])-1]) + '/'  # This would take the json File path
+
+    run(json_file_path, outputfile)
diff --git a/Tst/json_to_csv.py b/Tst/json_to_csv.py
index 33a044c85e74c53cb0f9f2a0d53752fea4359aa1..3243f6858b11e31ed819063e6231c3204fbe7fbf 100755
--- a/Tst/json_to_csv.py
+++ b/Tst/json_to_csv.py
@@ -2,34 +2,46 @@
 
 import datetime
 import json
+import os
 import sys
 
-jfile = sys.argv[1]
-# = 'IASW-FFT-1-TS-1.csv.json'
+def run(jfile, outfile):
 
-data = json.load(open(jfile, 'r'))
+    data = json.load(open(jfile, 'r'))
 
-header = 'Item|Description|Verification|TestResult'
-name = '{}|{}|Test spec. version: {}|'.format(data['_name'], data['_description'], data['_version'])
-date = 'Date||{}|'.format(datetime.datetime.now().strftime('%Y-%m-%d'))
-precond = 'Precond.|{}||'.format(data['_precon_descr'])
-postcond = 'Postcond.|{}||'.format(data['_postcon_descr'])
-steps = []
+    header = 'Item|Description|Verification|TestResult'
+    name = '{}|{}|Test spec. version: {}| IASW-{}'.format(data['_name'], data['_description'], data['_spec_version'], data['_sw_version'])
+    # Date from last time the json file was changed + current date
+    date = 'Date||{}|{}'.format(datetime.datetime.strftime(datetime.datetime.fromtimestamp(os.stat(jfile).st_mtime), '%Y-%m-%d'), datetime.datetime.now().strftime('%Y-%m-%d'))
+    precond = 'Precond.|{}||'.format(data['_precon_descr'])
+    postcond = 'Postcond.|{}||'.format(data['_postcon_descr'])
+    steps = []
 
-for step in data['sequences'][0]['steps']:
+    for step in data['sequences'][0]['steps']:
 
-    line = 'Step {}|{}|{}|'.format(step['_step_number'], step['_description'], step['_verification_description'])
-    steps.append(line)
+        line = 'Step {}|{}|{}|'.format(step['_step_number'], step['_description'], step['_verification_description'])
+        steps.append(line)
 
-    if step['_step_comment'] != '':
-        comment = 'Comment|{}||'.format(step['_step_comment'])
-        steps.append(comment)
+        if step['_step_comment'] != '':
+            comment = 'Comment|{}||'.format(step['_step_comment'])
+            steps.append(comment)
 
+    if outfile[-1] == '/':  # If only path is given but no filename
+        outfile = outfile + data['_name'] + '-' + '-'.join(data['_spec_version'].split('-')[-2:]) + '.csv_PIPE'
 
-outpath = '/'.join(jfile.split('/')[:-1]) + '/'
-outfile = outpath + data['_name'] + '-' + '-'.join(data['_version'].split('-')[-2:]) + '.csv_PIPE'
+    with open(outfile, 'w') as fd:
+        buf = '\n'.join([header, name, date, precond] + steps + [postcond])
+        buf = buf.replace('_', '\\_')
+        fd.write(buf)
 
-with open(outfile, 'w') as fd:
-    buf = '\n'.join([header, name, date, precond] + steps + [postcond])
-    buf = buf.replace('_', '\\_')
-    fd.write(buf)
+
+if __name__ == '__main__':
+    json_file_path = sys.argv[1]
+
+    if len(sys.argv) > 1:  # If filename is given
+        outputfile = sys.argv[2]
+    else:  # If no filename is given take the working directory path, filename is used from the json file
+        outputfile = os.getcwd() + '/'
+        # outputfile = '/'.join(json_file_path[:-len(json_file_path.split('/')[-1])-1]) + '/'  # This would take the json File path
+
+    run(json_file_path, outputfile)
diff --git a/Tst/progress_view/progress_view.py b/Tst/progress_view/progress_view.py
index 2eb93362baacc89aa72c9438828c3d30e04694e8..f17d75672abce08830bb2e46d9dd5fcd41fa9eaa 100644
--- a/Tst/progress_view/progress_view.py
+++ b/Tst/progress_view/progress_view.py
@@ -228,6 +228,7 @@ class TestProgressView(Gtk.ApplicationWindow):
         self.resize(
             int(confignator.get_option(section='progress-viewer-window-size', option='basic-width-step-mode')),
             int(confignator.get_option(section='progress-viewer-window-size', option='basic-height')))
+        self.sort_button.set_active(True)
         self.show_all()
         logger.debug('__init__ succeeded')
 
@@ -292,7 +293,6 @@ class TestProgressView(Gtk.ApplicationWindow):
 
         self.sort_button = Gtk.Switch()
         self.sort_button.connect("notify::active", self.on_remake_treeview)
-        self.sort_button.set_active(True)
         self.box_buttons.pack_end(self.sort_button, False, True, 0)
 
         self.sort_label2 = Gtk.Label()
@@ -341,7 +341,7 @@ class TestProgressView(Gtk.ApplicationWindow):
 
         # column 4
         renderer_cmd_version = Gtk.CellRendererText(xalign=0.5)
-        column_cmd_version = Gtk.TreeViewColumn('Version', renderer_cmd_version, text=3, background=7)
+        column_cmd_version = Gtk.TreeViewColumn('Spec. Version', renderer_cmd_version, text=3, background=7)
         column_cmd_version.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
         column_cmd_version.set_resizable(True)
         column_cmd_version.set_min_width(50)
@@ -607,7 +607,7 @@ class TestProgressView(Gtk.ApplicationWindow):
         if not test_name and self.path_json:
             test_name = self.path_json.split('/')[-1].split('.')[0]
 
-        dialog = Save_to_File_Dialog(parent=self)
+        dialog = Save_to_File_Dialog(parent=self)  # Look were the output file should be saved and which files (log, json) should be used
         response = dialog.run()
         if response == Gtk.ResponseType.OK:
             if not test_name:
@@ -623,7 +623,7 @@ class TestProgressView(Gtk.ApplicationWindow):
             sent_run_id = None
             if run_count:
                 for run_id in self.run_count.keys():
-                    if self.run_count[run_id] == run_count:
+                    if self.run_count[run_id] == str(run_count):
                         sent_run_id = run_id
             if not log_file_path:
                 if not dialog.log_file_path_check.get_active():
@@ -641,7 +641,7 @@ class TestProgressView(Gtk.ApplicationWindow):
             return
 
         dialog.destroy()
-        if log_file_path == 'FIND':
+        if log_file_path == 'FIND':  # Get the log file path if they are not already given
             dialog = File_Path_Dialog(parent=self, file='Command or Verification Log File', is_json=False)
             response = dialog.run()
             if response == Gtk.ResponseType.OK:
@@ -651,7 +651,7 @@ class TestProgressView(Gtk.ApplicationWindow):
                 return
         dialog.destroy()
 
-        if json_file_path == 'FIND':
+        if json_file_path == 'FIND':  # Get the json file if it is not already given
             dialog = File_Path_Dialog(parent=self, file='the Json File', is_json=True)
             response = dialog.run()
             if response == Gtk.ResponseType.OK:
@@ -674,7 +674,7 @@ class TestProgressView(Gtk.ApplicationWindow):
 
     # ------------------- model functions ----------------------
     @staticmethod
-    def build_row_list(row=None, step_number=None, exec_date=None, entry_type=None, version=None, status=None, tcs=None,
+    def build_row_list(row=None, step_number=None, exec_date=None, entry_type=None, spec_version=None, status=None, tcs=None,
                        result=None, step_desc=None, tooltip_text=None, exec_int=None, exec_desc=None, sort_button_active=False):
         """
         Builds or updates a row of the TreeStore. For a new row, the argument 'row' is expected to be None.
@@ -682,7 +682,7 @@ class TestProgressView(Gtk.ApplicationWindow):
         :param str step_number:
         :param datetime.datetime exec_date:
         :param str entry_type:
-        :param str version:
+        :param str spec_version:
         :param str status:
         :param str tcs:
         :param boolean result:
@@ -729,8 +729,8 @@ class TestProgressView(Gtk.ApplicationWindow):
                 row[1] = exec_date
             if entry_type is not None:
                 row[2] = entry_type
-            if version is not None:
-                row[3] = version
+            if spec_version is not None:
+                row[3] = spec_version
             if status is not None:
                 row[4] = status
             if tcs is not None:
@@ -747,7 +747,7 @@ class TestProgressView(Gtk.ApplicationWindow):
                     step_number,
                     exec_date,
                     entry_type,
-                    version,
+                    spec_version,
                     status,
                     tcs,
                     result_value,
@@ -763,7 +763,7 @@ class TestProgressView(Gtk.ApplicationWindow):
                     step_number,
                     exec_date,
                     entry_type,
-                    version,
+                    spec_version,
                     status,
                     tcs,
                     result_value,
@@ -907,7 +907,7 @@ class TestProgressView(Gtk.ApplicationWindow):
         #   for item in row.iterchildren():
         #       if item[2] == 'specification':
         #           tree_store.remove(item.iter)
-        # # add a row for (**each version of**) the step specification
+        # # add a row for (**each spec version of**) the step specification
         # for row in tree_store:
         #     step_number_tree_store = int(row[0:1][0])
         #     for key in test_model.steps_dict:
@@ -1014,7 +1014,7 @@ class TestProgressView(Gtk.ApplicationWindow):
                             for item in cmd_steps:
                                 if item['run_id'] == exec_num and item['step'] == step_num:
                                     new_row_list = self.build_row_list(entry_type='command',
-                                                                       version=item['version'],
+                                                                       spec_version=item['spec_version'],
                                                                        exec_date=item['exec_date'],
                                                                        sort_button_active=self.sort_button.get_active(),
                                                                        tooltip_text=item['descr'])
@@ -1085,7 +1085,7 @@ class TestProgressView(Gtk.ApplicationWindow):
                         # # add a new row
                         # if not already_exists:
                         new_row_list = self.build_row_list(entry_type='command',
-                                                           version=item['version'],
+                                                           spec_version=item['spec_version'],
                                                            exec_date=item['exec_date'],
                                                            sort_button_active=self.sort_button.get_active(),
                                                            tooltip_text=item['descr'])
@@ -1196,7 +1196,7 @@ class TestProgressView(Gtk.ApplicationWindow):
                             for item in vrc_steps:
                                 if item['run_id'] == exec_num and item['step'] == step_num:
                                     new_row_list = self.build_row_list(entry_type='verification',
-                                                                       version=item['version'],
+                                                                       spec_version=item['spec_version'],
                                                                        exec_date=item['exec_date'],
                                                                        sort_button_active=self.sort_button.get_active(),
                                                                        tooltip_text=item['descr'])
@@ -1262,7 +1262,7 @@ class TestProgressView(Gtk.ApplicationWindow):
                         # # add a new row
                         # if not already_exists:
                         new_row_list = self.build_row_list(entry_type='verification',
-                                                           version=item['version'],
+                                                           spec_version=item['spec_version'],
                                                            exec_date=item['exec_date'],
                                                            sort_button_active=self.sort_button.get_active(),
                                                            tooltip_text=item['descr'])
@@ -1295,11 +1295,12 @@ class Save_to_File_Dialog(Gtk.FileChooserDialog):
     def __init__(self, parent=None):
         super(Save_to_File_Dialog, self).__init__(title='Please choose a Folder to save the Test Run',
                                        parent=parent,
-                                       action=Gtk.FileChooserAction.SELECT_FOLDER)
+                                       action=Gtk.FileChooserAction.OPEN_FOLDER)
 
         self.win = parent
         self.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_SAVE, Gtk.ResponseType.OK)
         self.set_current_folder(confignator.get_option(section='tst-logging', option='output-file-path'))
+        #self.set_current_name('{}-IASW-{}TS-{}TR-{}'.format())
 
         area = self.get_content_area()
 
@@ -1343,11 +1344,17 @@ class Save_to_File_Dialog(Gtk.FileChooserDialog):
             if iter:  # If a selection is made try to set it as active row, otherwise Whole file is active row
                 selected_step_id = model.get_value(iter, 12)  # Get the value
                 if not selected_step_id:  # Only execution rows ('Run X') have entry at coloumn 12, others dont
-                    self.run_id_selection.set_active(0)
+                    try:
+                        self.run_id_selection.set_active(1)
+                    except:
+                        self.run_id_selection.set_active(0)
                 else:
                     self.run_id_selection.set_active(int(self.win.run_count[selected_step_id]))
             else:
-                self.run_id_selection.set_active(0)
+                try:
+                    self.run_id_selection.set_active(1)
+                except:
+                    self.run_id_selection.set_active(0)
             self.run_id_selection.set_tooltip_text('Define which Run should be saved or the whole Log File')
 
         test_report_label = Gtk.Label(label='Test Report: ')
diff --git a/Tst/spec_to_json.py b/Tst/spec_to_json.py
index bf33d3fc284644c538f9b9739681b804c42a5804..5b8aaf3776b979d0eccd30bc2582fddbb4ef4e4d 100755
--- a/Tst/spec_to_json.py
+++ b/Tst/spec_to_json.py
@@ -7,16 +7,20 @@ sys.path.append('../Ccs')
 import ccs_function_lib as cfl
 
 
-def run(specfile, gen_cmd):
+def run(specfile, gen_cmd, save_json):
     tmp = json.load(open('tst_template_empty.json', 'r'))
     jspec = tmp.copy()
     specs = open(specfile, 'r').read().split('\n')
 
-    name, descr, *_ = specs[1].split('|')
+    name, descr, spec_version_entry, sw_version_entry = specs[1].split('|')
+    spec_version = spec_version_entry.split('version: ')[-1]
+    sw_version = sw_version_entry.split('IASW-')[-1]
 
     jspec['_name'] = name
     jspec['_description'] = descr
-    jspec['_version'] = ''
+    jspec['_spec_version'] = spec_version
+    jspec['_sw_version'] = sw_version
+    jspec['_primary_counter_locked'] = False
 
     steps = jspec['sequences'][0]['steps']
     step_temp = steps[0].copy()
@@ -37,8 +41,10 @@ def run(specfile, gen_cmd):
             step['_step_comment'] = descr
             continue
 
-        step_temp['_step_number'] = n.replace('Step ', '') + '.0'
-        step_temp['_primary_counter'] = int(n.replace('Step ', ''))
+        step_num = n.replace('Step ', '')
+        step_temp['_step_number'] = step_num
+        step_temp['_primary_counter'] = int(step_num.split('.')[0])
+        step_temp['_secondary_counter'] = int(step_num.split('.')[1])
         step_temp['_description'] = descr
         step_temp['_verification_description'] = ver
 
@@ -67,7 +73,11 @@ def run(specfile, gen_cmd):
         steps.append(step_temp.copy())
 
     jspec['sequences'][0]['steps'] = steps
-    json.dump(jspec, open(specfile + '.json', 'w'), indent=4)
+    if save_json:
+        json.dump(jspec, open(specfile + '.json', 'w'), indent=4)
+    else:
+        json_data = json.dumps(jspec)
+        return jspec
 
 
 if __name__ == "__main__":
@@ -78,4 +88,5 @@ if __name__ == "__main__":
         gen_cmd = True
 
     specfile = sys.argv[1]
-    run(specfile, gen_cmd)
+    save = True
+    run(specfile, gen_cmd, save)
diff --git a/Tst/testing_library/testlib/analyse_command_log.py b/Tst/testing_library/testlib/analyse_command_log.py
index d61d4ed5915c02eb936b3e8c0eedf9e8f1863873..3fb6af54577c87a5332765b391c46e609c6841e7 100644
--- a/Tst/testing_library/testlib/analyse_command_log.py
+++ b/Tst/testing_library/testlib/analyse_command_log.py
@@ -114,7 +114,7 @@ def get_steps_and_commands(filename):
     steps_end = []
 
     def new_step_template_start():
-        return {'step': None, 'version': '', 'tcs': [], 'date': ''}
+        return {'step': None, 'spec_version': '', 'tcs': [], 'date': ''}
 
     def new_step_template_end():
         return {'step': None, 'timestamp': '', 'step_id': ''}
@@ -140,7 +140,8 @@ def get_steps_and_commands(filename):
                 if step_start_info is not None:
                     new_step['step'] = step_start_info['step']
                     new_step['start_timestamp'] = step_start_info['timestamp']
-                    new_step['version'] = step_start_info['version']
+                    new_step['spec_version'] = step_start_info['spec_version']
+                    new_step['iasw_version'] = step_start_info['iasw_version']
                     new_step['descr'] = step_start_info['descr']
                     new_step['run_id'] = step_start_info['run_id']
                     new_step['step_id'] = step_start_info['step_id']
diff --git a/Tst/testing_library/testlib/analyse_test_run.py b/Tst/testing_library/testlib/analyse_test_run.py
index a64a7f866b62663b78dd9c3b2681c605e06d5af6..e72bcc16e2e3f965ec5c24c07d18bbf1b16c6d90 100644
--- a/Tst/testing_library/testlib/analyse_test_run.py
+++ b/Tst/testing_library/testlib/analyse_test_run.py
@@ -87,7 +87,7 @@ def save_result_to_file(test_name, log_file_path=None, output_file_path=None, js
     general_run_infos, precon_info, postcon_info = analyse_command_log.get_general_run_info(cmd_log_file, run_id=run_id)
 
     # Give the output file its name, consits of test name, the specification nbr (version)
-    name_start = '{}-TS-{}-TR-'.format(test_name, cmd_steps[0]['version'])
+    name_start = '{}-TS-{}-TR-'.format(test_name, cmd_steps[0]['spec_version'])
 
     # Check if output folder exists otherwise make it
     if not os.path.isdir(output_file_path):
@@ -115,9 +115,9 @@ def save_result_to_file(test_name, log_file_path=None, output_file_path=None, js
         writer.writerow(output_file_header)
 
         # write the general info line, if multiple descriptions/versions are found all are written to the output file
-        version = get_version(cmd_steps, logger)
+        spec_version, iasw_version = get_version(cmd_steps, logger)
         description = get_general_run_info_info(general_run_infos, 'descr', logger)
-        writer.writerow([test_name, description, 'Test Spec. Version: ' + version, 'Test Rep. Version: ' + f'{test_report:03d}'])
+        writer.writerow([test_name, description, 'Test Spec. Version: ' + 'IASW-{}TS-{}'.format(iasw_version, spec_version), 'Test Rep. Version: ' + f'{test_report:03d}'])
 
         # write date line, first Date (Specification Date) is the last time the json file was changed or None if no json file was given
         # second Date (Execution Date), Is the execution Date of the first step
@@ -182,21 +182,37 @@ def get_version(steps, logger):
     :param list of dicts steps: all the steps from the log file
     :return str version_final: A string that contains all found versions
     """
-    version_list = []
-    version_final = ''
+    spec_version_list = []
+    spec_version_final = ''
+    iasw_version_list = []
+    iasw_version_final = ''
     for step in steps:
-        if step['version'] not in version_list:
-            version_list.append(step['version'])
-    for count, version in enumerate(version_list):
+        if step['spec_version'] not in spec_version_list:
+            spec_version_list.append(step['spec_version'])
+        if step['iasw_version'] not in iasw_version_list:
+            iasw_version_list.append(step['iasw_version'])
+
+    for count, version in enumerate(spec_version_list):
         if count == 0:
-            version_final = version
+            spec_version_final = version
         else:
-            version_final += ' / ' + version
+            spec_version_final += ' / ' + version
             if logger:
-                logger.warning('More than one Version was found in the command log File')
+                logger.warning('More than one Specification Version was found in the command log File')
             else:
-                print('More than one Version was found in the command log File')
-    return version_final
+                print('More than one Specification Version was found in the command log File')
+
+    for count, version in enumerate(iasw_version_list):
+        if count == 0:
+            iasw_version_final = version
+        else:
+            iasw_version_final += ' / ' + version
+            if logger:
+                logger.warning('More than one IASW Version was found in the command log File')
+            else:
+                print('More than one IASW Version was found in the command log File')
+
+    return spec_version_final, iasw_version_final
 
 def show_basic_results(test_name, log_file_path=None):
     """
diff --git a/Tst/testing_library/testlib/analyse_verification_log.py b/Tst/testing_library/testlib/analyse_verification_log.py
index 1340f4b37c9542018525e8e87d311dc3e47f8e1c..75f9074cc01874601d2a7aedefcda19c29ca8561 100644
--- a/Tst/testing_library/testlib/analyse_verification_log.py
+++ b/Tst/testing_library/testlib/analyse_verification_log.py
@@ -55,7 +55,7 @@ def get_verification_steps(filename):
         new_vrc_step['step'] = item['step']
         new_vrc_step['start_timestamp'] = item['timestamp']
         new_vrc_step['exec_date'] = item['exec_date']
-        new_vrc_step['version'] = item['version']
+        new_vrc_step['spec_version'] = item['spec_version']
         new_vrc_step['vrc_descr'] = item['vrc_descr']
         new_vrc_step['descr'] = item['descr']
         new_vrc_step['run_id'] = item['run_id']
diff --git a/Tst/testing_library/testlib/report.py b/Tst/testing_library/testlib/report.py
index ac6920e00717d9c3230447417373f0e78f2bd278..f7abc97473d0389e78b45ab032546435080a9e79 100644
--- a/Tst/testing_library/testlib/report.py
+++ b/Tst/testing_library/testlib/report.py
@@ -49,7 +49,7 @@ def key_word_found(line, key_word):
     return found
 
 
-def encode_to_json_string(step_number, timestamp, step_version=None, step_result=None, descr=None, run_id=None, step_id=None, comment=None, vrc_descr=None):
+def encode_to_json_string(step_number, timestamp, spec_version=None, iasw_version=None, step_result=None, descr=None, run_id=None, step_id=None, comment=None, vrc_descr=None):
     """
     Make a JSON string out of the step number and timestamp
     :param step_number: number of the step
@@ -59,8 +59,10 @@ def encode_to_json_string(step_number, timestamp, step_version=None, step_result
     """
     od = collections.OrderedDict([('step', step_number),
                                   ('timestamp', timestamp)])
-    if step_version is not None:
-        od['version'] = step_version
+    if spec_version is not None:
+        od['spec_version'] = spec_version
+    if iasw_version is not None:
+        od['iasw_version'] = iasw_version
     if step_result is not None:
         od['result'] = step_result
     if vrc_descr is not None:
@@ -110,12 +112,12 @@ def parse_step_from_json_string(line, key_word):
             logger.error('parse_tc_id_from_json_string: parsing of the TC JSON string failed!')
 
 
-def command_step_begin(step_param, script_version, pool_name, step_start_cuc, run_id, step_id):
+def command_step_begin(step_param, spec_version, iasw_version, pool_name, step_start_cuc, run_id, step_id):
     """
     Builds a string and writes it into the logging file. A keyword is set to enable a machine read out of the log file.
     All information of the step is written in a JSON string.
     :param step_param:
-    :param script_version:
+    :param spec__version:
     :param pool_name:
     :param step_start_cuc:
     :return:
@@ -125,7 +127,8 @@ def command_step_begin(step_param, script_version, pool_name, step_start_cuc, ru
                                   step_param['step_no'],
                                   encode_to_json_string(step_number=step_param['step_no'],
                                                         timestamp=step_start_cuc,
-                                                        step_version=script_version,
+                                                        spec_version=spec_version,
+                                                        iasw_version=iasw_version,
                                                         run_id=run_id,
                                                         step_id=step_id,
                                                         descr=step_param['descr'],
@@ -145,13 +148,13 @@ def command_step_end(step_param, step_end_cuc, step_id):
     logger.info('{} {}\n'.format(cmd_step_keyword_done, encode_to_json_string(step_param['step_no'], step_end_cuc, step_id=step_id)))
 
 
-def verification_step_begin(step_param, script_version, pool_name, step_start_cuc, run_id, step_id):
+def verification_step_begin(step_param, spec_version, pool_name, step_start_cuc, run_id, step_id):
 
     logger.info('{} {} {}'.format(vrc_step_keyword,
                                   step_param['step_no'],
                                   encode_to_json_string(step_number=step_param['step_no'],
                                                         timestamp=step_start_cuc,
-                                                        step_version=script_version,
+                                                        spec_version=spec_version,
                                                         vrc_descr=step_param['vrc_descr'],
                                                         run_id=run_id,
                                                         step_id=step_id,
diff --git a/Tst/tst/data_model.py b/Tst/tst/data_model.py
index 24ea10b9dc0bc5ea24509d31e2c3a69ae3be7303..2c795eaef9b5124a962ce024c38e87a277ec9360 100644
--- a/Tst/tst/data_model.py
+++ b/Tst/tst/data_model.py
@@ -339,7 +339,7 @@ class TestSequence:
         self._sequence = sequence
         self._name = ''
         self._description = ''
-        self._version = ''
+        self._spec_version = ''
         self._primary_counter_locked = False
         self.steps = []
 
@@ -354,7 +354,7 @@ class TestSequence:
         new_test_seq.sequence = copy.copy(self.sequence)
         new_test_seq.name = copy.copy(self.name)
         new_test_seq.description = copy.copy(self.description)
-        new_test_seq.version = copy.copy(self.version)
+        new_test_seq.spec_version = copy.copy(self.spec_version)
         new_test_seq.primary_counter_locked = copy.copy(self.primary_counter_locked)
         new_test_seq.steps = copy.deepcopy(self.steps)
 
@@ -397,13 +397,13 @@ class TestSequence:
         self._description = value
 
     @property
-    def version(self):
-        return self._version
+    def spec_version(self):
+        return self._spec_version
 
-    @version.setter
-    def version(self, value: str):
+    @spec_version.setter
+    def spec_version(self, value: str):
         assert isinstance(value, str)
-        self._version = value
+        self._spec_version = value
 
     def verify_step_list_consistency(self) -> bool:
         """
@@ -863,7 +863,7 @@ class TestSequence:
         try:
             self.name = json_data['_name']
             self.description = json_data['_description']
-            self.version = json_data['_version']
+            self.spec_version = json_data['_spec_version']
             self.sequence = json_data['_sequence']
         except KeyError as keyerror:
             self.logger.error('KeyError: no {} could be found in the loaded data'.format(keyerror))
@@ -900,7 +900,8 @@ class TestSpecification:
         self.logger = logger
         self._name = ''
         self._description = ''
-        self._version = ''
+        self._spec_version = ''
+        self._iasw_version = ''
         self._primary_counter_locked = False
         self._precon_name = ''
         self._precon_code = ''
@@ -920,7 +921,8 @@ class TestSpecification:
         new_testspec.sequences = copy.copy(self.sequences)
         new_testspec.name = copy.copy(self.name)
         new_testspec.description = copy.copy(self.description)
-        new_testspec.version = copy.copy(self.version)
+        new_testspec.spec_version = copy.copy(self.spec_version)
+        new_testspec.iasw_version = copy.copy(self.iasw_version)
         new_testspec.primary_counter_locked = copy.copy(self.primary_counter_locked)
         new_testspec.precon_name = copy.copy(self.precon_name)
         new_testspec.precon_code = copy.copy(self.precon_code)
@@ -964,13 +966,22 @@ class TestSpecification:
         self._description = value
 
     @property
-    def version(self):
-        return self._version
+    def spec_version(self):
+        return self._spec_version
 
-    @version.setter
-    def version(self, value: str):
+    @spec_version.setter
+    def spec_version(self, value: str):
         assert isinstance(value, str)
-        self._version = value
+        self._spec_version = value
+
+    @property
+    def iasw_version(self):
+        return self._iasw_version
+
+    @iasw_version.setter
+    def iasw_version(self, value: str):
+        assert isinstance(value, str)
+        self._iasw_version = value
 
     @property
     def precon_name(self):
@@ -1050,7 +1061,8 @@ class TestSpecification:
         try:
             self.name = json_data['_name']
             self.description = json_data['_description']
-            self.version = json_data['_version']
+            self.spec_version = json_data['_spec_version']
+            self.iasw_version = json_data['_iasw_version']
             self.primary_counter_locked = json_data['_primary_counter_locked']
             self.precon_name = json_data['_precon_name']
             self.precon_code = json_data['_precon_code']
diff --git a/Tst/tst/file_management.py b/Tst/tst/file_management.py
index 55005a6e8f36a03efb9d30a05b7453a4b1687b41..91570433e7748ba3e28cded6685722b221f1cb7d 100644
--- a/Tst/tst/file_management.py
+++ b/Tst/tst/file_management.py
@@ -36,6 +36,7 @@ def save_file(file_path, test_spec, file_extension=None, logger=module_logger, *
             logger.exception(e)
             logger.error('Failed to json-dump the instance into a file')
 
+    return
 
 def _to_json_string(test_to_save):
     assert isinstance(test_to_save, data_model.TestSequence)
@@ -55,3 +56,7 @@ def _from_json(text_io):
     data = text_io.read()
     decoded_data = json.loads(data)
     return decoded_data
+
+
+def from_json(text_io):
+    return _from_json(text_io)
diff --git a/Tst/tst/generator.py b/Tst/tst/generator.py
index f68a5385ac2d4e32dcc135253bf3650232bf87cf..76cea11cc7052c70841ef6a309f303c575afdead 100644
--- a/Tst/tst/generator.py
+++ b/Tst/tst/generator.py
@@ -109,7 +109,8 @@ def make_command_script(model, model_spec):
                                    testSpecFileName=create_file_name(model_spec.name),
                                    testSpecName=model_spec.name,
                                    testSpecDescription=model_spec.description,
-                                   testSpecVersion=model_spec.version,
+                                   testSpecVersion=model_spec.spec_version,
+                                   testIaswVersion=model_spec.iasw_version,
                                    testPreCondition=model_spec.precon_name,
                                    testPostCondition=model_spec.postcon_name,
                                    testComment=test_comment_w_indent)
@@ -277,7 +278,7 @@ def make_verification_script(model, model_spec):
                                    testSpecFileName=create_file_name(model_spec.name),
                                    testSpecName=model_spec.name,
                                    testSpecDescription=model_spec.description,
-                                   testSpecVersion=model_spec.version)
+                                   testSpecVersion=model_spec.spec_version)
         # add the header string
         content += '\n\n' + cls
 
diff --git a/Tst/tst/generator_templates/co_class.py b/Tst/tst/generator_templates/co_class.py
index 5138db8681caaff54fb40181696479b77eea185b..70d63d35e3f3f4d0870a63a4fe44900b16bb7492 100644
--- a/Tst/tst/generator_templates/co_class.py
+++ b/Tst/tst/generator_templates/co_class.py
@@ -2,6 +2,8 @@ class ${testSpecClassName}:
     def __init__(self, do_verification=False):
         self.id = '${testSpecFileName}'
         self.name = '${testSpecName}'
+        self.spec_version = '${testSpecVersion}'
+        self.iasw_version = '${testIaswVersion}'
         self.description = '${testSpecDescription}'
         self.precondition = '${testPreCondition}'
         self.postcondition = '${testPostCondition}'
@@ -19,7 +21,3 @@ class ${testSpecClassName}:
 
         # some tests are depended on other tests, thus information is stored on class level
         # insert class variables here
-
-    @staticmethod
-    def version():
-        return '${testSpecVersion}'
diff --git a/Tst/tst/generator_templates/co_pre_condition.py b/Tst/tst/generator_templates/co_pre_condition.py
index c4ca54867c084c20dbdb12f8650154f09d0a9808..b21e30d17a7d31dbeedce5019aa2311174c4b508 100644
--- a/Tst/tst/generator_templates/co_pre_condition.py
+++ b/Tst/tst/generator_templates/co_pre_condition.py
@@ -35,8 +35,9 @@
         testing_logger.cmd_log_handler(__name__)
         step_id = self.check_run_and_step_id(pool_name=pool_name)
         step_start_cuc = cfl.get_last_pckt_time(pool_name=pool_name, string=False)
-        report.command_step_begin(step_param=param, script_version=self.version(), pool_name=pool_name,
-                                  step_start_cuc=step_start_cuc, run_id=self.run_id, step_id=step_id)
+        report.command_step_begin(step_param=param, spec_version=self.spec_version, iasw_version=self.iasw_version,
+                                  pool_name=pool_name, step_start_cuc=step_start_cuc, run_id=self.run_id,
+                                  step_id=step_id)
 
         summary = report.StepSummary(step_number=param['step_no'])
         return step_start_cuc, summary, step_id
diff --git a/Tst/tst/generator_templates/ver_class.py b/Tst/tst/generator_templates/ver_class.py
index 4e380dd70830c1b97cea2d023a93200ad21db5f2..e04cc3ac803b2a5f4fedce20d3dd6b2646146da1 100644
--- a/Tst/tst/generator_templates/ver_class.py
+++ b/Tst/tst/generator_templates/ver_class.py
@@ -18,7 +18,7 @@ class ${testSpecClassName}Verification:
         # insert class variables here
 
     @staticmethod
-    def version():
+    def spec_version():
         return '${testSpecVersion}'
 
     def verify(self, command_log_file, saved_pool_file):
@@ -57,5 +57,5 @@ class ${testSpecClassName}Verification:
                 self.run_id = now.strftime("%Y%m%d%H%M%S")
 
         step_start_cuc = cfl.get_last_pckt_time(pool_name=pool_name, string=False)
-        report.verification_step_begin(step_param=param, script_version=self.version(), pool_name=pool_name,
+        report.verification_step_begin(step_param=param, spec_version=self.spec_version(), pool_name=pool_name,
                                        step_start_cuc=step_start_cuc, run_id=self.run_id, step_id=step_id)
diff --git a/Tst/tst/tst.py b/Tst/tst/tst.py
index b8d4741ed8054d89016c511a6125dcc25e6d8b3d..42be742bc957b2f5b26ccff8f07a910b3c2779fc 100755
--- a/Tst/tst/tst.py
+++ b/Tst/tst/tst.py
@@ -4,13 +4,16 @@ import os
 import logging
 import time
 import gi
+
 gi.require_version('Gtk', '3.0')
 gi.require_version('GtkSource', '3.0')
 from gi.repository import Gtk, Gdk, Gio, GtkSource, GLib
 import confignator
 import sys
+
 sys.path.append(confignator.get_option('paths', 'ccs'))
 import ccs_function_lib as cfl
+
 cfl.add_tst_import_paths()
 import view
 import data_model
@@ -22,15 +25,11 @@ import connect_apps
 import dbus
 import toolbox
 import tc_management as tcm
-
-
+import json_to_barescript
+import json_to_csv
+import spec_to_json
 
 # creating lists for type and subtype to get rid of duplicate entries, for TC List
-
-
-
-
-
 path_icon = os.path.join(os.path.dirname(__file__), 'style/tst.svg')
 menu_xml = os.path.join(os.path.dirname(__file__), 'app_menu.xml')
 css_file = os.path.join(os.path.dirname(__file__), 'style/style.css')
@@ -126,7 +125,9 @@ class TstApp(Gtk.Application):
         return
 
     def _on_quit(self, action, param):
-        self.window.on_delete_event()
+        response = self.window.on_delete_event()
+        if response:
+            return
         self.quit()
         return
 
@@ -179,7 +180,6 @@ class TestInstance:
     def filename(self, value):
         self._filename = value
 
-
 class TstAppWindow(Gtk.ApplicationWindow):
 
     def __init__(self, logger=logger, *args, **kwargs):
@@ -205,12 +205,17 @@ class TstAppWindow(Gtk.ApplicationWindow):
         action.connect('activate', self.on_save_as)
         self.add_action(action)
 
+        action = Gio.SimpleAction.new('csv_to_json', None)
+        action.connect('activate', self.on_csv_to_json)
+        self.add_action(action)
+
         action = Gio.SimpleAction.new('close', None)
         action.connect('activate', self.on_close)
         self.add_action(action)
 
         show_json_view = confignator.get_bool_option('tst-preferences', 'show-json-view')
-        action = Gio.SimpleAction.new_stateful('model_viewer_toggle_hide', None, GLib.Variant.new_boolean(show_json_view))
+        action = Gio.SimpleAction.new_stateful('model_viewer_toggle_hide', None,
+                                               GLib.Variant.new_boolean(show_json_view))
         action.connect('change-state', self.model_viewer_toggle_hide)
         self.add_action(action)
 
@@ -218,6 +223,8 @@ class TstAppWindow(Gtk.ApplicationWindow):
         action.connect('activate', self.on_apply_css)
         self.add_action(action)
 
+        self.create_make_menu()
+
         self.set_icon_from_file(path_icon)
 
         # GUI
@@ -241,10 +248,6 @@ class TstAppWindow(Gtk.ApplicationWindow):
         self.btn_save.set_icon_name('document-save')
         self.btn_save.set_tooltip_text('Save')
         self.btn_save.connect('clicked', self.on_save)
-        self.btn_show_model_viewer = Gtk.ToolButton()
-        self.btn_show_model_viewer.set_icon_name('accessories-dictionary-symbolic')
-        self.btn_show_model_viewer.set_tooltip_text('Show/hide model viewer')
-        self.btn_show_model_viewer.connect('clicked', self.model_viewer_toggle_hide)
         self.btn_generate_products = Gtk.ToolButton()
         self.btn_generate_products.set_label('Generate scripts')
         # self.btn_generate_products.set_icon_name('printer-printing-symbolic')
@@ -264,7 +267,6 @@ class TstAppWindow(Gtk.ApplicationWindow):
         self.toolbar.insert(self.btn_new_file, 0)
         self.toolbar.insert(self.btn_open_file, 1)
         self.toolbar.insert(self.btn_save, 2)
-        # self.toolbar.insert(self.btn_show_model_viewer, 2)
         self.toolbar.insert(self.btn_generate_products, 3)
         self.toolbar.insert(self.btn_start_ccs_editor, 4)
         self.toolbar.insert(self.btn_open_progress_view, 5)
@@ -307,7 +309,6 @@ class TstAppWindow(Gtk.ApplicationWindow):
         self.label_widget_tcm.set_text('TC Table')
         self.feature_area.append_page(child=self.tcm, tab_label=self.label_widget_tcm)
 
-
         """
         self.tcm = TCTableClass()
         self.label_widget_tcm = Gtk.Label()
@@ -315,8 +316,6 @@ class TstAppWindow(Gtk.ApplicationWindow):
         self.feature_area.append_page(child=self.tcm, tab_label=self.label_widget_tcm)
         """
 
-
-
         self.box.pack_start(self.work_desk, True, True, 0)
 
         # # panes for the step grid an so on
@@ -367,6 +366,19 @@ class TstAppWindow(Gtk.ApplicationWindow):
         Gtk.StyleContext.add_class(context, 'tst-css')
         self.on_apply_css()
 
+    def create_make_menu(self):
+        action = Gio.SimpleAction.new('generate_scripts', None)
+        action.connect('activate', self.on_generate_products)
+        self.add_action(action)
+
+        action = Gio.SimpleAction.new('generate_barescript', None)
+        action.connect('activate', self.on_generate_barescript)
+        self.add_action(action)
+
+        action = Gio.SimpleAction.new('generate_csv', None)
+        action.connect('activate', self.on_generate_csv)
+        self.add_action(action)
+
     def add_info_bar(self, message_type, message):
         """
         Adds a InfoBar and moves it below the toolbar
@@ -449,11 +461,11 @@ class TstAppWindow(Gtk.ApplicationWindow):
 
     def model_viewer_toggle_hide(self, action, value):
         visible = self.json_view.is_visible()
-        action.set_state(GLib.Variant.new_boolean(visible))
+        action.set_state(GLib.Variant.new_boolean(not visible))
         if visible:
-            self.json_view.show()
-        else:
             self.json_view.hide()
+        else:
+            self.json_view.show()
 
     def on_new_test(self, *args):
         # create a new test instance and add a sequence + first step
@@ -483,18 +495,19 @@ class TstAppWindow(Gtk.ApplicationWindow):
         Closing the page on which was clicked
         """
         for i in range(0, self.notebook.get_n_pages()):  # Loop over all availabe page numbers
-            page = self.notebook.get_nth_page(i)    # Get page widget
-            if self.notebook.get_tab_label(page) == widget.get_parent():    # Check if the label widget is the same as for the given widget
-                self.notebook.remove_page(i)    # If so close the page
+            page = self.notebook.get_nth_page(i)  # Get page widget
+            if self.notebook.get_tab_label(
+                    page) == widget.get_parent():  # Check if the label widget is the same as for the given widget
+                self.notebook.remove_page(i)  # If so close the page
                 return
 
-        #self.notebook.remove_page(widget.get_parent())
+        # self.notebook.remove_page(widget.get_parent())
 
     def on_open(self, *args):
         dialog = Gtk.FileChooserDialog('Please choose a file',
                                        self,
                                        Gtk.FileChooserAction.OPEN,
-                                       (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
+                                       (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
         # using the last folder from history
         last_folder = confignator.get_option('tst-history', 'last-folder')
         if os.path.isdir(last_folder):
@@ -504,28 +517,52 @@ class TstAppWindow(Gtk.ApplicationWindow):
         if response == Gtk.ResponseType.OK:
             file_selected = dialog.get_filename()
             confignator.save_option('tst-history', 'last-folder', os.path.dirname(file_selected))
-            data_from_file = file_management.open_file(file_name=file_selected)
+            try:
+                json_type = True
+                data_from_file = file_management.open_file(file_name=file_selected)
+                filename = file_selected
+            except json.decoder.JSONDecodeError:
+                # data_from_file = file_management.from_json(spec_to_json.run(specfile=file_selected, gen_cmd=True, save_json=False))
+                data_from_file = spec_to_json.run(specfile=file_selected, gen_cmd=True, save_json=False)
+                filename = file_selected.replace('.' + file_selected.split('.')[-1], '.json')
+                json_type = False
+                if os.path.exists(filename):
+                    self.existing_json_warn_dialog(filename)
+
             if data_from_file is not None:
-                # make a new test instance and notebook page
-                self.logger.info('make a new test instance and notebook page for: {}'.format(file_selected))
-                new_test = self.new_test()
-                new_test.model.decode_from_json(json_data=data_from_file)
-                new_test.filename = file_selected
-                new_page_index = self.new_page(test_instance=new_test)
-                self.update_model_viewer()
-                new_test.view.update_widget_data()
-                self.notebook.set_current_page(new_page_index)
-        elif response == Gtk.ResponseType.CANCEL:
-            pass
+                self.on_open_create_tab(data_from_file, filename, json_type)
+
         dialog.destroy()
+        return
+
+    def on_open_create_tab(self, data_from_file, filename, json_type):
+        # make a new test instance and notebook page
+        self.logger.info('make a new test instance and notebook page for: {}'.format(filename))
+        new_test = self.new_test()
+        new_test.model.decode_from_json(json_data=data_from_file)
+        new_test.filename = filename
+        if not json:
+            new_test.ask_overwrite = True
+        else:
+            new_test.ask_overwrite = True
+        new_page_index = self.new_page(test_instance=new_test)
+        self.update_model_viewer()
+        new_test.view.update_widget_data()
+        self.notebook.set_current_page(new_page_index)
+        return
 
     def on_save(self, *args):
         # get the  data model of the current notebook page
         current_test = self.current_test_instance()
         current_model = self.current_model()
-        #current_model2=current_model.serialize(current_model)
+        # current_model2=current_model.serialize(current_model)
         if current_model is not None and current_test.filename is None:
             self.save_as_file_dialog()
+        elif current_test and current_test.ask_overwrite and current_test.filename:
+            if os.path.exists(current_test.filename):
+                self.overwrite_dialog(current_test)
+            else:
+                self.save_as_file_dialog()
         elif current_model is not None:
             file_management.save_file(file_path=current_test.filename, test_spec=current_model, logger=self.logger)
 
@@ -541,38 +578,151 @@ class TstAppWindow(Gtk.ApplicationWindow):
                                        Gtk.FileChooserAction.SAVE,
                                        (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
         dialog.set_current_folder(confignator.get_option(section='tst-history', option='last-folder'))
-        dialog.set_current_name(current_name+'.json')
+        dialog.set_current_name('{}-TS-{}.json'.format(current_name, current_model.spec_version))
         self.add_filters(dialog)
+        dialog.set_do_overwrite_confirmation(True)
         response = dialog.run()
         if response == Gtk.ResponseType.OK:
             file_selected = dialog.get_filename()
             confignator.save_option('tst-history', 'last-folder', os.path.dirname(file_selected))
-            if '-v_' in file_selected:
-                test_name = file_selected.split('-v_')[0]
-                filename = file_selected
-            else:
-                test_name = file_selected.split('.json')[0]
-                filename = '{}-v_{}.json'.format(test_name, current_model.version)
-
-            file_management.save_file(file_path=filename, test_spec=current_model, file_extension='json', logger=self.logger)
-            current_test.filename = filename.split('/')[-1]
-            current_model.name = test_name.split('/')[-1]
-        elif response == Gtk.ResponseType.CANCEL:
-            pass
-        dialog.destroy()
-
-    def add_filters(self, dialog):
-        filter_text = Gtk.FileFilter()
-        filter_text.set_name('JSON format')
-        filter_text.add_mime_type('application/json')
-        filter_text.add_pattern('.json')
-        dialog.add_filter(filter_text)
+            file_management.save_file(file_path=file_selected, test_spec=current_model, file_extension='json',
+                                      logger=self.logger)
+            current_test.filename = file_selected
+            file_name = file_selected.split('/')[-1]
+            #current_model.name = file_selected.split('/')[-1].split('.')[0].split('-TS-')[0]  # Get only the name
+            current_test.update_widget_data()
+            self.notebook.set_tab_label(current_test, self.notebook_page_label(file_name))  # Update tab label
+            self.show_all()
+            dialog.destroy()
+            return True
+        else:
+            dialog.destroy()
+            return False
+
+    def add_filters(self, dialog, filter_json=True):
+        if json:
+            filter_text = Gtk.FileFilter()
+            filter_text.set_name('JSON format')
+            filter_text.add_mime_type('application/json')
+            filter_text.add_pattern('.json')
+            dialog.add_filter(filter_text)
+        else:
+            filter_text = Gtk.FileFilter()
+            filter_text.set_name('Spec Files')
+            filter_text.add_mime_type('text/csv')
+            filter_text.add_pattern('.csv*')
+            dialog.add_filter(filter_text)
 
         filter_any = Gtk.FileFilter()
         filter_any.set_name('Any files')
         filter_any.add_pattern('*')
         dialog.add_filter(filter_any)
 
+    def on_csv_to_json(self, *args):
+        dialog = Gtk.FileChooserDialog('Please choose a CSV File',
+                                       self,
+                                       Gtk.FileChooserAction.OPEN,
+                                       (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
+        # using the last folder from history
+        last_folder = confignator.get_option('tst-history', 'last-folder')
+        if os.path.isdir(last_folder):
+            dialog.set_current_folder(last_folder)
+        response = dialog.run()
+        self.add_filter_csv(dialog, filter_json=False)
+        if response == Gtk.ResponseType.OK:
+            confignator.save_option('tst-history', 'last-folder', dialog.get_current_folder())
+            file_selected = dialog.get_filename()
+            filename = file_selected.replace('.' + file_selected.split('.')[-1], '.json')
+            data_from_file = spec_to_json.run(specfile=file_selected, gen_cmd=True, save_json=False)
+            self.on_open_create_tab(data_from_file, filename, json_type=False)
+            self.on_open_create_tab(data_from_file, filename, json_type=False)
+            dialog.destroy()
+
+            self.save_as_file_dialog()
+        else:
+            dialog.destroy()
+
+        return
+
+    def overwrite_dialog(self, current_test):
+        filepath = current_test.filename
+        filename = filepath.split('/')[-1]
+        folder = filepath[:-len(filename)-1]
+        dialog = Gtk.MessageDialog()
+        dialog.add_buttons(Gtk.STOCK_YES, Gtk.ResponseType.YES, Gtk.STOCK_NO, Gtk.ResponseType.NO)
+        dialog.set_markup('Overwrite existing File?')
+        dialog.format_secondary_text('{} at {} already exists'.format(filename, folder))
+        response = dialog.run()
+
+        if response == Gtk.ResponseType.YES:
+            current_test.ask_overwrite = False
+            dialog.destroy()
+            self.on_save()
+        else:
+            dialog.destroy()
+
+        return
+
+    def existing_json_warn_dialog(self, filepath):
+        filename = filepath.split('/')[-1]
+        folder = filepath[:-len(filename)-1]
+        dialog = Gtk.MessageDialog()
+        dialog.add_buttons(Gtk.STOCK_OK, Gtk.ResponseType.OK)
+        dialog.set_markup('CSV converted Json File already Exists'.format(filename))
+        dialog.format_secondary_text('{} at {} already exists, temporarily saved in TST \nBe careful during saving'.format(filename, folder))
+        dialog.run()
+        dialog.destroy()
+        return True
+
+    def unsaved_changes_overwrite_dialog(self, current_test):
+        filepath = current_test.filename
+        filename = filepath.split('/')[-1]
+        folder = filepath[:-len(filename)-1]
+        dialog = Gtk.MessageDialog()
+        dialog.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_YES, Gtk.ResponseType.YES, Gtk.STOCK_NO, Gtk.ResponseType.NO)
+        dialog.set_markup('Unsaved changes in {}, Overwrite?'.format(filename))
+        dialog.format_secondary_text('{} at {} already exists'.format(filename, folder))
+        response = dialog.run()
+        if response == Gtk.ResponseType.YES:
+            current_test.ask_overwrite = False
+            dialog.destroy()
+            self.on_save()
+        elif response == Gtk.ResponseType.CANCEL:
+            dialog.destroy()
+            return False
+        else:
+            dialog.destroy()
+
+        return True
+
+    def unsaved_changes_newfile_dialog(self, current_test):
+        filepath = current_test.filename
+        if filepath:
+            filename = filepath.split('/')[-1]
+        else:
+            filename = 'New Test'
+        dialog = Gtk.MessageDialog()
+        dialog.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_YES, Gtk.ResponseType.YES, Gtk.STOCK_NO, Gtk.ResponseType.NO)
+        dialog.set_markup('Unsaved File {}, Save?'.format(filename))
+        #dialog.format_secondary_text('{} at {} is unsaved'.format(filename, folder))
+        response = dialog.run()
+
+        if response == Gtk.ResponseType.YES:
+            current_test.ask_overwrite = False
+            dialog.destroy()
+            response = self.save_as_file_dialog()
+            if response:
+                return True
+            else:
+                return False
+        elif response == Gtk.ResponseType.CANCEL:
+            dialog.destroy()
+            return False
+        else:
+            dialog.destroy()
+
+        return True
+
     def on_delete_event(self, *args):
         self.logger.info('save preferences')
         # saving the height and width of the main window
@@ -582,6 +732,28 @@ class TstAppWindow(Gtk.ApplicationWindow):
         confignator.save_option('tst-preferences', 'paned-position', str(self.work_desk.get_position()))
         # save the preferences of the CodeReuseFeature
         self.codeblockreuse.save_panes_positions()
+        self.logger.info('Check for Unsaved Buffer')
+        response = self._check_unsaved_buffer()
+        if not response:
+            return True
+        return False
+
+    def _check_unsaved_buffer(self):
+        for test_instance in self.notebook:
+            filename = test_instance.filename
+            tst_json = json.loads(test_instance.model.encode_to_json())
+            if filename and os.path.exists(filename):
+                file_json = file_management.open_file(filename)
+                if not tst_json == file_json:
+                    response = self.unsaved_changes_overwrite_dialog(test_instance)
+                    if not response:
+                        return False
+            else:
+                response = self.unsaved_changes_newfile_dialog(test_instance)
+                if not response:
+                    return False
+
+        return True
 
     def on_generate_products(self, *args):
         """
@@ -604,6 +776,70 @@ class TstAppWindow(Gtk.ApplicationWindow):
         # triggering the dialog after generation
         self.on_generate_products_message_dialog(paths=self.product_paths)
 
+    def on_generate_barescript(self, *args):
+        """
+        Generates a small python test file without all the additional staff from on_generate_scripts
+        """
+        dialog = Gtk.FileChooserDialog(
+            title="Save Script AS", parent=self, action=Gtk.FileChooserAction.SAVE)
+        dialog.add_buttons(
+            Gtk.STOCK_CANCEL,
+            Gtk.ResponseType.CANCEL,
+            Gtk.STOCK_SAVE,
+            Gtk.ResponseType.OK, )
+
+        if self.current_test_instance():
+            current_json_filename = self.current_test_instance().filename
+            current_model = self.current_model()
+        else:
+            logger.info('Small Script can not be generated without jsonfile')
+            print('Small Script can not be generated without json file')
+            return
+
+        outfile_basic = '{}-TS-{}.py'.format(current_model.name, current_model.spec_version)
+        dialog.set_current_name(outfile_basic)
+        dialog.set_current_folder(confignator.get_option('tst-history', 'last-folder'))
+
+        response = dialog.run()
+        if response == Gtk.ResponseType.OK:
+            json_to_barescript.run(current_json_filename, dialog.get_filename())
+            confignator.save_option('tst-history', 'last-folder', dialog.get_current_folder())
+
+        dialog.destroy()
+        return
+
+    def on_generate_csv(self, *args):
+        """
+        Generates a CSV Test Specification file
+        """
+        dialog = Gtk.FileChooserDialog(
+            title="Save CSV AS", parent=self, action=Gtk.FileChooserAction.SAVE)
+        dialog.add_buttons(
+            Gtk.STOCK_CANCEL,
+            Gtk.ResponseType.CANCEL,
+            Gtk.STOCK_SAVE,
+            Gtk.ResponseType.OK, )
+
+        if self.current_test_instance():
+            current_json_filename = self.current_test_instance().filename
+            current_model = self.current_model()
+        else:
+            logger.info('CSV File can not be generated without json file')
+            print('CSV File can not be generated without json file')
+            return
+
+        outfile_basic = '{}-IASW-{}-TS-{}.csv_PIPE'.format(current_model.name, current_model.iasw_version, current_model.spec_version)
+        dialog.set_current_name(outfile_basic)
+        dialog.set_current_folder(confignator.get_option('tst-history', 'last-folder'))
+
+        response = dialog.run()
+        if response == Gtk.ResponseType.OK:
+            json_to_csv.run(current_json_filename, dialog.get_filename())
+            confignator.save_option('tst-history', 'last-folder', dialog.get_current_folder())
+
+        dialog.destroy()
+        return
+
     def connect_to_ccs_editor(self):
         # get the DBus connection to the CCS-Editor
         editor = connect_apps.connect_to_editor()
@@ -717,7 +953,7 @@ class TstAppWindow(Gtk.ApplicationWindow):
         return paths
 
     def on_make_desktop_entry(self):
-        #ToDo: create a file for the desktop entry
+        # ToDo: create a file for the desktop entry
         pass
 
     def on_start_progress_viewer(self, *args):
@@ -815,7 +1051,7 @@ class ViewModelAsJson(Gtk.Box):
         """
         Gets the data of the model and makes a JSON string out of it. Intended to display the model data as plain JSON
         :param data_model.TestSpecification model: a instance of the TestSpecification class
-	    # param data_model.TestSequence model: a instance of the TestSpecification class
+        :param data_model.TestSequence model: a instance of the TestSpecification class
         """
         assert isinstance(model, data_model.TestSpecification) or model is None
         if model is not None:
diff --git a/Tst/tst/view.py b/Tst/tst/view.py
index e5360f945bc1a6e226e49498c88aad6559fde428..ae636b3920c79b9e31c662012384415679f8bac1 100644
--- a/Tst/tst/view.py
+++ b/Tst/tst/view.py
@@ -84,6 +84,8 @@ class Board(Gtk.Box):
         self.logger = logger
 
         self._test_is_locked = None
+        # Save Button in TST clicked for first time, Always do save_as to not overwrite something, used in tst.py
+        self._ask_overwrite = True
 
         Gtk.Box.__init__(self)
         self.set_orientation(Gtk.Orientation.VERTICAL)
@@ -113,13 +115,20 @@ class Board(Gtk.Box):
         self.test_meta_data_desc = Gtk.Entry()
         self.test_meta_data_desc.set_placeholder_text('< description of the test>')
         self.test_meta_data_entries.pack_start(self.test_meta_data_desc, True, True, 0)
-        # version
-        self.test_meta_data_version_label = Gtk.Label()
-        self.test_meta_data_version_label.set_text('Version:')
-        self.test_meta_data_labels.pack_start(self.test_meta_data_version_label, True, True, 0)
-        self.test_meta_data_version = Gtk.Entry()
-        self.test_meta_data_version.set_placeholder_text('< version >')
-        self.test_meta_data_entries.pack_start(self.test_meta_data_version, True, True, 0)
+        # spec_version
+        self.test_meta_data_spec_version_label = Gtk.Label()
+        self.test_meta_data_spec_version_label.set_text('Spec Version:')
+        self.test_meta_data_labels.pack_start(self.test_meta_data_spec_version_label, True, True, 0)
+        self.test_meta_data_spec_version = Gtk.Entry()
+        self.test_meta_data_spec_version.set_placeholder_text('< spec version >')
+        self.test_meta_data_entries.pack_start(self.test_meta_data_spec_version, True, True, 0)
+        # IASW Software Version
+        self.test_meta_data_iasw_version_label = Gtk.Label()
+        self.test_meta_data_iasw_version_label.set_text('IASW Version:')
+        self.test_meta_data_labels.pack_start(self.test_meta_data_iasw_version_label, True, True, 0)
+        self.test_meta_data_iasw_version = Gtk.Entry()
+        self.test_meta_data_iasw_version.set_placeholder_text('< IASW version >')
+        self.test_meta_data_entries.pack_start(self.test_meta_data_iasw_version, True, True, 0)
         # checkbox for locking the step numbers
         self.test_is_locked_label = Gtk.Label()
         self.test_is_locked_label.set_text(_('Lock step numeration:'))
@@ -217,7 +226,8 @@ class Board(Gtk.Box):
         # connect signals
         self.test_meta_data_name.connect('changed', self.on_test_name_change)
         self.test_meta_data_desc.connect('changed', self.on_test_desc_change)
-        self.test_meta_data_version.connect('changed', self.on_test_version_change)
+        self.test_meta_data_spec_version.connect('changed', self.on_test_spec_version_change)
+        self.test_meta_data_iasw_version.connect('changed', self.on_test_iasw_version_change)
         self.text_meta_data_test_is_locked.connect('toggled', self.on_test_locked_toggled)
         self.test_meta_data_comment.get_buffer().connect('changed', self.on_comment_change)
 
@@ -238,6 +248,14 @@ class Board(Gtk.Box):
     def filename(self, value):
         self._filename = value
 
+    @property
+    def ask_overwrite(self):
+        return self._ask_overwrite
+
+    @ask_overwrite.setter
+    def ask_overwrite(self, value):
+        self._ask_overwrite = value
+
     def update_widget_data(self):
         """
         Updates the grid with the steps. All widgets of the grid are destroyed. The grid is build new from the model.
@@ -256,8 +274,10 @@ class Board(Gtk.Box):
         self.test_meta_data_name.set_text(self.model.name)
         # set the description of the test specification using the data from the model
         self.test_meta_data_desc.set_text(self.model.description)
-        # set the version of the test specification from the data model
-        self.test_meta_data_version.set_text(self.model.version)
+        # set the Specification version of the test specification from the data model
+        self.test_meta_data_spec_version.set_text(self.model.spec_version)
+        # set the Software version of the test specification from the data model
+        self.test_meta_data_iasw_version.set_text(self.model.iasw_version)
         # set the pre-condition name
         if self.model.precon_name:
             found = False
@@ -443,11 +463,19 @@ class Board(Gtk.Box):
         # update the data model viewer
         self.app.update_model_viewer()
 
-    def on_test_version_change(self, widget):
-        # get the version out of the text buffer of the widget
-        version = widget.get_text()
+    def on_test_spec_version_change(self, widget):
+        # get the Specification Version out of the text buffer of the widget
+        spec_version = widget.get_text()
+        # update the model
+        self.model.spec_version = spec_version
+        # update the data model viewer
+        self.app.update_model_viewer()
+
+    def on_test_iasw_version_change(self, widget):
+        # get the IASW Version out of the text buffer of the widget
+        iasw_version = widget.get_text()
         # update the model
-        self.model.version = version
+        self.model.iasw_version = iasw_version
         # update the data model viewer
         self.app.update_model_viewer()
 
diff --git a/Tst/tst_template_empty.json b/Tst/tst_template_empty.json
index 5f9b979e0307a5b50d3ae5a75f2ae89a6636ee78..e89169b38c811d80a1361661e1eb12ef6c8c8952 100644
--- a/Tst/tst_template_empty.json
+++ b/Tst/tst_template_empty.json
@@ -9,14 +9,14 @@
       "_precon_descr": "",
       "_precon_name": "",
       "_primary_counter_locked": false,
-      "_version": "",
+      "_spec_version": "",
       "sequences": [
             {
                   "_description": "",
                   "_name": "",
                   "_primary_counter_locked": false,
                   "_sequence": 0,
-                  "_version": "",
+                  "_spec_version": "",
                   "steps": [
                         {
                               "_command_code": "",