diff --git a/source/python/_config.py b/source/python/_config.py
index 1460837cbd6eed37b9bc8eb23270ff5110a99826..27491f4447afe559b9690de6ab663e51e80cc9eb 100644
--- a/source/python/_config.py
+++ b/source/python/_config.py
@@ -29,7 +29,7 @@ import inspect
 
 _VERSION_STR = '7.1'
 
-QUEUES_LIST = ['ecgate', 'cca']
+QUEUES_LIST = ['ecgate', 'cca', 'ccb']
 
 # ------------------------------------------------------------------------------
 # FILENAMES
@@ -77,7 +77,7 @@ PATH_ECMWF_ENV = os.path.join(PATH_RUN_DIR, FILE_USER_ENVVARS)
 PATH_GRIBTABLE = os.path.join(PATH_TEMPLATES, FILE_GRIBTABLE)
 PATH_JOBSCRIPTS = os.path.join(PATH_RUN_DIR, 'jobscripts')
 PATH_FORTRAN_SRC = os.path.join(PATH_SOURCES, 'fortran')
-PATH_TEST_DIR = os.path.join(PATH_SOURCES, 'pythontest')
+PATH_PYTHONTEST_SRC = os.path.join(PATH_SOURCES, 'pythontest')
 PATH_INPUT_DIR = os.path.join(PATH_RUN_DIR, INPUT_DIRNAME_DEFAULT)
 if os.getenv('CONTROL'):
     # this is only needed if gateway version with job script is used!
diff --git a/source/python/classes/ControlFile.py b/source/python/classes/ControlFile.py
index a0f95918b702781fc7366e4e65ae175a95d59a91..bbf468c9a6258da59012f9fe1a3ad05d9c16c79d 100644
--- a/source/python/classes/ControlFile.py
+++ b/source/python/classes/ControlFile.py
@@ -147,6 +147,7 @@ class ControlFile(object):
         self.debug = 0
         self.request = 0
         self.public = 0
+        self.ecapi = None
 
         self.logicals = ['gauss', 'omega', 'omegadiff', 'eta', 'etadiff',
                          'dpdeta', 'cwc', 'wrf', 'grib2flexpart', 'ecstorage',
diff --git a/source/python/classes/EcFlexpart.py b/source/python/classes/EcFlexpart.py
index cb9a74b66c54a576dee7f80f076d4f960352af99..6576c892b69525b8fb9a5c587272316c2c2fc5a2 100644
--- a/source/python/classes/EcFlexpart.py
+++ b/source/python/classes/EcFlexpart.py
@@ -754,15 +754,12 @@ class EcFlexpart(object):
         # index_vals[1]: ('0', '1200', '1800', '600') ; time
         # index_vals[2]: ('0', '12', '3', '6', '9') ; stepRange
 
+        # initialize dictionaries
         valsdict = {}
         svalsdict = {}
-#        stepsdict = {}
         for p in pars:
             valsdict[str(p)] = []
             svalsdict[str(p)] = []
-#            stepsdict[str(p)] = []
-
-        print('maxstep: ', c.maxstep)
 
         # "product" genereates each possible combination between the
         # values of the index keys
@@ -827,7 +824,6 @@ class EcFlexpart(object):
                     values = grib_get_values(gid)
                     vdp = valsdict[cparamId]
                     svdp = svalsdict[cparamId]
- #                   sd = stepsdict[cparamId]
 
                     if cparamId == '142' or cparamId == '143':
                         fak = 1. / 1000.
@@ -1193,8 +1189,8 @@ class EcFlexpart(object):
             ofile = os.path.join(self.inputdir, ofile)
 
             if c.format.lower() == 'grib2':
-                p = subprocess.check_call(['grib_set', '-s', 'edition=2, \
-                                           productDefinitionTemplateNumber=8',
+                p = subprocess.check_call(['grib_set', '-s', 'edition=2,',
+                                           'productDefinitionTemplateNumber=8',
                                            ofile, ofile + '_2'])
                 p = subprocess.check_call(['mv', ofile + '_2', ofile])
 
diff --git a/source/python/mods/get_mars_data.py b/source/python/mods/get_mars_data.py
index 197c1c53157c7cae6a2ba290d2691dcded46baa0..b48859e4fea7f32f6c3db202b34b292620c2d8d3 100755
--- a/source/python/mods/get_mars_data.py
+++ b/source/python/mods/get_mars_data.py
@@ -41,7 +41,22 @@
 #    - do_retrievement
 #
 #*******************************************************************************
+"""ToDo: Name of litte program
 
+ToDo: Add desccription
+
+ToDo: Add Conditions
+
+This script requires that `...` be installed within the Python
+environment you are running this script in.
+
+This file can also be imported as a module and contains the following
+functions:
+
+    * get_mars_data -
+    * do_retrievement -
+    * main - the main function of the script
+"""
 # ------------------------------------------------------------------------------
 # MODULES
 # ------------------------------------------------------------------------------
@@ -90,7 +105,7 @@ def main():
     c.check_conditions(args.queue)
 
     get_mars_data(c)
-    normal_exit(c.mailfail, 'Done!')
+    normal_exit(c.mailops, c.queue, 'Done!')
 
     return
 
diff --git a/source/python/mods/tools.py b/source/python/mods/tools.py
index 2ab2ad4c2ec71d1a90f9f44dfad5d0418eddd1e0..d78a5f3a8834b2462f0aa9d738ad82fc789aac98 100644
--- a/source/python/mods/tools.py
+++ b/source/python/mods/tools.py
@@ -53,6 +53,7 @@ import sys
 import glob
 import subprocess
 import traceback
+import exceptions
 from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
 
 # ------------------------------------------------------------------------------
@@ -187,13 +188,13 @@ def get_cmdline_arguments():
 
     return args
 
-def read_ecenv(filename):
+def read_ecenv(filepath):
     '''Reads the file into a dictionary where the key values are the parameter
     names.
 
     Parameters
     ----------
-    filename : :obj:`string`
+    filepath : :obj:`string`
         Path to file where the ECMWF environment parameters are stored.
 
     Return
@@ -203,16 +204,25 @@ def read_ecenv(filename):
         and destination for ECMWF server environments.
     '''
     envs= {}
+    try:
+        with open(filepath, 'r') as f:
+            for line in f:
+                data = line.strip().split()
+                envs[str(data[0])] = str(data[1])
+    except OSError as e:
+        print('... ERROR CODE: ' + str(e.errno))
+        print('... ERROR MESSAGE:\n \t ' + str(e.strerror))
 
-    with open(filename, 'r') as f:
-        for line in f:
-            data = line.strip().split()
-            envs[str(data[0])] = str(data[1])
+        sys.exit('\n... Error occured while trying to read ECMWF_ENV '
+                     'file: ' + str(filepath))
 
     return envs
 
 def clean_up(c):
-    '''Remove all files from intermediate directory (inputdir).
+    '''Remove files from the intermediate directory (inputdir).
+
+    It keeps the final FLEXPART input files if program runs without
+    ECMWF Api and keywords "ectrans" or "ecstorage" are set to "1".
 
     Parameters
     ----------
@@ -225,16 +235,19 @@ def clean_up(c):
 
     '''
 
-    print("clean_up")
+    print("... clean inputdir!")
 
-    cleanlist = glob.glob(c.inputdir + "/*")
-    for clist in cleanlist:
-        if c.prefix not in clist:
-            silent_remove(clist)
-        if c.ecapi is False and (c.ectrans == '1' or c.ecstorage == '1'):
-            silent_remove(clist)
+    cleanlist = glob.glob(os.path.join(c.inputdir, "*"))
 
-    print("Done")
+    if cleanlist:
+        for element in cleanlist:
+            if c.prefix not in element:
+                silent_remove(element)
+            if c.ecapi is False and (c.ectrans == 1 or c.ecstorage == 1):
+                silent_remove(element)
+        print("... done!")
+    else:
+        print("... nothing to clean!")
 
     return
 
@@ -258,43 +271,32 @@ def my_error(users, message='ERROR'):
 
     '''
 
-    print(message)
+    trace = '\n'.join(traceback.format_stack())
+    full_message = message + '\n\n' + trace
 
-    # comment if user does not want email notification directly from python
-    for user in users:
-        if '${USER}' in user:
-            user = os.getenv('USER')
-        try:
-            p = subprocess.Popen(['mail', '-s flex_extract_v7.1 ERROR',
-                                  os.path.expandvars(user)],
-                                 stdin=subprocess.PIPE,
-                                 stdout=subprocess.PIPE,
-                                 stderr=subprocess.PIPE,
-                                 bufsize=1)
-            trace = '\n'.join(traceback.format_stack())
-            pout = p.communicate(input=message + '\n\n' + trace)[0]
-        except ValueError as e:
-            print('ERROR: ', e)
-            sys.exit('Email could not be sent!')
-        else:
-            print('Email sent to ' + os.path.expandvars(user) + ' ' +
-                  pout.decode())
+    print(full_message)
+
+    send_mail(users, 'ERROR', full_message)
 
     sys.exit(1)
 
     return
 
 
-def normal_exit(users, message='Done!'):
+def send_mail(users, success_mode, message):
     '''Prints a specific exit message which can be passed to the function.
 
     Parameters
     ----------
-    user : :obj:`list` of :obj:`string`
+    users : :obj:`list` of :obj:`string`
         Contains all email addresses which should be notified.
         It might also contain just the ecmwf user name which wil trigger
         mailing to the associated email address for this user.
 
+    success_mode : :obj:``string`
+        States the exit mode of the program to put into
+        the mail subject line.
+
     message : :obj:`string`, optional
         Message for exiting program. Default value is "Done!".
 
@@ -302,32 +304,53 @@ def normal_exit(users, message='Done!'):
     ------
 
     '''
-    print(message)
 
-    # comment if user does not want notification directly from python
     for user in users:
         if '${USER}' in user:
             user = os.getenv('USER')
         try:
-            p = subprocess.Popen(['mail', '-s flex_extract_v7.1 normal exit',
-                                  os.path.expandvars(user)],
+            p = subprocess.Popen(['mail', '-s flex_extract_v7.1 ' +
+                                  success_mode, os.path.expandvars(user)],
                                  stdin=subprocess.PIPE,
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE,
                                  bufsize=1)
-            pout = p.communicate(input=message+'\n\n')[0]
+            pout = p.communicate(input=message + '\n\n')[0]
         except ValueError as e:
-            print('ERROR: ', e)
-            print('Email could not be sent!')
+            print('... ERROR: ' + str(e))
+            sys.exit('... Email could not be sent!')
+        except OSError as e:
+            print('... ERROR CODE: ' + str(e.errno))
+            print('... ERROR MESSAGE:\n \t ' + str(e.strerror))
+            sys.exit('... Email could not be sent!')
         else:
-            print('Email sent to ' + os.path.expandvars(user) + ' ' +
-                  pout.decode())
+            print('Email sent to ' + os.path.expandvars(user))
+
+    return
+
+
+def normal_exit(message='Done!'):
+    '''Prints a specific exit message which can be passed to the function.
+
+    Parameters
+    ----------
+    message : :obj:`string`, optional
+        Message for exiting program. Default value is "Done!".
+
+    Return
+    ------
+
+    '''
+
+    print(str(message))
 
     return
 
 
 def product(*args, **kwds):
-    '''This method combines the single characters of the passed arguments
+    '''Creates combinations of all passed arguments.
+
+    This method combines the single characters of the passed arguments
     with each other. So that each character of each argument value
     will be combined with each character of the other arguments as a tuple.
 
@@ -344,7 +367,7 @@ def product(*args, **kwds):
 
     Parameters
     ----------
-    \*args : :obj:`tuple`
+    \*args : :obj:`list` or :obj:`string`
         Positional arguments (arbitrary number).
 
     \*\*kwds : :obj:`dictionary`
@@ -356,12 +379,15 @@ def product(*args, **kwds):
         Return will be done with "yield". A tuple of combined arguments.
         See example in description above.
     '''
-    pools = map(tuple, args) * kwds.get('repeat', 1)
-    result = [[]]
-    for pool in pools:
-        result = [x + [y] for x in result for y in pool]
-    for prod in result:
-        yield tuple(prod)
+    try:
+        pools = map(tuple, args) * kwds.get('repeat', 1)
+        result = [[]]
+        for pool in pools:
+            result = [x + [y] for x in result for y in pool]
+        for prod in result:
+            yield tuple(prod)
+    except TypeError as e:
+        sys.exit('... PRODUCT GENERATION FAILED!')
 
     return
 
@@ -382,8 +408,10 @@ def silent_remove(filename):
     try:
         os.remove(filename)
     except OSError as e:
-        if e.errno != errno.ENOENT:
-            # errno.ENOENT  =  no such file or directory
+        # errno.ENOENT  =  no such file or directory
+        if e.errno == errno.ENOENT:
+            pass
+        else:
             raise  # re-raise exception if a different error occured
 
     return
@@ -405,11 +433,19 @@ def init128(filepath):
         short name of the parameter.
     '''
     table128 = dict()
-    with open(filepath) as f:
-        fdata = f.read().split('\n')
-    for data in fdata:
-        if data[0] != '!':
-            table128[data[0:3]] = data[59:64].strip()
+    try:
+        with open(filepath) as f:
+            fdata = f.read().split('\n')
+    except OSError as e:
+        print('... ERROR CODE: ' + str(e.errno))
+        print('... ERROR MESSAGE:\n \t ' + str(e.strerror))
+
+        sys.exit('\n... Error occured while trying to read parameter '
+                 'table file: ' + str(filepath))
+    else:
+        for data in fdata:
+            if data[0] != '!':
+                table128[data[0:3]] = data[59:64].strip()
 
     return table128
 
@@ -436,6 +472,11 @@ def to_param_id(pars, table):
         List of addpar parameters from CONTROL file transformed to
         parameter ids in the format of integer.
     '''
+    if not pars:
+        return []
+    if not isinstance(pars, str):
+        pars=str(pars)
+
     cpar = pars.upper().split('/')
     ipar = []
     for par in cpar:
@@ -466,18 +507,22 @@ def get_list_as_string(list_obj, concatenate_sign=', '):
         The content of the list as a single string.
     '''
 
+    if not isinstance(list_obj, list):
+        list_obj = list(list_obj)
     str_of_list = concatenate_sign.join(str(l) for l in list_obj)
 
     return str_of_list
 
 def make_dir(directory):
-    '''Creates a directory and gives a warning if the directory
-    already exists. The program stops only if there is another problem.
+    '''Creates a directory.
+
+    It gives a warning if the directory already exists and skips process.
+    The program stops only if there is another problem.
 
     Parameters
     ----------
     directory : :obj:`string`
-        The directory name including the path which should be created.
+        The path to directory which should be created.
 
     Return
     ------
@@ -486,11 +531,11 @@ def make_dir(directory):
     try:
         os.makedirs(directory)
     except OSError as e:
-        if e.errno != errno.EEXIST:
-            # errno.EEXIST = directory already exists
-            raise # re-raise exception if a different error occured
-        else:
+        # errno.EEXIST = directory already exists
+        if e.errno == errno.EEXIST:
             print('WARNING: Directory {0} already exists!'.format(directory))
+        else:
+            raise # re-raise exception if a different error occured
 
     return
 
@@ -522,26 +567,30 @@ def put_file_to_ecserver(ecd, filename, target, ecuid, ecgid):
 
     Return
     ------
-    rcode : :obj:`string`
-        Resulting code of command execution. If successful the string
-        will be empty.
+
     '''
 
     try:
-        rcode = subprocess.check_output(['ecaccess-file-put',
-                                          ecd + '/' + filename,
-                                          target + ':/home/ms/' +
-                                          ecgid + '/' + ecuid +
-                                          '/' + filename],
-                                         stderr=subprocess.STDOUT)
+        subprocess.check_output(['ecaccess-file-put',
+                                 ecd + '/' + filename,
+                                 target + ':/home/ms/' +
+                                 ecgid + '/' + ecuid +
+                                 '/' + filename],
+                                stderr=subprocess.STDOUT)
     except subprocess.CalledProcessError as e:
-        print('... ERROR CODE:\n ... ' + str(e.returncode))
-        print('... ERROR MESSAGE:\n ... ' + str(e))
+        print('... ERROR CODE: ' + str(e.returncode))
+        print('... ERROR MESSAGE:\n \t ' + str(e))
 
         print('\n... Do you have a valid ecaccess certification key?')
         sys.exit('... ECACCESS-FILE-PUT FAILED!')
+    except OSError as e:
+        print('... ERROR CODE: ' + str(e.errno))
+        print('... ERROR MESSAGE:\n \t ' + str(e.strerror))
+
+        print('\n... Most likely the ECACCESS library is not available!')
+        sys.exit('... ECACCESS-FILE-PUT FAILED!')
 
-    return rcode
+    return
 
 def submit_job_to_ecserver(target, jobname):
     '''Uses ecaccess-job-submit command to submit a job to the ECMWF server.
@@ -562,22 +611,25 @@ def submit_job_to_ecserver(target, jobname):
 
     Return
     ------
-    rcode : :obj:`string`
-        Resulting code of command execution. If successful the string
-        will contain an integer number, representing the id of the job
-        at the ecmwf server.
+    job_id : :obj:`int`
+        The id number of the job as a reference at the ecmwf server.
     '''
 
     try:
-        rcode = subprocess.check_output(['ecaccess-job-submit',
-                                         '-queueName', target,
-                                         jobname])
-    except subprocess.CalledProcessError as e:
-        print('... ERROR CODE:\n ... ' + str(e.returncode))
-        print('... ERROR MESSAGE:\n ... ' + str(e))
+        job_id = subprocess.check_output(['ecaccess-job-submit', '-queueName',
+                                          target, jobname])
 
+    except subprocess.CalledProcessError as e:
+        print('... ERROR CODE: ' + str(e.returncode))
+        print('... ERROR MESSAGE:\n \t ' + str(e))
 
         print('\n... Do you have a valid ecaccess certification key?')
         sys.exit('... ECACCESS-JOB-SUBMIT FAILED!')
+    except OSError as e:
+        print('... ERROR CODE: ' + str(e.errno))
+        print('... ERROR MESSAGE:\n \t ' + str(e.strerror))
+
+        print('\n... Most likely the ECACCESS library is not available!')
+        sys.exit('... ECACCESS-JOB-SUBMIT FAILED!')
 
-    return rcode
+    return job_id
diff --git a/source/python/submit.py b/source/python/submit.py
index 1e13a9cf12e58ca98bac59a4093bd449a71c9015..4f80b285d72a02d737f2b62a6d1b225c7d7916b0 100755
--- a/source/python/submit.py
+++ b/source/python/submit.py
@@ -93,13 +93,15 @@ def main():
         get_mars_data(c)
         if c.request == 0 or c.request == 2:
             prepare_flexpart(args.ppid, c)
-            normal_exit(c.mailfail, 'FLEX_EXTRACT IS DONE!')
+            exit_message = 'FLEX_EXTRACT IS DONE!'
         else:
-            normal_exit(c.mailfail, 'PRINTING MARS_REQUESTS DONE!')
-    # send files to ECMWF server and install there
+            exit_message = 'PRINTING MARS_REQUESTS DONE!'
+    # send files to ECMWF server
     else:
         submit(args.job_template, c, args.queue)
 
+    normal_exit(c.mailops, c.queue, exit_message)
+
     return
 
 def submit(jtemplate, c, queue):
@@ -146,7 +148,7 @@ def submit(jtemplate, c, queue):
         with open(job_file, 'w') as f:
             f.write('\n'.join(lftextondemand))
 
-        submit_job_to_ecserver(queue, job_file)
+        job_id = submit_job_to_ecserver(queue, job_file)
 
     else:
     # --------- create operational job script ----------------------------------
@@ -172,9 +174,10 @@ def submit(jtemplate, c, queue):
         with open(job_file, 'w') as f:
             f.write('\n'.join(lftextoper))
 
-        submit_job_to_ecserver(queue, job_file)
+        job_id = submit_job_to_ecserver(queue, job_file)
 
     # --------------------------------------------------------------------------
+    print('The job id is: ' + str(job_id.strip()))
     print('You should get an email with subject flex.hostname.pid')
 
     return
diff --git a/source/pythontest/TestTools.py b/source/pythontest/TestTools.py
index a4f06734ad33893c422e836e0f55d6487abcbc5b..bd81ec58581c9799ff69a4e90e62beb38748c3bc 100644
--- a/source/pythontest/TestTools.py
+++ b/source/pythontest/TestTools.py
@@ -1,41 +1,93 @@
-#!/usr/bin/env python
+#!/opt/anaconda/bin/python
 # -*- coding: utf-8 -*-
 
+# for the gateway tests, the env vars of ECUID and ECGID have to be set upfront
+
 import os
 import sys
+import errno
+from exceptions import OSError
 import subprocess
 import pipes
 import pytest
+from mock import patch, call
+#from mock import PropertyMock
+
 
-sys.path.append('../python')
 import _config
-from mods.tools import (get_cmdline_arguments, read_ecenv, clean_up, my_error,
-                        normal_exit, product, silent_remove, init128,
-                        to_param_id, get_list_as_string, make_dir,
+import _config_test
+from classes.ControlFile import ControlFile
+from mods.tools import (none_or_str, none_or_int, get_cmdline_arguments,
+                        read_ecenv, clean_up, my_error, send_mail,
+                        normal_exit, product, silent_remove,
+                        init128, to_param_id, get_list_as_string, make_dir,
                         put_file_to_ecserver, submit_job_to_ecserver)
 
-
-class TestTools():
+class TestTools(object):
     '''
     '''
 
-    def test_get_cmdline_arguments(self):
+    def setup_method(self):
+        self.testdir = _config_test.PATH_TEST_DIR
+        self.testfilesdir = _config_test.PATH_TESTFILES_DIR
+        self.c = ControlFile(self.testdir+'/Controls/CONTROL.test')
+
+    def test_nonestr_none_or_int(self):
+        assert None == none_or_int('None')
+
+    def test_intstr_none_or_int(self):
+        assert 42 == none_or_int('42')
+
+    def test_nonestr_none_or_str(self):
+        assert None == none_or_str('None')
+
+    def test_anystr_none_or_str(self):
+        assert 'test' == none_or_str('test')
+
+    def test_default_get_cmdline_arguments(self):
+        cmd_dict_control = {'start_date':None,
+                            'end_date':None,
+                            'date_chunk':None,
+                            'basetime':None,
+                            'step':None,
+                            'levelist':None,
+                            'area':None,
+                            'inputdir':None,
+                            'outputdir':None,
+                            'flexpart_root_scripts':None,
+                            'ppid':None,
+                            'job_template':'job.temp',
+                            'queue':None,
+                            'controlfile':'CONTROL.temp',
+                            'debug':None,
+                            'public':None,
+                            'request':None}
+
+        sys.argv = ['dummy.py']
+
+        results = get_cmdline_arguments()
+
+        assert cmd_dict_control == vars(results)
+
+
+    def test_input_get_cmdline_arguments(self):
         cmd_dict_control = {'start_date':'20180101',
                             'end_date':'20180101',
-                            'date_chunk':'3',
-                            'basetime':'12',
+                            'date_chunk':3,
+                            'basetime':12,
                             'step':'1',
                             'levelist':'1/to/10',
                             'area':'50/10/60/20',
                             'inputdir':'../work',
-                            'outputdir':'../work',
+                            'outputdir':None,
                             'flexpart_root_scripts':'../',
-                            'ppid':'1234',
+                            'ppid':1234,
                             'job_template':'job.sh',
                             'queue':'ecgate',
                             'controlfile':'CONTROL.WORK',
-                            'debug':'1',
-                            'request':'0'}
+                            'debug':1,
+                            'public':None,
+                            'request':0}
 
         sys.argv = ['dummy.py',
                     '--start_date=20180101',
@@ -46,146 +98,271 @@ class TestTools():
                     '--levelist=1/to/10',
                     '--area=50/10/60/20',
                     '--inputdir=../work',
-                    '--outputdir=../work',
+                    '--outputdir=None',
                     '--flexpart_root_scripts=../',
                     '--ppid=1234',
                     '--job_template=job.sh',
                     '--queue=ecgate',
                     '--controlfile=CONTROL.WORK',
                     '--debug=1',
+                    '--public=None',
                     '--request=0']
 
         results = get_cmdline_arguments()
 
         assert cmd_dict_control == vars(results)
 
-    def test_init128(self):
+    def test_success_init128(self):
         table128 = init128(_config.PATH_GRIBTABLE)
-        expected = {'078': 'TCLW', '130': 'T', '034': 'SST'}
+        expected_sample = {'078': 'TCLW', '130': 'T', '034': 'SST'}
         # check a sample of parameters which must have been read in
-        result = all((k in table128 and table128[k]==v) for k,v in expected.iteritems())
-        assert result == True
+        assert all((k in table128 and table128[k]==v)
+                   for k,v in expected_sample.iteritems())
+
+    @patch('__builtin__.open', side_effect=[OSError(errno.EEXIST)])
+    def test_fail_open_init128(self, mock_openfile):
+        with pytest.raises(SystemExit):
+            table128 = init128(_config.PATH_GRIBTABLE)
 
-    def test_to_param_id(self):
+    @pytest.mark.parametrize(
+        'ipar_str, opar_listint',
+        [('SP/LSP/SSHF', [134, 142, 146]),
+         ('T', [130]),
+         ('', []),
+         (None, []),
+         ('testtest', []),
+         ('130/142', [130, 142]),
+         (130, [130]),
+         (50.56, [])])
+    def test_to_param_id(self, ipar_str, opar_listint):
         table128 = init128(_config.PATH_GRIBTABLE)
-        pars = to_param_id("T/SP/LSP/SSHF", table128)
-        for par in pars:
-            assert par in [130, 134, 142, 146]
-
-    def test_my_error(self):
-        with pytest.raises(SystemExit) as pytest_wrapped_e:
-            my_error(['${USER}', 'anne.philipp@univie.ac.at'], 'Failed!')
-        assert pytest_wrapped_e.type == SystemExit
-        assert pytest_wrapped_e.value.code == 1
-
-    def test_read_ecenv(self):
-        envs_ref = {'ECUID': 'km4a',
-                    'ECGID': 'at',
-                    'GATEWAY': 'srvx8.img.univie.ac.at',
-                    'DESTINATION': 'annep@genericSftp'
+        ipars = to_param_id(ipar_str, table128)
+        assert sorted(ipars) == sorted(opar_listint)
+
+    @patch('traceback.format_stack', return_value='empty trace')
+    @patch('mods.tools.send_mail', return_value=0)
+    def test_success_my_error(self, mock_mail, mock_trace, capfd):
+        with pytest.raises(SystemExit):
+            my_error(['any_user'], 'Failed!')
+            out, err = capfd.readouterr()
+            assert out == "Failed!\n\nempty_trace\n"
+
+    @patch('subprocess.Popen')
+    @patch('os.getenv', return_value='user')
+    @patch('os.path.expandvars', return_value='user')
+    def test_success_userenv_twouser_send_mail(self, mock_os, mock_env, mock_popen, capfd):
+        mock_popen.return_value = subprocess.Popen(["echo", "Hello Test!"],
+                                                   stdout=subprocess.PIPE)
+        send_mail(['${USER}', 'any_user'], 'ERROR', message='error mail')
+        out, err = capfd.readouterr()
+        assert out == b'Email sent to user\nEmail sent to user\n'
+
+    @patch('subprocess.Popen')
+    @patch('os.path.expandvars', return_value='any_user')
+    def test_success_send_mail(self, mock_os,  mock_popen, capfd):
+        mock_popen.return_value = subprocess.Popen(["echo", "Hello Test!"],
+                                                   stdout=subprocess.PIPE)
+        send_mail(['any-user'], 'ERROR', message='error mail')
+        out, err = capfd.readouterr()
+        assert out == b'Email sent to any_user\n'
+
+    @patch('subprocess.Popen', side_effect=[ValueError, OSError])
+    @patch('os.path.expandvars', return_value='any_user')
+    def test_fail_valueerror_send_mail(self, mock_osvar, mock_popen):
+        with pytest.raises(SystemExit): # ValueError
+            send_mail(['any-user'], 'ERROR', message='error mail')
+        with pytest.raises(SystemExit): # OSError
+            send_mail(['any-user'], 'ERROR', message='error mail')
+
+    def test_success_read_ecenv(self):
+        envs_ref = {'ECUID': 'testuser',
+                    'ECGID': 'testgroup',
+                    'GATEWAY': 'gateway.test.ac.at',
+                    'DESTINATION': 'user@destination'
                    }
-        envs = read_ecenv(os.getcwd() + '/TestData/ECMWF_ENV')
+        envs = read_ecenv(self.testfilesdir + '/ECMWF_ENV.test')
 
         assert envs_ref == envs
 
-    def test_clean_up(self):
+    @patch('__builtin__.open', side_effect=[OSError(errno.EPERM)])
+    def test_fail_read_ecenv(self, mock_open):
+        with pytest.raises(SystemExit):
+            read_ecenv('any_file')
 
-        assert True
+    @patch('glob.glob', return_value=[])
+    @patch('mods.tools.silent_remove')
+    def test_empty_clean_up(self, mock_rm, mock_clean):
+        clean_up(self.c)
+        mock_rm.assert_not_called()
 
-    def test_normal_exit(self):
-        assert True
+    @patch('glob.glob', return_value=['any_file','EIfile'])
+    @patch('os.remove', return_value=0)
+    def test_success_clean_up(self, mock_rm, mock_glob):
+        # ectrans=0; ecstorage=0; ecapi=None; prefix not in filename
+        clean_up(self.c)
+        mock_rm.assert_has_calls([call('any_file'), call('EIfile')])
+        mock_rm.reset_mock()
 
-    def test_product(self):
-        assert True
+        # ectrans=0; ecstorage=0; ecapi=False; prefix in filename
+        self.c.prefix = 'EI'
+        self.c.ecapi = False
+        clean_up(self.c)
+        mock_rm.assert_has_calls([call('any_file')])
+        mock_rm.reset_mock()
 
-    def test_success_silent_remove(self, capfd):
-        testfile = 'testfile.test'
-        open(testfile, 'w').close()
-        silent_remove(testfile)
+        # ectrans=0; ecstorage=0; ecapi=True; prefix in filename
+        self.c.prefix = 'EI'
+        self.c.ecapi = True
+        clean_up(self.c)
+        mock_rm.assert_has_calls([call('any_file')])
+        mock_rm.reset_mock()
+
+        # ectrans=1; ecstorage=0; ecapi=True; prefix in filename
+        self.c.prefix = 'EI'
+        self.c.ecapi = True
+        self.c.ectrans = 1
+        clean_up(self.c)
+        mock_rm.assert_has_calls([call('any_file')])
+        mock_rm.reset_mock()
+
+        # ectrans=1; ecstorage=0; ecapi=False; prefix in filename
+        self.c.prefix = 'EI'
+        self.c.ecapi = False
+        self.c.ectrans = 1
+        clean_up(self.c)
+        mock_rm.assert_has_calls([call('any_file'), call('EIfile')])
+        mock_rm.reset_mock()
+
+        # ectrans=1; ecstorage=1; ecapi=False; prefix in filename
+        self.c.prefix = 'EI'
+        self.c.ecapi = False
+        self.c.ectrans = 1
+        self.c.ecstorage = 1
+        clean_up(self.c)
+        mock_rm.assert_has_calls([call('any_file'), call('EIfile')])
+        mock_rm.reset_mock()
+
+    def test_default_normal_exit(self, capfd):
+        normal_exit()
         out, err = capfd.readouterr()
-        assert os.path.isfile(testfile) == False
-        assert out == ''
+        assert out == 'Done!\n'
 
-    def test_failnotexist_silent_remove(self, capfd):
-        testfile = 'testfile.test'
-        silent_remove(testfile)
+    def test_message_normal_exit(self, capfd):
+        normal_exit('Hi there!')
         out, err = capfd.readouterr()
+        assert out == 'Hi there!\n'
+
+    def test_int_normal_exit(self, capfd):
+        normal_exit(42)
+        out, err = capfd.readouterr()
+        assert out == '42\n'
+
+    @pytest.mark.parametrize(
+        'input1, input2, output_list',
+        [('ABC','xy',[('A','x'),('A','y'),('B','x'),('B','y'),('C','x'),('C','y')]),
+         (range(1), range(1), [(0,0),(0,1),(1,0),(1,1)])])
+    def test_success_product(self, input1, input2, output_list):
+        index = 0
+        for prod in product(input1, input2):
+            assert isinstance(prod, tuple)
+            assert prod == output_list[index]
+            index += 1
+
+    @pytest.mark.parametrize(
+        'input1, input2, output_list',
+        [(1,1,(1,1))])
+    def test_fail_product(self, input1, input2, output_list):
+        index = 0
+        with pytest.raises(SystemExit):
+            for prod in product(input1, input2):
+                assert isinstance(prod, tuple)
+                assert prod == output_list[index]
+                index += 1
+
+    def test_success_silent_remove(self):
+        testfile = self.testfilesdir + 'test.txt'
+        open(testfile, 'w').close()
+        silent_remove(testfile)
         assert os.path.isfile(testfile) == False
-        assert out == ''
 
-    @pytest.mark.skip(reason="no way of currently testing this")
-    def test_failany_silent_remove(self):
-        testfile = 'testfileany.test'
+    @patch('os.remove', side_effect=OSError(errno.ENOENT))
+    def test_fail_notexist_silent_remove(self, mock_rm):
         with pytest.raises(OSError) as pytest_wrapped_e:
-            silent_remove(testfile)
-        #out, err = capfd.readouterr()
-        #assert os.path.isfile(testfile) == False
-        #assert out == ''
-
-    def test_success_get_list_as_string(self):
-        list_object =  [1, 2, 3, '...', 'testlist']
-        list_as_string = '1, 2, 3, ..., testlist'
-        assert list_as_string == get_list_as_string(list_object)
-
-    @pytest.mark.skip(reason="no way of currently testing this")
-    def test_fail_get_list_as_string(self):
-        list_object =  [1, 2, 3, '...', 'testlist']
-        list_as_string = '1, 2, 3, ..., testlist'
-        with pytest.raises(Exception) as pytest_wrapped_e:
-            result = get_list_as_string(list_object)
-        assert result == list_as_string
-
-    def test_warningexist_make_dir(self, capfd):
-        testdir = 'TestData'
-        make_dir(testdir)
-        out, err = capfd.readouterr()
-        assert out.strip() == 'WARNING: Directory {0} already exists!'.format(testdir)
+            silent_remove('any_dir')
+            assert pytest_wrapped_e.e.errno == errno.ENOENT
+
+    @patch('os.remove', side_effect=OSError(errno.EEXIST))
+    def test_fail_any_silent_remove(self, mock_rm):
+        with pytest.raises(OSError):
+            silent_remove('any_dir')
 
-    def test_failany_make_dir(self):
-        testdir = '/test' # force a permission denied error
+    @pytest.mark.parametrize(
+        'input_list, output_list',
+        [([],''),
+         ([1, 2, 3.5, '...', 'testlist'], '1, 2, 3.5, ..., testlist'),
+         ('2', '2')])
+    def test_success_get_list_as_string(self, input_list, output_list):
+        assert output_list == get_list_as_string(input_list)
+
+    @patch('os.makedirs', side_effect=[OSError(errno.EEXIST)])
+    def test_warning_exist_make_dir(self, mock_make):
         with pytest.raises(OSError) as pytest_wrapped_e:
-            make_dir(testdir)
-        assert pytest_wrapped_e.type == OSError
+            make_dir('existing_dir')
+            assert pytest_wrapped_e.e.errno == errno.EEXIST
+
+    @patch('os.makedirs', side_effect=OSError)
+    def test_fail_any_make_dir(self, mock_makedir):
+        with pytest.raises(OSError):
+            make_dir('any_dir')
+
+    def test_fail_empty_make_dir(self):
+        with pytest.raises(OSError):
+            make_dir('')
 
     def test_success_make_dir(self):
-        testdir = 'testing_mkdir'
-        make_dir(testdir)
-        assert os.path.exists(testdir) == True
-        os.rmdir(testdir)
-
-    def test_fail_put_file_to_ecserver(self):
-        ecuid=os.environ['ECUID']
-        ecgid=os.environ['ECGID']
-        with pytest.raises(SystemExit) as pytest_wrapped_e:
-            put_file_to_ecserver('TestData/', 'testfil.txt',
-                                 'ecgate', ecuid, ecgid)
-        assert pytest_wrapped_e.type == SystemExit
-        assert pytest_wrapped_e.value.code == '... ECACCESS-FILE-PUT FAILED!'
-
-    def test_success_put_file_to_ecserver(self):
-        ecuid=os.environ['ECUID']
-        ecgid=os.environ['ECGID']
-        result = put_file_to_ecserver('TestData/', 'testfile.txt',
-                                      'ecgate', ecuid, ecgid)
-        assert result == ''
+        testdir = '/testing_mkdir'
+        make_dir(self.testdir + testdir)
+        assert os.path.exists(self.testdir + testdir) == True
+        os.rmdir(self.testdir + testdir)
+
+
+    @patch('subprocess.check_output', side_effect=[subprocess.CalledProcessError(1,'test')])
+    def test_fail_put_file_to_ecserver(self, mock_co):
+        with pytest.raises(SystemExit):
+            put_file_to_ecserver(self.testfilesdir, 'test_put_to_ecserver.txt',
+                                 'ecgate', 'ex_ECUID', 'ex_ECGID')
+
+    @patch('subprocess.check_output', return_value=0)
+    def test_general_success_put_file_to_ecserver(self, mock_co):
+        result = put_file_to_ecserver(self.testfilesdir, 'test_put_to_ecserver.txt',
+                                      'ecgate', 'ex_ECUID', 'ex_ECGID')
+        assert result == None
 
     @pytest.mark.msuser_pw
+    @pytest.mark.gateway
     @pytest.mark.skip(reason="easier to ignore for now - implement in final version")
-    def test_fullsuccess_put_file_to_ecserver(self):
-        ecuid=os.environ['ECUID']
-        ecgid=os.environ['ECGID']
-        put_file_to_ecserver('TestData/', 'testfile.txt', 'ecgate', ecuid, ecgid)
+    def test_full_success_put_file_to_ecserver(self):
+        ecuid = os.environ['ECUID']
+        ecgid = os.environ['ECGID']
+        put_file_to_ecserver(self.testfilesdir, 'test_put_to_ecserver.txt',
+                             'ecgate', ecuid, ecgid)
         assert subprocess.call(['ssh', ecuid+'@ecaccess.ecmwf.int' ,
                                 'test -e ' +
                                 pipes.quote('/home/ms/'+ecgid+'/'+ecuid)]) == 0
 
-    def test_fail_submit_job_to_ecserver(self):
-        with pytest.raises(SystemExit) as pytest_wrapped_e:
-            submit_job_to_ecserver('ecgate', 'job.ksh')
-        assert pytest_wrapped_e.type == SystemExit
-        assert pytest_wrapped_e.value.code == '... ECACCESS-JOB-SUBMIT FAILED!'
+    @patch('subprocess.check_output', side_effect=[subprocess.CalledProcessError(1,'test'),
+                                                   OSError])
+    def test_fail_submit_job_to_ecserver(self, mock_co):
+        with pytest.raises(SystemExit):
+            job_id = submit_job_to_ecserver('ecgate', 'job.ksh')
 
+    @pytest.mark.msuser_pw
+    @pytest.mark.gateway
+    @pytest.mark.skip(reason="easier to ignore for now - implement in final version")
     def test_success_submit_job_to_ecserver(self):
-        result = submit_job_to_ecserver('ecgate', 'TestData/testfile.txt')
-        assert result.strip().isdigit() == True
+        job_id = submit_job_to_ecserver('ecgate',
+                                        os.path.join(self.testfilesdir,
+                                                     'test_put_to_ecserver.txt'))
+        assert job_id.strip().isdigit() == True
+
 
diff --git a/source/pythontest/_config_test.py b/source/pythontest/_config_test.py
new file mode 100644
index 0000000000000000000000000000000000000000..9eeca9db2e201a6c971b9d5bee6f17503a3a2fb9
--- /dev/null
+++ b/source/pythontest/_config_test.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+'''
+*******************************************************************************
+ @Author: Anne Philipp (University of Vienna)
+
+ @Date: August 2018
+
+ @Change History:
+
+ @License:
+    (C) Copyright 2014-2018.
+
+    This software is licensed under the terms of the Apache Licence Version 2.0
+    which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+
+ @Description:
+    Contains constant value parameter for flex_extract.
+
+*******************************************************************************
+'''
+
+# ------------------------------------------------------------------------------
+# MODULES
+# ------------------------------------------------------------------------------
+import os
+import sys
+
+sys.path.append('../python')
+import _config
+
+# ------------------------------------------------------------------------------
+# FILENAMES
+# ------------------------------------------------------------------------------
+
+
+# ------------------------------------------------------------------------------
+# DIRECTORY NAMES
+# ------------------------------------------------------------------------------
+TEST_DIR = 'test'
+TESTFILES_DIR = 'Testfiles'
+
+# ------------------------------------------------------------------------------
+#  PATHES
+# ------------------------------------------------------------------------------
+PATH_TEST_DIR = os.path.join(_config.PATH_FLEXEXTRACT_DIR, TEST_DIR)
+PATH_TESTFILES_DIR = os.path.join(PATH_TEST_DIR, TESTFILES_DIR)
+
diff --git a/source/pythontest/conftest.py b/source/pythontest/conftest.py
new file mode 100644
index 0000000000000000000000000000000000000000..27469f2b3ec4bafcd75408e71751fcb452e00710
--- /dev/null
+++ b/source/pythontest/conftest.py
@@ -0,0 +1,10 @@
+import sys
+import pytest
+
+sys.path.append('../python')
+import _config
+
+#@pytest.fixture
+#def prep_test_env():
+#    testdir = _config.PATH_TEST_DIR
+print ''
diff --git a/source/pythontest/pytest.ini b/source/pythontest/pytest.ini
index fff665e6e68c39692076935031c96e80d55ab3bc..66e850a3a99e0733c970b96198f1be78c415151d 100644
--- a/source/pythontest/pytest.ini
+++ b/source/pythontest/pytest.ini
@@ -1,4 +1,5 @@
 # content of pytest.ini
 [pytest]
 markers =
-    msuser_pw: Test that can be executed only as a member-state user. Password required.
\ No newline at end of file
+    msuser_pw: Test that can be executed only as a member-state user. Password required.
+    gateway: Test that can be executed only in the gateway mode.
diff --git a/test/Controls/CONTROL.req.test b/test/Controls/CONTROL.req.test
new file mode 100644
index 0000000000000000000000000000000000000000..8bde8b88db9497b5292c19723c552c9484b5b7ff
--- /dev/null
+++ b/test/Controls/CONTROL.req.test
@@ -0,0 +1,37 @@
+DAY1 20100809
+DAY2
+DTIME 3
+TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC
+TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12
+STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11
+CLASS EI
+STREAM OPER
+NUMBER OFF
+EXPVER 1
+GRID 1000  
+LEFT -50000
+LOWER -90000
+UPPER 90000
+RIGHT 50000
+LEVEL 60
+LEVELIST 1/to/60
+RESOL 63
+GAUSS 1
+ACCURACY 16
+OMEGA 0
+OMEGADIFF 0
+ETA 0
+ETADIFF 0
+DPDETA 1
+SMOOTH 0
+FORMAT GRIB1
+ADDPAR 186/187/188/235/139/39
+PREFIX EN
+ECSTORAGE 1
+ECTRANS 0
+ECFSDIR ectmp:/${USER}/econdemand/
+MAILFAIL ${USER} 
+MAILOPS ${USER}
+GRIB2FLEXPART 0
+EOF
+
diff --git a/test/Controls/CONTROL.test b/test/Controls/CONTROL.test
new file mode 100644
index 0000000000000000000000000000000000000000..46b4008b87a0084ad1fbcd2b83255b8c63716efa
--- /dev/null
+++ b/test/Controls/CONTROL.test
@@ -0,0 +1,14 @@
+DTIME 3
+TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC
+TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12
+STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11
+CLASS EI
+STREAM OPER
+EXPVER 1
+GRID 5000  
+LEFT -10000
+LOWER 30000
+UPPER 40000
+RIGHT 10000
+LEVELIST 59/to/60
+RESOL 63
diff --git a/test/Controls/CONTROL.worktest b/test/Controls/CONTROL.worktest
new file mode 100644
index 0000000000000000000000000000000000000000..7bd637d8b4a27f63ffc03eb0ea1b4669661afa85
--- /dev/null
+++ b/test/Controls/CONTROL.worktest
@@ -0,0 +1,37 @@
+DAY1 20100101
+DAY2 
+DTIME 3
+TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC
+TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12
+STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11
+CLASS EI
+STREAM OPER
+NUMBER OFF
+EXPVER 1
+GRID 5000  
+LEFT -10000
+LOWER 30000
+UPPER 40000
+RIGHT 10000
+LEVEL 60
+LEVELIST 58/to/60
+RESOL 63
+GAUSS 1
+ACCURACY 16
+OMEGA 0
+OMEGADIFF 0
+ETA 0
+ETADIFF 0
+DPDETA 1
+SMOOTH 0
+FORMAT GRIB1
+ADDPAR 186/187/188/235/139/39
+PREFIX EI
+ECSTORAGE 0
+ECTRANS 1
+ECFSDIR ectmp:/${USER}/econdemand/
+MAILFAIL ${USER} 
+MAILOPS ${USER}
+GRIB2FLEXPART 0
+EOF
+
diff --git a/test/Data/CONTROL.temp b/test/Data/CONTROL.temp
new file mode 100644
index 0000000000000000000000000000000000000000..d5f4137f69a9180c44ce9dda8cbd7fd1298b2bcd
--- /dev/null
+++ b/test/Data/CONTROL.temp
@@ -0,0 +1,37 @@
+DAY1
+DAY2
+DTIME 3
+TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC
+TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12
+STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11
+CLASS EI
+STREAM OPER
+NUMBER OFF
+EXPVER 1
+GRID 1000  
+LEFT -15000
+LOWER 30000
+UPPER 75000
+RIGHT 45000
+LEVEL 60
+LEVELIST 55/to/60
+RESOL 63
+GAUSS 1
+ACCURACY 16
+OMEGA 0
+OMEGADIFF 0
+ETA 0
+ETADIFF 0
+DPDETA 1
+SMOOTH 0
+FORMAT GRIB1
+ADDPAR 186/187/188/235/139/39
+PREFIX EI
+ECSTORAGE 0
+ECTRANS 1
+ECFSDIR ectmp:/${USER}/econdemand/
+MAILFAIL ${USER} 
+MAILOPS ${USER}
+GRIB2FLEXPART 0
+EOF
+
diff --git a/test/Data/ECMWF_ENV b/test/Data/ECMWF_ENV
new file mode 100644
index 0000000000000000000000000000000000000000..5af57721445813f4a44c0b9562b8219196daeda9
--- /dev/null
+++ b/test/Data/ECMWF_ENV
@@ -0,0 +1,4 @@
+ECUID km4a
+ECGID at
+GATEWAY srvx8.img.univie.ac.at
+DESTINATION annep@genericSftp
diff --git a/test/Data/compilejob.test b/test/Data/compilejob.test
new file mode 100644
index 0000000000000000000000000000000000000000..9f9a5a1408656336350903200abeae414d2cbc34
--- /dev/null
+++ b/test/Data/compilejob.test
@@ -0,0 +1,68 @@
+#!/bin/ksh
+
+# ON ECGB:
+# start with ecaccess-job-submit -queueName ecgb NAME_OF_THIS_FILE  on gateway server
+# start with sbatch NAME_OF_THIS_FILE directly on machine
+
+#SBATCH --workdir=/scratch/ms/testgroup/testuser
+#SBATCH --qos=normal
+#SBATCH --job-name=flex_ecmwf
+#SBATCH --output=flex_ecmwf.%j.out
+#SBATCH --error=flex_ecmwf.%j.out
+#SBATCH --mail-type=FAIL
+#SBATCH --time=12:00:00
+
+## CRAY specific batch requests
+##PBS -N flex_ecmwf
+##PBS -q ns
+##PBS -S /usr/bin/ksh
+##PBS -o /scratch/ms/testgroup/testuser/flex_ecmwf.${Jobname}.${Job_ID}.out
+# job output is in .ecaccess_DO_NOT_REMOVE
+##PBS -j oe
+##PBS -V
+##PBS -l EC_threads_per_task=1
+##PBS -l EC_memory_per_task=3200MB
+
+set -x
+export VERSION=7.1
+case ${HOST} in
+  *ecg*)
+  module load python
+  module unload grib_api
+  module unload emos
+  module load grib_api/1.14.5
+  module load emos/437-r64
+  export FLEXPART_ROOT_SCRIPTS=fp_root_test_path
+  export MAKEFILE=Makefile.TEST
+  ;;
+  *cca*)
+  module switch PrgEnv-cray PrgEnv-intel
+  module load grib_api
+  module load emos
+  module load python
+  echo ${GROUP}
+  echo ${HOME}
+  echo ${HOME} | awk -F / '{print $1, $2, $3, $4}'
+  export GROUP=`echo ${HOME} | awk -F / '{print $4}'`
+  export SCRATCH=/scratch/ms/${GROUP}/${USER}
+  export FLEXPART_ROOT_SCRIPTS=fp_root_test_path
+  export MAKEFILE=Makefile.TEST
+  ;;
+esac
+
+mkdir -p ${FLEXPART_ROOT_SCRIPTS}/flex_extract_v${VERSION}
+cd ${FLEXPART_ROOT_SCRIPTS}/flex_extract_v${VERSION}   # if FLEXPART_ROOT is not set this means cd to the home directory
+tar -xvf ${HOME}/flex_extract_v${VERSION}.tar
+cd src
+\rm *.o *.mod CONVERT2 
+make -f ${MAKEFILE} >flexcompile 2>flexcompile
+
+ls -l CONVERT2 >>flexcompile
+if [ $? -eq 0 ]; then
+  echo 'SUCCESS!' >>flexcompile
+  mail -s flexcompile.${HOST}.$$ ${USER} <flexcompile
+else
+  echo Environment: >>flexcompile
+  env >> flexcompile
+  mail -s "ERROR! flexcompile.${HOST}.$$" ${USER} <flexcompile
+fi
diff --git a/test/Data/convert.nl.test b/test/Data/convert.nl.test
new file mode 100644
index 0000000000000000000000000000000000000000..6134989413cdb76683d7f2c06c99dfd14b6fa56c
--- /dev/null
+++ b/test/Data/convert.nl.test
@@ -0,0 +1,19 @@
+&NAMGEN
+  maxl = 61,
+  maxb = 46,
+  mlevel = 60,
+  mlevelist = "55/to/60",
+  mnauf = 63,
+  metapar = 77,
+  rlo0 = -15.0,
+  rlo1 = 45.0,
+  rla0 = 30.0,
+  rla1 = 75.0,
+  momega = 0,
+  momegadiff = 0,
+  mgauss = 1,
+  msmooth = 0,
+  meta = 0,
+  metadiff = 0,
+  mdpdeta = 1
+/
diff --git a/test/Data/job.temp.test b/test/Data/job.temp.test
new file mode 100644
index 0000000000000000000000000000000000000000..4103775ffeeacb62a2487c86b1b44c09919ee3a2
--- /dev/null
+++ b/test/Data/job.temp.test
@@ -0,0 +1,76 @@
+#!/bin/ksh
+
+# ON ECGB:
+# start with ecaccess-job-submit -queueName ecgb NAME_OF_THIS_FILE  on gateway server
+# start with sbatch NAME_OF_THIS_FILE directly on machine
+
+#SBATCH --workdir=/scratch/ms/testgroup/testuser
+#SBATCH --qos=normal
+#SBATCH --job-name=flex_ecmwf
+#SBATCH --output=flex_ecmwf.%j.out
+#SBATCH --error=flex_ecmwf.%j.out
+#SBATCH --mail-type=FAIL
+#SBATCH --time=12:00:00
+
+## CRAY specific batch requests
+##PBS -N flex_ecmwf
+##PBS -q np
+##PBS -S /usr/bin/ksh
+## -o /scratch/ms/testgroup/testuser/flex_ecmwf.${PBS_JOBID}.out
+## job output is in .ecaccess_DO_NOT_REMOVE
+##PBS -j oe
+##PBS -V
+##PBS -l EC_threads_per_task=24
+##PBS -l EC_memory_per_task=32000MB
+
+set -x
+export VERSION=7.1
+case ${HOST} in
+  *ecg*)
+  module load python
+  module unload grib_api
+  module unload emos
+  module load grib_api/1.14.5
+  module load emos/437-r64
+  export PATH=${PATH}:fp_root_test_path/flex_extract_v7.1/source/python
+  ;;
+  *cca*)
+  module switch PrgEnv-cray PrgEnv-intel
+  module load grib_api
+  module load emos
+  module load python
+  export SCRATCH=${TMPDIR}
+  export PATH=${PATH}:fp_root_test_path/flex_extract_v7.1/source/python
+  ;;
+esac
+
+cd ${SCRATCH}
+mkdir -p python$$
+cd python$$
+
+export CONTROL=CONTROL
+
+cat >${CONTROL}<<EOF
+EOF
+
+
+submit.py --controlfile=${CONTROL} --inputdir=./work --outputdir=./work 1> prot 2>&1
+
+if [ $? -eq 0 ] ; then
+  l=0
+  for muser in `grep -i MAILOPS ${CONTROL}`; do
+      if [ ${l} -gt 0 ] ; then 
+         mail -s flex.${HOST}.$$ ${muser} <prot
+      fi
+      l=$((${l}+1))
+  done
+else
+  l=0
+  for muser in `grep -i MAILFAIL ${CONTROL}`; do
+      if [ ${l} -gt 0 ] ; then 
+         mail -s "ERROR! flex.${HOST}.$$" ${muser} <prot
+      fi
+      l=$((${l}+1))
+  done
+fi
+
diff --git a/test/Dir/FCOG__ML.20160410.40429.16424.grb b/test/Dir/FCOG__ML.20160410.40429.16424.grb
new file mode 100644
index 0000000000000000000000000000000000000000..852a87f120f7f47d0d02897b30c7bdf4edc4ffd3
Binary files /dev/null and b/test/Dir/FCOG__ML.20160410.40429.16424.grb differ
diff --git a/test/Dir/FCOG__SL.20160410.40429.16424.grb b/test/Dir/FCOG__SL.20160410.40429.16424.grb
new file mode 100644
index 0000000000000000000000000000000000000000..e0a29285929408678276b7313097083e4ad72de1
Binary files /dev/null and b/test/Dir/FCOG__SL.20160410.40429.16424.grb differ
diff --git a/test/Dir/FCSH__ML.20160410.40429.16424.grb b/test/Dir/FCSH__ML.20160410.40429.16424.grb
new file mode 100644
index 0000000000000000000000000000000000000000..51e775c88990a5037b3a287e20674fd5d3f6aec6
Binary files /dev/null and b/test/Dir/FCSH__ML.20160410.40429.16424.grb differ
diff --git a/test/Dir/FCSH__SL.20160410.40429.16424.grb b/test/Dir/FCSH__SL.20160410.40429.16424.grb
new file mode 100644
index 0000000000000000000000000000000000000000..3d021c6a4e9eca56fe5ae95522091004f4443688
Binary files /dev/null and b/test/Dir/FCSH__SL.20160410.40429.16424.grb differ
diff --git a/test/Dir/SubTestDir/OG_OROLSM__SL.20160410.40429.16424.grb b/test/Dir/SubTestDir/OG_OROLSM__SL.20160410.40429.16424.grb
new file mode 100644
index 0000000000000000000000000000000000000000..10f1c96f45b0d5f6251546374d60d42f4b30103d
Binary files /dev/null and b/test/Dir/SubTestDir/OG_OROLSM__SL.20160410.40429.16424.grb differ
diff --git a/test/Dir/SubTestDir/SubSubTestDir/FCGG__SL.20160410.40429.16424.grb b/test/Dir/SubTestDir/SubSubTestDir/FCGG__SL.20160410.40429.16424.grb
new file mode 100644
index 0000000000000000000000000000000000000000..3e87854a2ff76d6f985bf777146a3fef4af382e9
Binary files /dev/null and b/test/Dir/SubTestDir/SubSubTestDir/FCGG__SL.20160410.40429.16424.grb differ
diff --git a/test/Dir/SubTestDir2/FCOG_acc_SL.20160409.40429.16424.grb b/test/Dir/SubTestDir2/FCOG_acc_SL.20160409.40429.16424.grb
new file mode 100644
index 0000000000000000000000000000000000000000..fa7cc0a415bf4dce32f26ae427cb3f4ab3ee5259
Binary files /dev/null and b/test/Dir/SubTestDir2/FCOG_acc_SL.20160409.40429.16424.grb differ
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/run/ECMWF_ENV b/test/InstallTar/flex_extract_v7.1_ecgate/run/ECMWF_ENV
new file mode 100644
index 0000000000000000000000000000000000000000..5af57721445813f4a44c0b9562b8219196daeda9
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/run/ECMWF_ENV
@@ -0,0 +1,4 @@
+ECUID km4a
+ECGID at
+GATEWAY srvx8.img.univie.ac.at
+DESTINATION annep@genericSftp
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL.temp b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL.temp
new file mode 100644
index 0000000000000000000000000000000000000000..b972567b215eeb95a15c4ad666f79263cbdd0e3b
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL.temp
@@ -0,0 +1,37 @@
+DAY1 20130501
+DAY2
+DTIME 3
+TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC
+TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12
+STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11
+CLASS EI
+STREAM OPER
+NUMBER OFF
+EXPVER 1
+GRID 5000  
+LEFT -15000
+LOWER 30000
+UPPER 75000
+RIGHT 45000
+LEVEL 60
+LEVELIST 55/to/60
+RESOL 63
+GAUSS 1
+ACCURACY 16
+OMEGA 0
+OMEGADIFF 0
+ETA 0
+ETADIFF 0
+DPDETA 1
+SMOOTH 0
+FORMAT GRIB1
+ADDPAR 186/187/188/235/139/39
+PREFIX EI
+ECSTORAGE 0
+ECTRANS 1
+ECFSDIR ectmp:/${USER}/econdemand/
+MAILFAIL ${USER} 
+MAILOPS ${USER}
+GRIB2FLEXPART 0
+EOF
+
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL.temp.backup b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL.temp.backup
new file mode 100644
index 0000000000000000000000000000000000000000..2ee99922380e222e1239f1f09ce7dcdd17ed2fb8
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL.temp.backup
@@ -0,0 +1,37 @@
+DAY1
+DAY2
+DTIME 3
+TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC
+TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12
+STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11
+CLASS EI
+STREAM OPER
+NUMBER OFF
+EXPVER 1
+GRID 5000  
+LEFT -175000
+LOWER -90000
+UPPER 90000
+RIGHT 180000
+LEVEL 60
+LEVELIST 1/to/60
+RESOL 63
+GAUSS 1
+ACCURACY 16
+OMEGA 0
+OMEGADIFF 0
+ETA 0
+ETADIFF 0
+DPDETA 1
+SMOOTH 0
+FORMAT GRIB1
+ADDPAR 186/187/188/235/139/39
+PREFIX EN
+ECSTORAGE 1
+ECTRANS 0
+ECFSDIR ectmp:/${USER}/econdemand/
+MAILFAIL ${USER} 
+MAILOPS ${USER}
+GRIB2FLEXPART 0
+EOF
+
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL.test b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL.test
new file mode 100644
index 0000000000000000000000000000000000000000..41018e17505c698eb19dd05d488cae897a843baa
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL.test
@@ -0,0 +1,18 @@
+DTIME 3
+TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC
+TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12
+STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11
+CLASS EI
+STREAM OPER
+EXPVER 1
+GRID 5000  
+LEFT -10000
+LOWER 30000
+UPPER 40000
+RIGHT 10000
+LEVELIST 59/to/60
+RESOL 63
+GAUSS 1
+ADDPAR 186/187/188/235/139/39
+PREFIX EItest_
+ECTRANS 1
\ No newline at end of file
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL.worktest b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL.worktest
new file mode 100644
index 0000000000000000000000000000000000000000..7bd637d8b4a27f63ffc03eb0ea1b4669661afa85
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL.worktest
@@ -0,0 +1,37 @@
+DAY1 20100101
+DAY2 
+DTIME 3
+TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC
+TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12
+STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11
+CLASS EI
+STREAM OPER
+NUMBER OFF
+EXPVER 1
+GRID 5000  
+LEFT -10000
+LOWER 30000
+UPPER 40000
+RIGHT 10000
+LEVEL 60
+LEVELIST 58/to/60
+RESOL 63
+GAUSS 1
+ACCURACY 16
+OMEGA 0
+OMEGADIFF 0
+ETA 0
+ETADIFF 0
+DPDETA 1
+SMOOTH 0
+FORMAT GRIB1
+ADDPAR 186/187/188/235/139/39
+PREFIX EI
+ECSTORAGE 0
+ECTRANS 1
+ECFSDIR ectmp:/${USER}/econdemand/
+MAILFAIL ${USER} 
+MAILOPS ${USER}
+GRIB2FLEXPART 0
+EOF
+
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_CV b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_CV
new file mode 100644
index 0000000000000000000000000000000000000000..39befc56a0df6afdea6229273ee3ad67b2f53d97
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_CV
@@ -0,0 +1,37 @@
+DAY1
+DAY2
+DTIME 3
+MAXSTEP 36
+TYPE CF CF 
+TIME 12 12 
+STEP 00 01 
+CLASS OD
+STREAM ENFO
+NUMBER OFF
+EXPVER 1
+GRID 1000  
+LEFT -179000
+LOWER -90000
+UPPER 90000
+RIGHT 180000
+LEVEL 62
+LEVELIST 1/to/62
+RESOL 159
+GAUSS 1
+ACCURACY 16
+OMEGA 1
+OMEGADIFF 0
+ETA 0
+ETADIFF 0
+DPDETA 1
+SMOOTH 0
+FORMAT GRIB1
+ADDPAR /186/187/188/235/139/39
+PREFIX EE
+ECSTORAGE 1
+ECTRANS 1
+ECFSDIR ectmp:/${USER}/econdemand/
+MAILOPS ${USER}
+MAILFAIL ${USER}
+GRIB2FLEXPART 1
+EOF
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_CV_PREOP b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_CV_PREOP
new file mode 100644
index 0000000000000000000000000000000000000000..24364a304f7ccec05630ff452ddb9050bc6a37b8
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_CV_PREOP
@@ -0,0 +1,37 @@
+DAY1
+DAY2
+DTIME 3
+MAXSTEP 36
+TYPE CV CV 
+TIME 12 12 
+STEP 00 01 
+CLASS OD
+STREAM ENFO
+NUMBER 1
+EXPVER 1
+GRID 1000  
+LEFT -179000
+LOWER -90000
+UPPER 90000
+RIGHT 180000
+LEVEL 91
+LEVELIST 1/to/91
+RESOL 159
+GAUSS 1
+ACCURACY 16
+OMEGA 1
+OMEGADIFF 0
+ETA 0
+ETADIFF 0
+DPDETA 1
+SMOOTH 0
+FORMAT GRIB1
+ADDPAR /186/187/188/235/139/39
+PREFIX EN
+ECSTORAGE 1
+ECTRANS 1
+ECFSDIR ectmp:/${USER}/econdemand/
+MAILOPS ${USER}
+MAILFAIL ${USER}
+GRIB2FLEXPART 1
+EOF
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_DELIA_HR b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_DELIA_HR
new file mode 100644
index 0000000000000000000000000000000000000000..49c0c14f7f381906c80717154663416c0e8c2848
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_DELIA_HR
@@ -0,0 +1,34 @@
+DAY1 20140918
+DAY2 20140920
+DTIME 3
+M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC
+M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12
+M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11
+M_CLASS OD
+M_STREAM OPER
+M_NUMBER OFF
+M_EXPVER 1
+M_GRID 500  
+M_LEFT  12000
+M_LOWER 47000
+M_UPPER 52000
+M_RIGHT 17000
+M_LEVEL 137
+M_RESOL 511
+M_GAUSS 0
+M_ACCURACY 24
+M_OMEGA 0
+M_OMEGADIFF 0
+M_ETA 1
+M_ETADIFF 0
+M_DPDETA 1
+M_SMOOTH 0
+M_FORMAT GRIB2
+M_ADDPAR 186/187/188/235/139/39
+PREFIX EN
+ECSTORAGE 1
+ECTRANS 0
+ECFSDIR ectmp:/${USER}/econdemand/
+MAILOPS ${USER}
+MAILFAIL ${USER}
+EOF
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_DELIA_LR b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_DELIA_LR
new file mode 100644
index 0000000000000000000000000000000000000000..b3b0f2ca13190c663694c595dff79253799efee1
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_DELIA_LR
@@ -0,0 +1,34 @@
+DAY1 20140918
+DAY2 20140920
+DTIME 3
+M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC
+M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12
+M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11
+M_CLASS OD
+M_STREAM OPER
+M_NUMBER OFF
+M_EXPVER 1
+M_GRID 1000  
+M_LEFT  10000
+M_LOWER 45000
+M_UPPER 55000
+M_RIGHT 20000
+M_LEVEL 137
+M_RESOL 511
+M_GAUSS 0
+M_ACCURACY 24
+M_OMEGA 0
+M_OMEGADIFF 0
+M_ETA 1
+M_ETADIFF 0
+M_DPDETA 1
+M_SMOOTH 0
+M_FORMAT GRIB2
+M_ADDPAR 186/187/188/235/139/39
+PREFIX EN
+ECSTORAGE 1
+ECTRANS 0
+ECFSDIR ectmp:/${USER}/econdemand/
+MAILOPS ${USER}
+MAILFAIL ${USER}
+EOF
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_EI b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_EI
new file mode 100644
index 0000000000000000000000000000000000000000..c3d097411cfc71a179dc87df88c0407b6f026d7c
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_EI
@@ -0,0 +1,37 @@
+DAY1
+DAY2
+DTIME 3
+TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC
+TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12
+STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11
+CLASS EI
+STREAM OPER
+NUMBER OFF
+EXPVER 1
+GRID 5000  
+LEFT -15000
+LOWER 30000
+UPPER 75000
+RIGHT 45000
+LEVEL 60
+LEVELIST 55/to/60
+RESOL 63
+GAUSS 1
+ACCURACY 16
+OMEGA 0
+OMEGADIFF 0
+ETA 0
+ETADIFF 0
+DPDETA 1
+SMOOTH 0
+FORMAT GRIB1
+ADDPAR 186/187/188/235/139/39
+PREFIX EI
+ECSTORAGE 0
+ECTRANS 1
+ECFSDIR ectmp:/${USER}/econdemand/
+MAILFAIL ${USER} 
+MAILOPS ${USER}
+GRIB2FLEXPART 0
+EOF
+
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_ERA_HAIYAN b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_ERA_HAIYAN
new file mode 100644
index 0000000000000000000000000000000000000000..a3e4b06ccbcab970611b7e93aa85bdc33a0e8d39
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_ERA_HAIYAN
@@ -0,0 +1,34 @@
+DAY1 20131107
+DAY2 20131108
+DTIME 3
+M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC
+M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12
+M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11
+M_CLASS OD
+M_STREAM OPER
+M_NUMBER OFF
+M_EXPVER 1
+M_GRID 200  
+M_LEFT 113000
+M_LOWER 00000
+M_UPPER 30000
+M_RIGHT 190000
+M_LEVEL 137
+M_RESOL 799
+M_GAUSS 0
+M_ACCURACY 24
+M_OMEGA 0
+M_OMEGADIFF 0
+M_ETA 1
+M_ETADIFF 0
+M_DPDETA 1
+M_SMOOTH 0
+M_FORMAT GRIB1
+M_ADDPAR /186/187/188/235/139/39
+PREFIX EH
+ECSTORAGE 1
+ECTRANS 0
+ECFSDIR ectmp:/${USER}/econdemand/
+MAILOPS ${USER}
+MAILFAIL ${USER}
+EOF
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_ERA__GLOBALETA b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_ERA__GLOBALETA
new file mode 100644
index 0000000000000000000000000000000000000000..4c4336716a1e07db42c58c02d3155a1c25d7a597
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_ERA__GLOBALETA
@@ -0,0 +1,37 @@
+DAY1 20131105
+DAY2 20131105
+DTIME 3
+TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC
+TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12
+STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11
+CLASS EI
+STREAM OPER
+NUMBER OFF
+EXPVER 1
+GRID 1000  
+LEFT -179000
+LOWER -90000
+UPPER 90000
+RIGHT 180000
+LEVEL 60
+LEVELIST 1/to/60
+RESOL 159
+GAUSS 1
+ACCURACY 16
+OMEGA 0
+OMEGADIFF 0
+ETA 0
+ETADIFF 0
+DPDETA 1
+SMOOTH 0
+FORMAT GRIB1
+ADDPAR /186/187/188/235/139/39
+PREFIX EE
+ECSTORAGE 1
+ECTRANS 1
+ECFSDIR ectmp:/${USER}/econdemand/
+MAILOPS ${USER}
+MAILFAIL ${USER}
+FLEXPARTDIR ${HOME}/ECMWFDATA7.0/flexpart_code
+GRIB2FLEXPART grib2flexpart
+EOF
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_ERA__HIRES b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_ERA__HIRES
new file mode 100644
index 0000000000000000000000000000000000000000..3ff11aaa3e7d245acbd46da1727c568182aebb12
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_ERA__HIRES
@@ -0,0 +1,34 @@
+DAY1 20151007
+DAY2 20151007
+DTIME 1
+M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC
+M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12
+M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11
+M_CLASS OD
+M_STREAM OPER
+M_NUMBER OFF
+M_EXPVER 1
+M_GRID 200  
+M_LEFT -10000
+M_LOWER 30000
+M_UPPER 60000
+M_RIGHT 30000
+M_LEVEL 137
+M_RESOL 799
+M_GAUSS 1
+M_ACCURACY 24
+M_OMEGA 0
+M_OMEGADIFF 0
+M_ETA 0
+M_ETADIFF 0
+M_DPDETA 1
+M_SMOOTH 0
+M_FORMAT GRIB1
+M_ADDPAR /186/187/188/235/139/39
+PREFIX EH
+ECSTORAGE 1
+ECTRANS 0
+ECFSDIR ectmp:/${USER}/econdemand/
+MAILOPS ${USER}
+MAILFAIL ${USER}
+EOF
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_FC b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_FC
new file mode 100644
index 0000000000000000000000000000000000000000..e05bac201300f65cb974f9aae68c59bd24b311ef
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_FC
@@ -0,0 +1,31 @@
+DAY1 
+DAY2 
+DTIME 3
+M_TYPE FC FC FC FC FC FC FC FC FC FC FC FC FC FC FC FC FC FC FC FC FC FC FC FC FC
+M_TIME 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+M_STEP 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
+ACCTYPE FC
+ACCTIME 00
+ACCMAXSTEP 36
+M_MAXSTEP 36
+M_LEVEL 137
+M_LEVELIST 136/to/137
+M_CLASS OD
+M_STREAM OPER
+M_NUMBER OFF
+M_EXPVER 1
+M_GRID 1000  
+M_LEFT -25000
+M_LOWER 10000
+M_UPPER 60000
+M_RIGHT 60000
+M_RESOL 159
+M_ETA 1
+M_DPDETA 1
+M_SMOOTH 0
+M_ADDPAR /186/187/188/235/139/39
+M_WRF 1
+M_CWC 1
+PREFIX EE
+ECTRANS 1
+EOF
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_FC12 b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_FC12
new file mode 100644
index 0000000000000000000000000000000000000000..1fcedce1266c2b252aa3009e4fb928c1086356df
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_FC12
@@ -0,0 +1,38 @@
+DAY1 20131107
+DAY2 20131108
+DTIME 3
+M_TYPE FC FC FC FC FC FC FC FC FC FC FC FC FC FC FC FC FC FC FC FC FC FC FC FC
+M_TIME 00 00 00 00 00 00 00 00 00 00 00 00 12 12 12 12 12 12 12 12 12 12 12 12 
+M_STEP 00 01 02 03 04 05 06 07 08 09 10 11 00 01 02 03 04 05 06 07 08 09 10 11
+M_MAXSTEP 12
+M_LEVEL 137
+M_LEVELIST 120/to/121
+M_CLASS OD
+M_STREAM OPER
+M_NUMBER OFF
+M_EXPVER 1
+M_GRID 1000  
+M_LEFT -179000
+M_LOWER -90000
+M_UPPER 90000
+M_RIGHT 180000
+M_RESOL 159
+M_GAUSS 0
+M_ACCURACY 24
+M_OMEGA 0
+M_OMEGADIFF 0
+M_ETA 1
+M_ETADIFF 0
+M_DPDETA 1
+M_SMOOTH 0
+M_FORMAT GRIB1
+M_ADDPAR /186/187/188/235/139/39
+M_WRF 1
+M_CWC 1
+PREFIX EE
+ECSTORAGE 1
+ECTRANS 0
+ECFSDIR ectmp:/${USER}/econdemand/
+MAILOPS ${USER}
+MAILFAIL ${USER}
+EOF
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_HIRES b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_HIRES
new file mode 100644
index 0000000000000000000000000000000000000000..b2a2cf7f28eea8d3b309b55fd0c91534a38b7ac2
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_HIRES
@@ -0,0 +1,34 @@
+DAY1 20151007
+DAY2 20151007
+DTIME 1
+M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC
+M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12
+M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11
+M_CLASS OD
+M_STREAM OPER
+M_NUMBER OFF
+M_EXPVER 1
+M_GRID 200  
+M_LEFT -10000
+M_LOWER 30000
+M_UPPER 60000
+M_RIGHT 30000
+M_LEVEL 137
+M_RESOL 1279
+M_GAUSS 0
+M_ACCURACY 16
+M_OMEGA 0
+M_OMEGADIFF 0
+M_ETA 1
+M_ETADIFF 0
+M_DPDETA 1
+M_SMOOTH 0
+M_FORMAT GRIB1
+M_ADDPAR 186/187/188/235/139/39
+PREFIX EH
+ECSTORAGE 1
+ECTRANS 0
+ECFSDIR ectmp:/${USER}/econdemand/
+MAILOPS ${USER}
+MAILFAIL ${USER}
+EOF
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_HIRESGAUSS b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_HIRESGAUSS
new file mode 100644
index 0000000000000000000000000000000000000000..66abd64cb64a4fde84f77222efc462e8c5a06429
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_HIRESGAUSS
@@ -0,0 +1,34 @@
+DAY1 20151007
+DAY2 20151007
+DTIME 3
+M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC
+M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12
+M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11
+M_CLASS OD
+M_STREAM OPER
+M_NUMBER OFF
+M_EXPVER 1
+M_GRID 200  
+M_LEFT -10000
+M_LOWER 30000
+M_UPPER 60000
+M_RIGHT 30000
+M_LEVEL 137
+M_RESOL 1279
+M_GAUSS 1
+M_ACCURACY 16
+M_OMEGA 0
+M_OMEGADIFF 0
+M_ETA 0
+M_ETADIFF 0
+M_DPDETA 1
+M_SMOOTH 0
+M_FORMAT GRIB1
+M_ADDPAR 186/187/188/235/139/39
+PREFIX EH
+ECSTORAGE 1
+ECTRANS 0
+ECFSDIR ectmp:/${USER}/econdemand/
+MAILOPS ${USER}
+MAILFAIL ${USER}
+EOF
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_OD b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_OD
new file mode 100644
index 0000000000000000000000000000000000000000..f82261e440a0f0cac1a9b44f8c9b15969d6feb58
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_OD
@@ -0,0 +1,35 @@
+DAY1 20151007
+DAY2 20151007
+DTIME 3
+M_TYPE AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC AN FC FC FC FC FC
+M_TIME 00 00 00 00 00 00 06 00 00 00 00 00 12 12 12 12 12 12 18 12 12 12 12 12
+M_STEP 00 01 02 03 04 05 00 07 08 09 10 11 00 01 02 03 04 05 00 07 08 09 10 11
+M_CLASS OD
+M_STREAM OPER
+M_NUMBER OFF
+M_EXPVER 1
+M_GRID 1000  
+M_LEFT -10000
+M_LOWER 30000
+M_UPPER 60000
+M_RIGHT 30000
+M_LEVEL 137
+M_LEVELIST 130/to/137
+M_RESOL 399
+M_GAUSS 0
+M_ACCURACY 16
+M_OMEGA 0
+M_OMEGADIFF 0
+M_ETA 1
+M_ETADIFF 0
+M_DPDETA 1
+M_SMOOTH 0
+M_FORMAT GRIB1
+M_ADDPAR 186/187/188/235/139/39
+PREFIX EO
+ECSTORAGE 0
+ECTRANS 1
+ECFSDIR ectmp:/${USER}/econdemand/
+MAILOPS ${USER}
+MAILFAIL ${USER}
+EOF
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_OPS_V4.temp b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_OPS_V4.temp
new file mode 100644
index 0000000000000000000000000000000000000000..adf002aefe15a4ea49263fb4e2999dcb1f12efb6
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_OPS_V4.temp
@@ -0,0 +1,17 @@
+M_GRID 50
+M_LEFT -17950
+M_RESOL 399
+M_GAUSS 0
+M_ETA 1
+M_EXPVER 1
+M_LEVEL 137
+M_LEVELIST 1/to/137
+M_LEVMAX=137
+M_FORMAT GRIB1
+M_ADDPAR /186/187/188/235/139/39
+ECSTORAGE 1
+ECTRANS 1
+ECFSDIR ectmp:/${USER}/ecops
+MAILOPS ${USER}
+MAILFAIL ${USER}
+
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_OPS_V6.0 b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_OPS_V6.0
new file mode 100644
index 0000000000000000000000000000000000000000..973e8e30e422c6fe6d1cbd4dc58c4e4c9ff4800b
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_OPS_V6.0
@@ -0,0 +1,29 @@
+M_TYPE AN FC FC FC FC FC FC FC FC FC FC FC AN FC FC FC FC FC FC FC FC FC FC FC FC
+M_TIME 00 00 00 00 00 00 00 00 00 00 00 00 12 12 12 12 12 12 12 12 12 12 12 12 12
+M_STEP 00 01 02 03 04 05 06 07 08 09 10 11 00 01 02 03 04 05 06 07 08 09 10 11 12
+DTIME 3
+PREFIX EN
+M_UPPER 90000
+M_LOWER -90000
+M_LEFT -179000
+M_RIGHT 180000
+M_CLASS OD
+M_STREAM OPER
+M_NUMBER OFF
+M_GRID 1000
+M_RESOL 255
+M_SMOOTH 0
+M_GAUSS 0
+M_ETA 1
+CWC 1
+M_ETAPAR 77
+M_DPDETA 1
+M_LEVEL 137
+M_LEVELIST 136/to/137
+M_ADDPAR /186/187/188/235/139/39
+M_FORMAT GRIB2
+ECSTORAGE 0
+ECTRANS 1
+ECFSDIR ectmp:/${USER}/ecops
+MAILOPS ${USER}
+MAILFAIL ${USER}
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_OPS_V6.0_4V.temp b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_OPS_V6.0_4V.temp
new file mode 100644
index 0000000000000000000000000000000000000000..02083f692683781acc822902fcf13101cc18fc48
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_OPS_V6.0_4V.temp
@@ -0,0 +1,28 @@
+M_TYPE AN FC FC FC FC FC AN FC FC 4V FC FC 4V FC FC FC FC FC AN FC FC 4V FC FC 4V
+M_TIME 00 00 00 00 00 00 06 00 00 09 00 00 09 12 12 12 12 12 18 12 12 21 12 12 21
+M_STEP 00 01 02 03 04 05 00 07 08 00 10 11 03 01 02 03 04 05 00 07 08 00 10 11 03
+DTIME 1
+PREFIX EN
+M_UPPER 90000
+M_LOWER -90000
+M_LEFT  -179000
+M_RIGHT 180000
+M_CLASS OD
+M_STREAM OPER
+M_NUMBER OFF
+M_GRID 1000
+M_RESOL 255
+M_SMOOTH 0
+M_GAUSS 1
+M_ETA 0
+M_ETAPAR 77
+M_DPDETA 1
+M_LEVEL 137
+M_LEVELIST 136/to/137
+M_ADDPAR 186/187/188/235/139/39
+M_FORMAT GRIB1
+ECSTORAGE 1
+ECTRANS 1
+ECFSDIR ectmp:/${USER}/ecops
+MAILOPS ${USER}
+MAILFAIL ${USER}
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_PF.temp b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_PF.temp
new file mode 100644
index 0000000000000000000000000000000000000000..8eb9cb511a84744878b370f3f9208c93080abc54
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/run/control/CONTROL_PF.temp
@@ -0,0 +1,38 @@
+DAY1
+DAY2
+DTIME 3
+MAXSTEP 36
+TYPE PF PF
+TIME 12 12
+STEP 00 03
+CLASS OD
+STREAM ENFO
+NUMBER 0/to/9
+EXPVER 1
+GRID 1000  
+LEFT -179000
+LOWER -90000
+UPPER 90000
+RIGHT 180000
+LEVEL 62
+LEVELIST 60-62
+RESOL 159
+GAUSS 1
+ACCURACY 16
+OMEGA 0
+OMEGADIFF 0
+ETA 0
+ETADIFF 0
+DPDETA 1
+SMOOTH 0
+FORMAT GRIB1
+ADDPAR /186/187/188/235/139/39
+PREFIX EE
+ECSTORAGE 1
+ECTRANS 1
+ECFSDIR ectmp:/${USER}/econdemand/
+MAILOPS ${USER}
+MAILFAIL ${USER}
+FLEXPARTDIR ${HOME}/flex_extract_v7.1/flexpart_code
+GRIB2FLEXPART grib2flexpart
+EOF
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/Makefile.CRAY b/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/Makefile.CRAY
new file mode 100644
index 0000000000000000000000000000000000000000..6ed57be95245136e040e65c5964a2ef4f93d48f9
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/Makefile.CRAY
@@ -0,0 +1,62 @@
+###############################################################################
+#
+# Top level Makefile for ECMWFDATA7.0 software
+#
+# Last modified:  December 1, 2015
+#
+###############################################################################
+
+
+.SUFFIXES: .o .c .c~ .f .f~ .F90 .f90 .f90~ .f95 .f95~ .F .F~ .y .y~ .l .l~ \
+           .s .s~ .sh .sh~ .h .h~ .C .C~ .a
+
+
+#GRIB_API_INCLUDE_DIR=/usr/local/gcc-4.9.3/grib1.12.3//include
+#GRIB_API_LIB=-openmp -L/usr/local/gcc-4.9.3/grib1.12.3/lib -Bstatic  -lgrib_api_f77 -lgrib_api_f90 -lgrib_api -Bdynamic  -lm  -ljasper
+#EMOSLIB=-lemosR64
+
+OPT	= 
+DEBUG	= -g
+LIB     =  $(GRIB_API_LIBS) $(EMOSLIB)
+
+FC=ftn  $(F90FLAGS)
+F90C=ftn    $(F90FLAGS)
+
+FFLAGS =  $(OPT) -I. -r8 -I$(GRIB_API_INCLUDE_DIR)
+F90FLAGS =  $(OPT) -I. -r8 -I$(GRIB_API_INCLUDE_DIR)
+
+LDFLAGS =  $(OPT)
+
+BINDIR  =      .
+
+EXE	=      CONVERT2
+
+
+.f.o:
+	$(F90C) -c $(F90FLAGS) $(DEBUG) $*.f
+.f90.o:
+	$(F90C) -c $(F90FLAGS) $(DEBUG) $*.f90
+
+all:	${EXE}
+
+clean:
+	rm *.o
+
+phgrreal.o: phgrreal.f
+	$(F90C) -c -g -O3 phgrreal.f
+
+grphreal.o: grphreal.f
+	$(F90C) -c -g -O3 grphreal.f
+
+ftrafo.o: ftrafo.f
+	$(F90C) -c -g -O3 ftrafo.f
+
+$(BINDIR)/CONVERT2:	phgrreal.o grphreal.o ftrafo.o rwGRIB2.o  posnam.o preconvert.o
+	$(F90C) $(DEBUG) $(OPT) -o $(BINDIR)/CONVERT2 ftrafo.o phgrreal.o grphreal.o rwGRIB2.o posnam.o preconvert.o ${LIB}
+
+
+###############################################################################
+#
+# End of the Makefile
+#
+###############################################################################
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/Makefile.gfortran b/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/Makefile.gfortran
new file mode 100644
index 0000000000000000000000000000000000000000..58923fa5bf9713717ca12a4f420f9fb5ead4d6f0
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/Makefile.gfortran
@@ -0,0 +1,62 @@
+###############################################################################
+#
+# Top level Makefile for ECMWFDATA7.0 software
+#
+# Last modified:  December 1, 2015
+#
+###############################################################################
+
+
+.SUFFIXES: .o .c .c~ .f .f~ .F90 .f90 .f90~ .f95 .f95~ .F .F~ .y .y~ .l .l~ \
+           .s .s~ .sh .sh~ .h .h~ .C .C~ .a
+
+
+#GRIB_API_INCLUDE_DIR=/usr/local/gcc-4.9.3/grib1.12.3//include
+#GRIB_API_LIB=-openmp -L/usr/local/gcc-4.9.3/grib1.12.3/lib -Bstatic  -lgrib_api_f77 -lgrib_api_f90 -lgrib_api -Bdynamic  -lm  -ljasper
+#EMOSLIB=-lemosR64
+
+OPT	= -g
+DEBUG	= -g
+LIB     =  $(GRIB_API_LIB) $(EMOSLIB)
+
+FC=gfortran   -m64 -fdefault-real-8 -fcray-pointer -fno-second-underscore  -ffixed-line-length-132 -fopenmp  -fconvert=big-endian  
+F90C=gfortran   -m64 -fdefault-real-8 -fcray-pointer -fno-second-underscore  -ffixed-line-length-132 -fopenmp  -fconvert=big-endian 
+
+FFLAGS =  $(OPT) -I. -I$(GRIB_API_INCLUDE_DIR)
+F90FLAGS =  $(OPT) -I. -I$(GRIB_API_INCLUDE_DIR)
+
+LDFLAGS =  $(OPT)
+
+BINDIR  =      .
+
+EXE	=      CONVERT2
+
+
+.f.o:
+	$(F90C) -c $(F90FLAGS) $(DEBUG) $*.f
+.f90.o:
+	$(F90C) -c $(F90FLAGS) $(DEBUG) $*.f90
+
+all:	${EXE}
+
+clean:
+	rm *.o
+
+phgrreal.o: phgrreal.f
+	$(F90C) -c -g -O3 -fopenmp phgrreal.f
+
+grphreal.o: grphreal.f
+	$(F90C) -c -g -O3 -fopenmp grphreal.f
+
+ftrafo.o: ftrafo.f
+	$(F90C) -c -g -O3 -fopenmp ftrafo.f
+
+$(BINDIR)/CONVERT2:	phgrreal.o grphreal.o ftrafo.o rwGRIB2.o  posnam.o preconvert.o
+	$(F90C) $(DEBUG) $(OPT) -o $(BINDIR)/CONVERT2 ftrafo.o phgrreal.o grphreal.o rwGRIB2.o posnam.o preconvert.o ${LIB}
+
+
+###############################################################################
+#
+# End of the Makefile
+#
+###############################################################################
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/Makefile.ifort b/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/Makefile.ifort
new file mode 100644
index 0000000000000000000000000000000000000000..038a1689708cdf956c1f3a89621d3cad58654414
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/Makefile.ifort
@@ -0,0 +1,61 @@
+###############################################################################
+#
+# Top level Makefile for ECMWFDATA7.0 software
+#
+# Last modified:  December 1, 2015
+#
+###############################################################################
+
+
+.SUFFIXES: .o .c .c~ .f .f~ .F90 .f90 .f90~ .f95 .f95~ .F .F~ .y .y~ .l .l~ \
+           .s .s~ .sh .sh~ .h .h~ .C .C~ .a
+
+
+#GRIB_API_INCLUDE_DIR=/usr/local/ifort/grib1.12.3//include
+#GRIB_API_LIB=-openmp -L/usr/local/ifort/grib1.12.3/lib -Bstatic  -lgrib_api_f77 -lgrib_api_f90 -lgrib_api -Bdynamic  -lm  -ljasper
+
+OPT	= -g
+DEBUG	= -g
+LIB     =  $(GRIB_API_LIBS) -lemosR64 -lgfortran
+
+FC=ifort -132  -traceback -r8
+F90C=ifort -132  -traceback -r8
+
+FFLAGS =  $(OPT) -I. -I$(GRIB_API_INCLUDE_DIR)
+F90FLAGS =  $(OPT) -I. -I$(GRIB_API_INCLUDE_DIR)
+
+LDFLAGS =  $(OPT)
+
+BINDIR  =      .
+
+EXE	=      CONVERT2
+
+
+.f.o:
+	$(F90C) -c $(F90FLAGS) -132 $(DEBUG) $*.f
+.f90.o:
+	$(F90C) -c $(F90FLAGS) -132 $(DEBUG) $*.f90
+
+all:	${EXE}
+
+clean:
+	rm *.o
+
+phgrreal.o: phgrreal.f
+	$(F90C) -c -g -O3 -fopenmp phgrreal.f
+
+grphreal.o: grphreal.f
+	$(F90C) -c -g -O3 -fopenmp grphreal.f
+
+ftrafo.o: ftrafo.f
+	$(F90C) -c -g -O3 -fopenmp ftrafo.f
+
+$(BINDIR)/CONVERT2:	phgrreal.o grphreal.o ftrafo.o rwGRIB2.o  posnam.o preconvert.o
+	$(F90C) $(DEBUG) $(OPT) -o $(BINDIR)/CONVERT2 ftrafo.o phgrreal.o grphreal.o rwGRIB2.o posnam.o preconvert.o ${LIB}
+
+
+###############################################################################
+#
+# End of the Makefile
+#
+###############################################################################
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/Makefile.local.gfortran b/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/Makefile.local.gfortran
new file mode 100644
index 0000000000000000000000000000000000000000..3847d57ad9e6c0b92d823eda01fb6f83e2221d33
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/Makefile.local.gfortran
@@ -0,0 +1,62 @@
+###############################################################################
+#
+# Top level Makefile for ECMWFDATA7.0 software
+#
+# Last modified:  December 1, 2015
+#
+###############################################################################
+
+
+.SUFFIXES: .o .c .c~ .f .f~ .F90 .f90 .f90~ .f95 .f95~ .F .F~ .y .y~ .l .l~ \
+           .s .s~ .sh .sh~ .h .h~ .C .C~ .a
+
+
+GRIB_API_INCLUDE_DIR=/usr/local/gcc-4.9.3/grib_api-1.14.3//include
+GRIB_API_LIB= -L/usr/local/gcc-4.9.3/grib_api-1.14.3/lib -Bstatic  -lgrib_api_f77 -lgrib_api_f90 -lgrib_api -Bdynamic  -lm  -ljasper
+EMOSLIB=-lemosR64
+
+OPT	= -g -O3 -fopenmp
+DEBUG	= -g
+LIB     =  $(GRIB_API_LIB) $(EMOSLIB)
+
+FC=gfortran   -m64 -fdefault-real-8 -fcray-pointer -fno-second-underscore  -ffixed-line-length-132 -fopenmp  -fconvert=big-endian  
+F90C=gfortran   -m64 -fdefault-real-8 -fcray-pointer -fno-second-underscore  -ffixed-line-length-132 -fopenmp  -fconvert=big-endian 
+
+FFLAGS =  $(OPT) -I. -I$(GRIB_API_INCLUDE_DIR)
+F90FLAGS =  $(OPT) -I. -I$(GRIB_API_INCLUDE_DIR)
+
+LDFLAGS =  $(OPT)
+
+BINDIR  =      .
+
+EXE	=      CONVERT2
+
+
+.f.o:
+	$(F90C) -c $(F90FLAGS) $(DEBUG) $*.f
+.f90.o:
+	$(F90C) -c $(F90FLAGS) $(DEBUG) $*.f90
+
+all:	${EXE}
+
+clean:
+	rm *.o
+
+phgrreal.o: phgrreal.f
+	$(F90C) -c -g -O3 -fopenmp phgrreal.f
+
+grphreal.o: grphreal.f
+	$(F90C) -c -g -O3 -fopenmp grphreal.f
+
+ftrafo.o: ftrafo.f
+	$(F90C) -c -g -O3 -fopenmp ftrafo.f
+
+$(BINDIR)/CONVERT2:	phgrreal.o grphreal.o ftrafo.o rwGRIB2.o  posnam.o preconvert.o
+	$(F90C) $(DEBUG) $(OPT) -o $(BINDIR)/CONVERT2 ftrafo.o phgrreal.o grphreal.o rwGRIB2.o posnam.o preconvert.o ${LIB}
+
+
+###############################################################################
+#
+# End of the Makefile
+#
+###############################################################################
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/Makefile.local.ifort b/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/Makefile.local.ifort
new file mode 100644
index 0000000000000000000000000000000000000000..6f58a3532815bb2766f1bcd5fb2677958eaae355
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/Makefile.local.ifort
@@ -0,0 +1,61 @@
+###############################################################################
+#
+# Top level Makefile for ECMWFDATA7.0 software
+#
+# Last modified:  December 1, 2015
+#
+###############################################################################
+
+
+.SUFFIXES: .o .c .c~ .f .f~ .F90 .f90 .f90~ .f95 .f95~ .F .F~ .y .y~ .l .l~ \
+           .s .s~ .sh .sh~ .h .h~ .C .C~ .a
+
+
+GRIB_API_INCLUDE_DIR=/home/srvx1/tmc/TestEnv/Libraries/eccodes-2.6.0_ifort/include
+GRIB_API_LIB= -L/home/srvx1/tmc/TestEnv/Libraries/eccodes-2.6.0_ifort/lib -Bstatic  -leccodes_f90  -leccodes -Bdynamic  -lm  -ljasper 
+
+OPT	= -g -O3 -mcmodel=medium -unroll -inline -heap-arrays 32 
+DEBUG	= -g
+LIB     =  $(GRIB_API_LIB) -lemosR64 -lgfortran
+
+FC=/opt/intel/bin/ifort -132  -traceback -r8
+F90C=/opt/intel/bin/ifort -132  -traceback -r8
+
+FFLAGS =  $(OPT) -I. -I$(GRIB_API_INCLUDE_DIR)
+F90FLAGS =  $(OPT) -I. -I$(GRIB_API_INCLUDE_DIR)
+
+LDFLAGS =  $(OPT)
+
+BINDIR  =      .
+
+EXE	=      CONVERT2
+
+
+.f.o:
+	$(F90C) -c $(F90FLAGS) -132 $(DEBUG) $*.f
+.f90.o:
+	$(F90C) -c $(F90FLAGS) -132 $(DEBUG) $*.f90
+
+all:	${EXE}
+
+clean:
+	rm *.o
+
+phgrreal.o: phgrreal.f
+	$(F90C) -c -g -O3 phgrreal.f
+
+grphreal.o: grphreal.f
+	$(F90C) -c -g -O3 grphreal.f
+
+ftrafo.o: ftrafo.f
+	$(F90C) -c -g -O3 ftrafo.f
+
+$(BINDIR)/CONVERT2:	phgrreal.o grphreal.o ftrafo.o rwGRIB2.o  posnam.o preconvert.o
+	$(F90C) $(DEBUG) $(OPT) -o $(BINDIR)/CONVERT2 ftrafo.o phgrreal.o grphreal.o rwGRIB2.o posnam.o preconvert.o ${LIB}
+
+
+###############################################################################
+#
+# End of the Makefile
+#
+###############################################################################
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/Makefile.new b/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/Makefile.new
new file mode 100644
index 0000000000000000000000000000000000000000..9953d130c88dbb3a07e54867ef5c700c12df799f
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/Makefile.new
@@ -0,0 +1,61 @@
+###############################################################################
+#
+# Top level Makefile for ECMWFDATA7.0 software
+#
+# Last modified:  December 1, 2015
+#
+###############################################################################
+
+
+.SUFFIXES: .o .c .c~ .f .f~ .F90 .f90 .f90~ .f95 .f95~ .F .F~ .y .y~ .l .l~ \
+           .s .s~ .sh .sh~ .h .h~ .C .C~ .a
+
+
+GRIB_API_INCLUDE_DIR=/usr/local/ifort/grib1.12.3//include
+GRIB_API_LIBS=-openmp -L/usr/local/ifort/grib1.12.3/lib -Bstatic  -lgrib_api_f77 -lgrib_api_f90 -lgrib_api -Bdynamic  -lm  -ljasper
+
+OPT	= -g
+DEBUG	= -g
+LIB     =  $(GRIB_API_LIBS) -lemosR64
+
+FC=ifort -132  -traceback -r8
+F90C=ifort -132  -traceback -r8
+
+FFLAGS =  $(OPT) -I. -I$(GRIB_API_INCLUDE_DIR)
+F90FLAGS =  $(OPT) -I. -I$(GRIB_API_INCLUDE_DIR)
+
+LDFLAGS =  $(OPT)
+
+BINDIR  =      .
+
+EXE	=      CONVERT2
+
+
+.f.o:
+	$(F90C) -c $(F90FLAGS) -132 $(DEBUG) $*.f
+.f90.o:
+	$(F90C) -c $(F90FLAGS) -132 $(DEBUG) $*.f90
+
+all:	${EXE}
+
+clean:
+	rm *.o
+
+phgrreal.o: phgrreal.f
+	$(F90C) -c -g -O3 -fopenmp phgrreal.f
+
+grphreal.o: grphreal.f
+	$(F90C) -c -g -O3 -fopenmp grphreal.f
+
+ftrafo.o: ftrafo.f
+	$(F90C) -c -g -O3 -fopenmp ftrafo.f
+
+$(BINDIR)/CONVERT2:	phgrreal.o grphreal.o ftrafo.o rwGRIB2.o  posnam.o preconvert.o
+	$(F90C) $(DEBUG) $(OPT) -o $(BINDIR)/CONVERT2 ftrafo.o phgrreal.o grphreal.o rwGRIB2.o posnam.o preconvert.o ${LIB}
+
+
+###############################################################################
+#
+# End of the Makefile
+#
+###############################################################################
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/ftrafo.f b/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/ftrafo.f
new file mode 100644
index 0000000000000000000000000000000000000000..affdccdcf8b2a439fbd5fd35435ac076eefe7ee5
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/ftrafo.f
@@ -0,0 +1,504 @@
+	MODULE FTRAFO
+
+	CONTAINS
+
+
+
+C
+C	Implementierung der spektralen Transformationsmethode unter Verwendung
+C	des reduzierten Gauss'schen Gitters
+C	
+C Berechnung der scale winds aus Vorticity und Divergenz
+C uebergibt man in XMN die Divergenz, so wird der divergente Anteil des
+C Windes (XPHI=Ud,XPHI=Vd) zurueckgegeben, uebergibt man die Vorticity, so 
+C erhaelt man den rotationellen Wind (XLAM=Vrot,XPHI=-Urot).
+C Summiert man beide, erhaelt man den gesamten Scale wind
+C	GWSAVE ist ein Hilfsfeld fuer die FFT
+C	P enthaelt die assoziierten Legendrepolynome, H deren Ableitung
+C	MLAT enthaelt die Anzahl der Gitterpunkte pro Breitenkreis
+C	MNAUF gibt die spektrale Aufloesung an,
+C	NI = Anzahl der Gauss'schen Gitterpunkte pro Flaeche
+C	NJ = Anzahl der Gauss'schen Breiten,
+C	NK = Anzahl der Niveaus
+ 
+	SUBROUTINE VDTOUV(XMN,XLAM,XPHI,GWSAVE,IFAX,P,MLAT,MNAUF,NI,NJ,NK)
+
+
+	USE PHTOGR
+
+	IMPLICIT NONE
+	INTEGER   J,N,NI,NJ,NK,MNAUF,GGIND(NJ/2)
+	INTEGER		MLAT(NJ),IFAX(10,NJ)
+	REAL			XMN(0:(MNAUF+1)*(MNAUF+2)-1,NK)
+	REAL		P(0:(MNAUF+3)*(MNAUF+4)/2,NJ/2)
+	REAL		H(0:(MNAUF+2)*(MNAUF+3)/2)
+	REAL			XLAM(NI,NK),XPHI(NI,NK)
+	REAL			GWSAVE(8*NJ+15,NJ/2)
+	REAL 		SCR,SCI,ACR,ACI,MUSCR,MUSCI,MUACR,MUACI
+	REAL	  RT,IT
+
+	GGIND(1)=0
+	DO 4 J = 2,NJ/2	   	   
+	  GGIND(J)=GGIND(J-1)+MLAT(J-1)
+4	CONTINUE
+!$OMP PARALLEL DO SCHEDULE(DYNAMIC)
+	DO 5 J = 1,NJ/2
+	   CALL VDUVSUB(J,XMN,XLAM,XPHI,GWSAVE,IFAX,P,GGIND(J),
+     *MLAT,MNAUF,NI,NJ,NK)   
+ 5	CONTINUE
+!$OMP END PARALLEL DO
+	RETURN
+	END SUBROUTINE VDTOUV
+
+	SUBROUTINE VDUVSUB(J,XMN,XLAM,XPHI,GWSAVE,IFAX,P,
+     *GGIND,MLAT,MNAUF,NI,NJ,NK) 
+
+	USE PHTOGR
+
+	IMPLICIT NONE
+	INTEGER   J,K,M,N,NI,NJ,NK,MNAUF,GGIND,LL,LLP,LLH,LLS,LLPS,LLHS
+	INTEGER		MLAT(NJ),IFAX(10,NJ)
+	REAL     	UFOUC(0:MAXAUF),MUFOUC(0:MAXAUF)
+	REAL 			VFOUC(0:MAXAUF),MVFOUC(0:MAXAUF)
+	REAL			XMN(0:(MNAUF+1)*(MNAUF+2)-1,NK)
+	REAL		P(0:(MNAUF+3)*(MNAUF+4)/2,NJ/2)
+	REAL		H(0:(MNAUF+2)*(MNAUF+3)/2)
+	REAL			XLAM(NI,NK),XPHI(NI,NK)
+	REAL			GWSAVE(8*NJ+15,NJ/2)
+	REAL 		ERAD,SCR,SCI,ACR,ACI,MUSCR,MUSCI,MUACR,MUACI
+	REAL	  FAC(0:MNAUF),RT,IT
+  
+	
+	ERAD = 6367470.D0
+	
+	FAC(0)=0.D0
+	DO 12 N=1,MNAUF
+	  FAC(N)=-ERAD/DBLE(N)/DBLE(N+1)
+12	CONTINUE
+
+	 CALL DPLGND(MNAUF,P(0,J),H)
+	 DO 3 K = 1,NK
+	  LL=0
+	  LLP=0
+	  LLH=0
+	  DO 2 M = 0,MNAUF
+	   SCR=0.D0
+	   SCI=0.D0
+	   ACR=0.D0
+	   ACI=0.D0
+	   MUSCR=0.D0
+	   MUSCI=0.D0
+	   MUACR=0.D0
+	   MUACI=0.D0
+	   LLS=LL
+	   LLPS=LLP
+	   LLHS=LLH
+	   IF(2*M+1.LT.MLAT(J)) THEN
+	      DO 1 N = M,MNAUF,2
+	       RT=XMN(2*LL,K)*FAC(N)
+	       IT=XMN(2*LL+1,K)*FAC(N)
+	       SCR =SCR+ RT*P(LLP,J)
+	       SCI =SCI+ IT*P(LLP,J)
+	       MUACR =MUACR+ RT*H(LLH)
+	       MUACI =MUACI+ IT*H(LLH)
+	       LL=LL+2
+	       LLP=LLP+2
+	       LLH=LLH+2
+ 1	      CONTINUE
+	      LL=LLS+1
+	      LLP=LLPS+1
+	      LLH=LLHS+1
+	      DO 11 N = M+1,MNAUF,2
+	       RT=XMN(2*LL,K)*FAC(N)
+	       IT=XMN(2*LL+1,K)*FAC(N)
+	       ACR =ACR+ RT*P(LLP,J)
+	       ACI =ACI+ IT*P(LLP,J)
+	       MUSCR =MUSCR+ RT*H(LLH)
+	       MUSCI =MUSCI+ IT*H(LLH)
+	       LL=LL+2
+	       LLP=LLP+2
+	       LLH=LLH+2
+ 11	      CONTINUE
+	   ENDIF
+	   LL=LLS+(MNAUF-M+1)
+	   LLP=LLPS+(MNAUF-M+3)
+	   LLH=LLHS+(MNAUF-M+2)
+
+	   UFOUC(2*M)=-M*(SCI-ACI)
+	   UFOUC(2*M+1)=M*(SCR-ACR)
+	   VFOUC(2*M)=-M*(SCI+ACI)
+	   VFOUC(2*M+1)=M*(SCR+ACR)
+	   
+	   MUFOUC(2*M)=-(MUSCR-MUACR)
+	   MUFOUC(2*M+1)=-(MUSCI-MUACI)
+	   MVFOUC(2*M)=-(MUSCR+MUACR)
+	   MVFOUC(2*M+1)=-(MUSCI+MUACI)
+ 2	  CONTINUE
+			
+	 CALL RFOURTR(VFOUC,
+     *GWSAVE(:,J),IFAX(:,J),MNAUF,MLAT(J),1)
+         XLAM(GGIND+1:GGIND+MLAT(J),K)=VFOUC(0:MLAT(J)-1)
+	 CALL RFOURTR(UFOUC,
+     *GWSAVE(:,J),IFAX(:,J),MNAUF,MLAT(J),1)
+         XLAM(NI-GGIND-MLAT(J)+1:NI-GGIND,K)=UFOUC(0:MLAT(J)-1)
+			
+	 CALL RFOURTR(MVFOUC,
+     *GWSAVE(:,J),IFAX(:,J),MNAUF,MLAT(J),1)
+         XPHI(GGIND+1:GGIND+MLAT(J),K)=MVFOUC(0:MLAT(J)-1)
+	 CALL RFOURTR(MUFOUC,
+     *GWSAVE(:,J),IFAX(:,J),MNAUF,MLAT(J),1)
+         XPHI(NI-GGIND-MLAT(J)+1:NI-GGIND,K)=MUFOUC(0:MLAT(J)-1)
+
+3		CONTINUE
+
+      RETURN
+      END SUBROUTINE VDUVSUB
+
+C Berechnung des Gradienten eines Skalars aus dem Feld des
+C	Skalars XMN im Phasenraum. Zurueckgegeben werden die Felder der
+C	Komponenten des horizontalen Gradienten XLAM,XPHI auf dem Gauss'schen Gitter.
+C	GWSAVE ist ein Hilfsfeld fuer die FFT
+C	P enthaelt die assoziierten Legendrepolynome, H deren Ableitung
+C	MLAT enthaelt die Anzahl der Gitterpunkte pro Breitenkreis
+C	MNAUF gibt die spektrale Aufloesung an, 
+C	NI = Anzahl der Gauss'schen Gitterpunkte,
+C	NJ = Anzahl der Gauss'schen Breiten,
+C	NK = Anzahl der Niveaus
+ 
+	SUBROUTINE PHGRAD(XMN,XLAM,XPHI,GWSAVE,IFAX,P,H,MLAT,
+     *MNAUF,NI,NJ,NK)
+
+	USE PHTOGR
+	IMPLICIT NONE
+	INTEGER   J,K,M,N,NI,NJ,NK,MNAUF,GGIND,LL,LLP,LLH,LLS,LLPS,LLHS
+	INTEGER		MLAT(NJ),IFAX(10,NJ)
+	REAL     	UFOUC(0:MAXAUF),MUFOUC(0:MAXAUF)
+	REAL 			VFOUC(0:MAXAUF),MVFOUC(0:MAXAUF)
+	REAL			XMN(0:(MNAUF+1)*(MNAUF+2)-1,NK)
+	REAL		P(0:(MNAUF+3)*(MNAUF+4)/2,NJ/2)
+	REAL		H(0:(MNAUF+2)*(MNAUF+3)/2)
+	REAL			XLAM(NI,NK),XPHI(NI,NK)
+	REAL			GWSAVE(8*NJ+15,NJ/2)
+	REAL      ERAD
+	REAL 		SCR,SCI,ACR,ACI,MUSCR,MUSCI,MUACR,MUACI,RT,IT
+	
+	ERAD = 6367470.0
+	
+	GGIND=0
+	DO 4 J = 1,NJ/2
+	 CALL DPLGND(MNAUF,P(0,J),H)
+	 DO 3 K = 1,NK
+	  LL=0
+	  LLP=0
+	  LLH=0
+	  DO 2 M = 0,MNAUF
+	   SCR=0.D0
+	   SCI=0.D0
+	   ACR=0.D0
+	   ACI=0.D0
+	   MUSCR=0.D0
+	   MUSCI=0.D0
+	   MUACR=0.D0
+	   MUACI=0.D0
+	   LLS=LL
+	   LLPS=LLP
+	   LLHS=LLH
+	   IF(2*M+1.LT.MLAT(J)) THEN
+	      DO 1 N = M,MNAUF,2
+	       RT=XMN(2*LL,K)
+	       IT=XMN(2*LL+1,K)
+	       SCR =SCR+ RT*P(LLP,J)
+	       SCI =SCI+ IT*P(LLP,J)
+	       MUACR =MUACR+RT*H(LLH)
+	       MUACI =MUACI+ IT*H(LLH)
+	       LL=LL+2
+	       LLP=LLP+2
+	       LLH=LLH+2
+ 1	      CONTINUE
+	      LL=LLS+1
+	      LLP=LLPS+1
+	      LLH=LLHS+1
+	      DO 11 N = M+1,MNAUF,2
+	       RT=XMN(2*LL,K)
+	       IT=XMN(2*LL+1,K)
+	       ACR =ACR+ RT*P(LLP,J)
+	       ACI =ACI+ IT*P(LLP,J)
+	       MUSCR =MUSCR+ RT*H(LLH)
+	       MUSCI =MUSCI+ IT*H(LLH)
+	       LL=LL+2
+	       LLP=LLP+2
+	       LLH=LLH+2
+ 11	      CONTINUE
+	   ENDIF
+          LL=LLS+(MNAUF-M+1)
+          LLP=LLPS+(MNAUF-M+3)
+          LLH=LLHS+(MNAUF-M+2)
+
+		UFOUC(2*M)=-M*(SCI-ACI)/ERAD
+		UFOUC(2*M+1)=M*(SCR-ACR)/ERAD
+		VFOUC(2*M)=-M*(SCI+ACI)/ERAD
+		VFOUC(2*M+1)=M*(SCR+ACR)/ERAD
+
+		MUFOUC(2*M)=-(MUSCR-MUACR)/ERAD
+		MUFOUC(2*M+1)=-(MUSCI-MUACI)/ERAD
+		MVFOUC(2*M)=-(MUSCR+MUACR)/ERAD
+		MVFOUC(2*M+1)=-(MUSCI+MUACI)/ERAD
+2	CONTINUE
+
+	 CALL RFOURTR(VFOUC,
+     *GWSAVE(:,J),IFAX(:,J),MNAUF,MLAT(J),1)
+         XLAM(GGIND+1:GGIND+MLAT(J),K)=VFOUC(0:MLAT(J)-1)
+	 CALL RFOURTR(UFOUC,
+     *GWSAVE(:,J),IFAX(:,J),MNAUF,MLAT(J),1)
+         XLAM(NI-GGIND-MLAT(J)+1:NI-GGIND,K)=UFOUC(0:MLAT(J)-1)
+			
+	 CALL RFOURTR(MVFOUC,
+     *GWSAVE(:,J),IFAX(:,J),MNAUF,MLAT(J),1)
+         XPHI(GGIND+1:GGIND+MLAT(J),K)=MVFOUC(0:MLAT(J)-1)
+	 CALL RFOURTR(MUFOUC,
+     *GWSAVE(:,J),IFAX(:,J),MNAUF,MLAT(J),1)
+         XPHI(NI-GGIND-MLAT(J)+1:NI-GGIND,K)=MUFOUC(0:MLAT(J)-1)
+			
+3		CONTINUE
+		GGIND=GGIND+MLAT(J)
+4	CONTINUE
+
+
+	RETURN
+	END SUBROUTINE PHGRAD
+
+C Berechnung des Gradienten eines Skalars aus dem Feld des
+C	Skalars XMN im Phasenraum. Zurueckgegeben werden die Felder der
+C	Komponenten des horizontalen Gradienten XLAM,XPHI auf dem Gauss'schen Gitter.
+C	GWSAVE ist ein Hilfsfeld fuer die FFT
+C	P enthaelt die assoziierten Legendrepolynome, H deren Ableitung
+C	MLAT enthaelt die Anzahl der Gitterpunkte pro Breitenkreis
+C	MNAUF gibt die spektrale Aufloesung an, 
+C	NI = Anzahl der Gauss'schen Gitterpunkte,
+C	NJ = Anzahl der Gauss'schen Breiten,
+C	NK = Anzahl der Niveaus
+ 
+	SUBROUTINE PHGRACUT(XMN,XLAM,XPHI,GWSAVE,IFAX,P,H,MAUF,
+     *MNAUF,NI,NJ,MANF,NK)
+
+	USE PHTOGR
+	IMPLICIT NONE
+	INTEGER   J,K,M,N,NI,NJ,NK,MNAUF,GGIND,LL,LLP,LLH,LLS,LLPS,LLHS
+	INTEGER		MAUF,MANF,I,IFAX(10)
+	REAL     	UFOUC(0:MAXAUF),MUFOUC(0:MAXAUF)
+	REAL 			VFOUC(0:MAXAUF),MVFOUC(0:MAXAUF)
+	REAL			XMN(0:(MNAUF+1)*(MNAUF+2)-1,NK)
+	REAL		P(0:(MNAUF+3)*(MNAUF+4)/2,NJ)
+	REAL		H(0:(MNAUF+2)*(MNAUF+3)/2)
+	REAL			XLAM(NI,NJ,NK),XPHI(NI,NJ,NK)
+	REAL			HLAM(MAXAUF,2),HPHI(MAXAUF,2)
+	REAL			GWSAVE(4*MAUF+15)
+	REAL      ERAD
+	REAL 		SCR,SCI,ACR,ACI,MUSCR,MUSCI,MUACR,MUACI,RT,IT
+	
+	ERAD = 6367470.0
+	
+	GGIND=0
+	DO 4 J = 1,NJ
+	 CALL DPLGND(MNAUF,P(0,J),H)
+	 DO 3 K = 1,NK
+	  LL=0
+	  LLP=0
+	  LLH=0
+	  DO 2 M = 0,MNAUF
+	   SCR=0.D0
+	   SCI=0.D0
+	   ACR=0.D0
+	   ACI=0.D0
+	   MUSCR=0.D0
+	   MUSCI=0.D0
+	   MUACR=0.D0
+	   MUACI=0.D0
+	   LLS=LL
+	   LLPS=LLP
+	   LLHS=LLH
+	   IF(2*M+1.LT.MAUF) THEN
+	      DO 1 N = M,MNAUF,2
+	       RT=XMN(2*LL,K)
+	       IT=XMN(2*LL+1,K)
+	       SCR =SCR+ RT*P(LLP,J)
+	       SCI =SCI+ IT*P(LLP,J)
+	       MUACR =MUACR+RT*H(LLH)
+	       MUACI =MUACI+ IT*H(LLH)
+	       LL=LL+2
+	       LLP=LLP+2
+	       LLH=LLH+2
+ 1	      CONTINUE
+	      LL=LLS+1
+	      LLP=LLPS+1
+	      LLH=LLHS+1
+	      DO 11 N = M+1,MNAUF,2
+	       RT=XMN(2*LL,K)
+	       IT=XMN(2*LL+1,K)
+	       ACR =ACR+ RT*P(LLP,J)
+	       ACI =ACI+ IT*P(LLP,J)
+	       MUSCR =MUSCR+ RT*H(LLH)
+	       MUSCI =MUSCI+ IT*H(LLH)
+	       LL=LL+2
+	       LLP=LLP+2
+	       LLH=LLH+2
+ 11	      CONTINUE
+	   ENDIF
+          LL=LLS+(MNAUF-M+1)
+          LLP=LLPS+(MNAUF-M+3)
+          LLH=LLHS+(MNAUF-M+2)
+
+		UFOUC(2*M)=-M*(SCI-ACI)/ERAD
+		UFOUC(2*M+1)=M*(SCR-ACR)/ERAD
+		VFOUC(2*M)=-M*(SCI+ACI)/ERAD
+		VFOUC(2*M+1)=M*(SCR+ACR)/ERAD
+
+		MUFOUC(2*M)=-(MUSCR-MUACR)/ERAD
+		MUFOUC(2*M+1)=-(MUSCI-MUACI)/ERAD
+		MVFOUC(2*M)=-(MUSCR+MUACR)/ERAD
+		MVFOUC(2*M+1)=-(MUSCI+MUACI)/ERAD
+2			CONTINUE
+			
+		CALL RFOURTR(VFOUC,
+     *GWSAVE,IFAX,MNAUF,MAUF,1)
+			
+		CALL RFOURTR(MVFOUC,
+     *GWSAVE,IFAX,MNAUF,MAUF,1)
+			
+            DO 6 I=0,NI-1
+                  IF(MANF+I.LE. MAUF) THEN
+                    XLAM(I+1,J,K)=VFOUC(MANF+I-1)
+                    XPHI(I+1,J,K)=MVFOUC(MANF+I-1)
+                  ELSE
+                    XLAM(I+1,J,K)=VFOUC(MANF-MAUF+I-1)
+                    XPHI(I+1,J,K)=MVFOUC(MANF-MAUF+I-1)
+                  ENDIF
+    6   CONTINUE
+3		CONTINUE
+		GGIND=GGIND+MAUF
+4	CONTINUE
+
+	RETURN
+	END SUBROUTINE PHGRACUT
+
+C Berechnung der Divergenz aus dem Windfeld (U,V)
+C	im Phasenraum. Zurueckgegeben werden die Felder der
+C	Komponenten des horizontalen Gradienten XLAM,XPHI auf dem Gauss'schen Gitter.
+C	GWSAVE ist ein Hilfsfeld fuer die FFT
+C	P enthaelt die assoziierten Legendrepolynome, H deren Ableitung
+C	MLAT enthaelt die Anzahl der Gitterpunkte pro Breitenkreis
+C	MNAUF gibt die spektrale Aufloesung an, 
+C	NI = Anzahl der Gauss'schen Gitterpunkte,
+C	NJ = Anzahl der Gauss'schen Breiten,
+C	NK = Anzahl der Niveaus
+C Beachte, dass das Windfeld eine um 1 erhoehte Aufloesung in mu-Richtung hat.
+ 
+	SUBROUTINE CONTGL(PS,DPSDL,DPSDM,DIV,U,V,BREITE,ETA,
+     *MLAT,A,B,NI,NJ,NK)
+				
+	IMPLICIT NONE
+	
+	INTEGER NI,NJ,NK,I,J,K,MLAT(NJ),L
+	
+	REAL A(NK+1),B(NK+1)
+	REAL PS(NI),DPSDL(NI),DPSDM(NI)
+	REAL DIV(NI,NK),U(NI,NK),V(NI,NK),ETA(NI,NK)
+	REAL BREITE(NJ)
+	
+	REAL DIVT1,DIVT2,POB,PUN,DPSDT,COSB
+	
+        L=0
+	DO 4 J=1,NJ
+		COSB=(1.0-BREITE(J)*BREITE(J))
+		DO 3 I=1,MLAT(J)
+                        L=L+1
+			DIVT1=0.0
+			DIVT2=0.0
+			DO 1 K=1,NK
+				POB=A(K)+B(K)*PS(L)
+				PUN=A(K+1)+B(K+1)*PS(L)
+				
+				DIVT1=DIVT1+DIV(L,K)*(PUN-POB)
+				if(cosb .gt. 0.) then
+                                  DIVT2=DIVT2+(B(K+1)-B(K))*PS(L)*
+     *(U(L,K)*DPSDL(L)+V(L,K)*DPSDM(L))/COSB
+                                endif
+     
+     		ETA(L,K)=-DIVT1-DIVT2
+1			CONTINUE
+
+			DPSDT=(-DIVT1-DIVT2)/PS(L)
+			
+			DO 2 K=1,NK
+				ETA(L,K)=ETA(L,K)-DPSDT*B(K+1)*PS(L)
+2			CONTINUE
+			PS(L)=DPSDT*PS(L)
+3		CONTINUE
+4	CONTINUE
+	RETURN
+	END SUBROUTINE CONTGL
+	
+C	OMEGA berechnet omega im Hybridkoordinatensystem
+C	PS ist der Bodendruck,
+C	DPSDL,DPSDM sind die Komponenten des Gradienten des Logarithmus des
+C	Bodendrucks
+C	DIV,U,V sind die horizontale Divergenz und das horizontale Windfeld
+C	BREITE ist das Feld der Gauss'schen Breiten
+C	E ist omega,
+
+	SUBROUTINE OMEGA(PS,DPSDL,DPSDM,DIV,U,V,BREITE,E,MLAT,A,B,NGI
+     *	 ,NGJ,MKK) 
+				
+	IMPLICIT NONE
+		
+	INTEGER I,J,K,L,NGI,NGJ,MKK,MLAT(NGJ)
+	
+	REAL PS(NGI),DPSDL(NGI),DPSDM(NGI),A(MKK+1),B(MKK+1)
+	REAL DIV(NGI,MKK),U(NGI,MKK),V(NGI,MKK),E(NGI,MKK)
+	REAL BREITE(NGJ)
+	
+	REAL DIVT1,DIVT2,POB,PUN,DP,X,Y,COSB
+	REAL DIVT3(MKK+2)
+	
+	L=0
+	DO 4 J=1,NGJ
+		COSB=(1.0-BREITE(J)*BREITE(J))
+		DO 3 I=1,MLAT(J)
+			L=L+1
+			DIVT1=0.0
+			DIVT2=0.0
+			DIVT3(1)=0.0
+			DO 1 K=1,MKK
+				POB=A(K)+B(K)*PS(L)
+				PUN=A(K+1)+B(K+1)*PS(L)
+				DP=PUN-POB
+				
+		Y=PS(L)*(U(L,K)*DPSDL(L)+V(L,K)*DPSDM(L))/COSB
+     		IF(K.LT.3) THEN
+     		X=0.0
+     		ELSE
+				X=(B(K+1)-B(K))*Y
+				ENDIF
+
+				DIVT1=DIVT1+DIV(L,K)*DP			
+				DIVT2=DIVT2+X
+     
+     		DIVT3(K+1)=-DIVT1-DIVT2
+     		
+     		IF(K.GT.1) THEN
+				E(L,K) = 0.5*(POB+PUN)/DP*Y*
+     *((B(K+1)-B(K))+(A(K+1)*B(K)-A(K)*B(K+1))/
+     *DP*LOG(PUN/POB))
+				ELSE
+					E(L,K) = 0.0
+				ENDIF
+								
+			E(L,K) = E(L,K)+0.5*(DIVT3(K)+DIVT3(K+1))
+
+1			CONTINUE
+3		CONTINUE
+4	CONTINUE
+	RETURN
+	END SUBROUTINE OMEGA
+	
+	END MODULE FTRAFO
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/grphreal.f b/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/grphreal.f
new file mode 100644
index 0000000000000000000000000000000000000000..dae342bf336d149d97ffa55234c0b1375eff2661
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/grphreal.f
@@ -0,0 +1,188 @@
+      MODULE GRTOPH
+
+      USE PHTOGR
+
+      CONTAINS
+C
+      SUBROUTINE GRPH213(CXMN,FELD,WSAVE,IFAX,Z,W,MLAT,
+     *MNAUF,MAXL,MAXB,MLEVEL)
+
+C     DIE ROUTINE F]HRT EINE TRANSFORMATION EINER
+C     FELDVARIABLEN VOM PHASENRAUM IN  DEN PHYSIKALISCHEN
+C     RAUM AUF KUGELKOORDINATEN DURCH
+C
+C     CXMN   = SPEKTRALKOEFFIZIENTEN IN DER REIHENFOLGE
+C              CX00,CX01,CX11,CX02,....CXMNAUFMNAUF
+C			CXM		 = FOURIERKOEFFIZIENTEN - nur ein Hilfsfeld
+C     FELD   = FELD DER METEOROLOGISCHEN VARIABLEN
+C			WSAVE  = Working Array fuer Fouriertransformation
+C     Z 	 = LEGENDREFUNKTIONSWERTE
+C
+C     MNAUF    ANZAHL DER FOURIERKOEFFIZIENTEN
+C     MAXL     ANZAHL DER FUER DAS GITTER BENUTZTEN LAENGEN
+C     MAXB     ANZAHL DER FUER DAS GITTER BENOETIGTEN BREITEN
+C     MLEVEL   ANZAHL DER LEVELS, DIE TRANSFORMIERT WERDEN
+C
+      IMPLICIT REAL (A-H,O-Z)
+
+
+C			Anzahl der Gitterpunkte pro Breitenkreis des reduzierten 
+C			Gauss'schen Gitters
+	INTEGER MLAT(MAXB),ISIZE,IFAX(10,MAXB)
+			
+C    FELD DER LEGENDREPOLYNOME FUER EINE BREITE
+      REAL*8 Z(MAXB/2,0:((MNAUF+3)*(MNAUF+4))/2)
+      
+C      LOGICAL*1 USED(((216*217)/2+1)*160)
+
+      DIMENSION CXMN(0:(MNAUF+1)*(MNAUF+2)-1,MLEVEL)
+      REAL FELD(MAXL,MLEVEL)
+      DIMENSION WSAVE(8*MAXB+15,MAXB/2)
+      REAL*8 W(MAXB) 
+      DIMENSION IND(MAXB)
+			
+			
+      	IND(1)=0
+      DO 6 J=2,MAXB/2
+	 IND(j)=IND(J-1)+MLAT(J-1)
+ 6    CONTINUE
+!$OMP PARALLEL DO SCHEDULE(DYNAMIC)
+      DO 16 L=1,MLEVEL
+        CALL GRPHSUB(L,IND,CXMN,FELD,WSAVE,IFAX,Z,W,MLAT,
+     *MNAUF,MAXL,MAXB,MLEVEL)
+16    CONTINUE
+!$omp end parallel do
+
+
+      RETURN
+      END SUBROUTINE GRPH213
+C
+      SUBROUTINE GRPHSUB(L,IND,CXMN,FELD,WSAVE,IFAX,Z,W,MLAT,
+     *MNAUF,MAXL,MAXB,MLEVEL)
+
+C     DIE ROUTINE F]HRT EINE TRANSFORMATION EINER
+C     FELDVARIABLEN VOM PHASENRAUM IN  DEN PHYSIKALISCHEN
+C     RAUM AUF KUGELKOORDINATEN DURCH
+C
+C     CXMN   = SPEKTRALKOEFFIZIENTEN IN DER REIHENFOLGE
+C              CX00,CX01,CX11,CX02,....CXMNAUFMNAUF
+C			CXM		 = FOURIERKOEFFIZIENTEN - nur ein Hilfsfeld
+C     FELD   = FELD DER METEOROLOGISCHEN VARIABLEN
+C			WSAVE  = Working Array fuer Fouriertransformation
+C     Z 	 = LEGENDREFUNKTIONSWERTE
+C
+C     MNAUF    ANZAHL DER FOURIERKOEFFIZIENTEN
+C     MAXL     ANZAHL DER FUER DAS GITTER BENUTZTEN LAENGEN
+C     MAXB     ANZAHL DER FUER DAS GITTER BENOETIGTEN BREITEN
+C     MLEVEL   ANZAHL DER LEVELS, DIE TRANSFORMIERT WERDEN
+C
+      IMPLICIT REAL (A-H,O-Z)
+
+C    FELD DER FOURIERKOEFFIZIENTEN
+      REAL CXMS(4*(MNAUF+1))
+      REAL CXMA(4*(MNAUF+1))
+      REAL,ALLOCATABLE :: CXM(:,:)
+
+C			Anzahl der Gitterpunkte pro Breitenkreis des reduzierten 
+C			Gauss'schen Gitters
+			INTEGER MLAT(MAXB),ISIZE
+			
+C    FELD DER LEGENDREPOLYNOME FUER EINE BREITE
+      REAL Z(MAXB/2,0:((MNAUF+3)*(MNAUF+4))/2)
+      
+C      LOGICAL*1 USED(((216*217)/2+1)*160)
+
+      REAL CXMN(0:(MNAUF+1)*(MNAUF+2)-1,MLEVEL)
+      REAL FELD(MAXL,MLEVEL)
+      REAL WSAVE(8*MAXB+15,MAXB/2)
+      INTEGER IFAX(10,MAXB)
+      REAL W(MAXB)
+      INTEGER IND(MAXB)
+			
+      ALLOCATE(CXM( 4*MAXB,MAXB))
+	  DO 5 J=1,MAXB/2
+            CXMS(1:MLAT(J))=FELD(IND(J)+1:IND(J)+MLAT(J),L)
+	    CALL RFOUFTR(CXMS,WSAVE(1,J),IFAX(:,J),MNAUF,MLAT(J),1)
+            CXMA(1:MLAT(J))=FELD(MAXL-IND(J)-MLAT(J)+1:MAXL-IND(J),L)
+	    CALL RFOUFTR(CXMA,
+     *WSAVE(1,J),IFAX(:,J),MNAUF,MLAT(J),1)
+	   	DO 4 I=1,2*(MNAUF+1)
+	    	CXM(I,J)=CXMS(I)+CXMA(I)
+	    	CXM(I,MAXB+1-J)=CXMS(I)-CXMA(I)
+4			CONTINUE
+    5 	CONTINUE
+        CALL LGTR213(CXMN(0,L),CXM,Z,W,MLAT,MNAUF,MAXB)
+
+      DEALLOCATE(CXM)
+
+      RETURN
+      END SUBROUTINE GRPHSUB
+C
+        SUBROUTINE LGTR213(CXMN,CXM,Z,W,MLAT,MNAUF,MAXB)
+        IMPLICIT REAL (A-H,O-Z)
+        INTEGER MLAT(MAXB)
+        DIMENSION CXM(0:4*MAXB-1,MAXB)
+        DIMENSION CXMN(0:2*(((MNAUF+1)*MNAUF)/2+MNAUF)+1)
+        REAL*8 Z(MAXB/2,0:((MNAUF+3)*(MNAUF+4))/2)
+        REAL*8 W(MAXB),CR,CI,HILF
+        LOGICAL EVEN
+C
+C     DIESE ROUTINE BERECHNET DIE KFFKs CXMN
+C
+			LL=0
+			LLP=0
+      DO 1 I=0,MNAUF
+        KM=0
+    9   KM=KM+1
+        IF(MLAT(KM).LE.2*I) THEN
+           GOTO 9
+        ENDIF
+        DO 2 J=I,MNAUF
+          CR=0
+          CI=0
+          EVEN=MOD(I+J,2).EQ.0
+          IF(EVEN) THEN
+            DO 3 K=KM,MAXB/2
+        			  HILF=W(K)*Z(K,LLP)
+        	      CR=CR+CXM(2*I,K)*HILF
+        	      CI=CI+CXM(2*I+1,K)*HILF
+    3     	CONTINUE
+          ELSE
+            DO 4 K=KM,MAXB/2
+        			  HILF=W(K)*Z(K,LLP)
+        	      CR=CR+CXM(2*I,MAXB+1-K)*HILF
+        	      CI=CI+CXM(2*I+1,MAXB+1-K)*HILF
+    4     	CONTINUE
+          ENDIF
+    5     CXMN(2*LL)=CR
+          CXMN(2*LL+1)=CI
+          LL=LL+1
+          LLP=LLP+1
+    2   CONTINUE
+        LLP=LLP+2
+    1 CONTINUE
+        RETURN
+        END SUBROUTINE LGTR213
+C
+
+C
+      SUBROUTINE RFOUFTR(CXM,TRIGS,IFAX,MNAUF,MAXL,ISIGN)
+C     BERECHNET DIE FOURIERSUMME MIT EINEM FFT-ALGORITHMUS
+      IMPLICIT REAL (A-H,O-Z)
+      DIMENSION CXM(0:2*MAXL-1)
+      DIMENSION FELD(MAXL),TRIGS(2*MAXL)
+      DIMENSION WSAVE(MAXAUF)
+      INTEGER IFAX(10)
+
+
+C NORMIERUNG...
+      WSAVE(1)=CXM(MAXL-1)
+
+      CXM(1:MAXL)=CXM(0:MAXL-1)/2
+      CXM(0)=WSAVE(1)/2
+!      CALL CFFTF(MAXL,CXM,WSAVE)
+      CALL FFT99(CXM,WSAVE,TRIGS,IFAX,1,1,MAXL,1,-1)
+      RETURN
+      END SUBROUTINE RFOUFTR
+
+      END MODULE GRTOPH
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/jparams.h b/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/jparams.h
new file mode 100644
index 0000000000000000000000000000000000000000..146a7f05c10fdeaadb611686c4c95f7fdc2f7a28
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/jparams.h
@@ -0,0 +1,34 @@
+C
+C     Parameters
+C
+      INTEGER JP32, JPLONO, J2NFFT, JPFFT, JPLOOK, JPMAX, JPMAXITER
+      INTEGER JPMXTRY, JPTRNC, JPK, JPTRP1
+      PARAMETER ( JP32 = 32 )
+C
+C     The following value for JPLONO (2560) will handle regular grids 
+C     from N1 to N720 derived from spectral truncations from T1 to
+C     T639.
+C
+Cjdc  PARAMETER ( JPLONO = 2560 , J2NFFT = 2 + JPLONO, JPFFT = 12000)
+      PARAMETER ( JPLONO = 6000 , J2NFFT = 2 + JPLONO, JPFFT = 12000)
+      PARAMETER ( JPLOOK = 50)
+      PARAMETER ( JPMAX = 2048 )
+      PARAMETER ( JPMAXITER = 10)
+      PARAMETER ( JPMXTRY = 3 )
+      PARAMETER ( JPTRNC = 2047, JPK = (JPTRNC + 1)*(JPTRNC + 4) )
+      PARAMETER ( JPTRP1 = (JPTRNC + 1) )
+C
+      REAL PPEPSA, PPQUART, PPHALF, PPTWO, PP90
+      PARAMETER ( PPEPSA = 1.0E-6)
+      PARAMETER ( PPQUART = 0.25E0)
+      PARAMETER ( PPHALF = 0.5E0)
+      PARAMETER ( PPTWO = 2.0E0)
+      PARAMETER ( PP90 = 90.0E0)
+C
+      REAL PPI
+      PARAMETER ( PPI = 3.14159265358979 )
+C
+C     Debug parameters
+C
+      INTEGER NDBG, NDBGLP
+      COMMON /JDCNDBG/ NDBG, NDBGLP
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/phgrreal.f b/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/phgrreal.f
new file mode 100644
index 0000000000000000000000000000000000000000..aa3658c917fd35d15dd4c2b9959f4fcf074923a1
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/phgrreal.f
@@ -0,0 +1,553 @@
+      MODULE PHTOGR
+
+      INTEGER, PARAMETER :: MAXAUF=36000
+
+      CONTAINS
+
+      SUBROUTINE PHGR213(CXMN,FELD,WSAVE,IFAX,Z,MLAT,MNAUF,
+     *MAXL,MAXB,MLEVEL)
+
+C     DIE ROUTINE F]HRT EINE TRANSFORMATION EINER
+C     FELDVARIABLEN VOM PHASENRAUM IN  DEN PHYSIKALISCHEN
+C     RAUM AUF DAS REDUZIERTE GAUSS'SCHE GITTER DURCH
+C
+C     CXMN   = SPEKTRALKOEFFIZIENTEN IN DER REIHENFOLGE
+C              CX00,CX01,CX11,CX02,....CXMNAUFMNAUF
+C     FELD   = FELD DER METEOROLOGISCHEN VARIABLEN
+C	WSAVE  = Working Array fuer Fouriertransformation
+C     Z 	 = LEGENDREFUNKTIONSWERTE
+C
+C     MNAUF    ANZAHL DER FOURIERKOEFFIZIENTEN
+C     MAXL     ANZAHL DER FUER DAS GITTER BENUTZTEN LAENGEN
+C     MAXB     ANZAHL DER FUER DAS GITTER BENOETIGTEN BREITEN
+C     MLEVEL   ANZAHL DER LEVELS, DIE TRANSFORMIERT WERDEN
+C
+      IMPLICIT NONE
+
+C			Anzahl der Gitterpunkte auf jedem Breitenkreis
+      INTEGER MLAT(MAXB/2)
+      INTEGER K,MAXL,MAXB,MLEVEL,MNAUF
+      INTEGER IND(MAXB)
+      
+			
+C    FELD DER LEGENDREPOLYNOME FUER EINE BREITE
+      REAL Z(0:((MNAUF+3)*(MNAUF+4))/2,MAXB/2)
+
+      REAL CXMN(0:(MNAUF+1)*(MNAUF+2)-1,MLEVEL)
+      REAL FELD(MAXL,MLEVEL)
+      REAL WSAVE(8*MAXB+15,MAXB/2)
+      INTEGER :: IFAX(10,MAXB)
+      
+      IND(1)=0
+     	DO 7 K=2,MAXB/2
+       	IND(K)=IND(K-1)+MLAT(K-1)
+7 		CONTINUE
+
+!$OMP PARALLEL DO SCHEDULE(DYNAMIC)
+     	DO 17 K=1,MAXB/2
+        CALL PHSYM(K,IND,CXMN,FELD,Z,WSAVE,IFAX,MLAT,
+     *MNAUF,MAXL,MAXB,MLEVEL)
+
+17 		CONTINUE
+!$OMP END PARALLEL DO
+
+        RETURN
+        END SUBROUTINE PHGR213
+C
+C
+      SUBROUTINE PHSYM(K,IND,CXMN,FELD,Z,WSAVE,IFAX,MLAT,
+     *MNAUF,MAXL,MAXB,MLEVEL)
+
+      IMPLICIT NONE
+
+      INTEGER MLAT(MAXB/2)
+      INTEGER K,L,I,J,LLS,LLPS,LL,LLP,MAXL,MAXB,MLEVEL,MNAUF
+      INTEGER IND(MAXB)
+      INTEGER :: IFAX(10,MAXB)
+      
+			
+C    FELD DER FOURIERKOEFFIZIENTEN
+      REAL :: CXMS(0:MAXAUF-1),CXMA(0:MAXAUF-1)
+
+C    FELD DER LEGENDREPOLYNOME FUER EINE BREITE
+      REAL Z(0:((MNAUF+3)*(MNAUF+4))/2,MAXB/2)
+      REAL ACR,ACI,SCR,SCI
+
+      REAL CXMN(0:(MNAUF+1)*(MNAUF+2)-1,MLEVEL)
+      REAL FELD(MAXL,MLEVEL)
+      REAL WSAVE(8*MAXB+15,MAXB/2)
+
+      	DO 6 L=1,MLEVEL
+      	 LL=0
+      	 LLP=0
+         DO 1 I=0,MNAUF
+          SCR=0.D0
+          SCI=0.D0
+          ACR=0.D0
+          ACI=0.D0
+          LLS=LL
+          LLPS=LLP
+          IF(2*I+1.LT.MLAT(K)) THEN
+C	Innerste Schleife aufgespalten um if-Abfrage zu sparen
+            DO 18 J=I,MNAUF,2
+              SCR=SCR+Z(LLP,K)*CXMN(2*LL,L)
+              SCI=SCI+Z(LLP,K)*CXMN(2*LL+1,L)
+              LL=LL+2            
+              LLP=LLP+2            
+18          CONTINUE
+            LL=LLS+1
+            LLP=LLPS+1
+            DO 19 J=I+1,MNAUF,2
+              ACR=ACR+Z(LLP,K)*CXMN(2*LL,L)
+              ACI=ACI+Z(LLP,K)*CXMN(2*LL+1,L)
+              LL=LL+2            
+              LLP=LLP+2            
+19          CONTINUE
+          ENDIF
+          LL=LLS+(MNAUF-I+1)
+          LLP=LLPS+(MNAUF-I+3)
+          CXMS(2*I)=SCR+ACR
+          CXMS(2*I+1)=SCI+ACI
+          CXMA(2*I)=SCR-ACR
+          CXMA(2*I+1)=SCI-ACI
+    1    CONTINUE
+C         CALL FOURTR(CXMS,FELD(IND(k)+1,L),WSAVE(:,K),MNAUF,
+C     *MLAT(K),1)
+C         CALL FOURTR(CXMA,FELD(MAXL-IND(k)-MLAT(K)+1,L),
+C     *WSAVE(:,K),MNAUF,MLAT(K),1)
+         CALL RFOURTR(CXMS,WSAVE(:,K),IFAX(:,K),MNAUF,
+     *MLAT(K),1)
+          FELD(IND(k)+1:IND(K)+MLAT(K),L)=CXMS(0:MLAT(K)-1)
+         CALL RFOURTR(CXMA,
+     *WSAVE(:,K),IFAX(:,K),MNAUF,MLAT(K),1)
+         FELD(MAXL-IND(k)-MLAT(K)+1:MAXL-IND(k),L)=CXMA(0:MLAT(K)-1)
+C         WRITE(*,*) IND+1,FELD(IND+1,L)
+6 			CONTINUE
+
+      END SUBROUTINE PHSYM
+
+      SUBROUTINE PHGCUT(CXMN,FELD,WSAVE,IFAX,Z,
+     *                  MNAUF,MMAX,MAUF,MANF,MAXL,MAXB,MLEVEL)
+
+C     DIE ROUTINE FUEHRT EINE TRANSFORMATION EINER
+C     FELDVARIABLEN VOM PHASENRAUM IN  DEN PHYSIKALISCHEN
+C     RAUM AUF KUGELKOORDINATEN DURCH. Es kann ein Teilausschnitt
+C			Der Erde angegeben werden. Diese Routine ist langsamer als
+C			phgrph
+C
+C     CXMN   = SPEKTRALKOEFFIZIENTEN IN DER REIHENFOLGE
+C              CX00,CX01,CX11,CX02,....CXMNAUFMNAUF
+C     FELD   = FELD DER METEOROLOGISCHEN VARIABLEN
+C     BREITE = SINUS DER GEOGRAFISCHEN BREITEN
+C
+C     MNAUF    ANZAHL DER FOURIERKOEFFIZIENTEN
+C     MAUF     ANZAHL DER LAENGEN UND DER FOURIERKOEFFIZIENTEN
+C     MANF     ANFANG DES LAENGENBEREICHS FUER DAS GITTER,
+C              AUF DAS INTERPOLIERT WERDEN SOLL
+C     MAXL     ANZAHL DER FUER DAS GITTER BENUTZTEN LAENGEN
+C     MAXB     ANZAHL DER FUER DAS GITTER BENOETIGTEN BREITEN
+C     MLEVEL   ANZAHL DER LEVELS, DIE TRANSFORMIERT WERDEN
+C
+        IMPLICIT REAL (A-H,O-Z)
+
+C    FELD DER FOURIERKOEFFIZIENTEN
+
+C    FELD DER LEGENDREPOLYNOME FUER EINE BREITE
+        REAL Z(0:((MMAX+3)*(MMAX+4))/2,MAXB)
+
+        DIMENSION CXMN(0:(MMAX+1)*(MMAX+2)-1,MLEVEL)
+        REAL FELD(MAXL,MAXB,MLEVEL)
+      DIMENSION WSAVE(4*MAUF+15)
+      INTEGER:: IFAX(10)
+      
+      LOGICAL SYM
+
+C
+C      write(*,*)mauf,mnauf,manf,maxl
+
+     
+        IF(MAUF.LE.MNAUF) WRITE(*,*) 'TOO COARSE LONGITUDE RESOLUTION'
+          IF((MANF.LT.1).OR.(MAXL.LT.1).OR.
+     *       (MANF.GT.MAUF).OR.(MAXL.GT.MAUF)) THEN
+            WRITE(*,*) 'WRONG LONGITUDE RANGE',MANF,MAXL
+            STOP
+          ENDIF
+
+C Pruefe, ob Ausgabegitter symmetrisch zum Aequator ist
+C Wenn ja soll Symmetrie der Legendrepolynome ausgenutzt werden
+      IF(MAXB .GT. 4) THEN
+          SYM=.TRUE.
+	    DO 11 J=5,5
+	      IF(ABS(ABS(Z(100,J))-ABS(Z(100,MAXB+1-J))).GT.1E-11)
+     *    SYM=.FALSE.
+C	      WRITE(*,*) ABS(Z(100,J)),ABS(Z(100,MAXB+1-J))
+11	  CONTINUE
+      WRITE(*,*) 'Symmetrisch: ',SYM
+      ELSE
+        SYM=.FALSE.
+      ENDIF
+
+	
+		IF(SYM) THEN
+!$OMP PARALLEL DO 
+      	DO J=1,(MAXB+1)/2
+          CALL PHSYMCUT(J,CXMN,FELD,Z,WSAVE,IFAX,
+     *MAUF,MNAUF,MAXL,MAXB,MLEVEL,MANF)
+
+        ENDDO
+!$OMP END PARALLEL DO
+		ELSE
+!$OMP PARALLEL DO 
+        DO J=1,MAXB
+            CALL PHGPNS(CXMN,FELD,Z,WSAVE,IFAX,
+     *J,MNAUF,MAUF,MANF,MAXL,MAXB,MLEVEL)
+        ENDDO
+!$OMP END PARALLEL DO
+
+      ENDIF
+
+
+        RETURN
+        END SUBROUTINE PHGCUT
+
+        SUBROUTINE PHSYMCUT(J,CXMN,FELD,Z,WSAVE,IFAX,
+     *MAUF,MNAUF,MAXL,MAXB,MLEVEL,MANF)
+
+        IMPLICIT REAL (A-H,O-Z)
+
+C    FELD DER FOURIERKOEFFIZIENTEN
+
+        REAL :: CXM(0:MAXAUF-1),CXMA(0:MAXAUF-1)
+
+
+C    FELD DER LEGENDREPOLYNOME FUER EINE BREITE
+        REAL Z(0:((MNAUF+3)*(MNAUF+4))/2,MAXB)
+        REAL SCR,SCI,ACR,ACI
+
+        DIMENSION CXMN(0:(MNAUF+1)*(MNAUF+2)-1,MLEVEL)
+        REAL FELD(MAXL,MAXB,MLEVEL)
+      DIMENSION WSAVE(4*MAUF+15)
+        INTEGER :: IFAX(10)
+
+        DO 16 L=1,MLEVEL
+      	 LL=0
+      	 LLP=0
+         DO 17 I=0,MNAUF
+          SCR=0.D0
+          SCI=0.D0
+          ACR=0.D0
+          ACI=0.D0
+          LLS=LL
+          LLPS=LLP
+C	Innerste Schleife aufgespalten um if-Abfrage zu sparen
+          DO 18 K=I,MNAUF,2
+            SCR=SCR+Z(LLP,J)*CXMN(2*LL,L)
+            SCI=SCI+Z(LLP,J)*CXMN(2*LL+1,L)
+            LL=LL+2            
+            LLP=LLP+2            
+18        CONTINUE
+          LL=LLS+1
+          LLP=LLPS+1
+          DO 19 K=I+1,MNAUF,2
+            ACR=ACR+Z(LLP,J)*CXMN(2*LL,L)
+            ACI=ACI +Z(LLP,J)*CXMN(2*LL+1,L)
+            LL=LL+2            
+            LLP=LLP+2            
+19        CONTINUE
+          LL=LLS+MNAUF-I+1
+          LLP=LLPS+MNAUF-I+3
+          CXM(2*I)=SCR+ACR
+          CXM(2*I+1)=SCI+ACI
+          CXMA(2*I)=SCR-ACR
+          CXMA(2*I+1)=SCI-ACI
+17       CONTINUE
+         
+         CALL RFOURTR(CXM,WSAVE,IFAX,MNAUF,MAUF,1)
+         DO 26 I=0,MAXL-1
+           IF(MANF+I.LE.MAUF) THEN
+             FELD(I+1,J,L)=CXM(MANF+I-1)
+           ELSE
+             FELD(I+1,J,L)=CXM(MANF-MAUF+I-1)
+           ENDIF
+26       CONTINUE
+         CALL RFOURTR(CXMA,WSAVE,IFAX,MNAUF,MAUF,1)
+         DO 36 I=0,MAXL-1
+           IF(MANF+I.LE.MAUF) THEN
+             FELD(I+1,MAXB+1-J,L)=CXMA(MANF+I-1)
+           ELSE
+             FELD(I+1,MAXB+1-J,L)=CXMA(MANF-MAUF+I-1)
+           ENDIF
+36       CONTINUE
+16 			CONTINUE
+
+      END SUBROUTINE PHSYMCUT
+
+      SUBROUTINE PHGPNS(CXMN,FELD,Z,WSAVE,IFAX,
+     *J,MNAUF,MAUF,MANF,MAXL,MAXB,MLEVEL)
+
+        IMPLICIT NONE
+        INTEGER,intent(in) :: MNAUF,MAUF,MANF,J,MAXL,MAXB,MLEVEL
+        REAL :: CXM(0:MAXAUF-1)
+        REAL,intent(in) :: Z(0:((MNAUF+3)*(MNAUF+4))/2,MAXB)
+
+        REAL,intent(in) :: CXMN(0:(MNAUF+1)*(MNAUF+2)-1,MLEVEL)
+
+        REAL,intent(in) :: WSAVE(4*MAUF+15)
+
+        REAL :: FELD(MAXL,MAXB,MLEVEL)
+        INTEGER :: IFAX(10)
+
+        INTEGER I,L
+
+          DO L=1,MLEVEL
+            CALL LEGTR(CXMN(:,L),CXM,Z(:,J),MNAUF,MAUF)
+            CALL RFOURTR(CXM,WSAVE,IFAX,MNAUF,MAUF,1)
+           
+            DO I=0,MAXL-1
+                  IF(MANF+I.LE.MAUF) THEN
+                    FELD(I+1,J,L)=CXM(MANF+I-1)
+                  ELSE
+                    FELD(I+1,J,L)=CXM(MANF-MAUF+I-1)
+                  ENDIF
+            ENDDO
+          ENDDO
+      END SUBROUTINE PHGPNS
+C
+        SUBROUTINE LEGTR(CXMN,CXM,Z,MNAUF,MAUF)
+        IMPLICIT NONE
+        INTEGER MNAUF,MAUF,LL,LLP,I,J
+        REAL CXM(0:MAXAUF-1)
+        REAL CXMN(0:(MNAUF+1)*(MNAUF+2)-1)
+        REAL Z(0:((MNAUF+3)*(MNAUF+4))/2)
+        REAL CI,CR
+C
+C     DIESE ROUTINE BERECHNET DIE FOURIERKOEFFIZIENTEN CXM
+C
+        LL=0
+        LLP=0
+        DO 1 I=0,MNAUF
+            CR=0.D0
+            CI=0.D0
+            DO 2 J=I,MNAUF
+              CR=CR+Z(LLP)*CXMN(2*LL)
+              CI=CI+Z(LLP)*CXMN(2*LL+1)
+              LL=LL+1
+              LLP=LLP+1
+    2     CONTINUE
+          LLP=LLP+2
+          CXM(2*I)=CR
+          CXM(2*I+1)=CI
+    1 CONTINUE
+        RETURN
+        END SUBROUTINE LEGTR
+C
+C     
+C
+      SUBROUTINE RFOURTR(CXM,TRIGS,IFAX,MNAUF,MAXL,ISIGN)
+C     BERECHNET DIE FOURIERSUMME MIT EINEM FFT-ALGORITHMUS
+      IMPLICIT REAL (A-H,O-Z)
+      DIMENSION CXM(0:MAXAUF-1)
+      REAL :: WSAVE(2*MAXL),TRIGS(2*MAXL)
+      INTEGER IFAX(10)
+
+      DO I=MNAUF+1,MAXL-1
+          CXM(2*I)=0.0
+          CXM(2*I+1)=0.0
+      ENDDO
+      CALL FFT99(CXM,WSAVE,TRIGS,IFAX,1,1,MAXL,1,1)
+      DO I=0,MAXL-1
+        CXM(I)=CXM(I+1)
+      ENDDO
+
+      RETURN
+      END SUBROUTINE RFOURTR
+C     
+C     
+      SUBROUTINE GAULEG(X1,X2,X,W,N)
+C     BERECHNET DIE GAUSS+SCHEN BREITEN
+        IMPLICIT REAL (A-H,O-Z)
+        DIMENSION X(N),W(N)
+      PARAMETER (EPS=3.D-14)
+      M=(N+1)/2
+      XM=0.5D0*(X2+X1)
+      XL=0.5D0*(X2-X1)
+      DO 12 I=1,M
+        Z=DCOS(3.141592654D0*(I-.25D0)/(N+.5D0))
+1       CONTINUE
+          P1=1.D0
+          P2=0.D0
+          DO 11 J=1,N
+            P3=P2
+            P2=P1
+            P1=((2.D0*J-1.D0)*Z*P2-(J-1.D0)*P3)/J
+11        CONTINUE
+          PP=N*(Z*P1-P2)/(Z*Z-1.D0)
+          Z1=Z
+          Z=Z1-P1/PP
+        IF(ABS(Z-Z1).GT.EPS)GO TO 1
+        X(I)=XM-XL*Z
+        X(N+1-I)=XM+XL*Z
+        W(I)=2.D0*XL/((1.D0-Z*Z)*PP*PP)
+        W(N+1-I)=W(I)
+12    CONTINUE
+      RETURN
+      END SUBROUTINE GAULEG
+C
+C
+        SUBROUTINE PLGNFA(LL,X,Z)
+C
+C PLGNDN BERECHNET ALLE NORMIERTEN ASSOZIIERTEN
+C LEGENDREFUNKTIONEN VON P00(X) BIS PLL(X)
+C UND SCHREIBT SIE IN DAS FELD Z
+C Die Polynome sind wie im ECMWF indiziert, d.h.
+C P00,P10,P11,P20,P21,P22,...
+C	Ansonsten ist die Routine analog zu PLGNDN
+C X IST DER COSINUS DES ZENITWINKELS ODER
+C       DER SINUS DER GEOGRAFISCHEN BREITE
+C
+        IMPLICIT REAL (A-H,O-Z)
+        DIMENSION Z(0:((LL+3)*(LL+4))/2)
+C
+      L=LL+2
+      I=1
+      Z(0)=1.D0
+      FACT=1.D0
+      POT=1.D0
+      SOMX2=DSQRT(1.D0-X*X)
+        DO 14 J=0,L
+          DJ=DBLE(J)
+        IF(J.GT.0) THEN
+          FACT=FACT*(2.D0*DJ-1.D0)/(2.D0*DJ)
+            POT=POT*SOMX2
+          Z(I)=DSQRT((2.D0*DJ+1.D0)*FACT)*POT
+          I=I+1
+        ENDIF
+          IF(J.LT.L) THEN
+            Z(I)=X*
+     *DSQRT((4.D0*DJ*DJ+8.D0*DJ+3.D0)/(2.D0*DJ+1.D0))*Z(I-1)
+            I=I+1
+          ENDIF
+          DK=DJ+2.D0
+        DO 14 K=J+2,L
+          DDK=(DK*DK-DJ*DJ)
+          Z(I)=X*DSQRT((4.D0*DK*DK-1.D0)/DDK)*Z(I-1)-
+     *    DSQRT(((2.D0*DK+1.D0)*(DK-DJ-1.D0)*(DK+DJ-1.D0))/
+     *    ((2.D0*DK-3.D0)*DDK))*Z(I-2)
+          DK=DK+1.D0
+          I=I+1
+14    CONTINUE
+      RETURN
+      END SUBROUTINE PLGNFA
+
+
+      SUBROUTINE DPLGND(MNAUF,Z,DZ)
+C
+C DPLGND BERECHNET DIE ABLEITUNG DER NORMIERTEN ASSOZIIERTEN
+C LEGENDREFUNKTIONEN VON P00(X) BIS PLL(X)
+C UND SCHREIBT SIE IN DAS FELD DZ
+C DIE REIHENFOLGE IST
+C P00(X),P01(X),P11(X),P02(X),P12(X),P22(X),..PLL(X)
+C
+        IMPLICIT REAL (A-H,O-Z)
+        DIMENSION Z(0:((MNAUF+3)*(MNAUF+4))/2)
+        DIMENSION DZ(0:((MNAUF+2)*(MNAUF+3))/2)
+C
+				IF(Z(0).NE.1.D0) THEN
+			WRITE(*,*) 'DPLGND: Z(0) must be 1.0'
+					STOP
+				ENDIF
+				
+				LLP=0
+				LLH=0
+        DO 1 I=0,MNAUF+1
+            DO 2 J=I,MNAUF+1
+              IF(I.EQ.J) THEN
+              	WURZELA=
+     *DSQRT(DBLE((J+1)*(J+1)-I*I)/DBLE(4*(J+1)*(J+1)-1))
+                DZ(LLH)=DBLE(J)*WURZELA*Z(LLP+1)
+              ELSE
+              		WURZELB=
+     *DSQRT(DBLE((J+1)*(J+1)-I*I)/DBLE(4*(J+1)*(J+1)-1))
+                DZ(LLH)=
+     *DBLE(J)*WURZELB*Z(LLP+1)-DBLE(J+1)*WURZELA*Z(LLP-1)
+     						WURZELA=WURZELB
+	        ENDIF
+	        LLH=LLH+1              
+          LLP=LLP+1
+2	      CONTINUE
+        LLP=LLP+1
+1	CONTINUE
+	RETURN
+	END SUBROUTINE DPLGND
+	
+
+* Spectral Filter of Sardeshmukh and Hoskins (1984, MWR)
+* MM=Spectral truncation of field
+* MMAX= Spectral truncation of filter
+*
+      SUBROUTINE SPFILTER(FELDMN,MM,MMAX)
+
+      IMPLICIT NONE
+
+      INTEGER MM,MMAX,I,J,K,L
+      REAL FELDMN(0:(MM+1)*(MM+2)-1)
+      REAL KMAX,SMAX,FAK
+
+      SMAX=0.1
+      KMAX=-ALOG(SMAX)
+      KMAX=KMAX/(float(MMAX)*float(MMAX+1))**2
+c      WRITE(*,*)'alogsmax',alog(smax),'KMAX:',KMAX
+        l=0
+        do i=0,MM
+          do j=i,MM
+c          write(*,*) i,j,feld(k),feld(k)*exp(-KMAX*(j*(j+1))**2)
+            if(j .le. MMAX) then
+c               fak=exp(-KMAX*(j*(j+1))**2)
+               fak=1.0
+               feldmn(2*l)=feldmn(2*l)*fak
+               feldmn(2*l+1)=feldmn(2*l+1)*fak
+            else
+               feldmn(2*l)=0.
+               feldmn(2*l+1)=0.
+            endif
+            l=l+1
+          enddo
+        enddo
+      END SUBROUTINE SPFILTER
+
+      END MODULE PHTOGR
+    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/posnam.f b/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/posnam.f
new file mode 100644
index 0000000000000000000000000000000000000000..c5d12d2b9928e581f67ef0c6388dd3e641693aed
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/posnam.f
@@ -0,0 +1,25 @@
+      SUBROUTINE POSNAM(KULNAM,CDNAML)
+!-------------------------------------
+
+!--- position in namelist file. 
+!    author:  Mats Hamrud, ECMWF
+
+      INTEGER, INTENT(IN)       :: KULNAM
+      CHARACTER*(*), INTENT(IN) :: CDNAML
+      CHARACTER*120 CLINE
+      CHARACTER*1 CLTEST
+      REWIND(KULNAM)
+      ILEN=LEN(CDNAML)
+ 102  CONTINUE
+      CLINE=' '
+      READ(KULNAM,'(A)') CLINE
+      IND1=INDEX(CLINE,'&'//CDNAML)
+      IF(IND1.EQ.0) GO TO 102
+      CLTEST=CLINE(IND1+ILEN+1:IND1+ILEN+1)
+      IF((LGE(CLTEST,'0').AND.LLE(CLTEST,'9')).OR.
+     &   (LGE(CLTEST,'A').AND.LLE(CLTEST,'Z'))) GO TO 102
+      BACKSPACE(KULNAM)
+
+      RETURN
+      END SUBROUTINE POSNAM
+
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/preconvert.f90 b/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/preconvert.f90
new file mode 100644
index 0000000000000000000000000000000000000000..c28610f2aecb31a3f4c3860d7a482ae0fa85d23f
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/preconvert.f90
@@ -0,0 +1,807 @@
+      PROGRAM PRECONVERT
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!                                                                 !
+! PROGRAM PRECONVERT - PREPARES INPUT DATA FOR POP MODEL METEOR-  !
+!                      OLOGICAL PREPROCESSOR                      !
+!                                                                 !
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!                                                                 !
+! CALCULATION OF ETAPOINT ON A REGULAR LAMDA/PHI GRID AND WRITING !
+! U,V,ETAPOINT,T,PS,Q,SD,MSL,TCC,10U, 10V, 2T,2D,LSP,CP,SSHF,SSR, !
+! EWSS,NSSS TO AN OUTPUT FILE (GRIB 1 or 2 FORMAT).               ! 
+!                                                                 !
+! AUTHORS: L. HAIMBERGER, G. WOTAWA, 1994-04                      !
+!                     adapted: A. BECK                            !
+!                     2003-05-11                                  !
+!          L. Haimberger 2006-12    V2.0                          !
+!                    modified to handle arbitrary regular grids   !
+!                    and T799 resolution data                     !
+!          L. Haimberger 2010-03    V4.0                          !
+!                    modified to grib edition 2 fields            !
+!                    and T1279 resolution data                    !
+!                                                                 !
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!                                                                 !
+! DESCRIPTION OF NEEDED INPUT:                                    !
+!                                                                 !
+! UNIT  FILE      PARAMETER(S)    DATA REPRESENTATION             !
+!                                                                 !
+! 11    fort.11   T,U,V           regular lamda phi grid          !
+! 12    fort.12   D               regular lamda phi grid          !
+! 13    fort.13   LNSP          fort.13  spherical harmonics             !
+! 14    fort.14   SD,MSL,TCC,10U,                                 !
+!                 10V,2T,2D       regular lamda phi grid          !
+! 16    fort.16   LSP,CP,SSHF,                                    !
+!                 SSR,EWSS,NSSS   regular lamda phi grid          !
+! 17    fort.17   Q               regular lamda phi grid          !
+!                                                                 !
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!                                                                 !
+! DESCRIPTION OF OUTPUT:                                          !
+!                                                                 !
+! UNIT  FILE      PARAMETER(S)    DATA REPRESENTATION             !
+!                                                                 !
+! 15    fort.15   U,V,ETA,T,PS,                                   !
+!                 Q,SD,MSL,TCC,                                   !
+!                 10U,10V,2T,2D,  regular lamda phi grid          !
+!                 LSP,CP,SSHF,                                    !
+!                 SSR,EWSS,NSSS                                   !
+!                                                                 !
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+
+      USE PHTOGR
+      USE GRTOPH
+      USE FTRAFO
+      USE RWGRIB2
+      USE GRIB_API
+
+      IMPLICIT NONE
+
+      REAL, ALLOCATABLE, DIMENSION (:,:) :: LNPS
+      REAL, ALLOCATABLE, DIMENSION (:,:) :: Z
+      REAL, ALLOCATABLE, DIMENSION (:,:,:) :: T, UV , UV2
+      REAL, ALLOCATABLE, DIMENSION (:,:,:) :: QA,OM,OMR
+      REAL, ALLOCATABLE, DIMENSION (:,:,:) :: DIV, ETA,ETAR
+      REAL, ALLOCATABLE, DIMENSION (:,:) :: DPSDL, DPSDM
+      REAL, ALLOCATABLE, DIMENSION (:,:,:) :: PS,DPSDT
+      REAL, ALLOCATABLE, DIMENSION (:,:,:) :: SURF,FLUX,OROLSM
+      REAL, ALLOCATABLE, DIMENSION (:) :: WSAVE,H,SINL,COSL,WSAVE2
+      REAL, ALLOCATABLE, DIMENSION (:) :: BREITE, GBREITE,AK, BK,pv
+
+! Arrays for Gaussian grid calculations
+
+      REAL  :: X1,X2,RMS,MW,SIG,LAM
+      REAL,ALLOCATABLE :: CUA(:,:,:),CVA(:,:,:)
+
+      REAL, ALLOCATABLE, DIMENSION (:,:) :: P,PP !,P2
+      REAL, ALLOCATABLE, DIMENSION (:,:) :: XMN,HILFUV
+      REAL, ALLOCATABLE, DIMENSION (:) :: LNPMN,LNPMN2,LNPMN3
+      REAL, ALLOCATABLE, DIMENSION (:) :: WEIGHT
+      REAL, ALLOCATABLE, DIMENSION (:,:) :: UGVG
+      REAL, ALLOCATABLE, DIMENSION (:,:) :: DG, ETAG
+      REAL, ALLOCATABLE, DIMENSION (:,:) :: GWSAVE
+      REAL, ALLOCATABLE, DIMENSION (:) :: PSG,HILF
+
+! end arrays for Gaussian grid calculations
+
+      INTEGER, ALLOCATABLE, DIMENSION (:) :: MLAT,MPSURF,MPFLUX,MPORO,MPAR
+      INTEGER, ALLOCATABLE :: GIFAX(:,:)
+
+      REAL PI,COSB,DAK,DBK,P00
+      REAL URLAR8,JMIN1,LLLAR8,MAXBMIN1,PIR8,DCOSB
+
+      INTEGER I,J,K,L,IERR,M,LTEST,MK,NGI,NGJ
+      INTEGER MFLUX,MSURF,MORO
+      INTEGER LUNIT,LUNIT2
+
+      INTEGER MAXL, MAXB, MLEVEL, LEVOUT,LEVMIN,LEVMAX
+      INTEGER MOMEGA,MOMEGADIFF,MGAUSS,MSMOOTH, MNAUF,META,METADIFF
+      INTEGER MDPDETA,METAPAR
+      REAL RLO0, RLO1, RLA0, RLA1
+      CHARACTER*300 MLEVELIST
+
+      INTEGER MAUF, MANF,IFAX(10)
+
+      INTEGER IGRIB(1),iret,ogrib
+
+      CHARACTER*80 FILENAME
+
+      NAMELIST /NAMGEN/ &
+                 MAXL, MAXB, &
+                 MLEVEL,MLEVELIST,MNAUF,METAPAR, &
+                 RLO0, RLO1, RLA0, RLA1, &
+                 MOMEGA,MOMEGADIFF,MGAUSS,MSMOOTH,META,METADIFF,&
+                 MDPDETA
+
+      LTEST=1
+
+      call posnam (4,'NAMGEN')
+      read (4,NAMGEN)
+
+      MAUF=INT(360.*(REAL(MAXL)-1.)/(RLO1-RLO0)+0.0001)
+!      PRINT*, MAUF
+
+      MANF=INT(REAL(MAUF)/360.*(360.+RLO0)+1.0001)
+      IF(MANF .gt. MAUF) MANF=MANF-MAUF
+
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!                       ALLOCATE VARIABLES                        !
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+      ALLOCATE (LNPS(0:(MNAUF+1)*(MNAUF+2)-1,1))
+
+      ALLOCATE (H(0:(MNAUF+2)*(MNAUF+3)/2))
+
+     
+      ALLOCATE (OM(MAXL, MAXB, MLEVEL))
+
+      ALLOCATE (ETA(MAXL,MAXB,MLEVEL))
+
+      ALLOCATE (PS(MAXL, MAXB,1),DPSDT(MAXL, MAXB,1))
+
+      
+      ALLOCATE (WSAVE(4*MAUF+15),WSAVE2(4*MAUF+15))
+
+      ALLOCATE (BREITE(MAXB),AK(MLEVEL+1),BK(MLEVEL+1),pv(2*mlevel+2))
+      
+      ALLOCATE (MPAR(2))
+
+      ALLOCATE (COSL(MAXL),SINL(MAXL))
+		
+      ALLOCATE (CUA(2,4,MLEVEL),CVA(2,4,MLEVEL))
+    	
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!     GAUSS STUFF !
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+
+      IF(MGAUSS .EQ. 1) THEN
+      LUNIT=0
+      FILENAME='fort.18'
+
+      call grib_open_file(LUNIT, TRIM(FILENAME),'r')
+ 
+      call grib_new_from_file(LUNIT,igrib(1), iret)
+ 
+! we can close the file
+      call grib_close_file(LUNIT)
+ 
+!      call grib_get(igrib(1),'gridType', j)
+
+      NGJ=MNAUF+1
+
+      ALLOCATE (GWSAVE(8*NGJ+15,NGJ/2))
+      ALLOCATE(GIFAX(10,NGJ))
+      ALLOCATE (GBREITE(NGJ),WEIGHT(NGJ))
+      ALLOCATE (MLAT(NGJ))
+      ALLOCATE (P(0:((MNAUF+3)*(MNAUF+4))/2,NGJ/2))
+      ALLOCATE (PP(NGJ/2,0:((MNAUF+3)*(MNAUF+4))/2))
+      ALLOCATE (Z(0:((MNAUF+3)*(MNAUF+4))/2,MAXB))
+
+      call grib_get(igrib(1),'numberOfPointsAlongAMeridian', NGJ)
+ 
+      !     get as a integer
+      call grib_get(igrib(1),'pl', MLAT)
+
+      NGI=SUM(MLAT)
+
+      call grib_get(igrib(1),'numberOfVerticalCoordinateValues',mk)
+
+      IF(mk/2-1 .ne. MLEVEL) THEN 
+        WRITE(*,*) 'FATAL: Number of model levels',mk, &
+          ' does not agree with', MLEVEL,' in namelist'
+        STOP
+      ENDIF
+      call grib_get(igrib(1),'pv',pv)
+        AK=pv(1:1+MLEVEL)
+        BK=pv(2+MLEVEL:2*MLEVEL+2)
+
+      ALLOCATE (LNPMN(0:(MNAUF+1)*(MNAUF+2)-1))
+      ALLOCATE (LNPMN2(0:(MNAUF+1)*(MNAUF+2)-1))
+      ALLOCATE (UGVG(NGI, 2*MLEVEL),HILFUV(2*MAXL,2))
+
+
+      ALLOCATE (DPSDL(NGI,1),DPSDM(NGI,1))
+
+      ALLOCATE (PSG(NGI),HILF(NGI))
+      ALLOCATE (UV(MAXL, MAXB, 2*MLEVEL))
+!      ALLOCATE (UV2(MAXL, MAXB, 2*MLEVEL))
+
+      ALLOCATE (XMN(0:(MNAUF+1)*(MNAUF+2)-1, 2*MLEVEL))
+      ALLOCATE (DG(NGI,MLEVEL),ETAG(NGI,MLEVEL))
+
+! Initialisieren  Legendretransformation
+!	auf das LaT/LON Gitter
+
+      PI=ACOS(-1.D0)
+!$OMP PARALLEL DO
+      DO 20 J=1,MAXB
+
+      BREITE(J)=SIN((RLA1-(J-1.D0)*(RLA1-RLA0)/(MAXB-1))* PI/180.D0)
+
+      CALL PLGNFA(MNAUF,BREITE(J),Z(0,J))
+
+20    CONTINUE
+!$OMP END PARALLEL DO
+
+! Avoid possible Pole problem
+!      IF(RLA0 .EQ. -90.0) BREITE(MAXB)=sin(-89.99*PI/180.d0)
+!      IF(RLA1 .EQ. 90.0)  BREITE(1)=sin(89.99*PI/180.d0)
+
+! Initialisation of fields for  FFT and Legendre transformation
+!	to  Gaussian grid and back to phase space
+	X1=-1.D0
+	X2=1.D0
+	CALL GAULEG(X1,X2,GBREITE,WEIGHT,NGJ)
+
+!$OMP PARALLEL DO PRIVATE(M)
+	DO J=1,NGJ/2
+               CALL PLGNFA(MNAUF,GBREITE(J),P(:,J))
+		DO M=0,(MNAUF+3)*(MNAUF+4)/2
+		  PP(J,M)=P(M,J)
+	ENDDO
+	ENDDO
+!$OMP END PARALLEL DO
+
+
+!       MPAR(1)=152
+        FILENAME='fort.12'
+        CALL READSPECTRAL(FILENAME,LNPMN,MNAUF,1,MLEVEL,(/152/),AK,BK)
+!      goto 111
+        CALL SET99(WSAVE,IFAX,mauf)
+        CALL PHGCUT(LNPMN,PS,WSAVE,IFAX,Z, &
+      MNAUF,MNAUF,MAUF,MANF,MAXL,MAXB,1)
+      CALL STATIS(MAXL,MAXB,1,EXP(PS),RMS,MW,SIG)
+      WRITE(*,'(A12,3F12.4)') 'STATISTICS: ',RMS,MW,SIG
+
+        DO J=1,NGJ/2
+          CALL SET99(GWSAVE(1,J),GIFAX(1,J),MLAT(J))
+        ENDDO
+	CALL PHGR213(LNPMN,HILF,GWSAVE,GIFAX,P,MLAT,MNAUF,NGI,NGJ,1)
+        PSG=HILF
+	CALL GRPH213(LNPMN2,PSG,GWSAVE,GIFAX,PP,WEIGHT,MLAT, &
+      MNAUF,NGI,NGJ,1)
+	CALL PHGR213(LNPMN2,HILF,GWSAVE,GIFAX,P,MLAT,MNAUF,NGI,NGJ,1)
+
+
+        HILF=exp(PSG)-exp(HILF)
+
+      CALL STATIS(NGI,1,1,HILF,RMS,MW,SIG)
+      WRITE(*,'(A12,3F11.4)') 'STATISTICS: ',RMS,MW,SIG
+
+        PSG=EXP(PSG)
+        HILF=PSG
+      CALL STATIS(NGI,1,1,HILF,RMS,MW,SIG)
+      WRITE(*,'(A12,3F11.4)') 'STATISTICS: ',RMS,MW,SIG
+
+  111         FILENAME='fort.10'
+       CALL READSPECTRAL(FILENAME, &
+      XMN,MNAUF,2*MLEVEL,MLEVEL,(/131,132/),AK,BK) 
+!	Transformieren des Windes auf das Gaussgitter	
+	CALL PHGR213(XMN,UGVG,GWSAVE,GIFAX,P,MLAT,MNAUF,NGI,NGJ,2*MLEVEL)
+       DO K=1,MLEVEL
+! North Pole
+            CALL JSPPOLE(XMN(:,K),1,MNAUF,.TRUE.,CUA(:,:,K))
+            CALL JSPPOLE(XMN(:,MLEVEL+K),1,MNAUF,.TRUE.,CVA(:,:,K))
+! South Pole
+            CALL JSPPOLE(XMN(:,K),-1,MNAUF,.TRUE.,CUA(:,3:4,K))
+            CALL JSPPOLE(XMN(:,MLEVEL+K),-1,MNAUF,.TRUE.,CVA(:,3:4,K))
+       ENDDO
+    
+        DO K=1,2*MLEVEL
+          IF(MSMOOTH .ne. 0) CALL SPFILTER(XMN(:,K),MNAUF,MSMOOTH)
+        ENDDO
+        CALL PHGCUT(XMN,UV,WSAVE,IFAX,Z, &
+      MNAUF,MNAUF,MAUF,MANF,MAXL,MAXB,2*MLEVEL)
+
+
+ 112        FILENAME='fort.13'
+      CALL READSPECTRAL(FILENAME,XMN,MNAUF,MLEVEL,MLEVEL,(/155/),AK,BK)
+!	Transformieren der horizontalen Divergenz auf das Gaussgitter			
+	CALL PHGR213(XMN,DG,GWSAVE,GIFAX,P,MLAT,MNAUF,NGI,NGJ,MLEVEL)
+
+
+!	Berechnung des Gradienten des Logarithmus des Bodendrucks 
+!       auf dem Gaussgitter	
+	CALL PHGRAD(LNPMN,DPSDL,DPSDM,GWSAVE,GIFAX,P,H,MLAT,MNAUF,NGI,NGJ,1)
+
+!	Berechnung der Vertikalgeschwindigkeit auf dem Gaussgitter
+      CALL CONTGL(HILF,DPSDL,DPSDM,DG,UGVG(:,1),UGVG(:,MLEVEL+1), &
+      GBREITE,ETAG,MLAT,AK,BK,NGI,NGJ,MLEVEL)
+
+ 
+ 	CALL GRPH213(XMN,ETAG,GWSAVE,GIFAX,PP,WEIGHT,MLAT, &
+      MNAUF,NGI,NGJ,MLEVEL)
+        DO K=1,MLEVEL
+          IF(MSMOOTH .ne. 0) CALL SPFILTER(XMN(:,K),MNAUF,MSMOOTH)
+        ENDDO
+        CALL PHGCUT(XMN,ETA,WSAVE,IFAX,Z,MNAUF,MNAUF,MAUF,MANF,MAXL,MAXB,MLEVEL)
+
+	CALL GRPH213(XMN,HILF,GWSAVE,GIFAX,PP,WEIGHT,MLAT, MNAUF,NGI,NGJ,1)
+
+        IF(MSMOOTH .ne. 0) CALL SPFILTER(XMN(:,1),MNAUF,MSMOOTH)
+        CALL PHGCUT(XMN,DPSDT,WSAVE,IFAX,Z,MNAUF,MNAUF,MAUF,MANF,MAXL,MAXB,1)
+!       GOTO 114
+
+      CALL STATIS(MAXL,MAXB,1,DPSDT,RMS,MW,SIG)
+      WRITE(*,'(A12,3F11.4)') 'STATISTICS DPSDT: ',RMS,MW,SIG
+
+       IF(MOMEGADIFF .ne. 0) THEN
+!	Berechnung von Omega auf dem Gaussgitter
+	CALL OMEGA(PSG,DPSDL,DPSDM,DG,UGVG(:,1),UGVG(:,MLEVEL+1), &
+      GBREITE,ETAG,MLAT,AK,BK,NGI ,NGJ,MLEVEL) 
+
+	CALL GRPH213(XMN,ETAG,GWSAVE,GIFAX,PP,WEIGHT,MLAT,&
+      MNAUF,NGI,NGJ,MLEVEL)
+        DO K=1,MLEVEL
+          IF(MSMOOTH .ne. 0) CALL SPFILTER(XMN(:,K),MNAUF,MSMOOTH)
+        ENDDO
+        CALL PHGCUT(XMN,OM,WSAVE,IFAX,Z,MNAUF,MNAUF,MAUF,MANF,MAXL,MAXB,MLEVEL)
+
+       ENDIF !MOMEGA
+
+	CALL GRPH213(XMN,PSG,GWSAVE,GIFAX,PP,WEIGHT,MLAT,MNAUF,NGI,NGJ,1)
+        CALL PHGCUT(XMN,PS,WSAVE,IFAX,Z,MNAUF,MNAUF,MAUF,MANF,MAXL,MAXB,1)
+
+      CALL STATIS(MAXL,MAXB,1,PS,RMS,MW,SIG)
+      WRITE(*,'(A12,3F11.4)') 'STATISTICS: ',RMS,MW,SIG
+
+ 114  DEALLOCATE(HILF,PSG,DPSDL,DPSDM,ETAG,DG,LNPMN)
+
+!      ALLOCATE (UV(MAXL, MAXB, 2*MLEVEL))
+!	CALL GRPH213(XMN,UGVG,GWSAVE,GIFAX,PP,WEIGHT,MLAT,
+!     *MNAUF,NGI,NGJ,2*MLEVEL)
+!        DO K=1,2*MLEVEL
+!          IF(MSMOOTH .ne. 0) CALL SPFILTER(XMN(:,K),MNAUF,MSMOOTH)
+!        ENDDO
+!        CALL PHGCUT(XMN,UV,WSAVE,IFAX,Z,
+!     *MNAUF,MNAUF,MAUF,MANF,MAXL,MAXB,2*MLEVEL)
+        DEALLOCATE(PP,P,UGVG,MLAT,GBREITE,WEIGHT,GWSAVE,XMN)
+
+!        CALL ETAGAUSS(Z,WSAVE
+!     *,BREITE,UV,ETA,OM,PS,
+!     *MAUF,MAXB,MAXL,MANF,MNAUF,MLEVEL,MSMOOTH)
+
+      ELSE
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!          READING OF PREPARED METEOROLOGICAL FIELDS              !
+!                                                                 !
+!          THE FOLLOWING FIELDS ARE EXPECTED:                     !
+!                                                                 !
+!          UNIT 11: T,U,V        (REGULAR GRID)                   !
+!          UNIT 17: Q            (REGULAR GRID)                   !
+!          UNIT 13: D            (REGULAR GRID)                   !
+!          UNIT 12: LNSP         (SPHERICAL HARMONICS)            !
+!          UNIT 14: SURFACE DATA (REGULAR GRID)                   !
+!          UNIT 16: FLUX DATA    (REGULAR GRID)                   !
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+      ALLOCATE (MLAT(MAXB))
+      MLAT=MAXL
+      ALLOCATE (Z(0:((MNAUF+3)*(MNAUF+4))/2,1))
+      ALLOCATE (DPSDL(MAXL,MAXB),DPSDM(MAXL,MAXB))
+      ALLOCATE (UV(MAXL, MAXB, 2*MLEVEL),DIV(MAXL,MAXB,MLEVEL))
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!                  READING OF SURFACE PRESSURE                    !
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+      FILENAME='fort.12'
+        CALL READSPECTRAL(FILENAME,LNPS,MNAUF,1,MLEVEL,(/152/),AK,BK)
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!                      READING OF U,V                      !
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! OPENING OF UNBLOCKED GRIB FILE
+!
+      FILENAME='fort.10'
+      CALL READLATLON(FILENAME,UV,MAXL,MAXB,2*MLEVEL,(/131,132/))
+
+
+      PI=ACOS(-1.D0)
+      DO J=1,MAXB
+
+        BREITE(J)=SIN((RLA1-(J-1.D0)*(RLA1-RLA0)/(MAXB-1))*PI/180.D0)
+
+      ENDDO
+! Avoid possible Pole problem
+!      IF(RLA0 .EQ. -90.0) BREITE(MAXB)=sin(-89.99*PI/180.d0)
+!      IF(RLA1 .EQ. 90.0)  BREITE(1)=sin(89.99*PI/180.d0)
+
+      DO K=1,2*MLEVEL
+        DO J=1,MAXB
+          COSB=SQRT(1.0-(BREITE(J))*(BREITE(J)))
+          IF(RLA0 .EQ. -90.0 .AND. J .EQ. MAXB .OR. &
+             RLA1 .EQ. 90.0 .AND. J .EQ. 1) then
+            UV(:,J,K)=UV(:,J,K)/1.D6
+          else
+            UV(:,J,K)=UV(:,J,K)*COSB
+          endif
+      ENDDO
+      ENDDO
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!                     READING OF LNSP on grid                !
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! For debugging only
+!      FILENAME='LNSPG_G.20060330.600'
+!      INQUIRE(FILE=FILENAME,EXIST=EX)
+!      CALL READLATLON(FILENAME,QA,
+!     *MAXL,MAXB,1,1,(/152/))
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!                     READING OF DIVERGENCE                       !
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+      IF(META .EQ. 0 .OR. METADIFF .EQ. 1) THEN
+        FILENAME='fort.13'
+        CALL READLATLON(FILENAME,DIV,MAXL,MAXB,MLEVEL,(/155/))
+      ENDIF
+
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!       CALCULATION OF ETAPOINT --> TOTAL TIME DERIVATIVE OF       !
+!      ECMWF VERTICAL COORDINATE ETA MULTIPLIED BY DERIVATIVE     !
+!      OF PRESSURE IN ETA DIRECTION                               !
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+! Initialisieren  Legendretransformation
+!	auf das LaT/LON Gitter
+! Without Gaussian grid calculation Legendre Polynomials are calculated
+! only for one latitude to save space
+
+      DO J=1,MAXB
+
+        CALL PLGNFA(MNAUF,BREITE(J),Z(0,1))
+
+        CALL PHGCUT(LNPS,PS(:,J,1),WSAVE,IFAX,Z,MNAUF,MNAUF,MAUF,MANF,MAXL,1,1)
+
+
+        IF(META .EQ. 0 .or. METADIFF .EQ. 1 ) THEN
+          CALL PHGRACUT(LNPS,DPSDL(:,J),DPSDM(:,J),WSAVE,IFAX,Z,H,MAUF, &
+      MNAUF,MAXL,1,MANF,1)
+        ENDIF
+      ENDDO
+     
+      PS=EXP(PS)
+
+! For debugging only
+      CALL STATIS(MAXL,MAXB,1,PS(:,:,1),RMS,MW,SIG)
+      WRITE(*,'(A12,3F11.4)') 'STATISTICS: ',RMS,MW,SIG
+      
+      
+       IF(MOMEGADIFF .ne. 0) THEN
+
+         CALL OMEGA(PS,DPSDL,DPSDM,DIV,UV(:,:,1),UV(:,:,MLEVEL+1), &
+      BREITE,OM,MLAT,AK,BK,MAXL*MAXB,MAXB,MLEVEL) 
+       ENDIF
+     
+       IF(META .EQ. 0 .OR. METADIFF .ne. 0) THEN
+         DPSDT=PS
+         CALL CONTGL(DPSDT,DPSDL,DPSDM,DIV,UV(:,:,1),UV(:,:,MLEVEL+1), &
+      BREITE,ETA,MLAT,AK,BK,MAXL*MAXB,MAXB,MLEVEL)
+       ENDIF
+
+      ENDIF ! MGAUSS
+
+! CREATE FILE VERTICAL.EC NEEDED BY POP MODEL
+
+      open(21,file='VERTICAL.EC')
+      write(21,'(a)')
+      write(21,'(a)') 'VERTICAL DISCRETIZATION OF POP MODEL'
+      write(21,'(a)')
+      write(21,'(i3,a)') MLEVEL,'   number of layers'
+      write(21,'(a)')
+      write(21,'(a)') '* A(NLEV+1)'
+      write(21,'(a)')
+      do 205 i=1,MLEVEL+1
+205      write(21,'(f18.12)') AK(I)
+      write(21,'(a)')
+      write(21,'(a)') '* B(NLEV+1)'
+      write(21,'(a)')
+      do 210 i=1,MLEVEL+1
+210      write(21,'(f18.12)') BK(I)
+      close(21)
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!                     READING OF OMEGA                       !
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+      IF(MOMEGA .NE. 0 ) THEN
+
+
+
+         ALLOCATE (OMR(MAXL, MAXB, MLEVEL))
+ 
+         FILENAME='fort.19'
+         CALL READLATLON(FILENAME,OMR,MAXL,MAXB,MLEVEL,(/135/))
+
+      IF(MOMEGADIFF .NE. 0 ) THEN
+
+      DO K=1,MLEVEL
+        CALL STATIS(MAXL,MAXB,1,ETA(:,:,K),RMS,MW,SIG)        
+        WRITE(*,'(A12,I3,3F11.4)') '       ETA: ',K,RMS,MW,SIG
+        CALL STATIS(MAXL,MAXB,1,OMR(:,:,K),RMS,MW,SIG)        
+        WRITE(*,'(A12,I3,3F11.4)') '     OMEGA: ',K,RMS,MW,SIG
+        CALL STATIS(MAXL,MAXB,1,OM(:,:,K)-OMR(:,:,K),RMS,MW,SIG)        
+        WRITE(*,'(A12,I3,3F11.4)') 'OMEGA DIFF: ',K,RMS,MW,SIG
+      ENDDO
+
+      ENDIF
+      ENDIF
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!                     READING OF ETA                       !
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+      IF(META .NE. 0 ) THEN
+
+         ALLOCATE (ETAR(MAXL, MAXB, MLEVEL))
+ 
+         P00=101325.
+         FILENAME='fort.21'
+         CALL READLATLON(FILENAME,ETAR,MAXL,MAXB,MLEVEL,(/77/))
+
+         if(MDPDETA .EQ. 1) THEN
+          DO K=1,MLEVEL
+           DAK=AK(K+1)-AK(K)
+           DBK=BK(K+1)-BK(K)
+           DO J=1,MAXB
+             DO I=1,MAXL
+               ETAR(I,J,K)=2*ETAR(I,J,K)*PS(I,J,1)*(DAK/PS(I,J,1)+DBK)/ &
+                          (DAK/P00+DBK)
+               IF(K .GT. 1) ETAR(I,J,K)=ETAR(I,J,K)-ETAR(I,J,K-1)
+             ENDDO
+           ENDDO
+          ENDDO
+         ENDIF
+
+        IF(METADIFF .NE. 0 ) THEN
+
+         DO K=1,MLEVEL
+          CALL STATIS(MAXL,MAXB,1,ETA(:,:,K),RMS,MW,SIG)        
+          WRITE(*,'(A12,I3,3F11.4)') '       ETA: ',K,RMS,MW,SIG
+          CALL STATIS(MAXL,MAXB,1,ETAR(:,:,K),RMS,MW,SIG)        
+          WRITE(*,'(A12,I3,3F11.4)') '     ETAR: ',K,RMS,MW,SIG
+          CALL STATIS(MAXL,MAXB,1,ETA(:,:,K)-ETAR(:,:,K),RMS,MW,SIG)        
+          WRITE(*,'(A12,I3,3F11.4)') 'ETA DIFF: ',K,RMS,MW,SIG
+         ENDDO
+         DO K=1,MLEVEL
+          WRITE(*,'(I3,2F11.4)') K,ETA(1,MAXB/2,K),ETAR(1,MAXB/2,K)
+         ENDDO
+        ELSE
+          ETA=ETAR
+        ENDIF
+      ENDIF
+
+      ALLOCATE (T(MAXL, MAXB, MLEVEL))
+      ALLOCATE (QA(MAXL, MAXB, MLEVEL))
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!                      READING OF T                      !
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!
+! OPENING OF UNBLOCKED GRIB FILE
+!
+      FILENAME='fort.11'
+      CALL READLATLON(FILENAME,T,MAXL,MAXB,MLEVEL,(/130/))
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!                     READING OF SPECIFIC HUMIDITY                !
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+      FILENAME='fort.17'
+      CALL READLATLON(FILENAME,QA,MAXL,MAXB,MLEVEL,(/133/))
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!                     TEST READING OF UV from MARS (debug only)   !
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+!      FILENAME='fort.22'
+!      CALL READLATLON(FILENAME,UV2,MAXL,MAXB,2*MLEVEL,2,(/131,132/))
+
+
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!                    WRITE MODEL LEVEL DATA TO fort.15            !
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+!     Calculation of etadot in CONTGL needed scaled winds (ucosphi,vcosphi)
+!     Now we are transforming back to the usual winds. 
+      DO K=1,MLEVEL
+        DO J=2,MAXB-1
+          COSB=SQRT(1.0-(BREITE(J))*(BREITE(J)))
+          UV(:,J,K)=UV(:,J,K)/COSB
+          UV(:,J,MLEVEL+K)=UV(:,J,MLEVEL+K)/COSB
+        ENDDO
+! special treatment for poles, if necessary. 
+        DO J=1,MAXB,MAXB-1
+          COSB=SQRT(1.0-(BREITE(J))*(BREITE(J)))
+          if(1.0-BREITE(J)*BREITE(J) .gt. 0 .OR. MGAUSS .NE. 1) then
+            IF(RLA0 .EQ. -90.0 .AND. J .EQ. MAXB .OR. &
+             RLA1 .EQ. 90.0 .AND. J .EQ. 1) then
+             UV(:,J,K)=UV(:,J,K)*1.D6
+             UV(:,J,MLEVEL+K)=UV(:,J,MLEVEL+K)*1.D6
+            else
+             UV(:,J,K)=UV(:,J,K)/COSB
+             UV(:,J,MLEVEL+K)=UV(:,J,MLEVEL+K)/COSB
+            endif
+          else
+              HILFUV(5:MAXL,:)=0.
+              HILFUV(1:2,:)=0.
+            IF(J.EQ.MAXB) THEN
+! Suedpol
+              HILFUV(3:4,1)=CUA(:,4,K)
+              HILFUV(3:4,2)=CVA(:,4,K)
+            ELSE
+! Nordpol
+              HILFUV(3:4,1)=CUA(:,2,K)
+              HILFUV(3:4,2)=CVA(:,2,K)
+            ENDIF
+              CALL RFOURTR(HILFUV(:,1),WSAVE,IFAX,MAXL/2-1,MAXL,-1)
+              DO I=0,MAXL-1
+                IF(MANF+I.LE.MAXL) THEN
+                  UV(I+1,J,K)=HILFUV(MANF+I,1)
+                ELSE
+                  UV(I+1,J,K)=HILFUV(MANF-MAXL+I,1)
+                ENDIF
+              ENDDO
+              CALL RFOURTR(HILFUV(:,2),WSAVE,IFAX,MAXL/2-1,MAXL,-1)
+              DO I=0,MAXL-1
+                IF(MANF+I.LE.MAXL) THEN
+                  UV(I+1,J,MLEVEL+K)=HILFUV(MANF+I,2)
+                ELSE
+                  UV(I+1,J,MLEVEL+K)=HILFUV(MANF-MAXL+I,2)
+                ENDIF
+              ENDDO
+          endif
+      ENDDO
+      ENDDO
+
+! open output file
+      call grib_open_file(LUNIT,'fort.15','w')
+
+! we use temperature on lat/lon on model levels as template for model level data
+      LUNIT2=0
+      call grib_open_file(LUNIT2,'fort.11','r')
+      call grib_new_from_file(LUNIT2,igrib(1), iret)
+      call grib_close_file(LUNIT2)
+
+
+      CALL WRITELATLON(LUNIT,igrib(1),ogrib,UV(:,:,1),MAXL,MAXB,MLEVEL,MLEVELIST,1,(/131/))
+
+      CALL WRITELATLON(LUNIT,igrib(1),ogrib,UV(:,:,MLEVEL+1),MAXL,MAXB,MLEVEL,MLEVELIST,1,(/132/))
+
+      IF(MDPDETA .ne. 1 .AND. MGAUSS .EQ. 0 .and. META .eq. 1) THEN
+        CALL WRITELATLON(LUNIT,igrib(1),ogrib,ETA,MAXL,MAXB,MLEVEL,MLEVELIST,1,(/77/))
+      ELSE
+        CALL WRITELATLON(LUNIT,igrib(1),ogrib,ETA,MAXL,MAXB,MLEVEL,MLEVELIST,1,(/METAPAR/))
+      ENDIF
+
+      CALL WRITELATLON(LUNIT,igrib(1),ogrib,T,MAXL,MAXB,MLEVEL,MLEVELIST,1,(/130/))
+
+      CALL WRITELATLON(LUNIT,igrib(1),ogrib,PS,MAXL,MAXB,1,'1',1,(/134/))
+ 
+      call grib_set(igrib(1),"levelType","ml")
+      call grib_set(igrib(1),"typeOfLevel","hybrid")
+      CALL WRITELATLON(LUNIT,igrib(1),ogrib,QA,MAXL,MAXB,MLEVEL,MLEVELIST,1,(/133/))
+
+  
+      IF(MOMEGA .EQ. 1) THEN
+        call grib_open_file(LUNIT2,'fort.25','w')
+        CALL WRITELATLON(LUNIT2,igrib(1),ogrib,OMR,MAXL,MAXB,MLEVEL,MLEVELIST,1,(/135/))
+
+        IF(MOMEGADIFF .EQ. 1) THEN
+
+          CALL WRITELATLON(LUNIT2,igrib(1),ogrib,DPSDT,MAXL,MAXB,1,'1',1,(/158/))
+
+        OM=OM-OMR
+        CALL WRITELATLON(LUNIT2,igrib(1),ogrib,OM,MAXL,MAXB,MLEVEL,MLEVELIST,1,(/001/))
+      call grib_close_file(LUNIT2)
+        ENDIF
+      ENDIF
+
+      IF(META .EQ. 1 .and. METADIFF .EQ. 1) THEN
+        call grib_open_file(LUNIT2,'fort.26','w')
+        CALL WRITELATLON(LUNIT2,igrib(1),ogrib,ETAR,MAXL,MAXB,MLEVEL,MLEVELIST,1,(/135/))
+
+!        IF(MOMEGADIFF .EQ. 1) THEN
+
+          CALL WRITELATLON(LUNIT2,igrib(1),ogrib,DPSDT,MAXL,MAXB,1,'1',1,(/158/))
+
+        OM=ETA-ETAR
+        CALL WRITELATLON(LUNIT2,igrib(1),ogrib,OM,MAXL,MAXB,MLEVEL,MLEVELIST,1,(/001/))
+      call grib_close_file(LUNIT2)
+!        ENDIF
+      ENDIF
+
+
+      call grib_close_file(LUNIT)
+
+
+
+ 2000 STOP 'SUCCESSFULLY FINISHED CONVERT_PRE: CONGRATULATIONS'
+ 3000 STOP 'ROUTINE CONVERT_PRE: ERROR'
+ 9999 stop 'ROUTINE CONVERT_PRE: ERROR'
+      END
+
+      
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+      INTEGER FUNCTION IA (FIELD1,NI,NJ,NK,G)
+
+      IMPLICIT NONE
+      INTEGER NI,NJ,NK,I,J,K
+      REAL FIELD1(NI,NJ,NK)
+      REAL G
+      REAL RMIN,RMAX,XMAX,A,A1,A2
+
+      RMAX=FIELD1(1,1,1)
+      RMIN=FIELD1(1,1,1)
+      
+      DO 100 K=1,NK
+      DO 100 J=1,NJ
+        DO 100 I=1,NI
+          IF (FIELD1(I,J,K).GT.RMAX)RMAX=FIELD1(I,J,K)
+          IF (FIELD1(I,J,K).LT.RMIN)RMIN=FIELD1(I,J,K)
+100   CONTINUE
+
+      IF (ABS(RMIN).GT.RMAX.OR.ABS(RMIN).EQ.RMAX) THEN
+      XMAX=ABS(RMIN)
+      ELSE
+      XMAX=RMAX
+      ENDIF
+      
+      IF (XMAX.EQ.0) THEN
+      IA = 0
+      RETURN
+      ENDIF
+      
+      A1=LOG10 ((G/10.d0)/XMAX)
+      A2=LOG10 ( G/XMAX )
+      IF(A1 .gt. A2) THEN
+        A=A2
+      ELSE 
+        A=A1
+      ENDIF
+      
+      IF (A.GT.0) IA=INT(A)
+      IF (A.LT.0) IA=INT(A-1.0)
+      
+      RETURN
+      END
+      
+      SUBROUTINE STATIS (NI,NJ,NK,PHI,RMS,MW,SIG)
+	IMPLICIT REAL (A-H,O-Z)
+
+      REAL PHI(NI,NJ,NK),SIG,MW,RMS,P
+ 
+      N=NI*NJ*NK
+ 
+      RMS=0.
+	MW=0.
+ 
+      DO 10 I=1,NI
+      DO 10 J=1,NJ
+        DO 10 K=1,NK
+	      P=PHI(I,J,K)
+          RMS=RMS+P*P
+ 		MW=MW+P
+10    CONTINUE
+
+      RMS=SQRT(RMS/N)
+	MW=MW/N
+	
+	IF(RMS*RMS-MW*MW.LT.0.) THEN	  
+	  SIG=0.0
+	ELSE
+	  SIG=SQRT(RMS*RMS-MW*MW)
+	ENDIF
+ 
+      RETURN
+      END
+      
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/rwGRIB2.f90 b/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/rwGRIB2.f90
new file mode 100644
index 0000000000000000000000000000000000000000..09ec94e305507d30e37c43009d306ffd343cbe05
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/fortran/rwGRIB2.f90
@@ -0,0 +1,263 @@
+      MODULE RWGRIB2
+
+      CONTAINS
+
+      SUBROUTINE READLATLON(FILENAME,FELD,MAXL,MAXB,MLEVEL,MPAR)
+
+      USE GRIB_API
+
+      IMPLICIT NONE
+
+        integer                            ::  ifile
+        integer                            ::  iret
+   integer                            ::  n,mk,parid,nm
+   integer                            ::  i,k
+   integer,dimension(:),allocatable   ::  igrib
+   integer                            ::  numberOfPointsAlongAParallel
+   integer                            ::  numberOfPointsAlongAMeridian
+   real, dimension(:), allocatable    ::  values
+   integer                            ::  numberOfValues
+   real,dimension(maxl,maxb,mlevel)   ::  feld  
+   integer:: maxl,maxb,mlevel,mstride,mpar(:),irest,div,level
+   integer :: l(size(mpar))
+   character*(*):: filename                             
+
+   call grib_open_file(ifile, TRIM(FILENAME),'r')
+ 
+   ! count the messages in the file
+   call grib_count_in_file(ifile,n)
+   allocate(igrib(n))
+   igrib=-1
+ 
+   ! Load the messages from the file.
+   DO i=1,n
+      call grib_new_from_file(ifile,igrib(i), iret)
+   END DO
+ 
+   ! we can close the file
+   call grib_close_file(ifile)
+ 
+      nm=size(mpar)
+      div=mlevel/nm
+      l=0
+      
+   ! Loop on all the messages in memory
+  iloop:  DO i=1,n
+!      write(*,*) 'processing message number ',i
+      !     get as a integer
+      call grib_get(igrib(i),'numberOfPointsAlongAParallel', &
+           numberOfPointsAlongAParallel)
+ 
+      !     get as a integer
+      call grib_get(igrib(i),'numberOfPointsAlongAMeridian', &
+           numberOfPointsAlongAMeridian)
+
+      call grib_get(igrib(i),'numberOfVerticalCoordinateValues',mk)
+
+      call grib_get_size(igrib(i),'values',numberOfValues)
+!      write(*,*) 'numberOfValues=',numberOfValues
+ 
+      allocate(values(numberOfValues), stat=iret)
+      !     get data values
+      call grib_get(igrib(i),'values',values)
+
+      call grib_get(igrib(i),'paramId',parid)
+      call grib_get(igrib(i),'level',level)
+
+ kloop:  do k=1,nm
+        if(parid .eq. mpar(k)) then
+!         l(k)=l(k)+1
+         feld(:,:,(k-1)*div+level)=reshape(values,(/maxl,maxb/))
+!         print*,(k-1)*div+l(k),parid
+         exit kloop
+        endif
+      enddo kloop
+      if(k .gt. nm .and. parid .ne. mpar(nm)) then
+        write(*,*) k,nm,parid,mpar(nm)
+        write(*,*) 'ERROR readlatlon: parameter ',parid,'is not',mpar
+        stop
+      endif
+
+!      print*,i
+   END DO iloop
+   write(*,*) 'readlatlon: ',i-1,' records read'
+ 
+   DO i=1,n
+     call grib_release(igrib(i))
+   END DO
+ 
+   deallocate(values)
+   deallocate(igrib)
+
+      END SUBROUTINE READLATLON
+
+      SUBROUTINE WRITELATLON(iunit,igrib,ogrib,FELD,MAXL,MAXB,MLEVEL,&
+      MLEVELIST,MSTRIDE,MPAR)
+
+      USE GRIB_API
+
+      IMPLICIT NONE
+
+      INTEGER IFIELD,MLEVEL,MNAUF,I,J,K,L,MSTRIDE,IERR,JOUT
+      INTEGER MPAR(MSTRIDE),MAXL,MAXB,LEVMIN,LEVMAX
+      INTEGER IUNIT,igrib,ogrib
+      REAL ZSEC4(MAXL*MAXB)
+      REAL    FELD(MAXL,MAXB,MLEVEL)
+      CHARACTER*(*) MLEVELIST
+      INTEGER ILEVEL(MLEVEL),MLINDEX(MLEVEL+1),LLEN
+
+    ! parse MLEVELIST
+   
+      LLEN=len(trim(MLEVELIST))
+      if(index(MLEVELIST,'to') .ne. 0 .or. index(MLEVELIST,'TO') .ne. 0) THEN
+        i=index(MLEVELIST,'/')
+        read(MLEVELIST(1:i-1),*) LEVMIN
+        i=index(MLEVELIST,'/',.true.)
+        read(MLEVELIST(i+1:LLEN),*) LEVMAX
+        l=0
+        do i=LEVMIN,LEVMAX
+          l=l+1
+          ILEVEL(l)=i
+        enddo
+      else
+        l=1
+	MLINDEX(1)=0
+        do i=1,LLEN
+          if(MLEVELIST(i:i) .eq. '/') THEN
+	    l=l+1
+	    MLINDEX(l)=i
+	  endif
+	enddo
+	MLINDEX(l+1)=LLEN+1
+	do i=1,l
+	  read(MLEVELIST(MLINDEX(i)+1:MLINDEX(i+1)-1),*) ILEVEL(i)
+	enddo
+      endif 
+
+      DO k=1,l
+        call grib_set(igrib,"level",ILEVEL(k))
+        DO j=1,MSTRIDE
+         call grib_set(igrib,"paramId",MPAR(j))
+!         if(MPAR(j) .eq. 87) then
+!           call grib_set(igrib,"shortName","etadot")
+!           call grib_set(igrib,"units","Pa,s**-1")
+!         endif
+!         if(MPAR(j) .eq. 77) then
+!           call grib_set(igrib,"shortName","etadot")
+!           call grib_set(igrib,"units","s**-1")
+!         endif
+	 if(l .ne. mlevel) then
+           zsec4(1:maxl*maxb)=RESHAPE(FELD(:,:,ILEVEL(k)),(/maxl*maxb/))
+	 else
+	   zsec4(1:maxl*maxb)=RESHAPE(FELD(:,:,k),(/maxl*maxb/))
+	 endif
+         call grib_set(igrib,"values",zsec4)
+
+         call grib_write(igrib,iunit)
+
+        ENDDO
+      ENDDO
+
+
+
+      END SUBROUTINE WRITELATLON
+
+      SUBROUTINE READSPECTRAL(FILENAME,CXMN,MNAUF,MLEVEL,&
+        MAXLEV,MPAR,A,B)
+
+      USE GRIB_API
+
+      IMPLICIT NONE
+
+
+        integer                            ::  ifile
+   integer                            ::  iret
+   integer                            ::  n,mk,div,nm,k
+   integer                            ::  i,j,parid
+   integer,dimension(:),allocatable   ::  igrib
+   real, dimension(:), allocatable    ::  values
+   integer                            ::  numberOfValues,maxlev
+   REAL :: A(MAXLEV+1),B(MAXLEV+1),pv(2*MAXLEV+2)
+   REAL:: CXMN(0:(MNAUF+1)*(MNAUF+2)-1,MLEVEL)
+integer:: maxl,maxb,mlevel,mstride,mpar(:),mnauf,ioffset,ipar,ilev,l(size(mpar))
+character*(*):: filename                             
+ 
+   call grib_open_file(ifile, TRIM(FILENAME),'r')
+ 
+   ! count the messages in the file
+   call grib_count_in_file(ifile,n)
+   allocate(igrib(n))
+   igrib=-1
+ 
+   ! Load the messages from the file.
+   DO i=1,n
+      call grib_new_from_file(ifile,igrib(i), iret)
+   END DO
+ 
+   ! we can close the file
+   call grib_close_file(ifile)
+ 
+    l=0
+   ! Loop on all the messages in memory
+   iloop: DO i=1,n
+   ! write(*,*) 'processing message number ',i
+      !     get as a integer
+      call grib_get(igrib(i),'pentagonalResolutionParameterJ', j)
+
+      call grib_get_size(igrib(i),'values',numberOfValues)
+   !   write(*,*) 'numberOfValues=',numberOfValues
+ 
+      call grib_get(igrib(i),'numberOfVerticalCoordinateValues',mk)
+
+      call grib_get(igrib(i),'level',ilev)
+
+      
+
+      call grib_get(igrib(i),'pv',pv)
+
+      allocate(values(numberOfValues), stat=iret)
+      !     get data values
+      call grib_get(igrib(i),'values',values)
+
+!      IOFFSET=mod(i-1,MSTRIDE)*(mk/2-1)
+!           CXMN(:,IOFFSET+ilev)=values(1:(MNAUF+1)*(MNAUF+2))
+
+      call grib_get(igrib(i),'paramId',parid)
+    nm=size(mpar)
+    div=mlevel/nm
+    kloop:  do k=1,nm
+        if(parid .eq. mpar(k)) then
+         l(k)=l(k)+1
+         cxmn(:,(k-1)*div+l(k))=values(1:(MNAUF+1)*(MNAUF+2))
+!         print*,(k-1)*div+l(k),parid
+         exit kloop
+        endif
+        
+      enddo kloop
+      if(k .gt. nm .and. parid .ne. mpar(nm)) then
+        write(*,*) k,nm,parid,mpar(nm)
+        write(*,*) 'ERROR readspectral: parameter ',parid,'is not',mpar
+        stop
+      endif
+
+!      print*,i
+
+   END DO iloop
+
+   write(*,*) 'readspectral: ',i-1,' records read'
+ 
+   DO i=1,n
+     call grib_release(igrib(i))
+   END DO
+ 
+   deallocate(values)
+   deallocate(igrib)
+
+
+
+        A=pv(1:1+MAXLEV)
+        B=pv(2+MAXLEV:2*MAXLEV+2)
+
+      END SUBROUTINE READSPECTRAL
+
+      END MODULE RWGRIB2
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/python/__init__.py b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..4609bf2c36fe073fdb731fa34a23fa45990e8b57
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/__init__.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#*******************************************************************************
+# @Author: Anne Philipp (University of Vienna)
+#
+# @Date: September 2018
+#
+# @License:
+#    (C) Copyright 2015-2018.
+#
+#    This software is licensed under the terms of the Apache Licence Version 2.0
+#    which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+#
+#*******************************************************************************
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/python/_config.py b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/_config.py
new file mode 100644
index 0000000000000000000000000000000000000000..e25aaa35b27fa66762e0f4605512be312b8abfa3
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/_config.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#*******************************************************************************
+# @Author: Anne Philipp (University of Vienna)
+#
+# @Date: August 2018
+#
+# @Change History:
+#
+# @License:
+#    (C) Copyright 2014-2018.
+#
+#    This software is licensed under the terms of the Apache Licence Version 2.0
+#    which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+#
+# @Description:
+#    Contains constant value parameter for flex_extract.
+#
+#*******************************************************************************
+
+# ------------------------------------------------------------------------------
+# MODULES
+# ------------------------------------------------------------------------------
+import os
+import sys
+import inspect
+
+_VERSION_STR = '7.1'
+
+# ------------------------------------------------------------------------------
+# FILENAMES
+# ------------------------------------------------------------------------------
+
+FILE_MARS_REQUESTS = 'mars_requests.dat'
+FORTRAN_EXECUTABLE = 'CONVERT2'
+FILE_USER_ENVVARS = 'ECMWF_ENV'
+TEMPFILE_INSTALL_COMPILEJOB = 'compilejob.temp'
+FILE_INSTALL_COMPILEJOB = 'compilejob.ksh'
+TEMPFILE_INSTALL_JOB = 'job.temp.o'
+TEMPFILE_JOB = 'job.temp'
+FILE_JOB_OD = 'job.ksh'
+FILE_JOB_OP = 'jopoper.ksh'
+FILE_NAMELIST = 'fort.4'
+FILE_GRIB_INDEX = 'date_time_stepRange.idx'
+FILE_GRIBTABLE = 'ecmwf_grib1_table_128'
+
+# ------------------------------------------------------------------------------
+# DIRECTORY NAMES
+# ------------------------------------------------------------------------------
+
+FLEXEXTRACT_DIRNAME = 'flex_extract_v' + _VERSION_STR
+INPUT_DIRNAME_DEFAULT = 'workspace'
+
+# ------------------------------------------------------------------------------
+#  PATHES
+# ------------------------------------------------------------------------------
+
+# path to the local python source files
+# first thing to get because the submitted python script starts in here
+PATH_LOCAL_PYTHON = os.path.dirname(os.path.abspath(
+    inspect.getfile(inspect.currentframe())))
+# add path to pythonpath
+if PATH_LOCAL_PYTHON not in sys.path:
+    sys.path.append(PATH_LOCAL_PYTHON)
+PATH_FLEXEXTRACT_DIR = os.path.normpath(os.path.dirname(os.path.abspath(
+    inspect.getfile(inspect.currentframe()))) + '/../../')
+PATH_RUN_DIR = os.path.join(PATH_FLEXEXTRACT_DIR, 'run')
+PATH_SOURCES = os.path.join(PATH_FLEXEXTRACT_DIR, 'source')
+PATH_TEMPLATES = os.path.join(PATH_FLEXEXTRACT_DIR, 'templates')
+PATH_ECMWF_ENV = os.path.join(PATH_RUN_DIR, FILE_USER_ENVVARS)
+PATH_GRIBTABLE = os.path.join(PATH_TEMPLATES, FILE_GRIBTABLE)
+PATH_JOBSCRIPTS = os.path.join(PATH_RUN_DIR, 'jobscripts')
+PATH_FORTRAN_SRC = os.path.join(PATH_SOURCES, 'fortran')
+PATH_TEST_DIR = os.path.join(PATH_SOURCES, 'pythontest')
+PATH_INPUT_DIR = os.path.join(PATH_RUN_DIR, INPUT_DIRNAME_DEFAULT)
+if os.getenv('CONTROL') and '/' in os.getenv('CONTROL'):
+    # this is only needed if remote version with job script is used!
+    # because job is directly submitted from SCRATCH and because the
+    # CONTROL file is stored there, the normal path is not valid.
+    PATH_CONTROLFILES = os.getenv('CONTROL')
+else:
+    PATH_CONTROLFILES = os.path.join(PATH_RUN_DIR, 'control')
+#
+# ------------------------------------------------------------------------------
+#
+# for making the installation tar ball the relative pathes to the
+# flex_extract root directory are needed
+PATH_REL_PYTHON = os.path.relpath(PATH_LOCAL_PYTHON, PATH_FLEXEXTRACT_DIR)
+PATH_REL_CONTROLFILES = os.path.relpath(PATH_CONTROLFILES, PATH_FLEXEXTRACT_DIR)
+PATH_REL_TEMPLATES = os.path.relpath(PATH_TEMPLATES, PATH_FLEXEXTRACT_DIR)
+PATH_REL_ECMWF_ENV = os.path.relpath(PATH_ECMWF_ENV, PATH_FLEXEXTRACT_DIR)
+PATH_REL_RUN_DIR = os.path.relpath(PATH_RUN_DIR, PATH_FLEXEXTRACT_DIR)
+PATH_REL_JOBSCRIPTS = os.path.relpath(PATH_JOBSCRIPTS, PATH_FLEXEXTRACT_DIR)
+PATH_REL_FORTRAN_SRC = os.path.relpath(PATH_FORTRAN_SRC, PATH_FLEXEXTRACT_DIR)
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/python/classes/ControlFile.py b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/classes/ControlFile.py
new file mode 100644
index 0000000000000000000000000000000000000000..97e6989b336ac4d35730e424da7e82aac7c060f6
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/classes/ControlFile.py
@@ -0,0 +1,532 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#*******************************************************************************
+# @Author: Leopold Haimberger (University of Vienna)
+#
+# @Date: November 2015
+#
+# @Change History:
+#
+#   February 2018 - Anne Philipp (University of Vienna):
+#        - applied PEP8 style guide
+#        - added documentation
+#        - applied some minor modifications in programming style/structure
+#        - changed name of class Control to ControlFile for more
+#          self-explanation naming
+#        - outsource of class ControlFile
+#        - initialisation of class attributes ( to avoid high number of
+#          conditional statements and set default values )
+#        - divided assignment of attributes and the check of conditions
+#        - outsourced the commandline argument assignments to control attributes
+#
+# @License:
+#    (C) Copyright 2015-2018.
+#
+#    This software is licensed under the terms of the Apache Licence Version 2.0
+#    which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+#
+# @Class Description:
+#    The CONTROL file is the steering part of the FLEXPART extraction
+#    software. All necessary parameters needed to retrieve the data fields
+#    from the MARS archive for driving FLEXPART are set in a CONTROL file.
+#    Some specific parameters like the start and end dates can be overwritten
+#    by the command line parameters, but in generel all parameters needed
+#    for a complete set of fields for FLEXPART can be set in the CONTROL file.
+#
+# @Class Content:
+#    - __init__
+#    - __read_controlfile__
+#    - __str__
+#    - assign_args_to_control
+#    - assign_envs_to_control
+#    - check_conditions
+#    - check_install_conditions
+#    - to_list
+#
+# @Class Attributes:
+#
+#
+#*******************************************************************************
+
+# ------------------------------------------------------------------------------
+# MODULES
+# ------------------------------------------------------------------------------
+import os
+import re
+import sys
+import inspect
+
+import _config
+
+# ------------------------------------------------------------------------------
+# CLASS
+# ------------------------------------------------------------------------------
+class ControlFile(object):
+    '''
+    Class containing the information of the flex_extract CONTROL file.
+
+    Contains all the parameters of CONTROL file, which are e.g.:
+    DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
+    STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
+    LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
+    OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
+    ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
+    MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR,
+    BASETIME, DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+
+    For more information about format and content of the parameter
+    see documentation.
+
+    '''
+
+    def __init__(self, filename):
+        '''
+        @Description:
+            Initialises the instance of ControlFile class and defines
+            all class attributes with default values. Afterwards calls
+            function __read_controlfile__ to read parameter from
+            Control file.
+
+        @Input:
+            self: instance of ControlFile class
+                Description see class documentation.
+
+            filename: string
+                Name of CONTROL file.
+
+        @Return:
+            <nothing>
+        '''
+
+        # list of all possible class attributes and their default values
+        self.controlfile = filename
+        self.start_date = None
+        self.end_date = None
+        self.date_chunk = 3
+        self.dtime = None
+        self.basetime = None
+        self.maxstep = None
+        self.type = None
+        self.time = None
+        self.step = None
+        self.marsclass = None
+        self.stream = None
+        self.number = 'OFF'
+        self.expver = '1'
+        self.grid = None
+        self.area = ''
+        self.left = None
+        self.lower = None
+        self.upper = None
+        self.right = None
+        self.level = None
+        self.levelist = None
+        self.resol = None
+        self.gauss = 0
+        self.accuracy = 24
+        self.omega = 0
+        self.omegadiff = 0
+        self.eta = 0
+        self.etadiff = 0
+        self.etapar = 77
+        self.dpdeta = 1
+        self.smooth = 0
+        self.format = 'GRIB1'
+        self.addpar = None
+        self.prefix = 'EN'
+        self.cwc = 0
+        self.wrf = 0
+        self.ecfsdir = 'ectmp:/${USER}/econdemand/'
+        self.mailfail = ['${USER}']
+        self.mailops = ['${USER}']
+        self.grib2flexpart = 0
+        self.ecstorage = 0
+        self.ectrans = 0
+        self.inputdir = _config.PATH_INPUT_DIR
+        self.outputdir = self.inputdir
+        self.ecmwfdatadir = _config.PATH_FLEXEXTRACT_DIR
+        self.exedir = _config.PATH_FORTRAN_SRC
+        self.flexpart_root_scripts = None
+        self.makefile = 'Makefile.gfortran'
+        self.destination = None
+        self.gateway = None
+        self.ecuid = None
+        self.ecgid = None
+        self.install_target = None
+        self.debug = 0
+        self.request = 0
+
+        self.logicals = ['gauss', 'omega', 'omegadiff', 'eta', 'etadiff',
+                         'dpdeta', 'cwc', 'wrf', 'grib2flexpart', 'ecstorage',
+                         'ectrans', 'debug', 'request']
+
+        self.__read_controlfile__()
+
+        return
+
+    def __read_controlfile__(self):
+        '''
+        @Description:
+            Read CONTROL file and assign all CONTROL file variables.
+
+        @Input:
+            self: instance of ControlFile class
+                Description see class documentation.
+
+        @Return:
+            <nothing>
+        '''
+        from mods.tools import my_error
+
+        # read whole CONTROL file
+        with open(os.path.join(_config.PATH_CONTROLFILES,
+                               self.controlfile)) as f:
+            fdata = f.read().split('\n')
+
+        # go through every line and store parameter
+        for ldata in fdata:
+            data = ldata.split()
+            if len(data) > 1:
+                if 'm_' in data[0].lower():
+                    data[0] = data[0][2:]
+                if data[0].lower() == 'class':
+                    data[0] = 'marsclass'
+                if data[0].lower() == 'day1':
+                    data[0] = 'start_date'
+                if data[0].lower() == 'day2':
+                    data[0] = 'end_date'
+                if data[0].lower() == 'addpar':
+                    if '/' in data[1]:
+                        # remove leading '/' sign from addpar content
+                        if data[1][0] == '/':
+                            data[1] = data[1][1:]
+                        dd = data[1].split('/')
+                        data = [data[0]]
+                        for d in dd:
+                            data.append(d)
+                if len(data) == 2:
+                    if '$' in data[1]:
+                        setattr(self, data[0].lower(), data[1])
+                        while '$' in data[1]:
+                            i = data[1].index('$')
+                            j = data[1].find('{')
+                            k = data[1].find('}')
+                            var = os.getenv(data[1][j+1:k])
+                            if var is not None:
+                                data[1] = data[1][:i] + var + data[1][k+1:]
+                            else:
+                                my_error(self.mailfail,
+                                         'Could not find variable '
+                                         + data[1][j+1:k] + ' while reading ' +
+                                         self.controlfile)
+                        setattr(self, data[0].lower() + '_expanded', data[1])
+                    else:
+                        if data[1].lower() != 'none':
+                            setattr(self, data[0].lower(), data[1])
+                        else:
+                            setattr(self, data[0].lower(), None)
+                elif len(data) > 2:
+                    setattr(self, data[0].lower(), (data[1:]))
+            else:
+                pass
+
+        return
+
+    def __str__(self):
+        '''
+        @Description:
+            Prepares a string which have all the ControlFile
+            class attributes with its associated values.
+            Each attribute is printed in one line and in
+            alphabetical order.
+
+            Example:
+            'age': 10
+            'color': 'Spotted'
+            'kids': 0
+            'legs': 2
+            'name': 'Dog'
+            'smell': 'Alot'
+
+        @Input:
+            self: instance of ControlFile class
+                Description see class documentation.
+
+        @Return:
+            string of ControlFile class attributes with their values
+        '''
+        import collections
+
+        attrs = vars(self)
+        attrs = collections.OrderedDict(sorted(attrs.items()))
+
+        return '\n'.join("%s: %s" % item for item in attrs.items())
+
+    def assign_args_to_control(self, args):
+        '''
+        @Description:
+            Overwrites the existing ControlFile instance attributes with
+            the command line arguments.
+
+        @Input:
+            self: instance of ControlFile class
+                Description see class documentation.
+
+            args: instance of ArgumentParser
+                Contains the commandline arguments from script/program call.
+
+        @Return:
+            <nothing>
+        '''
+
+        # get dictionary of command line parameters and eliminate all
+        # parameters which are None (were not specified)
+        args_dict = vars(args)
+        arguments = {k : args_dict[k] for k in args_dict
+                     if args_dict[k] != None}
+
+        # assign all passed command line arguments to ControlFile instance
+        for k, v in arguments.iteritems():
+            setattr(self, str(k), v)
+
+        return
+
+    def assign_envs_to_control(self, envs):
+        '''
+        @Description:
+            Assigns the ECMWF environment parameter.
+
+        @Input:
+            envs: dict of strings
+                Contains the ECMWF environment parameternames "ECUID", "ECGID",
+                "DESTINATION" and "GATEWAY" with its corresponding values.
+                They were read from the file "ECMWF_ENV".
+
+        @Return:
+            <nothing>
+        '''
+
+        for k, v in envs.iteritems():
+            setattr(self, str(k).lower(), str(v))
+
+        return
+
+    def check_conditions(self, queue):
+        '''
+        @Description:
+            Checks a couple of necessary attributes and conditions,
+            such as if they exist and contain values.
+            Otherwise set default values.
+
+        @Input:
+            self: instance of ControlFile class
+                Description see class documentation.
+
+            queue: string
+                Name of the queue if submitted to the ECMWF servers.
+                Used to check if ecuid, ecgid, gateway and destination
+                are set correctly and are not empty.
+
+        @Return:
+            <nothing>
+        '''
+        from mods.tools import my_error
+        import numpy as np
+
+        # check for having at least a starting date
+        # otherwise program is not allowed to run
+        if self.start_date is None:
+            print('start_date specified neither in command line nor \
+                   in CONTROL file ' +  self.controlfile)
+            print('Try "' + sys.argv[0].split('/')[-1] +
+                  ' -h" to print usage information')
+            sys.exit(1)
+
+        # retrieve just one day if end_date isn't set
+        if self.end_date is None:
+            self.end_date = self.start_date
+
+        # assure consistency of levelist and level
+        if self.levelist is None and self.level is None:
+            print('Warning: neither levelist nor level \
+                               specified in CONTROL file')
+            sys.exit(1)
+        elif self.levelist is None and self.level:
+            self.levelist = '1/to/' + self.level
+        elif (self.levelist and self.level is None) or \
+             (self.levelist[-1] != self.level[-1]):
+            self.level = self.levelist.split('/')[-1]
+        else:
+            pass
+
+        # if area was provided (only from commandline)
+        # decompose area into its 4 components
+        if self.area:
+            components = self.area.split('/')
+            # convert float to integer coordinates
+            if '.' in self.area:
+                components = [str(int(float(item) * 1000))
+                              for i, item in enumerate(components)]
+            self.upper, self.left, self.lower, self.right = components
+
+        # prepare step list if "/" signs are found
+        if '/' in self.step:
+            steps = self.step.split('/')
+            if 'to' in self.step.lower() and 'by' in self.step.lower():
+                ilist = np.arange(int(steps[0]),
+                                  int(steps[2]) + 1,
+                                  int(steps[4]))
+                self.step = ['{:0>3}'.format(i) for i in ilist]
+            elif 'to' in self.step.lower() and 'by' not in self.step.lower():
+                my_error(self.mailfail, self.step + ':\n' +
+                         'if "to" is used in steps parameter, \
+                         please use "by" as well')
+            else:
+                self.step = steps
+
+        # if maxstep wasn't provided
+        # search for it in the "step" parameter
+        if self.maxstep is None:
+            self.maxstep = 0
+            for s in self.step:
+                if int(s) > self.maxstep:
+                    self.maxstep = int(s)
+        else:
+            self.maxstep = int(self.maxstep)
+
+        # set root scripts since it is needed later on
+        if not self.flexpart_root_scripts:
+            self.flexpart_root_scripts = self.ecmwfdatadir
+
+        if not isinstance(self.mailfail, list):
+            if ',' in self.mailfail:
+                self.mailfail = self.mailfail.split(',')
+            elif ' ' in self.mailfail:
+                self.mailfail = self.mailfail.split()
+            else:
+                self.mailfail = [self.mailfail]
+
+        if not isinstance(self.mailops, list):
+            if ',' in self.mailops:
+                self.mailops = self.mailops.split(',')
+            elif ' ' in self.mailops:
+                self.mailops = self.mailops.split()
+            else:
+                self.mailops = [self.mailops]
+
+        if queue in ['ecgate', 'cca'] and \
+           not self.gateway or not self.destination or \
+           not self.ecuid or not self.ecgid:
+            print('\nEnvironment variables GATEWAY, DESTINATION, ECUID and \
+                   ECGID were not set properly!')
+            print('Please check for existence of file "ECMWF_ENV" in the \
+                   python directory!')
+            sys.exit(1)
+
+        if self.request != 0:
+            marsfile = os.path.join(self.inputdir,
+                                    _config.FILE_MARS_REQUESTS)
+            if os.path.isfile(marsfile):
+                os.remove(marsfile)
+
+        # check all logical variables for data type
+        # if its a string change to integer
+        for var in self.logicals:
+            if not isinstance(getattr(self, var), int):
+                setattr(self, var, int(getattr(self, var)))
+
+        return
+
+    def check_install_conditions(self):
+        '''
+        @Description:
+            Checks a couple of necessary attributes and conditions
+            for the installation such as if they exist and contain values.
+            Otherwise set default values.
+
+        @Input:
+            self: instance of ControlFile class
+                Description see class documentation.
+
+        @Return:
+            <nothing>
+        '''
+
+        if self.install_target and \
+           self.install_target not in ['local', 'ecgate', 'cca']:
+            print('ERROR: unknown or missing installation target ')
+            print('target: ', self.install_target)
+            print('please specify correct installation target ' +
+                  '(local | ecgate | cca)')
+            print('use -h or --help for help')
+            sys.exit(1)
+
+        if self.install_target and self.install_target != 'local':
+            if not self.ecgid or not self.ecuid or \
+               not self.gateway or not self.destination:
+                print('Please enter your ECMWF user id and group id as well ' +
+                      'as the \nname of the local gateway and the ectrans ' +
+                      'destination ')
+                print('with command line options --ecuid --ecgid \
+                       --gateway --destination')
+                print('Try "' + sys.argv[0].split('/')[-1] + \
+                      ' -h" to print usage information')
+                print('Please consult ecaccess documentation or ECMWF user \
+                       support for further details')
+                sys.exit(1)
+
+            if not self.flexpart_root_scripts:
+                self.flexpart_root_scripts = '${HOME}'
+            else:
+                self.flexpart_root_scripts = self.flexpart_root_scripts
+        else: # local
+            if not self.flexpart_root_scripts:
+                self.flexpart_root_scripts = _config.PATH_FLEXEXTRACT_DIR
+
+        return
+
+    def to_list(self):
+        '''
+        @Description:
+            Just generates a list of strings containing the attributes and
+            assigned values except the attributes "_expanded", "exedir",
+            "ecmwfdatadir" and "flexpart_root_scripts".
+
+        @Input:
+            self: instance of ControlFile class
+                Description see class documentation.
+
+        @Return:
+            l: list
+                A sorted list of the all ControlFile class attributes with
+                their values except the attributes "_expanded", "exedir",
+                "ecmwfdatadir" and "flexpart_root_scripts".
+        '''
+
+        import collections
+
+        attrs = collections.OrderedDict(sorted(vars(self).items()))
+
+        l = list()
+
+        for item in attrs.items():
+            if '_expanded' in item[0]:
+                pass
+            elif 'exedir' in item[0]:
+                pass
+            elif 'flexpart_root_scripts' in item[0]:
+                pass
+            elif 'ecmwfdatadir' in item[0]:
+                pass
+            else:
+                if isinstance(item[1], list):
+                    stot = ''
+                    for s in item[1]:
+                        stot += s + ' '
+
+                    l.append("%s %s" % (item[0], stot))
+                else:
+                    l.append("%s %s" % item)
+
+        return sorted(l)
+
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/python/classes/EcFlexpart.py b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/classes/EcFlexpart.py
new file mode 100644
index 0000000000000000000000000000000000000000..6f4fbaec9372c3f9b0ea550f46b7371da5431ecd
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/classes/EcFlexpart.py
@@ -0,0 +1,1296 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#*******************************************************************************
+# @Author: Anne Fouilloux (University of Oslo)
+#
+# @Date: October 2014
+#
+# @Change History:
+#
+#    November 2015 - Leopold Haimberger (University of Vienna):
+#        - extended with class Control
+#        - removed functions mkdir_p, daterange, years_between, months_between
+#        - added functions darain, dapoly, to_param_id, init128, normal_exit,
+#          my_error, clean_up, install_args_and_control,
+#          interpret_args_and_control,
+#        - removed function __del__ in class EIFLexpart
+#        - added the following functions in EIFlexpart:
+#            - create_namelist
+#            - process_output
+#            - deacc_fluxes
+#        - modified existing EIFlexpart - functions for the use in
+#          flex_extract
+#        - retrieve also longer term forecasts, not only analyses and
+#          short term forecast data
+#        - added conversion into GRIB2
+#        - added conversion into .fp format for faster execution of FLEXPART
+#          (see https://www.flexpart.eu/wiki/FpCtbtoWo4FpFormat)
+#
+#    February 2018 - Anne Philipp (University of Vienna):
+#        - applied PEP8 style guide
+#        - added documentation
+#        - removed function getFlexpartTime in class EcFlexpart
+#        - outsourced class ControlFile
+#        - outsourced class MarsRetrieval
+#        - changed class name from EIFlexpart to EcFlexpart
+#        - applied minor code changes (style)
+#        - removed "dead code" , e.g. retrieval of Q since it is not needed
+#        - removed "times" parameter from retrieve-method since it is not used
+#
+# @License:
+#    (C) Copyright 2014-2018.
+#
+#    This software is licensed under the terms of the Apache Licence Version 2.0
+#    which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+#
+# @Class Description:
+#    FLEXPART needs grib files in a specifc format. All necessary data fields
+#    for one time step are stored in a single file. The class represents an
+#    instance with all the parameter and settings necessary for retrieving
+#    MARS data and modifing them so they are fitting FLEXPART need. The class
+#    is able to disaggregate the fluxes and convert grid types to the one needed
+#    by FLEXPART, therefore using the FORTRAN program.
+#
+# @Class Content:
+#    - __init__
+#    - write_namelist
+#    - retrieve
+#    - process_output
+#    - create
+#    - deacc_fluxes
+#
+# @Class Attributes:
+#
+#  TODO
+#
+#*******************************************************************************
+#pylint: disable=unsupported-assignment-operation
+# this is disabled because for this specific case its an error in pylint
+#pylint: disable=consider-using-enumerate
+# this is not useful in this case
+# ------------------------------------------------------------------------------
+# MODULES
+# ------------------------------------------------------------------------------
+import subprocess
+import shutil
+import os
+import glob
+from datetime import datetime, timedelta
+import numpy as np
+from gribapi import grib_set, grib_index_select, grib_new_from_index, grib_get,\
+                    grib_write, grib_get_values, grib_set_values, grib_release,\
+                    grib_index_release, grib_index_get
+
+# software specific classes and modules from flex_extract
+import _config
+from GribTools import GribTools
+from mods.tools import init128, to_param_id, silent_remove, product, my_error
+from MarsRetrieval import MarsRetrieval
+import mods.disaggregation
+
+# ------------------------------------------------------------------------------
+# CLASS
+# ------------------------------------------------------------------------------
+class EcFlexpart(object):
+    '''
+    Class to retrieve FLEXPART specific ECMWF data.
+    '''
+    # --------------------------------------------------------------------------
+    # CLASS FUNCTIONS
+    # --------------------------------------------------------------------------
+    def __init__(self, c, fluxes=False):
+        '''
+        @Description:
+            Creates an object/instance of EcFlexpart with the
+            associated settings of its attributes for the retrieval.
+
+        @Input:
+            self: instance of EcFlexpart
+                The current object of the class.
+
+            c: instance of class ControlFile
+                Contains all the parameters of CONTROL file, which are e.g.:
+                DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
+                STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
+                LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
+                OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
+                ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
+                MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
+                DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+
+                For more information about format and content of the parameter
+                see documentation.
+
+            fluxes: boolean, optional
+                Decides if the flux parameter settings are stored or
+                the rest of the parameter list.
+                Default value is False.
+
+        @Return:
+            <nothing>
+        '''
+
+        # different mars types for retrieving data for flexpart
+        self.types = dict()
+
+        if c.maxstep > len(c.type):    # Pure forecast mode
+            c.type = [c.type[1]]
+            c.step = ['{:0>3}'.format(int(c.step[0]))]
+            c.time = [c.time[0]]
+            for i in range(1, c.maxstep + 1):
+                c.type.append(c.type[0])
+                c.step.append('{:0>3}'.format(i))
+                c.time.append(c.time[0])
+
+        self.inputdir = c.inputdir
+        self.basetime = c.basetime
+        self.dtime = c.dtime
+        i = 0
+        if fluxes and c.maxstep <= 24:
+            # no forecast beyond one day is needed!
+            # Thus, prepare flux data manually as usual
+            # with only forecast fields with start times at 00/12
+            # (but without 00/12 fields since these are
+            # the initialisation times of the flux fields
+            # and therefore are zero all the time)
+            self.types[c.type[1]] = {'times': '00/12', 'steps':
+                                     '{}/to/12/by/{}'.format(c.dtime, c.dtime)}
+        else:
+            for ty, st, ti in zip(c.type, c.step, c.time):
+                btlist = range(24)
+                if c.basetime == '12':
+                    btlist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
+                if c.basetime == '00':
+                    btlist = [13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 0]
+
+                if i % int(c.dtime) == 0 and (i in btlist or c.maxstep > 24):
+
+                    if ty not in self.types.keys():
+                        self.types[ty] = {'times': '', 'steps': ''}
+
+                    if ti not in self.types[ty]['times']:
+                        if self.types[ty]['times']:
+                            self.types[ty]['times'] += '/'
+                        self.types[ty]['times'] += ti
+
+                    if st not in self.types[ty]['steps']:
+                        if self.types[ty]['steps']:
+                            self.types[ty]['steps'] += '/'
+                        self.types[ty]['steps'] += st
+                i += 1
+
+        self.marsclass = c.marsclass
+        self.stream = c.stream
+        self.number = c.number
+        self.resol = c.resol
+        self.accuracy = c.accuracy
+        self.level = c.level
+        self.expver = c.expver
+        self.levelist = c.levelist
+        # for gaussian grid retrieval
+        self.glevelist = '1/to/' + c.level
+
+        if hasattr(c, 'gaussian') and c.gaussian:
+            self.gaussian = c.gaussian
+        else:
+            self.gaussian = ''
+
+        if 'N' in c.grid:  # Gaussian output grid
+            self.grid = c.grid
+            self.area = 'G'
+        else:
+            self.grid = '{}/{}'.format(int(c.grid) / 1000., int(c.grid) / 1000.)
+            self.area = '{}/{}/{}/{}'.format(int(c.upper) / 1000.,
+                                             int(c.left) / 1000.,
+                                             int(c.lower) / 1000.,
+                                             int(c.right) / 1000.)
+
+        self.outputfilelist = []
+
+
+        # Now comes the nasty part that deals with the different
+        # scenarios we have:
+        # 1) Calculation of etadot on
+        #    a) Gaussian grid
+        #    b) Output grid
+        #    c) Output grid using parameter 77 retrieved from MARS
+        # 3) Calculation/Retrieval of omega
+        # 4) Download also data for WRF
+
+        # Different grids need different retrievals
+        # SH = Spherical Harmonics, GG = Gaussian Grid,
+        # OG = Output Grid, ML = MultiLevel, SL = SingleLevel
+        self.params = {'SH__ML': '', 'SH__SL': '',
+                       'GG__ML': '', 'GG__SL': '',
+                       'OG__ML': '', 'OG__SL': '',
+                       'OG_OROLSM_SL': '', 'OG_acc_SL': ''}
+
+        if fluxes is False:
+            self.params['SH__SL'] = ['LNSP', 'ML', '1', 'OFF']
+            #                        "SD/MSL/TCC/10U/10V/2T/2D/129/172"
+            self.params['OG__SL'] = ["141/151/164/165/166/167/168/129/172", \
+                                     'SFC', '1', self.grid]
+            if c.addpar:
+                if c.addpar[0] == '/':
+                    c.addpar = c.addpar[1:]
+                self.params['OG__SL'][0] += '/' + '/'.join(c.addpar)
+
+            self.params['OG_OROLSM__SL'] = ["160/27/28/173", \
+                                            'SFC', '1', self.grid]
+
+            self.params['OG__ML'] = ['T/Q', 'ML', self.levelist, self.grid]
+
+            #if c.gauss == '0' and c.eta == '1':
+            if not c.gauss and c.eta:
+                # the simplest case
+                self.params['OG__ML'][0] += '/U/V/77'
+            #elif c.gauss == '0' and c.eta == '0':
+            elif not c.gauss and not c.eta:
+            # this is not recommended (inaccurate)
+                self.params['OG__ML'][0] += '/U/V'
+            #elif c.gauss == '1' and c.eta == '0':
+            elif c.gauss and not c.eta:
+                # this is needed for data before 2008, or for reanalysis data
+                self.params['GG__SL'] = ['Q', 'ML', '1', \
+                                         '{}'.format((int(self.resol) + 1) / 2)]
+                self.params['SH__ML'] = ['U/V/D', 'ML', self.glevelist, 'OFF']
+            else:
+                print('Warning: This is a very costly parameter combination, \
+                      use only for debugging!')
+                self.params['GG__SL'] = ['Q', 'ML', '1', \
+                                         '{}'.format((int(self.resol) + 1) / 2)]
+                self.params['GG__ML'] = ['U/V/D/77', 'ML', self.glevelist, \
+                                         '{}'.format((int(self.resol) + 1) / 2)]
+
+            if c.omega:
+                self.params['OG__ML'][0] += '/W'
+
+            # add cloud water content if necessary
+            if c.cwc:
+                self.params['OG__ML'][0] += '/CLWC/CIWC'
+
+            # add vorticity and geopotential height for WRF if necessary
+            if c.wrf:
+                self.params['OG__ML'][0] += '/Z/VO'
+                if '/D' not in self.params['OG__ML'][0]:
+                    self.params['OG__ML'][0] += '/D'
+                #wrf_sfc = 'sp/msl/skt/2t/10u/10v/2d/z/lsm/sst/ci/sd/stl1/ /
+                #           stl2/stl3/stl4/swvl1/swvl2/swvl3/swvl4'.upper()
+                wrf_sfc = '134/235/167/165/166/168/129/172/34/31/141/ \
+                           139/170/183/236/39/40/41/42'.upper()
+                lwrt_sfc = wrf_sfc.split('/')
+                for par in lwrt_sfc:
+                    if par not in self.params['OG__SL'][0]:
+                        self.params['OG__SL'][0] += '/' + par
+
+        else:
+            self.params['OG_acc_SL'] = ["LSP/CP/SSHF/EWSS/NSSS/SSR", \
+                                        'SFC', '1', self.grid]
+
+        # if needed, add additional WRF specific parameters here
+
+        return
+
+
+    def write_namelist(self, c, filename):
+        '''
+        @Description:
+            Creates a namelist file in the temporary directory and writes
+            the following values to it: maxl, maxb, mlevel,
+            mlevelist, mnauf, metapar, rlo0, rlo1, rla0, rla1,
+            momega, momegadiff, mgauss, msmooth, meta, metadiff, mdpdeta
+
+        @Input:
+            self: instance of EcFlexpart
+                The current object of the class.
+
+            c: instance of class ControlFile
+                Contains all the parameters of CONTROL files, which are e.g.:
+                DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
+                STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
+                LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
+                OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
+                ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
+                MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
+                DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+
+                For more information about format and content of the parameter
+                see documentation.
+
+            filename: string
+                Name of the namelist file.
+
+        @Return:
+            <nothing>
+        '''
+
+        self.inputdir = c.inputdir
+        area = np.asarray(self.area.split('/')).astype(float)
+        grid = np.asarray(self.grid.split('/')).astype(float)
+
+        if area[1] > area[3]:
+            area[1] -= 360
+        maxl = int((area[3] - area[1]) / grid[1]) + 1
+        maxb = int((area[0] - area[2]) / grid[0]) + 1
+
+        with open(self.inputdir + '/' + filename, 'w') as f:
+            f.write('&NAMGEN\n')
+            f.write(',\n  '.join(['maxl = ' + str(maxl), 'maxb = ' + str(maxb),
+                                  'mlevel = ' + str(self.level),
+                                  'mlevelist = ' + '"' + str(self.levelist)
+                                                 + '"',
+                                  'mnauf = ' + str(self.resol),
+                                  'metapar = ' + '77',
+                                  'rlo0 = ' + str(area[1]),
+                                  'rlo1 = ' + str(area[3]),
+                                  'rla0 = ' + str(area[2]),
+                                  'rla1 = ' + str(area[0]),
+                                  'momega = ' + str(c.omega),
+                                  'momegadiff = ' + str(c.omegadiff),
+                                  'mgauss = ' + str(c.gauss),
+                                  'msmooth = ' + str(c.smooth),
+                                  'meta = ' + str(c.eta),
+                                  'metadiff = ' + str(c.etadiff),
+                                  'mdpdeta = ' + str(c.dpdeta)]))
+
+            f.write('\n/\n')
+
+        return
+
+    def retrieve(self, server, dates, request, inputdir='.'):
+        '''
+        @Description:
+            Finalizing the retrieval information by setting final details
+            depending on grid type.
+            Prepares MARS retrievals per grid type and submits them.
+
+        @Input:
+            self: instance of EcFlexpart
+                The current object of the class.
+
+            server: instance of ECMWFService or ECMWFDataServer
+                The connection to the ECMWF server. This is different
+                for member state users which have full access and non
+                member state users which have only access to the public
+                data sets. The decision is made from command line argument
+                "public"; for public access its True (ECMWFDataServer)
+                for member state users its False (ECMWFService)
+
+            dates: string
+                Contains start and end date of the retrieval in the format
+                "YYYYMMDD/to/YYYYMMDD"
+
+            inputdir: string, optional
+                Path to the directory where the retrieved data is about
+                to be stored. The default is the current directory ('.').
+
+        @Return:
+            <nothing>
+        '''
+        self.dates = dates
+        self.server = server
+        self.inputdir = inputdir
+        oro = False
+
+        for ftype in self.types:
+            for pk, pv in self.params.iteritems():
+                if isinstance(pv, str):
+                    continue
+                mftype = '' + ftype
+                mftime = self.types[ftype]['times']
+                mfstep = self.types[ftype]['steps']
+                mfdate = self.dates
+                mfstream = self.stream
+                mftarget = self.inputdir + "/" + ftype + pk + '.' + \
+                           self.dates.split('/')[0] + '.' + str(os.getppid()) +\
+                           '.' + str(os.getpid()) + ".grb"
+                if pk == 'OG__SL':
+                    pass
+                if pk == 'OG_OROLSM__SL':
+                    if not oro:
+                        mfstream = 'OPER'
+                        mftype = 'AN'
+                        mftime = '00'
+                        mfstep = '000'
+                        mfdate = self.dates.split('/')[0]
+                        mftarget = self.inputdir + "/" + pk + '.' + mfdate + \
+                                   '.' + str(os.getppid()) + '.' + \
+                                   str(os.getpid()) + ".grb"
+                        oro = True
+                    else:
+                        continue
+                if pk == 'GG__SL' and pv[0] == 'Q':
+                    area = ""
+                    gaussian = 'reduced'
+                else:
+                    area = self.area
+                    gaussian = self.gaussian
+
+    # ------  on demand path  --------------------------------------------------
+                if not self.basetime:
+                    MR = MarsRetrieval(self.server,
+                                       marsclass=self.marsclass,
+                                       stream=mfstream,
+                                       type=mftype,
+                                       levtype=pv[1],
+                                       levelist=pv[2],
+                                       resol=self.resol,
+                                       gaussian=gaussian,
+                                       accuracy=self.accuracy,
+                                       grid=pv[3],
+                                       target=mftarget,
+                                       area=area,
+                                       date=mfdate,
+                                       time=mftime,
+                                       number=self.number,
+                                       step=mfstep,
+                                       expver=self.expver,
+                                       param=pv[0])
+
+                    if request == 0:
+                        MR.display_info()
+                        MR.data_retrieve()
+                    elif request == 1:
+                        MR.print_info(self.inputdir)
+                    elif request == 2:
+                        MR.print_info(self.inputdir)
+                        MR.display_info()
+                        MR.data_retrieve()
+                    else:
+                        print('Failure')
+    # ------  operational path  ------------------------------------------------
+                else:
+                    # check if mars job requests fields beyond basetime.
+                    # If yes eliminate those fields since they may not
+                    # be accessible with user's credentials
+                    if 'by' in mfstep:
+                        sm1 = 2
+                    else:
+                        sm1 = -1
+
+                    if 'by' in mftime:
+                        tm1 = 2
+                    else:
+                        tm1 = -1
+
+                    maxdate = datetime.strptime(mfdate.split('/')[-1] +
+                                                mftime.split('/')[tm1],
+                                                '%Y%m%d%H')
+                    istep = int(mfstep.split('/')[sm1])
+                    maxtime = maxdate + timedelta(hours=istep)
+
+                    elimit = datetime.strptime(mfdate.split('/')[-1] +
+                                               self.basetime, '%Y%m%d%H')
+
+                    if self.basetime == '12':
+                        # --------------  flux data ----------------------------
+                        if 'acc' in pk:
+
+                        # Strategy:
+                        # if maxtime-elimit >= 24h reduce date by 1,
+                        # if 12h <= maxtime-elimit<12h reduce time for last date
+                        # if maxtime-elimit<12h reduce step for last time
+                        # A split of the MARS job into 2 is likely necessary.
+                            maxtime = elimit - timedelta(hours=24)
+                            mfdate = '/'.join(['/'.join(mfdate.split('/')[:-1]),
+                                               datetime.strftime(maxtime,
+                                                                 '%Y%m%d')])
+
+                            MR = MarsRetrieval(self.server,
+                                               marsclass=self.marsclass,
+                                               stream=self.stream,
+                                               type=mftype,
+                                               levtype=pv[1],
+                                               levelist=pv[2],
+                                               resol=self.resol,
+                                               gaussian=gaussian,
+                                               accuracy=self.accuracy,
+                                               grid=pv[3],
+                                               target=mftarget,
+                                               area=area,
+                                               date=mfdate,
+                                               time=mftime,
+                                               number=self.number,
+                                               step=mfstep,
+                                               expver=self.expver,
+                                               param=pv[0])
+
+                            MR.display_info()
+                            MR.data_retrieve()
+
+                            maxtime = elimit - timedelta(hours=12)
+                            mfdate = datetime.strftime(maxtime, '%Y%m%d')
+                            mftime = '00'
+                            mftarget = self.inputdir + "/" + ftype + pk + \
+                                       '.' + mfdate + '.' + str(os.getppid()) +\
+                                       '.' + str(os.getpid()) + ".grb"
+
+                            MR = MarsRetrieval(self.server,
+                                               marsclass=self.marsclass,
+                                               stream=self.stream,
+                                               type=mftype,
+                                               levtype=pv[1],
+                                               levelist=pv[2],
+                                               resol=self.resol,
+                                               gaussian=gaussian,
+                                               accuracy=self.accuracy,
+                                               grid=pv[3],
+                                               target=mftarget,
+                                               area=area,
+                                               date=mfdate,
+                                               time=mftime,
+                                               number=self.number,
+                                               step=mfstep,
+                                               expver=self.expver,
+                                               param=pv[0])
+
+                            MR.display_info()
+
+                            MR.data_retrieve()
+                        # --------------  non flux data ------------------------
+                        else:
+                            MR = MarsRetrieval(self.server,
+                                               marsclass=self.marsclass,
+                                               stream=self.stream,
+                                               type=mftype,
+                                               levtype=pv[1],
+                                               levelist=pv[2],
+                                               resol=self.resol,
+                                               gaussian=gaussian,
+                                               accuracy=self.accuracy,
+                                               grid=pv[3],
+                                               target=mftarget,
+                                               area=area,
+                                               date=mfdate,
+                                               time=mftime,
+                                               number=self.number,
+                                               step=mfstep,
+                                               expver=self.expver,
+                                               param=pv[0])
+
+                            MR.display_info()
+                            MR.data_retrieve()
+                    else: # basetime == 0 ??? #AP
+
+                        maxtime = elimit - timedelta(hours=24)
+                        mfdate = datetime.strftime(maxtime, '%Y%m%d')
+                        mftimesave = ''.join(mftime)
+
+                        if '/' in mftime:
+                            times = mftime.split('/')
+                            while ((int(times[0]) +
+                                    int(mfstep.split('/')[0]) <= 12) and
+                                   (pk != 'OG_OROLSM__SL') and 'acc' not in pk):
+                                times = times[1:]
+                            if len(times) > 1:
+                                mftime = '/'.join(times)
+                            else:
+                                mftime = times[0]
+
+                        MR = MarsRetrieval(self.server,
+                                           marsclass=self.marsclass,
+                                           stream=self.stream,
+                                           type=mftype,
+                                           levtype=pv[1],
+                                           levelist=pv[2],
+                                           resol=self.resol,
+                                           gaussian=gaussian,
+                                           accuracy=self.accuracy,
+                                           grid=pv[3],
+                                           target=mftarget,
+                                           area=area,
+                                           date=mfdate,
+                                           time=mftime,
+                                           number=self.number,
+                                           step=mfstep,
+                                           expver=self.expver,
+                                           param=pv[0])
+
+                        MR.display_info()
+                        MR.data_retrieve()
+
+                        if (int(mftimesave.split('/')[0]) == 0 and
+                                int(mfstep.split('/')[0]) == 0 and
+                                pk != 'OG_OROLSM__SL'):
+
+                            mfdate = datetime.strftime(elimit, '%Y%m%d')
+                            mftime = '00'
+                            mfstep = '000'
+                            mftarget = self.inputdir + "/" + ftype + pk + \
+                                       '.' + mfdate + '.' + str(os.getppid()) +\
+                                       '.' + str(os.getpid()) + ".grb"
+
+                            MR = MarsRetrieval(self.server,
+                                               marsclass=self.marsclass,
+                                               stream=self.stream,
+                                               type=mftype,
+                                               levtype=pv[1],
+                                               levelist=pv[2],
+                                               resol=self.resol,
+                                               gaussian=gaussian,
+                                               accuracy=self.accuracy,
+                                               grid=pv[3],
+                                               target=mftarget,
+                                               area=area,
+                                               date=mfdate,
+                                               time=mftime,
+                                               number=self.number,
+                                               step=mfstep,
+                                               expver=self.expver,
+                                               param=pv[0])
+
+                            MR.display_info()
+                            MR.data_retrieve()
+
+        if request == 0 or request == 2:
+            print('MARS retrieve done ... ')
+        elif request == 1:
+            print('MARS request printed ...')
+
+        return
+
+
+    def process_output(self, c):
+        '''
+        @Description:
+            The grib files are postprocessed depending on the selection in
+            CONTROL file. The resulting files are moved to the output
+            directory if its not equla to the input directory.
+            The following modifications might be done if
+            properly switched in CONTROL file:
+            GRIB2 - Conversion to GRIB2
+            ECTRANS - Transfer of files to gateway server
+            ECSTORAGE - Storage at ECMWF server
+            GRIB2FLEXPART - Conversion of GRIB files to FLEXPART binary format
+
+        @Input:
+            self: instance of EcFlexpart
+                The current object of the class.
+
+            c: instance of class ControlFile
+                Contains all the parameters of CONTROL file, which are e.g.:
+                DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
+                STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
+                LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
+                OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
+                ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
+                MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
+                DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+
+                For more information about format and content of the parameter
+                see documentation.
+
+        @Return:
+            <nothing>
+
+        '''
+
+        print('\n\nPostprocessing:\n Format: {}\n'.format(c.format))
+
+        if not c.ecapi:
+            print('ecstorage: {}\n ecfsdir: {}\n'.
+                  format(c.ecstorage, c.ecfsdir))
+            #if not hasattr(c, 'gateway'):
+            #    c.gateway = os.getenv('GATEWAY')
+            #if not hasattr(c, 'destination'):
+            #    c.destination = os.getenv('DESTINATION')
+            print('ectrans: {}\n gateway: {}\n destination: {}\n '
+                  .format(c.ectrans, c.gateway, c.destination))
+
+        print('Output filelist: \n')
+        print(self.outputfilelist)
+
+        if c.format.lower() == 'grib2':
+            for ofile in self.outputfilelist:
+                p = subprocess.check_call(['grib_set', '-s', 'edition=2, \
+                                           productDefinitionTemplateNumber=8',
+                                           ofile, ofile + '_2'])
+                p = subprocess.check_call(['mv', ofile + '_2', ofile])
+
+        if c.ectrans and not c.ecapi:
+            for ofile in self.outputfilelist:
+                p = subprocess.check_call(['ectrans', '-overwrite', '-gateway',
+                                           c.gateway, '-remote', c.destination,
+                                           '-source', ofile])
+                #print('ectrans:', p)
+
+        if c.ecstorage and not c.ecapi:
+            for ofile in self.outputfilelist:
+                p = subprocess.check_call(['ecp', '-o', ofile,
+                                           os.path.expandvars(c.ecfsdir)])
+
+        if c.outputdir != c.inputdir:
+            for ofile in self.outputfilelist:
+                p = subprocess.check_call(['mv', ofile, c.outputdir])
+
+        # prepare environment for the grib2flexpart run
+        # to convert grib to flexpart binary
+        if c.grib2flexpart:
+
+            # generate AVAILABLE file
+            # Example of AVAILABLE file data:
+            # 20131107 000000      EN13110700              ON DISC
+            clist = []
+            for ofile in self.outputfilelist:
+                fname = ofile.split('/')
+                if '.' in fname[-1]:
+                    l = fname[-1].split('.')
+                    timestamp = datetime.strptime(l[0][-6:] + l[1],
+                                                  '%y%m%d%H')
+                    timestamp += timedelta(hours=int(l[2]))
+                    cdate = datetime.strftime(timestamp, '%Y%m%d')
+                    chms = datetime.strftime(timestamp, '%H%M%S')
+                else:
+                    cdate = '20' + fname[-1][-8:-2]
+                    chms = fname[-1][-2:] + '0000'
+                clist.append(cdate + ' ' + chms + ' '*6 +
+                             fname[-1] + ' '*14 + 'ON DISC')
+            clist.sort()
+            with open(c.outputdir + '/' + 'AVAILABLE', 'w') as f:
+                f.write('\n'.join(clist) + '\n')
+
+            # generate pathnames file
+            pwd = os.path.abspath(c.outputdir)
+            with open(pwd + '/pathnames', 'w') as f:
+                f.write(pwd + '/Options/\n')
+                f.write(pwd + '/\n')
+                f.write(pwd + '/\n')
+                f.write(pwd + '/AVAILABLE\n')
+                f.write(' = == = == = == = == = == ==  = \n')
+
+            # create Options dir if necessary
+            if not os.path.exists(pwd + '/Options'):
+                os.makedirs(pwd+'/Options')
+
+            # read template COMMAND file
+            with open(os.path.expandvars(os.path.expanduser(
+                c.flexpart_root_scripts)) + '/../Options/COMMAND', 'r') as f:
+                lflist = f.read().split('\n')
+
+            # find index of list where to put in the
+            # date and time information
+            # usually after the LDIRECT parameter
+            i = 0
+            for l in lflist:
+                if 'LDIRECT' in l.upper():
+                    break
+                i += 1
+
+            # insert the date and time information of run start and end
+            # into the list of lines of COMMAND file
+            lflist = lflist[:i+1] + \
+                     [clist[0][:16], clist[-1][:16]] + \
+                     lflist[i+3:]
+
+            # write the new COMMAND file
+            with open(pwd + '/Options/COMMAND', 'w') as g:
+                g.write('\n'.join(lflist) + '\n')
+
+            # change to outputdir and start the grib2flexpart run
+            # afterwards switch back to the working dir
+            os.chdir(c.outputdir)
+            p = subprocess.check_call([
+                os.path.expandvars(os.path.expanduser(c.flexpart_root_scripts))
+                + '/../FLEXPART_PROGRAM/grib2flexpart', 'useAvailable', '.'])
+            os.chdir(pwd)
+
+        return
+
+    def create(self, inputfiles, c):
+        '''
+        @Description:
+            This method is based on the ECMWF example index.py
+            https://software.ecmwf.int/wiki/display/GRIB/index.py
+
+            An index file will be created which depends on the combination
+            of "date", "time" and "stepRange" values. This is used to iterate
+            over all messages in each grib file which were passed through the
+            parameter "inputfiles" to seperate specific parameters into fort.*
+            files. Afterwards the FORTRAN program Convert2 is called to convert
+            the data fields all to the same grid and put them in one file
+            per unique time step (combination of "date", "time" and
+            "stepRange").
+
+        @Input:
+            self: instance of EcFlexpart
+                The current object of the class.
+
+            inputfiles: instance of UioFiles
+                Contains a list of files.
+
+            c: instance of class ControlFile
+                Contains all the parameters of CONTROL files, which are e.g.:
+                DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
+                STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
+                LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
+                OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
+                ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
+                MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
+                DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+
+                For more information about format and content of the parameter
+                see documentation.
+
+        @Return:
+            <nothing>
+        '''
+
+        table128 = init128(_config.PATH_GRIBTABLE)
+        wrfpars = to_param_id('sp/mslp/skt/2t/10u/10v/2d/z/lsm/sst/ci/sd/\
+                            stl1/stl2/stl3/stl4/swvl1/swvl2/swvl3/swvl4',
+                            table128)
+
+        index_keys = ["date", "time", "step"]
+        indexfile = os.path.join(c.inputdir, _config.FILE_GRIB_INDEX)
+        silent_remove(indexfile)
+        grib = GribTools(inputfiles.files)
+        # creates new index file
+        iid = grib.index(index_keys=index_keys, index_file=indexfile)
+
+        # read values of index keys
+        index_vals = []
+        for key in index_keys:
+            index_vals.append(grib_index_get(iid, key))
+            print(index_vals[-1])
+            # index_vals looks for example like:
+            # index_vals[0]: ('20171106', '20171107', '20171108') ; date
+            # index_vals[1]: ('0', '1200', '1800', '600') ; time
+            # index_vals[2]: ('0', '12', '3', '6', '9') ; stepRange
+
+        fdict = {'10':None, '11':None, '12':None, '13':None, '16':None,
+                 '17':None, '19':None, '21':None, '22':None, '20':None}
+
+        for prod in product(*index_vals):
+            # e.g. prod = ('20170505', '0', '12')
+            #             (  date    ,time, step)
+            # per date e.g. time = 0, 1200
+            # per time e.g. step = 3, 6, 9, 12
+            # flag for Fortran program CONVERT2 and file merging
+            convertFlag = False
+            print('current prod: ', prod)
+            # e.g. prod = ('20170505', '0', '12')
+            #             (  date    ,time, step)
+            # per date e.g. time = 0, 600, 1200, 1800
+            # per time e.g. step = 0, 3, 6, 9, 12
+            for i in range(len(index_keys)):
+                grib_index_select(iid, index_keys[i], prod[i])
+
+            # get first id from current product
+            gid = grib_new_from_index(iid)
+
+            # if there is data for this product combination
+            # prepare some date and time parameter before reading the data
+            if gid is not None:
+                # Combine all temporary data files into final grib file if
+                # gid is at least one time not None. Therefore set convertFlag
+                # to save information. The fortran program CONVERT2 is also
+                # only done if convertFlag is True
+                convertFlag = True
+                # remove old fort.* files and open new ones
+                # they are just valid for a single product
+                for k, f in fdict.iteritems():
+                    fortfile = os.path.join(c.inputdir, 'fort.' + k)
+                    silent_remove(fortfile)
+                    fdict[k] = open(fortfile, 'w')
+
+                cdate = str(grib_get(gid, 'date'))
+                time = grib_get(gid, 'time')
+                step = grib_get(gid, 'step')
+                # create correct timestamp from the three time informations
+                # date, time, step
+                timestamp = datetime.strptime(cdate + '{:0>2}'.format(time/100),
+                                              '%Y%m%d%H')
+                timestamp += timedelta(hours=int(step))
+                cdateH = datetime.strftime(timestamp, '%Y%m%d%H')
+
+                if c.basetime is not None:
+                    slimit = datetime.strptime(c.start_date + '00', '%Y%m%d%H')
+                    bt = '23'
+                    if c.basetime == '00':
+                        bt = '00'
+                        slimit = datetime.strptime(c.end_date + bt, '%Y%m%d%H')\
+                            - timedelta(hours=12-int(c.dtime))
+                    if c.basetime == '12':
+                        bt = '12'
+                        slimit = datetime.strptime(c.end_date + bt, '%Y%m%d%H')\
+                            - timedelta(hours=12-int(c.dtime))
+
+                    elimit = datetime.strptime(c.end_date + bt, '%Y%m%d%H')
+
+                    if timestamp < slimit or timestamp > elimit:
+                        continue
+            else:
+                pass
+
+            try:
+                if c.wrf:
+                    if 'olddate' not in locals() or cdate != olddate:
+                        fwrf = open(os.path.join(c.outputdir,
+                                    'WRF' + cdate + '.{:0>2}'.format(time) +
+                                    '.000.grb2'), 'w')
+                        olddate = cdate[:]
+            except AttributeError:
+                pass
+
+            # helper variable to remember which fields were already used.
+            savedfields = []
+            while 1:
+                if gid is None:
+                    break
+                paramId = grib_get(gid, 'paramId')
+                gridtype = grib_get(gid, 'gridType')
+                levtype = grib_get(gid, 'typeOfLevel')
+                if paramId == 133 and gridtype == 'reduced_gg':
+                # Specific humidity (Q.grb) is used as a template only
+                # so we need the first we "meet"
+                    with open(os.path.join(c.inputdir, 'fort.18'), 'w') as fout:
+                        grib_write(gid, fout)
+                elif paramId == 131 or paramId == 132:
+                    grib_write(gid, fdict['10'])
+                elif paramId == 130:
+                    grib_write(gid, fdict['11'])
+                elif paramId == 133 and gridtype != 'reduced_gg':
+                    grib_write(gid, fdict['17'])
+                elif paramId == 152:
+                    grib_write(gid, fdict['12'])
+                elif paramId == 155 and gridtype == 'sh':
+                    grib_write(gid, fdict['13'])
+                elif  paramId in [129, 138, 155] and levtype == 'hybrid' \
+                        and c.wrf:
+                    pass
+                elif paramId == 246 or paramId == 247:
+                    # cloud liquid water and ice
+                    if paramId == 246:
+                        clwc = grib_get_values(gid)
+                    else:
+                        clwc += grib_get_values(gid)
+                        grib_set_values(gid, clwc)
+                        grib_set(gid, 'paramId', 201031)
+                        grib_write(gid, fdict['22'])
+                elif paramId == 135:
+                    grib_write(gid, fdict['19'])
+                elif paramId == 77:
+                    grib_write(gid, fdict['21'])
+                else:
+                    if paramId not in savedfields:
+                        grib_write(gid, fdict['16'])
+                        savedfields.append(paramId)
+                    else:
+                        print('duplicate ' + str(paramId) + ' not written')
+
+                try:
+                    if c.wrf:
+                        # model layer
+                        if levtype == 'hybrid' and \
+                           paramId in [129, 130, 131, 132, 133, 138, 155]:
+                            grib_write(gid, fwrf)
+                        # sfc layer
+                        elif paramId in wrfpars:
+                            grib_write(gid, fwrf)
+                except AttributeError:
+                    pass
+
+                grib_release(gid)
+                gid = grib_new_from_index(iid)
+
+            for f in fdict.values():
+                f.close()
+
+            # call for CONVERT2 if flag is True
+            if convertFlag:
+                pwd = os.getcwd()
+                os.chdir(c.inputdir)
+                if os.stat('fort.21').st_size == 0 and c.eta:
+                    print('Parameter 77 (etadot) is missing, most likely it is \
+                           not available for this type or date/time\n')
+                    print('Check parameters CLASS, TYPE, STREAM, START_DATE\n')
+                    my_error(c.mailfail, 'fort.21 is empty while parameter eta \
+                             is set to 1 in CONTROL file')
+
+                # create the corresponding output file fort.15
+                # (generated by CONVERT2) + fort.16 (paramId 167 and 168)
+                p = subprocess.check_call([os.path.join(c.exedir, 'CONVERT2')],
+                                          shell=True)
+                os.chdir(pwd)
+
+                # create final output filename, e.g. EN13040500 (ENYYMMDDHH)
+                fnout = os.path.join(c.inputdir, c.prefix)
+                if c.maxstep > 12:
+                    suffix = cdate[2:8] + '.{:0>2}'.format(time/100) + \
+                             '.{:0>3}'.format(step)
+                else:
+                    suffix = cdateH[2:10]
+                fnout += suffix
+                print("outputfile = " + fnout)
+                self.outputfilelist.append(fnout) # needed for final processing
+
+                # create outputfile and copy all data from intermediate files
+                # to the outputfile (final GRIB files)
+                orolsm = os.path.basename(glob.glob(
+                    c.inputdir + '/OG_OROLSM__SL.*.' + c.ppid + '*')[0])
+                fluxfile = 'flux' + cdate[0:2] + suffix
+                if not c.cwc:
+                    flist = ['fort.15', fluxfile, 'fort.16', orolsm]
+                else:
+                    flist = ['fort.15', 'fort.22', fluxfile, 'fort.16', orolsm]
+
+                with open(fnout, 'wb') as fout:
+                    for f in flist:
+                        shutil.copyfileobj(open(os.path.join(c.inputdir, f),
+                                                'rb'), fout)
+
+                if c.omega:
+                    with open(os.path.join(c.outputdir, 'OMEGA'), 'wb') as fout:
+                        shutil.copyfileobj(
+                            open(os.path.join(c.inputdir, 'fort.25'),
+                                 'rb'), fout)
+            else:
+                pass
+
+        if c.wrf:
+            fwrf.close()
+
+        grib_index_release(iid)
+
+        return
+
+    def deacc_fluxes(self, inputfiles, c):
+        '''
+        @Description:
+            Goes through all flux fields in ordered time and de-accumulate
+            the fields. Afterwards the fields are disaggregated in time.
+            Different versions of disaggregation is provided for rainfall
+            data (darain, modified linear) and the surface fluxes and
+            stress data (dapoly, cubic polynomial).
+
+        @Input:
+            self: instance of EcFlexpart
+                The current object of the class.
+
+            inputfiles: instance of UioFiles
+                Contains a list of files.
+
+            c: instance of class ControlFile
+                Contains all the parameters of CONTROL file, which are e.g.:
+                DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
+                STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
+                LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
+                OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
+                ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
+                MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
+                DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+
+                For more information about format and content of the parameter
+                see documentation.
+
+        @Return:
+            <nothing>
+        '''
+
+        table128 = init128(_config.PATH_GRIBTABLE)
+        pars = to_param_id(self.params['OG_acc_SL'][0], table128)
+        index_keys = ["date", "time", "step"]
+        indexfile = os.path.join(c.inputdir, _config.FILE_GRIB_INDEX)
+        silent_remove(indexfile)
+        grib = GribTools(inputfiles.files)
+        # creates new index file
+        iid = grib.index(index_keys=index_keys, index_file=indexfile)
+
+        # read values of index keys
+        index_vals = []
+        for key in index_keys:
+            key_vals = grib_index_get(iid, key)
+            print(key_vals)
+            # have to sort the steps for disaggregation,
+            # therefore convert to int first
+            if key == 'step':
+                key_vals = [int(k) for k in key_vals]
+                key_vals.sort()
+                key_vals = [str(k) for k in key_vals]
+            index_vals.append(key_vals)
+            # index_vals looks for example like:
+            # index_vals[0]: ('20171106', '20171107', '20171108') ; date
+            # index_vals[1]: ('0', '1200') ; time
+            # index_vals[2]: (3', '6', '9', '12') ; stepRange
+
+        valsdict = {}
+        svalsdict = {}
+        stepsdict = {}
+        for p in pars:
+            valsdict[str(p)] = []
+            svalsdict[str(p)] = []
+            stepsdict[str(p)] = []
+
+        print('maxstep: ', c.maxstep)
+
+        for prod in product(*index_vals):
+            # e.g. prod = ('20170505', '0', '12')
+            #             (  date    ,time, step)
+            # per date e.g. time = 0, 1200
+            # per time e.g. step = 3, 6, 9, 12
+            print('current prod: ', prod)
+            for i in range(len(index_keys)):
+                grib_index_select(iid, index_keys[i], prod[i])
+
+            # get first id from current product
+            gid = grib_new_from_index(iid)
+
+            # if there is data for this product combination
+            # prepare some date and time parameter before reading the data
+            if gid is not None:
+                cdate = grib_get(gid, 'date')
+                time = grib_get(gid, 'time')
+                step = grib_get(gid, 'step')
+                # date+time+step-2*dtime
+                # (since interpolated value valid for step-2*dtime)
+                sdate = datetime(year=cdate/10000,
+                                 month=(cdate % 10000)/100,
+                                 day=(cdate % 100),
+                                 hour=time/100)
+                fdate = sdate + timedelta(hours=step-2*int(c.dtime))
+                sdates = sdate + timedelta(hours=step)
+                elimit = None
+            else:
+                break
+
+            if c.maxstep > 12:
+                fnout = os.path.join(c.inputdir, 'flux' +
+                                     sdate.strftime('%Y%m%d') +
+                                     '.{:0>2}'.format(time/100) +
+                                     '.{:0>3}'.format(step-2*int(c.dtime)))
+                gnout = os.path.join(c.inputdir, 'flux' +
+                                     sdate.strftime('%Y%m%d') +
+                                     '.{:0>2}'.format(time/100) +
+                                     '.{:0>3}'.format(step-int(c.dtime)))
+                hnout = os.path.join(c.inputdir, 'flux' +
+                                     sdate.strftime('%Y%m%d') +
+                                     '.{:0>2}'.format(time/100) +
+                                     '.{:0>3}'.format(step))
+            else:
+                fnout = os.path.join(c.inputdir, 'flux' +
+                                     fdate.strftime('%Y%m%d%H'))
+                gnout = os.path.join(c.inputdir, 'flux' +
+                                     (fdate + timedelta(hours=int(c.dtime))).
+                                     strftime('%Y%m%d%H'))
+                hnout = os.path.join(c.inputdir, 'flux' +
+                                     sdates.strftime('%Y%m%d%H'))
+
+            print("outputfile = " + fnout)
+            f_handle = open(fnout, 'w')
+            g_handle = open(gnout, 'w')
+            h_handle = open(hnout, 'w')
+
+            # read message for message and store relevant data fields
+            # data keywords are stored in pars
+            while 1:
+                if gid is None:
+                    break
+                cparamId = str(grib_get(gid, 'paramId'))
+                step = grib_get(gid, 'step')
+                atime = grib_get(gid, 'time')
+                ni = grib_get(gid, 'Ni')
+                nj = grib_get(gid, 'Nj')
+                if cparamId in valsdict.keys():
+                    values = grib_get_values(gid)
+                    vdp = valsdict[cparamId]
+                    svdp = svalsdict[cparamId]
+                    sd = stepsdict[cparamId]
+
+                    if cparamId == '142' or cparamId == '143':
+                        fak = 1. / 1000.
+                    else:
+                        fak = 3600.
+
+                    values = (np.reshape(values, (nj, ni))).flatten() / fak
+                    vdp.append(values[:])  # save the accumulated values
+                    if step <= int(c.dtime):
+                        svdp.append(values[:] / int(c.dtime))
+                    else:  # deaccumulate values
+                        svdp.append((vdp[-1] - vdp[-2]) / int(c.dtime))
+
+                    print(cparamId, atime, step, len(values),
+                          values[0], np.std(values))
+                    # save the 1/3-hourly or specific values
+                    # svdp.append(values[:])
+                    sd.append(step)
+                    # len(svdp) correspond to the time
+                    if len(svdp) >= 3:
+                        if len(svdp) > 3:
+                            if cparamId == '142' or cparamId == '143':
+                                values = disaggregation.darain(svdp)
+                            else:
+                                values = disaggregation.dapoly(svdp)
+
+                            if not (step == c.maxstep and c.maxstep > 12 \
+                                    or sdates == elimit):
+                                vdp.pop(0)
+                                svdp.pop(0)
+                        else:
+                            if c.maxstep > 12:
+                                values = svdp[1]
+                            else:
+                                values = svdp[0]
+
+                        grib_set_values(gid, values)
+                        if c.maxstep > 12:
+                            grib_set(gid, 'step', max(0, step-2*int(c.dtime)))
+                        else:
+                            grib_set(gid, 'step', 0)
+                            grib_set(gid, 'time', fdate.hour*100)
+                            grib_set(gid, 'date', fdate.year*10000 +
+                                     fdate.month*100+fdate.day)
+                        grib_write(gid, f_handle)
+
+                        if c.basetime is not None:
+                            elimit = datetime.strptime(c.end_date +
+                                                       c.basetime, '%Y%m%d%H')
+                        else:
+                            elimit = sdate + timedelta(2*int(c.dtime))
+
+                        # squeeze out information of last two steps contained
+                        # in svdp
+                        # if step+int(c.dtime) == c.maxstep and c.maxstep>12
+                        # or sdates+timedelta(hours = int(c.dtime))
+                        # >= elimit:
+                        # Note that svdp[0] has not been popped in this case
+
+                        if step == c.maxstep and c.maxstep > 12 or \
+                           sdates == elimit:
+
+                            values = svdp[3]
+                            grib_set_values(gid, values)
+                            grib_set(gid, 'step', 0)
+                            truedatetime = fdate + timedelta(hours=
+                                                             2*int(c.dtime))
+                            grib_set(gid, 'time', truedatetime.hour * 100)
+                            grib_set(gid, 'date', truedatetime.year * 10000 +
+                                     truedatetime.month * 100 +
+                                     truedatetime.day)
+                            grib_write(gid, h_handle)
+
+                            #values = (svdp[1]+svdp[2])/2.
+                            if cparamId == '142' or cparamId == '143':
+                                values = disaggregation.darain(list(reversed(svdp)))
+                            else:
+                                values = disaggregation.dapoly(list(reversed(svdp)))
+
+                            grib_set(gid, 'step', 0)
+                            truedatetime = fdate + timedelta(hours=int(c.dtime))
+                            grib_set(gid, 'time', truedatetime.hour * 100)
+                            grib_set(gid, 'date', truedatetime.year * 10000 +
+                                     truedatetime.month * 100 +
+                                     truedatetime.day)
+                            grib_set_values(gid, values)
+                            grib_write(gid, g_handle)
+
+                    grib_release(gid)
+
+                    gid = grib_new_from_index(iid)
+
+            f_handle.close()
+            g_handle.close()
+            h_handle.close()
+
+        grib_index_release(iid)
+
+        return
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/python/classes/GribTools.py b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/classes/GribTools.py
new file mode 100644
index 0000000000000000000000000000000000000000..7d375b18bce7fbaeace888d41fadcb27c46f012f
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/classes/GribTools.py
@@ -0,0 +1,318 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#*******************************************************************************
+# @Author: Anne Fouilloux (University of Oslo)
+#
+# @Date: July 2014
+#
+# @Change History:
+#   February 2018 - Anne Philipp (University of Vienna):
+#        - applied PEP8 style guide
+#        - added documentation
+#        - changed some naming
+#
+# @License:
+#    (C) Copyright 2014-2018.
+#
+#    This software is licensed under the terms of the Apache Licence Version 2.0
+#    which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+#
+# @Class Description:
+#    The GRIB API provides all necessary tools to work directly with the
+#    grib files. Nevertheless, the GRIB API tools are very basic and are in
+#    direct connection with the grib files. This class provides some higher
+#    functions which apply a set of GRIB API tools together in the respective
+#    context. So, the class initially contains a list of grib files (their
+#    names) and the using program then applies the methods directly on the
+#    class objects without having to think about how the actual GRIB API
+#    tools have to be arranged.
+#
+# @Class Content:
+#    - __init__
+#    - get_keys
+#    - set_keys
+#    - copy
+#    - index
+#
+# @Class Attributes:
+#    - filenames
+#
+#*******************************************************************************
+
+# ------------------------------------------------------------------------------
+# MODULES
+# ------------------------------------------------------------------------------
+import os
+from gribapi import grib_new_from_file, grib_is_defined, grib_get, \
+                    grib_release, grib_set, grib_write, grib_index_read, \
+                    grib_index_new_from_file, grib_index_add_file,  \
+                    grib_index_write
+
+# ------------------------------------------------------------------------------
+# CLASS
+# ------------------------------------------------------------------------------
+class GribTools(object):
+    '''
+    Class for GRIB utilities (new methods) based on GRIB API
+    '''
+    # --------------------------------------------------------------------------
+    # CLASS FUNCTIONS
+    # --------------------------------------------------------------------------
+    def __init__(self, filenames):
+        '''
+        @Description:
+            Initialise an object of GribTools and assign a list
+            of filenames.
+
+        @Input:
+            filenames: list of strings
+                A list of filenames.
+
+        @Return:
+            <nothing>
+        '''
+
+        self.filenames = filenames
+
+        return
+
+
+    def get_keys(self, keynames, wherekeynames=[], wherekeyvalues=[]):
+        '''
+        @Description:
+            get keyvalues for a given list of keynames
+            a where statement can be given (list of key and list of values)
+
+        @Input:
+            keynames: list of strings
+                List of keynames.
+
+            wherekeynames: list of strings, optional
+                Default value is an empty list.
+
+            wherekeyvalues: list of strings, optional
+                Default value is an empty list.
+
+        @Return:
+            return_list: list of strings
+                List of keyvalues for given keynames.
+        '''
+
+        fileid = open(self.filenames, 'r')
+
+        return_list = []
+
+        while 1:
+            gid_in = grib_new_from_file(fileid)
+
+            if gid_in is None:
+                break
+
+            if len(wherekeynames) != len(wherekeyvalues):
+                raise Exception("Number of key values and key names must be \
+                                 the same. Give a value for each keyname!")
+
+            select = True
+            i = 0
+            for wherekey in wherekeynames:
+                if not grib_is_defined(gid_in, wherekey):
+                    raise Exception("where key was not defined")
+
+                select = (select and (str(wherekeyvalues[i]) ==
+                                      str(grib_get(gid_in, wherekey))))
+                i += 1
+
+            if select:
+                llist = []
+                for key in keynames:
+                    llist.extend([str(grib_get(gid_in, key))])
+                return_list.append(llist)
+
+            grib_release(gid_in)
+
+        fileid.close()
+
+        return return_list
+
+
+    def set_keys(self, fromfile, keynames, keyvalues, wherekeynames=[],
+                 wherekeyvalues=[], strict=False, filemode='w'):
+        '''
+        @Description:
+            Opens the file to read the grib messages and then write
+            them to a new output file. By default all messages are
+            written out. Also, the keyvalues of the passed list of
+            keynames are set or only those meeting the where statement.
+            (list of key and list of values).
+
+        @Input:
+            fromfile: string
+                Filename of the input file to read the grib messages from.
+
+            keynames: list of strings
+                List of keynames. Default is an empty list.
+
+            keyvalues: list of strings
+                List of keynames. Default is an empty list.
+
+            wherekeynames: list of strings, optional
+                Default value is an empty list.
+
+            wherekeyvalues: list of strings, optional
+                Default value is an empty list.
+
+            strict: boolean, optional
+                Decides if everything from keynames and keyvalues
+                is written out the grib file (False) or only those
+                meeting the where statement (True). Default is False.
+
+            filemode: string, optional
+                Sets the mode for the output file. Default is "w".
+
+        @Return:
+            <nothing>
+
+        '''
+        fout = open(self.filenames, filemode)
+        fin = open(fromfile)
+
+        while 1:
+            gid_in = grib_new_from_file(fin)
+
+            if gid_in is None:
+                break
+
+            if len(wherekeynames) != len(wherekeyvalues):
+                raise Exception("Give a value for each keyname!")
+
+            select = True
+            i = 0
+            for wherekey in wherekeynames:
+                if not grib_is_defined(gid_in, wherekey):
+                    raise Exception("where Key was not defined")
+
+                select = (select and (str(wherekeyvalues[i]) ==
+                                      str(grib_get(gid_in, wherekey))))
+                i += 1
+
+            if select:
+                i = 0
+                for key in keynames:
+                    grib_set(gid_in, key, keyvalues[i])
+                    i += 1
+
+            grib_write(gid_in, fout)
+
+            grib_release(gid_in)
+
+        fin.close()
+        fout.close()
+
+        return
+
+    def copy(self, filename_in, selectWhere=True,
+             keynames=[], keyvalues=[], filemode='w'):
+        '''
+        Add the content of another input grib file to the objects file but
+        only messages corresponding to keys/values passed to the function.
+        The selectWhere switch decides if to copy the keys equal to (True) or
+        different to (False) the keynames/keyvalues list passed to the function.
+
+        @Input:
+            filename_in: string
+                Filename of the input file to read the grib messages from.
+
+            selectWhere: boolean, optional
+                Decides if to copy the keynames and values equal to (True) or
+                different to (False) the keynames/keyvalues list passed to the
+                function. Default is True.
+
+            keynames: list of strings, optional
+                List of keynames. Default is an empty list.
+
+            keyvalues: list of strings, optional
+                List of keynames. Default is an empty list.
+
+            filemode: string, optional
+                Sets the mode for the output file. Default is "w".
+
+        @Return:
+            <nothing>
+        '''
+
+        fin = open(filename_in)
+        fout = open(self.filenames, filemode)
+
+        while 1:
+            gid_in = grib_new_from_file(fin)
+
+            if gid_in is None:
+                break
+
+            if len(keynames) != len(keyvalues):
+                raise Exception("Give a value for each keyname!")
+
+            select = True
+            i = 0
+            for key in keynames:
+                if not grib_is_defined(gid_in, key):
+                    raise Exception("Key was not defined")
+
+                if selectWhere:
+                    select = (select and (str(keyvalues[i]) ==
+                                          str(grib_get(gid_in, key))))
+                else:
+                    select = (select and (str(keyvalues[i]) !=
+                                          str(grib_get(gid_in, key))))
+                i += 1
+
+            if select:
+                grib_write(gid_in, fout)
+
+            grib_release(gid_in)
+
+        fin.close()
+        fout.close()
+
+        return
+
+    def index(self, index_keys=["mars"], index_file="my.idx"):
+        '''
+        @Description:
+            Create index file from a list of files if it does not exist or
+            read an index file.
+
+        @Input:
+            index_keys: list of strings, optional
+                Contains the list of key parameter names from
+                which the index is to be created.
+                Default is a list with a single entry string "mars".
+
+            index_file: string, optional
+                Filename where the indices are stored.
+                Default is "my.idx".
+
+        @Return:
+            iid: integer
+                Grib index id.
+        '''
+        print("... index will be done")
+        iid = None
+
+        if os.path.exists(index_file):
+            iid = grib_index_read(index_file)
+            print("Use existing index file: %s " % (index_file))
+        else:
+            for filename in self.filenames:
+                print("Inputfile: %s " % (filename))
+                if iid is None:
+                    iid = grib_index_new_from_file(filename, index_keys)
+                else:
+                    grib_index_add_file(iid, filename)
+
+            if iid is not None:
+                grib_index_write(iid, index_file)
+
+        print('... index done')
+
+        return iid
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/python/classes/MarsRetrieval.py b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/classes/MarsRetrieval.py
new file mode 100644
index 0000000000000000000000000000000000000000..bb86f2b6077d1913ea03f33d5ecae791fc7c40c9
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/classes/MarsRetrieval.py
@@ -0,0 +1,433 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#*******************************************************************************
+# @Author: Anne Fouilloux (University of Oslo)
+#
+# @Date: October 2014
+#
+# @Change History:
+#
+#   November 2015 - Leopold Haimberger (University of Vienna):
+#        - optimized display_info
+#        - optimized data_retrieve and seperate between python and shell
+#          script call
+#
+#   February 2018 - Anne Philipp (University of Vienna):
+#        - applied PEP8 style guide
+#        - added documentation
+#        - applied some minor modifications in programming style/structure
+#
+# @License:
+#    (C) Copyright 2015-2018.
+#
+#    This software is licensed under the terms of the Apache Licence Version 2.0
+#    which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+#
+# @Class Description:
+#    A MARS revtrieval has a specific syntax with a selection of keywords and
+#    their corresponding values. This class provides the necessary functions
+#    by displaying the selected parameters and their values and the actual
+#    retrievement of the data through a mars request or a Python web api
+#    interface. The initialization already expects all the keyword values.
+#
+# @Class Content:
+#    - __init__
+#    - display_info
+#    - data_retrieve
+#
+# @Class Attributes:
+#    - server
+#    - marsclass
+#    - dtype
+#    - levtype
+#    - levelist
+#    - repres
+#    - date
+#    - resol
+#    - stream
+#    - area
+#    - time
+#    - step
+#    - expver
+#    - number
+#    - accuracy
+#    - grid
+#    - gaussian
+#    - target
+#    - param
+#
+#*******************************************************************************
+
+# ------------------------------------------------------------------------------
+# MODULES
+# ------------------------------------------------------------------------------
+import subprocess
+import os
+
+import _config
+# ------------------------------------------------------------------------------
+# CLASS
+# ------------------------------------------------------------------------------
+class MarsRetrieval(object):
+    '''
+    Class for submitting MARS retrievals.
+
+    A description of MARS keywords/arguments and examples of their
+    values can be found here:
+    https://software.ecmwf.int/wiki/display/UDOC/\
+                   Identification+keywords#Identificationkeywords-class
+
+    '''
+
+    def __init__(self, server, marsclass="ei", type="", levtype="",
+                 levelist="", repres="", date="", resol="", stream="",
+                 area="", time="", step="", expver="1", number="",
+                 accuracy="", grid="", gaussian="", target="",
+                 param=""):
+        '''
+        @Description:
+            Initialises the instance of the MarsRetrieval class and
+            defines and assigns a set of the necessary retrieval parameters
+            for the FLEXPART input data.
+            A description of MARS keywords/arguments, their dependencies
+            on each other and examples of their values can be found here:
+
+            https://software.ecmwf.int/wiki/display/UDOC/MARS+keywords
+
+        @Input:
+            self: instance of MarsRetrieval
+                For description see class documentation.
+
+            server: instance of ECMWFService (from ECMWF Web-API)
+                This is the connection to the ECMWF data servers.
+                It is needed for the pythonic access of ECMWF data.
+
+            marsclass: string, optional
+                Characterisation of dataset. E.g. EI (ERA-Interim),
+                E4 (ERA40), OD (Operational archive), ea (ERA5).
+                Default is the ERA-Interim dataset "ei".
+
+            type: string, optional
+                Determines the type of fields to be retrieved.
+                Selects between observations, images or fields.
+                Examples for fields: Analysis (an), Forecast (fc),
+                Perturbed Forecast (pf), Control Forecast (cf) and so on.
+                Default is an empty string.
+
+            levtype: string, optional
+                Denotes type of level. Has a direct implication on valid
+                levelist values!
+                E.g. model level (ml), pressure level (pl), surface (sfc),
+                potential vorticity (pv), potential temperature (pt)
+                and depth (dp).
+                Default is an empty string.
+
+            levelist: string, optional
+                Specifies the required levels. It has to have a valid
+                correspondence to the selected levtype.
+                Examples: model level: 1/to/137, pressure levels: 500/to/1000
+                Default is an empty string.
+
+            repres: string, optional
+                Selects the representation of the archived data.
+                E.g. sh - spherical harmonics, gg - Gaussian grid,
+                ll - latitude/longitude, ...
+                Default is an empty string.
+
+            date: string, optional
+                Specifies the Analysis date, the Forecast base date or
+                Observations date. Valid formats are:
+                Absolute as YYYY-MM-DD or YYYYMMDD.
+                Default is an empty string.
+
+            resol: string, optional
+                Specifies the desired triangular truncation of retrieved data,
+                before carrying out any other selected post-processing.
+                The default is automatic truncation (auto), by which the lowest
+                resolution compatible with the value specified in grid is
+                automatically selected for the retrieval.
+                Users wanting to perform post-processing from full spectral
+                resolution should specify Archived Value (av).
+                The following are examples of existing resolutions found in
+                the archive: 63, 106, 159, 213, 255, 319, 399, 511, 799 or 1279.
+                This keyword has no meaning/effect if the archived data is
+                not in spherical harmonics representation.
+                The best selection can be found here:
+                https://software.ecmwf.int/wiki/display/UDOC/\
+                      Retrieve#Retrieve-Truncationbeforeinterpolation
+                Default is an empty string.
+
+            stream: string, optional
+                Identifies the forecasting system used to generate the data.
+                E.g. oper (Atmospheric model), enfo (Ensemble forecats), ...
+                Default is an empty string.
+
+            area: string, optional
+                Specifies the desired sub-area of data to be extracted.
+                Areas can be defined to wrap around the globe.
+
+                Latitude values must be given as signed numbers, with:
+                    north latitudes (i.e. north of the equator)
+                        being positive (e.g: 40.5)
+                    south latitutes (i.e. south of the equator)
+                        being negative (e.g: -50.5)
+                Longtitude values must be given as signed numbers, with:
+                    east longitudes (i.e. east of the 0 degree meridian)
+                        being positive (e.g: 35.0)
+                    west longitudes (i.e. west of the 0 degree meridian)
+                        being negative (e.g: -20.5)
+
+                E.g.: North/West/South/East
+                Default is an empty string.
+
+            time: string, optional
+                Specifies the time of the data in hours and minutes.
+                Valid values depend on the type of data: Analysis time,
+                Forecast base time or First guess verification time
+                (all usually at synoptic hours: 00, 06, 12 and 18 ).
+                Observation time (any combination in hours and minutes is valid,
+                subject to data availability in the archive).
+                The syntax is HHMM or HH:MM. If MM is omitted it defaults to 00.
+                Default is an empty string.
+
+            step: string, optional
+                Specifies the forecast time step from forecast base time.
+                Valid values are hours (HH) from forecast base time. It also
+                specifies the length of the forecast which verifies at
+                First Guess time.
+                E.g. 1/3/6-hourly
+                Default is an empty string.
+
+            expver: string, optional
+                The version of the dataset. Each experiment is assigned a
+                unique code (version). Production data is assigned 1 or 2,
+                and experimental data in Operations 11, 12 ,...
+                Research or Member State's experiments have a four letter
+                experiment identifier.
+                Default is "1".
+
+            number: string, optional
+                Selects the member in ensemble forecast run. (Only then it
+                is necessary.) It has a different meaning depending on
+                the type of data.
+                E.g. Perturbed Forecasts: specifies the Ensemble forecast member
+                Default is an empty string.
+
+            accuracy: string, optional
+                Specifies the number of bits per value to be used in the
+                generated GRIB coded fields.
+                A positive integer may be given to specify the preferred number
+                of bits per packed value. This must not be greater than the
+                number of bits normally used for a Fortran integer on the
+                processor handling the request (typically 32 or 64 bit).
+                Within a compute request the accuracy of the original fields
+                can be passed to the result field by specifying accuracy=av.
+                Default is an empty string.
+
+            grid: string, optional
+                Specifies the output grid which can be either a Gaussian grid
+                or a Latitude/Longitude grid. MARS requests specifying
+                grid=av will return the archived model grid.
+
+                Lat/Lon grid: The grid spacing needs to be an integer
+                fraction of 90 degrees e.g. grid = 0.5/0.5
+
+                Gaussian grid: specified by a letter denoting the type of
+                Gaussian grid followed by an integer (the grid number)
+                representing the number of lines between the Pole and Equator,
+                e.g.
+                grid = F160 - full (or regular) Gaussian grid with
+                       160 latitude lines between the pole and equator
+                grid = N320 - ECMWF original reduced Gaussian grid with
+                       320 latitude lines between the pole and equator,
+                       see Reduced Gaussian Grids for grid numbers used at ECMWF
+                grid = O640 - ECMWF octahedral (reduced) Gaussian grid with
+                       640 latitude lines between the pole and equator
+                Default is an empty string.
+
+            gaussian: string, optional
+                This parameter is deprecated and should no longer be used.
+                Specifies the desired type of Gaussian grid for the output.
+                Valid Gaussian grids are quasi-regular (reduced) or regular.
+                Keyword gaussian can only be specified together with
+                keyword grid. Gaussian without grid has no effect.
+                Default is an empty string.
+
+            target: string, optional
+                Specifies a file into which data is to be written after
+                retrieval or manipulation. Path names should always be
+                enclosed in double quotes. The MARS client supports automatic
+                generation of multiple target files using MARS keywords
+                enclosed in square brackets [ ].  If the environment variable
+                MARS_MULTITARGET_STRICT_FORMAT is set to 1 before calling mars,
+                the keyword values will be used in the filename as shown by
+                the ecCodes GRIB tool grib_ls -m, e.g. with
+                MARS_MULTITARGET_STRICT_FORMAT set to 1 the keywords time,
+                expver and param will be formatted as 0600, 0001 and 129.128
+                rather than 600, 1 and 129.
+                Default is an empty string.
+
+            param: string, optional
+                Specifies the meteorological parameter.
+                The list of meteorological parameters in MARS is extensive.
+                Their availability is directly related to their meteorological
+                meaning and, therefore, the rest of directives specified
+                in the MARS request.
+                Meteorological parameters can be specified by their
+                GRIB code (param=130), their mnemonic (param=t) or
+                full name (param=temperature).
+                The list of parameter should be seperated by a "/"-sign.
+                E.g. 130/131/133
+                Default is an empty string.
+
+        @Return:
+            <nothing>
+        '''
+
+        self.server = server
+        self.marsclass = marsclass
+        self.type = type
+        self.levtype = levtype
+        self.levelist = levelist
+        self.repres = repres
+        self.date = date
+        self.resol = resol
+        self.stream = stream
+        self.area = area
+        self.time = time
+        self.step = step
+        self.expver = expver
+        self.number = number
+        self.accuracy = accuracy
+        self.grid = grid
+        self.gaussian = gaussian
+        self.target = target
+        self.param = param
+
+        return
+
+
+    def display_info(self):
+        '''
+        @Description:
+            Prints all class attributes and their values to the
+            standard output.
+
+        @Input:
+            self: instance of MarsRetrieval
+                For description see class documentation.
+
+        @Return:
+            <nothing>
+        '''
+        # Get all class attributes and their values as a dictionary
+        attrs = vars(self)
+
+        # iterate through all attributes and print them
+        # with their corresponding values
+        for item in attrs.items():
+            if item[0] in 'server':
+                pass
+            else:
+                print(item[0] + ': ' + str(item[1]))
+
+        return
+
+
+    def print_info(self, inputdir):
+        '''
+        @Description:
+            Prints all mars requests to an extra file for debugging and
+            information.
+
+        @Input:
+            self: instance of MarsRetrieval
+                For description see class documentation.
+
+            inputdir: string
+                The path where all data from the retrievals are stored.
+
+        @Return:
+            <nothing>
+        '''
+        # Get all class attributes and their values as a dictionary
+        attrs = vars(self)
+
+        # open a file to store all requests to
+        with open(os.path.join(inputdir,
+                               _config.FILE_MARS_REQUESTS), 'a') as f:
+            f.write('mars\n')
+            # iterate through all attributes and print them
+            # with their corresponding values
+            for item in attrs.items():
+                if item[0] in 'server':
+                    pass
+                else:
+                    f.write(item[0] + ': ' + str(item[1]) + '\n')
+            f.write('\n\n')
+
+        return
+
+    def data_retrieve(self):
+        '''
+        @Description:
+            Submits a MARS retrieval. Depending on the existence of
+            ECMWF Web-API it is submitted via Python or a
+            subprocess in the Shell. The parameter for the mars retrieval
+            are taken from the defined class attributes.
+
+        @Input:
+            self: instance of MarsRetrieval
+                For description see class documentation.
+
+        @Return:
+            <nothing>
+        '''
+        # Get all class attributes and their values as a dictionary
+        attrs = vars(self)
+
+        # convert the dictionary of attributes into a comma
+        # seperated list of attributes with their values
+        # needed for the retrieval call
+        s = 'ret'
+        for k, v in attrs.iteritems():
+            if k in 'server':
+                continue
+            if k == 'marsclass':
+                k = 'class'
+            if v == '':
+                continue
+            if k.lower() == 'target':
+                target = v
+            else:
+                s = s + ',' + k + '=' + str(v)
+
+        # MARS request via Python script
+        if self.server is not False:
+            try:
+                self.server.execute(s, target)
+            except:
+                print('MARS Request failed, \
+                      have you already registered at apps.ecmwf.int?')
+                raise IOError
+            if os.stat(target).st_size == 0:
+                print('MARS Request returned no data - please check request')
+                raise IOError
+        # MARS request via extra process in shell
+        else:
+            s += ',target = "' + target + '"'
+            p = subprocess.Popen(['mars'], stdin=subprocess.PIPE,
+                                 stdout=subprocess.PIPE,
+                                 stderr=subprocess.PIPE, bufsize=1)
+            pout = p.communicate(input=s)[0]
+            print(pout.decode())
+
+            if 'Some errors reported' in pout.decode():
+                print('MARS Request failed - please check request')
+                raise IOError
+
+            if os.stat(target).st_size == 0:
+                print('MARS Request returned no data - please check request')
+                raise IOError
+
+        return
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/python/classes/UioFiles.py b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/classes/UioFiles.py
new file mode 100644
index 0000000000000000000000000000000000000000..e9eaf8609a17a917e0a0dd9e710a84d7a2dd4c5e
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/classes/UioFiles.py
@@ -0,0 +1,159 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#*******************************************************************************
+# @Author: Anne Fouilloux (University of Oslo)
+#
+# @Date: October 2014
+#
+# @Change History:
+#
+#    November 2015 - Leopold Haimberger (University of Vienna):
+#        - modified method list_files to work with glob instead of listdir
+#        - added pattern search in method list_files
+#
+#    February 2018 - Anne Philipp (University of Vienna):
+#        - applied PEP8 style guide
+#        - added documentation
+#        - optimisation of method list_files since it didn't work correctly
+#          for sub directories
+#        - additional speed up of method list_files
+#        - modified the class so that it is initiated with a pattern instead
+#          of suffixes. Gives more precision in selection of files.
+#
+# @License:
+#    (C) Copyright 2014-2018.
+#
+#    This software is licensed under the terms of the Apache Licence Version 2.0
+#    which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+#
+# @Class Decription:
+#    The class is for file manipulation. It is initiated with a regular
+#    expression pattern for this instance and can produce a list of Files
+#    from the given file pattern. These files can be deleted.
+#
+# @Class Content:
+#    - __init__
+#    - __str__
+#    - __list_files__
+#    - delete_files
+#
+# @Class Attributes:
+#    - pattern
+#    - files
+#
+#*******************************************************************************
+
+# ------------------------------------------------------------------------------
+# MODULES
+# ------------------------------------------------------------------------------
+import os
+import fnmatch
+
+# software specific module from flex_extract
+#import profiling
+from mods.tools import silent_remove, get_list_as_string
+
+# ------------------------------------------------------------------------------
+# CLASS
+# ------------------------------------------------------------------------------
+
+class UioFiles(object):
+    '''
+    Class to manipulate files. At initialisation it has the pattern
+    which stores a regular expression pattern for the files, the path
+    to the files and the files already.
+    '''
+    # --------------------------------------------------------------------------
+    # CLASS FUNCTIONS
+    # --------------------------------------------------------------------------
+    def __init__(self, path, pattern):
+        '''
+        @Description:
+            Assignes a specific pattern for these files.
+
+        @Input:
+            self: instance of UioFiles
+                Description see class documentation.
+
+            path: string
+                Directory where to list the files.
+
+            pattern: string
+                Regular expression pattern. For example: '*.grb'
+
+        @Return:
+            <nothing>
+        '''
+
+        self.path = path
+        self.pattern = pattern
+        self.files = []
+
+        self.__list_files__(self.path)
+
+        return
+
+    #@profiling.timefn
+    def __list_files__(self, path):
+        '''
+        @Description:
+            Lists all files in the directory with the matching
+            regular expression pattern.
+
+        @Input:
+            self: instance of UioFiles
+                Description see class documentation.
+
+            path: string
+                Path to the files.
+
+        @Return:
+            <nothing>
+        '''
+        # Get the absolute path
+        path = os.path.abspath(path)
+
+        # get all files in the dir and subdir as absolut path
+        for root, dirnames, filenames in os.walk(path):
+            for filename in fnmatch.filter(filenames, self.pattern):
+                self.files.append(os.path.join(root, filename))
+
+        return
+
+    def __str__(self):
+        '''
+        @Description:
+            Converts the list of files into a single string.
+            The entries are sepereated by "," sign.
+
+        @Input:
+            self: instance of UioFiles
+                Description see class documentation.
+
+        @Return:
+            files_string: string
+                The content of the list as a single string.
+        '''
+
+        filenames = [os.path.basename(f) for f in self.files]
+        files_string = get_list_as_string(filenames, concatenate_sign=', ')
+
+        return files_string
+
+    def delete_files(self):
+        '''
+        @Description:
+            Deletes the files.
+
+        @Input:
+            self: instance of UioFiles
+                Description see class documentation.
+
+        @Return:
+            <nothing>
+        '''
+
+        for old_file in self.files:
+            silent_remove(old_file)
+
+        return
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/python/classes/__init__.py b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/classes/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..4609bf2c36fe073fdb731fa34a23fa45990e8b57
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/classes/__init__.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#*******************************************************************************
+# @Author: Anne Philipp (University of Vienna)
+#
+# @Date: September 2018
+#
+# @License:
+#    (C) Copyright 2015-2018.
+#
+#    This software is licensed under the terms of the Apache Licence Version 2.0
+#    which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+#
+#*******************************************************************************
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/python/install.py b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/install.py
new file mode 100755
index 0000000000000000000000000000000000000000..4d5c972ccb0d7de0e7ce8e0669dde385213f14be
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/install.py
@@ -0,0 +1,547 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#*******************************************************************************
+# @Author: Leopold Haimberger (University of Vienna)
+#
+# @Date: November 2015
+#
+# @Change History:
+#
+#    February 2018 - Anne Philipp (University of Vienna):
+#        - applied PEP8 style guide
+#        - added documentation
+#        - moved install_args_and_control in here
+#        - splitted code in smaller functions
+#        - delete convert build files in here instead of compile job script
+#        - changed static path names to Variables from config file
+#
+# @License:
+#    (C) Copyright 2015-2018.
+#
+#    This software is licensed under the terms of the Apache Licence Version 2.0
+#    which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+#
+# @Program Functionality:
+#    Depending on the selected installation environment (locally or on the
+#    ECMWF server ecgate or cca) the program extracts the commandline
+#    arguments and the CONTROL file parameter and prepares the corresponding
+#    environment. The necessary files are collected in a tar-ball and placed
+#    at the target location. There its untared, the environment variables will
+#    be set and the Fortran code will be compiled. If the ECMWF environment is
+#    selected a job script is prepared and submitted for the remaining
+#    configurations after putting the tar-ball to the target ECMWF server.
+#
+# @Program Content:
+#    - main
+#    - get_install_cmdline_arguments
+#    - install_via_gateway
+#    - mk_tarball
+#    - un_tarball
+#    - mk_env_vars
+#    - mk_compilejob
+#    - mk_job_template
+#    - delete_convert_build
+#    - make_convert_build
+#
+#*******************************************************************************
+
+# ------------------------------------------------------------------------------
+# MODULES
+# ------------------------------------------------------------------------------
+import os
+import sys
+import glob
+import subprocess
+import inspect
+from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
+
+# software specific classes and modules from flex_extract
+import _config
+from classes.ControlFile import ControlFile
+from classes.UioFiles import UioFiles
+from mods.tools import make_dir, put_file_to_ecserver, submit_job_to_ecserver
+
+# ------------------------------------------------------------------------------
+# FUNCTIONS
+# ------------------------------------------------------------------------------
+def main():
+    '''
+    @Description:
+        Controls the installation process. Calls the installation function
+        if target is specified.
+
+    @Intput:
+        <nothing>
+
+    @Return:
+        <nothing>
+    '''
+
+    #os.chdir(_config.PATH_LOCAL_PYTHON)
+
+    args = get_install_cmdline_arguments()
+
+    try:
+        c = ControlFile(args.controlfile)
+    except IOError:
+        print('Could not read CONTROL file "' + args.controlfile + '"')
+        print('Either it does not exist or its syntax is wrong.')
+        print('Try "' + sys.argv[0].split('/')[-1] +
+              ' -h" to print usage information')
+        exit(1)
+
+    c.assign_args_to_control(args)
+    c.check_install_conditions()
+
+    install_via_gateway(c)
+
+    return
+
+def get_install_cmdline_arguments():
+    '''
+    @Description:
+        Decomposes the command line arguments and assigns them to variables.
+        Apply default values for non mentioned arguments.
+
+    @Input:
+        <nothing>
+
+    @Return:
+        args: instance of ArgumentParser
+            Contains the commandline arguments from script/program call.
+    '''
+    parser = ArgumentParser(description='Install flex_extract software locally or \
+                            on ECMWF machines',
+                            formatter_class=ArgumentDefaultsHelpFormatter)
+
+    parser.add_argument('--target', dest='install_target', default=None,
+                        help="Valid targets: local | ecgate | cca , \
+                        the latter two are at ECMWF")
+    parser.add_argument("--makefile", dest="makefile", default=None,
+                        help='Name of Makefile to use for compiling CONVERT2')
+    parser.add_argument("--ecuid", dest="ecuid", default=None,
+                        help='user id at ECMWF')
+    parser.add_argument("--ecgid", dest="ecgid", default=None,
+                        help='group id at ECMWF')
+    parser.add_argument("--gateway", dest="gateway", default=None,
+                        help='name of local gateway server')
+    parser.add_argument("--destination", dest="destination", default=None,
+                        help='ecaccess destination, e.g. leo@genericSftp')
+
+    parser.add_argument("--flexpart_root_scripts", dest="flexpart_root_scripts",
+                        default=None, help="FLEXPART root directory on ECMWF \
+                        servers (to find grib2flexpart and COMMAND file)\n\
+                        Normally flex_extract resides in the scripts directory \
+                        of the FLEXPART distribution.")
+
+    # arguments for job submission to ECMWF, only needed by submit.py
+    parser.add_argument("--job_template", dest='job_template',
+                        default="job.temp.o",
+                        help="job template file for submission to ECMWF")
+
+    parser.add_argument("--controlfile", dest="controlfile",
+                        default='CONTROL.temp',
+                        help="file with CONTROL parameters")
+
+    args = parser.parse_args()
+
+    return args
+
+
+def install_via_gateway(c):
+    '''
+    @Description:
+        Perform the actual installation on local machine or prepare data
+        transfer to remote gate and submit a job script which will
+        install everything on the remote gate.
+
+    @Input:
+        c: instance of class ControlFile
+            Contains all necessary information of a CONTROL file. The parameters
+            are: DAY1, DAY2, DTIME, MAXSTEP, TYPE, TIME, STEP, CLASS, STREAM,
+            NUMBER, EXPVER, GRID, LEFT, LOWER, UPPER, RIGHT, LEVEL, LEVELIST,
+            RESOL, GAUSS, ACCURACY, OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA,
+            SMOOTH, FORMAT, ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS,
+            ECFSDIR, MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR
+            For more information about format and content of the parameter see
+            documentation.
+
+    @Return:
+        <nothing>
+    '''
+    import tarfile
+
+    ecd = _config.PATH_FLEXEXTRACT_DIR
+    tarball_name = _config.FLEXEXTRACT_DIRNAME + '.tar'
+    tar_file = os.path.join(ecd, tarball_name)
+
+    target_dirname = _config.FLEXEXTRACT_DIRNAME
+    fortran_executable = _config.FORTRAN_EXECUTABLE
+
+    if c.install_target.lower() != 'local': # ecgate or cca
+
+        mk_compilejob(c.makefile, c.install_target, c.ecuid, c.ecgid,
+                      c.flexpart_root_scripts)
+
+        mk_job_template(c.ecuid, c.ecgid, c.gateway,
+                        c.destination, c.flexpart_root_scripts)
+
+        mk_env_vars(c.ecuid, c.ecgid, c.gateway, c.destination)
+
+        mk_tarball(tar_file, c.install_target)
+
+        put_file_to_ecserver(ecd, tarball_name, c.install_target,
+                             c.ecuid, c.ecgid)
+
+        submit_job_to_ecserver(c.install_target,
+                               os.path.join(_config.PATH_REL_JOBSCRIPTS,
+                                            _config.FILE_INSTALL_COMPILEJOB))
+
+        print('job compilation script has been submitted to ecgate for ' +
+              'installation in ' + c.flexpart_root_scripts +
+               '/' + target_dirname)
+        print('You should get an email with subject "flexcompile" within ' +
+              'the next few minutes!')
+
+    else: #local
+        if c.flexpart_root_scripts == _config.PATH_FLEXEXTRACT_DIR :
+            print('WARNING: FLEXPART_ROOT_SCRIPTS has not been specified')
+            print('flex_extract will be installed in here by compiling the ' +
+                  'Fortran source in ' + _config.PATH_FORTRAN_SRC)
+            os.chdir(_config.PATH_FORTRAN_SRC)
+        else: # creates the target working directory for flex_extract
+            c.flexpart_root_scripts = os.path.expandvars(os.path.expanduser(
+                                        c.flexpart_root_scripts))
+            if os.path.abspath(ecd) != os.path.abspath(c.flexpart_root_scripts):
+                mk_tarball(tar_file, c.install_target)
+                make_dir(os.path.join(c.flexpart_root_scripts,
+                                      target_dirname))
+                os.chdir(os.path.join(c.flexpart_root_scripts,
+                                      target_dirname))
+                un_tarball(tar_file)
+                os.chdir(os.path.join(c.flexpart_root_scripts,
+                                      target_dirname,
+                                      _config.PATH_REL_FORTRAN_SRC))
+
+        # Create Fortran executable - CONVERT2
+        print('Install ' + target_dirname + ' software at ' +
+              c.install_target + ' in directory ' +
+              os.path.abspath(c.flexpart_root_scripts) + '\n')
+
+        delete_convert_build('.')
+        make_convert_build('.', c.makefile)
+
+        os.chdir(ecd)
+#        if os.path.isfile(tar_file):
+#            os.remove(tar_file)
+
+    return
+
+def mk_tarball(tarball_path, target):
+    '''
+    @Description:
+        Creates a tarball with all necessary files which need to be sent to the
+        installation directory.
+        It does not matter if this is local or remote.
+        Collects all python files, the Fortran source and makefiles,
+        the ECMWF_ENV file, the CONTROL files as well as the
+        template files.
+
+    @Input:
+        tarball_path: string
+            The complete path to the tar file which will contain all
+            relevant data for flex_extract.
+
+        target: string
+            The queue where the job is submitted to.
+
+    @Return:
+        <nothing>
+    '''
+    import tarfile
+    from glob import glob
+
+    print('Create tarball ...')
+
+    # change to FLEXEXTRACT directory so that the tar can contain
+    # relative pathes to the files and directories
+    ecd = _config.PATH_FLEXEXTRACT_DIR + '/'
+    os.chdir(ecd)
+
+    # get lists of the files to be added to the tar file
+    if target == 'local':
+        ECMWF_ENV_FILE = []
+    else:
+        ECMWF_ENV_FILE = [_config.PATH_REL_ECMWF_ENV]
+
+    pyfiles = [os.path.relpath(x, ecd)
+               for x in UioFiles(_config.PATH_LOCAL_PYTHON, '*py').files]
+    controlfiles = [os.path.relpath(x, ecd)
+                    for x in UioFiles(_config.PATH_CONTROLFILES,
+                                      'CONTROL*').files]
+    tempfiles = [os.path.relpath(x, ecd)
+                 for x in UioFiles(_config.PATH_TEMPLATES , '*').files]
+    ffiles = [os.path.relpath(x, ecd)
+              for x in UioFiles(_config.PATH_FORTRAN_SRC, '*.f*').files]
+    hfiles = [os.path.relpath(x, ecd)
+              for x in UioFiles(_config.PATH_FORTRAN_SRC, '*.h').files]
+    makefiles = [os.path.relpath(x, ecd)
+                 for x in UioFiles(_config.PATH_FORTRAN_SRC, 'Makefile*').files]
+
+    # concatenate single lists to one for a better looping
+    filelist = pyfiles + controlfiles + tempfiles + ffiles + hfiles + \
+               makefiles + ECMWF_ENV_FILE
+
+    # create installation tar-file
+    try:
+        with tarfile.open(tarball_path, "w:gz") as tar_handle:
+            for file in filelist:
+                tar_handle.add(file)
+
+    except subprocess.CalledProcessError as e:
+        print('... ERROR CODE:\n ... ' + str(e.returncode))
+        print('... ERROR MESSAGE:\n ... ' + str(e))
+
+        sys.exit('... could not make installation tar ball!')
+
+    return
+
+
+def un_tarball(tarball_path):
+    '''
+    @Description:
+        Extracts the given tarball into current directory.
+
+    @Input:
+        tarball_path: string
+            The complete path to the tar file which will contain all
+            relevant data for flex_extract.
+
+    @Return:
+        <nothing>
+    '''
+    import tarfile
+
+    print('Untar ...')
+
+    with tarfile.open(tarball_path) as tar_handle:
+        tar_handle.extractall()
+
+    return
+
+def mk_env_vars(ecuid, ecgid, gateway, destination):
+    '''
+    @Description:
+        Creates a file named ECMWF_ENV which contains the
+        necessary environmental variables at ECMWF servers.
+
+    @Input:
+        ecuid: string
+            The user id on ECMWF server.
+
+        ecgid: string
+            The group id on ECMWF server.
+
+        gateway: string
+            The gateway server the user is using.
+
+        destination: string
+            The remote destination which is used to transfer files
+            from ECMWF server to local gateway server.
+
+    @Return:
+        <nothing>
+    '''
+
+    with open(_config.PATH_REL_ECMWF_ENV, 'w') as fo:
+        fo.write('ECUID ' + ecuid + '\n')
+        fo.write('ECGID ' + ecgid + '\n')
+        fo.write('GATEWAY ' + gateway + '\n')
+        fo.write('DESTINATION ' + destination + '\n')
+
+    return
+
+def mk_compilejob(makefile, target, ecuid, ecgid, fp_root):
+    '''
+    @Description:
+        Modifies the original job template file so that it is specified
+        for the user and the environment were it will be applied. Result
+        is stored in a new file "job.temp" in the python directory.
+
+    @Input:
+        makefile: string
+            Name of the makefile which should be used to compile FORTRAN
+            CONVERT2 program.
+
+        target: string
+            The target where the installation should be done, e.g. the queue.
+
+        ecuid: string
+            The user id on ECMWF server.
+
+        ecgid: string
+            The group id on ECMWF server.
+
+        fp_root: string
+           Path to the root directory of FLEXPART environment or flex_extract
+           environment.
+
+    @Return:
+        <nothing>
+    '''
+
+    template = os.path.join(_config.PATH_REL_TEMPLATES,
+                            _config.TEMPFILE_INSTALL_COMPILEJOB)
+    with open(template) as f:
+        fdata = f.read().split('\n')
+
+    compilejob = os.path.join(_config.PATH_REL_JOBSCRIPTS,
+                              _config.FILE_INSTALL_COMPILEJOB)
+    with open(compilejob, 'w') as fo:
+        for data in fdata:
+            if 'MAKEFILE=' in data:
+                data = 'export MAKEFILE=' + makefile
+            elif 'FLEXPART_ROOT_SCRIPTS=' in data:
+                if fp_root != '../':
+                    data = 'export FLEXPART_ROOT_SCRIPTS=' + fp_root
+                else:
+                    data = 'export FLEXPART_ROOT_SCRIPTS=$HOME'
+            elif target.lower() != 'local':
+                if '--workdir' in data:
+                    data = '#SBATCH --workdir=/scratch/ms/' + \
+                            ecgid + '/' + ecuid
+                elif '##PBS -o' in data:
+                    data = '##PBS -o /scratch/ms/' + ecgid + '/' + ecuid + \
+                           'flex_ecmwf.$Jobname.$Job_ID.out'
+                elif 'FLEXPART_ROOT_SCRIPTS=' in data:
+                    if fp_root != '../':
+                        data = 'export FLEXPART_ROOT_SCRIPTS=' + fp_root
+                    else:
+                        data = 'export FLEXPART_ROOT_SCRIPTS=$HOME'
+            fo.write(data + '\n')
+
+    return
+
+def mk_job_template(ecuid, ecgid, gateway, destination, fp_root):
+    '''
+    @Description:
+        Modifies the original job template file so that it is specified
+        for the user and the environment were it will be applied. Result
+        is stored in a new file.
+
+    @Input:
+        ecuid: string
+            The user id on ECMWF server.
+
+        ecgid: string
+            The group id on ECMWF server.
+
+        gateway: string
+            The gateway server the user is using.
+
+        destination: string
+            The remote destination which is used to transfer files
+            from ECMWF server to local gateway server.
+
+        fp_root: string
+           Path to the root directory of FLEXPART environment or flex_extract
+           environment.
+
+    @Return:
+        <nothing>
+    '''
+    fp_root_path_to_python = os.path.join(fp_root, _config.FLEXEXTRACT_DIRNAME,
+                         _config.PATH_REL_PYTHON)
+
+    template = os.path.join(_config.PATH_REL_TEMPLATES,
+                            _config.TEMPFILE_INSTALL_JOB)
+    with open(template) as f:
+        fdata = f.read().split('\n')
+
+    jobfile_temp = os.path.join(_config.PATH_REL_TEMPLATES,
+                                _config.TEMPFILE_JOB)
+    with open(jobfile_temp, 'w') as fo:
+        for data in fdata:
+            if '--workdir' in data:
+                data = '#SBATCH --workdir=/scratch/ms/' + ecgid + '/' + ecuid
+            elif '##PBS -o' in data:
+                data = '##PBS -o /scratch/ms/' + ecgid + '/' + \
+                        ecuid + 'flex_ecmwf.$Jobname.$Job_ID.out'
+            elif  'export PATH=${PATH}:' in data:
+                data += fp_root_path_to_python
+
+            fo.write(data + '\n')
+    return
+
+def delete_convert_build(src_path):
+    '''
+    @Description:
+        Clean up the Fortran source directory and remove all
+        build files (e.g. *.o, *.mod and CONVERT2)
+
+    @Input:
+        src_path: string
+            Path to the fortran source directory.
+
+    @Return:
+        <nothing>
+    '''
+
+    modfiles = UioFiles(src_path, '*.mod')
+    objfiles = UioFiles(src_path, '*.o')
+    exefile = UioFiles(src_path, _config.FORTRAN_EXECUTABLE)
+
+    modfiles.delete_files()
+    objfiles.delete_files()
+    exefile.delete_files()
+
+    return
+
+def make_convert_build(src_path, makefile):
+    '''
+    @Description:
+        Compiles the Fortran code and generates the executable.
+
+    @Input:
+        src_path: string
+            Path to the fortran source directory.
+
+        makefile: string
+            The name of the makefile which should be used.
+
+    @Return:
+        <nothing>
+    '''
+
+    try:
+        print('Using makefile: ' + makefile)
+        p = subprocess.Popen(['make', '-f',
+                              os.path.join(src_path, makefile)],
+                             stdin=subprocess.PIPE,
+                             stdout=subprocess.PIPE,
+                             stderr=subprocess.PIPE,
+                             bufsize=1)
+        pout, perr = p.communicate()
+        print(pout)
+        if p.returncode != 0:
+            print(perr)
+            print('Please edit ' + makefile +
+                  ' or try another Makefile in the src directory.')
+            print('Most likely GRIB_API_INCLUDE_DIR, GRIB_API_LIB '
+                  'and EMOSLIB must be adapted.')
+            print('Available Makefiles:')
+            print(UioFiles(src_path, 'Makefile*'))
+            sys.exit('Compilation failed!')
+    except ValueError as e:
+        print('ERROR: Makefile call failed:')
+        print(e)
+    else:
+        subprocess.check_call(['ls', '-l',
+                               os.path.join(src_path,
+                                            _config.FORTRAN_EXECUTABLE)])
+
+    return
+
+
+if __name__ == "__main__":
+    main()
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/python/mods/__init__.py b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/mods/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..4609bf2c36fe073fdb731fa34a23fa45990e8b57
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/mods/__init__.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#*******************************************************************************
+# @Author: Anne Philipp (University of Vienna)
+#
+# @Date: September 2018
+#
+# @License:
+#    (C) Copyright 2015-2018.
+#
+#    This software is licensed under the terms of the Apache Licence Version 2.0
+#    which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+#
+#*******************************************************************************
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/python/mods/disaggregation.py b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/mods/disaggregation.py
new file mode 100644
index 0000000000000000000000000000000000000000..aa84eaf0c28110f6772ff3e7a48fd411082d52a4
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/mods/disaggregation.py
@@ -0,0 +1,141 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#*******************************************************************************
+# @Author: Anne Philipp (University of Vienna)
+#
+# @Date: March 2018
+#
+# @Change History:
+#
+#    November 2015 - Leopold Haimberger (University of Vienna):
+#        - migration of the methods dapoly and darain from Fortran
+#          (flex_extract_v6 and earlier) to Python
+#
+#    April 2018 - Anne Philipp (University of Vienna):
+#        - applied PEP8 style guide
+#        - added structured documentation
+#        - outsourced the disaggregation functions dapoly and darain
+#          to a new module named disaggregation
+#
+# @License:
+#    (C) Copyright 2015-2018.
+#
+#    This software is licensed under the terms of the Apache Licence Version 2.0
+#    which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+#
+# @Module Description:
+#    disaggregation of deaccumulated flux data from an ECMWF model FG field.
+#    Initially the flux data to be concerned are:
+#    - large-scale precipitation
+#    - convective precipitation
+#    - surface sensible heat flux
+#    - surface solar radiation
+#    - u stress
+#    - v stress
+#    Different versions of disaggregation is provided for rainfall
+#    data (darain, modified linear) and the surface fluxes and
+#    stress data (dapoly, cubic polynomial).
+#
+# @Module Content:
+#    - dapoly
+#    - darain
+#
+#*******************************************************************************
+
+# ------------------------------------------------------------------------------
+# MODULES
+# ------------------------------------------------------------------------------
+
+# ------------------------------------------------------------------------------
+# FUNCTIONS
+# ------------------------------------------------------------------------------
+def dapoly(alist):
+    '''
+    @Author: P. JAMES
+
+    @Date: 2000-03-29
+
+    @ChangeHistory:
+        June 2003     - A. BECK (2003-06-01)
+            adaptaions
+        November 2015 - Leopold Haimberger (University of Vienna)
+            migration from Fortran to Python
+
+    @Description:
+        Interpolation of deaccumulated fluxes of an ECMWF model FG field
+        using a cubic polynomial solution which conserves the integrals
+        of the fluxes within each timespan.
+        disaggregationregation is done for 4 accumluated timespans which generates
+        a new, disaggregated value which is output at the central point
+        of the 4 accumulation timespans. This new point is used for linear
+        interpolation of the complete timeseries afterwards.
+
+    @Input:
+        alist: list of size 4, array(2D), type=float
+            List of 4 timespans as 2-dimensional, horizontal fields.
+            E.g. [[array_t1], [array_t2], [array_t3], [array_t4]]
+
+    @Return:
+        nfield: array(2D), type=float
+            New field which replaces the field at the second position
+            of the accumulation timespans.
+
+    '''
+    pya = (alist[3] - alist[0] + 3. * (alist[1] - alist[2])) / 6.
+    pyb = (alist[2] + alist[0]) / 2. - alist[1] - 9. * pya / 2.
+    pyc = alist[1] - alist[0] - 7. * pya / 2. - 2. * pyb
+    pyd = alist[0] - pya / 4. - pyb / 3. - pyc / 2.
+    nfield = 8. * pya + 4. * pyb + 2. * pyc + pyd
+
+    return nfield
+
+
+def darain(alist):
+    '''
+    @Author: P. JAMES
+
+    @Date: 2000-03-29
+
+    @ChangeHistory:
+        June 2003     - A. BECK (2003-06-01)
+            adaptaions
+        November 2015 - Leopold Haimberger (University of Vienna)
+            migration from Fortran to Python
+
+    @Description:
+        Interpolation of deaccumulated fluxes of an ECMWF model FG rainfall
+        field using a modified linear solution which conserves the integrals
+        of the fluxes within each timespan.
+        disaggregationregation is done for 4 accumluated timespans which generates
+        a new, disaggregated value which is output at the central point
+        of the 4 accumulation timespans. This new point is used for linear
+        interpolation of the complete timeseries afterwards.
+
+    @Input:
+        alist: list of size 4, array(2D), type=float
+            List of 4 timespans as 2-dimensional, horizontal fields.
+            E.g. [[array_t1], [array_t2], [array_t3], [array_t4]]
+
+    @Return:
+        nfield: array(2D), type=float
+            New field which replaces the field at the second position
+            of the accumulation timespans.
+    '''
+    xa = alist[0]
+    xb = alist[1]
+    xc = alist[2]
+    xd = alist[3]
+    xa[xa < 0.] = 0.
+    xb[xb < 0.] = 0.
+    xc[xc < 0.] = 0.
+    xd[xd < 0.] = 0.
+
+    xac = 0.5 * xb
+    mask = xa + xc > 0.
+    xac[mask] = xb[mask] * xc[mask] / (xa[mask] + xc[mask])
+    xbd = 0.5 * xc
+    mask = xb + xd > 0.
+    xbd[mask] = xb[mask] * xc[mask] / (xb[mask] + xd[mask])
+    nfield = xac + xbd
+
+    return nfield
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/python/mods/get_mars_data.py b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/mods/get_mars_data.py
new file mode 100755
index 0000000000000000000000000000000000000000..1ccdfa972088d84bf9dbd230b625c6d1c481954f
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/mods/get_mars_data.py
@@ -0,0 +1,291 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#*******************************************************************************
+# @Author: Anne Fouilloux (University of Oslo)
+#
+# @Date: October 2014
+#
+# @Change History:
+#
+#    November 2015 - Leopold Haimberger (University of Vienna):
+#        - moved the getEIdata program into a function "get_mars_data"
+#        - moved the AgurmentParser into a seperate function
+#        - adatpted the function for the use in flex_extract
+#        - renamed file to get_mars_data
+#
+#    February 2018 - Anne Philipp (University of Vienna):
+#        - applied PEP8 style guide
+#        - added structured documentation
+#        - minor changes in programming style for consistence
+#        - added function main and moved function calls vom __main__ there
+#          (necessary for better documentation with docstrings for later
+#          online documentation)
+#        - use of UIFiles class for file selection and deletion
+#
+#
+# @License:
+#    (C) Copyright 2014-2018.
+#
+#    This software is licensed under the terms of the Apache Licence Version 2.0
+#    which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+#
+# @Program Functionality:
+#    This program can be used as a module in the whole flex_extract process
+#    or can be run by itself to just extract MARS data from ECMWF. To do so,
+#    a couple of necessary parameters has to be passed with the program call.
+#    See documentation for more details.
+#
+# @Program Content:
+#    - main
+#    - get_mars_data
+#    - do_retrievement
+#
+#*******************************************************************************
+
+# ------------------------------------------------------------------------------
+# MODULES
+# ------------------------------------------------------------------------------
+import os
+import sys
+import datetime
+import inspect
+try:
+    ecapi = True
+    import ecmwfapi
+except ImportError:
+    ecapi = False
+
+# software specific classes and modules from flex_extract
+import _config
+from tools import my_error, normal_exit, get_cmdline_arguments, read_ecenv
+from classes.EcFlexpart import EcFlexpart
+from classes.UioFiles import UioFiles
+# ------------------------------------------------------------------------------
+# FUNCTION
+# ------------------------------------------------------------------------------
+def main():
+    '''
+    @Description:
+        If get_mars_data is called from command line, this function controls
+        the program flow and calls the argumentparser function and
+        the get_mars_data function for retrieving EC data.
+
+    @Input:
+        <nothing>
+
+    @Return:
+        <nothing>
+    '''
+
+    args = get_cmdline_arguments()
+
+    try:
+        c = ControlFile(args.controlfile)
+    except IOError:
+        print('Could not read CONTROL file "' + args.controlfile + '"')
+        print('Either it does not exist or its syntax is wrong.')
+        print('Try "' + sys.argv[0].split('/')[-1] + \
+              ' -h" to print usage information')
+        sys.exit(1)
+
+    env_parameter = read_ecenv(_config.PATH_ECMWF_ENV)
+    c.assign_args_to_control(args, env_parameter)
+    c.assign_envs_to_control(env_parameter)
+    c.check_conditions(args.queue)
+
+    get_mars_data(c)
+    normal_exit(c.mailfail, 'Done!')
+
+    return
+
+def get_mars_data(c):
+    '''
+    @Description:
+        Retrieves the EC data needed for a FLEXPART simulation.
+        Start and end dates for retrieval period is set. Retrievals
+        are divided into smaller periods if necessary and datechunk parameter
+        is set.
+
+    @Input:
+        c: instance of class ControlFile
+            Contains all the parameters of CONTROL file, which are e.g.:
+            DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
+            STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
+            LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
+            OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
+            ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
+            MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
+            DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+
+            For more information about format and content of the parameter
+            see documentation.
+
+    @Return:
+        <nothing>
+    '''
+
+    if not os.path.exists(c.inputdir):
+        os.makedirs(c.inputdir)
+
+    if c.request == 0 or c.request == 2:
+        print("Retrieving EC data!")
+    elif c.request == 1:
+        print("Printing mars requests!")
+
+    print("start date %s " % (c.start_date))
+    print("end date %s " % (c.end_date))
+
+    if ecapi:
+        server = ecmwfapi.ECMWFService("mars")
+    else:
+        server = False
+
+    c.ecapi = ecapi
+    print('Using ECMWF WebAPI: ' + str(c.ecapi))
+
+    # basetime geht rückwärts
+
+    # if basetime 00
+    # dann wird von 12 am vortag bis 00 am start tag geholt
+    # aber ohne 12 selbst sondern 12 + step
+
+    # if basetime 12
+    # dann wird von 00 + step bis 12 am start tag geholt
+
+    # purer forecast wird vorwärts bestimmt.
+    # purer forecast mode ist dann wenn  größer 24 stunden
+    # wie kann das noch festgestellt werden ????
+    # nur FC und steps mehr als 24 ?
+    # die einzige problematik beim reinen forecast ist die benennung der files!
+    # also sobald es Tagesüberschneidungen gibt
+    # allerdings ist das relevant und ersichtlich an den NICHT FLUSS DATEN
+
+
+    # set start date of retrieval period
+    start = datetime.date(year=int(c.start_date[:4]),
+                          month=int(c.start_date[4:6]),
+                          day=int(c.start_date[6:]))
+    startm1 = start - datetime.timedelta(days=1)
+
+    # set end date of retrieval period
+    end = datetime.date(year=int(c.end_date[:4]),
+                        month=int(c.end_date[4:6]),
+                        day=int(c.end_date[6:]))
+
+    # set time period for one single retrieval
+    datechunk = datetime.timedelta(days=int(c.date_chunk))
+
+    if c.basetime == '00':
+        start = startm1
+
+    if c.basetime == '00' or c.basetime == '12':
+        # endp1 = end + datetime.timedelta(days=1)
+        endp1 = end
+    else:
+        # endp1 = end + datetime.timedelta(days=2)
+        endp1 = end + datetime.timedelta(days=1)
+
+    # --------------  flux data ------------------------------------------------
+    if c.request == 0 or c.request == 2:
+        print('... removing old flux content of ' + c.inputdir)
+        tobecleaned = UioFiles(c.inputdir,
+                               '*_acc_*.' + str(os.getppid()) + '.*.grb')
+        tobecleaned.delete_files()
+
+    # if forecast for maximum one day (upto 24h) are to be retrieved,
+    # collect accumulation data (flux data)
+    # with additional days in the beginning and at the end
+    # (used for complete disaggregation of original period)
+    if c.maxstep <= 24:
+        do_retrievement(c, server, startm1, endp1, datechunk, fluxes=True)
+
+    # if forecast data longer than 24h are to be retrieved,
+    # collect accumulation data (flux data)
+    # with the exact start and end date
+    # (disaggregation will be done for the
+    # exact time period with boundary conditions)
+    else:
+        do_retrievement(c, server, start, end, datechunk, fluxes=True)
+
+    # --------------  non flux data --------------------------------------------
+    if c.request == 0 or c.request == 2:
+        print('... removing old non flux content of ' + c.inputdir)
+        tobecleaned = UioFiles(c.inputdir,
+                               '*__*.' + str(os.getppid()) + '.*.grb')
+        tobecleaned.delete_files()
+
+    do_retrievement(c, server, start, end, datechunk, fluxes=False)
+
+    return
+
+def do_retrievement(c, server, start, end, delta_t, fluxes=False):
+    '''
+    @Description:
+        Divides the complete retrieval period in smaller chunks and
+        retrieves the data from MARS.
+
+    @Input:
+        c: instance of ControlFile
+            Contains all the parameters of CONTROL file, which are e.g.:
+            DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
+            STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
+            LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
+            OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
+            ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
+            MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
+            DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+
+            For more information about format and content of the parameter
+            see documentation.
+
+        server: instance of ECMWFService
+            The server connection to ECMWF
+
+        start: instance of datetime
+            The start date of the retrieval.
+
+        end: instance of datetime
+            The end date of the retrieval.
+
+        delta_t: instance of datetime
+            Delta_t +1 is the maximal time period of a single
+            retrieval.
+
+        fluxes: boolean, optional
+            Decides if the flux parameters are to be retrieved or
+            the rest of the parameter list.
+            Default value is False.
+
+    @Return:
+        <nothing>
+    '''
+
+    # since actual day also counts as one day,
+    # we only need to add datechunk - 1 days to retrieval
+    # for a period
+    delta_t_m1 = delta_t - datetime.timedelta(days=1)
+
+    day = start
+    while day <= end:
+        flexpart = EcFlexpart(c, fluxes)
+        tmpday = day + delta_t_m1
+        if tmpday < end:
+            dates = day.strftime("%Y%m%d") + "/to/" + \
+                    tmpday.strftime("%Y%m%d")
+        else:
+            dates = day.strftime("%Y%m%d") + "/to/" + \
+                    end.strftime("%Y%m%d")
+
+        print("... retrieve " + dates + " in dir " + c.inputdir)
+
+        try:
+            flexpart.retrieve(server, dates, c.request, c.inputdir)
+        except IOError:
+            my_error(c.mailfail, 'MARS request failed')
+
+        day += delta_t
+
+    return
+
+if __name__ == "__main__":
+    main()
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/python/mods/plot_retrieved.py b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/mods/plot_retrieved.py
new file mode 100755
index 0000000000000000000000000000000000000000..21e27e7af636e24aa3411fbe1a7e50485917e181
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/mods/plot_retrieved.py
@@ -0,0 +1,670 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#*******************************************************************************
+# @Author: Leopold Haimberger (University of Vienna)
+#
+# @Date: November 2015
+#
+# @Change History:
+#
+#    February 2018 - Anne Philipp (University of Vienna):
+#        - applied PEP8 style guide
+#        - added documentation
+#        - created function main and moved the two function calls for
+#          arguments and plotting into it
+#        - added function get_basics to extract the boundary conditions
+#          of the data fields from the first grib file it gets.
+#
+# @License:
+#    (C) Copyright 2015-2018.
+#
+#    This software is licensed under the terms of the Apache Licence Version 2.0
+#    which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+#
+# @Program Functionality:
+#    Simple tool for creating maps and time series of retrieved fields.
+#
+# @Program Content:
+#    - main
+#    - get_basics
+#    - get_files_per_date
+#    - plot_retrieved
+#    - plot_timeseries
+#    - plot_map
+#    - get_plot_args
+#
+#*******************************************************************************
+
+# ------------------------------------------------------------------------------
+# MODULES
+# ------------------------------------------------------------------------------
+import time
+import datetime
+import os
+import inspect
+import sys
+from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
+import matplotlib
+import matplotlib.pyplot as plt
+from mpl_toolkits.basemap import Basemap
+from eccodes import codes_grib_new_from_file, codes_get, codes_release, \
+                    codes_get_values
+import numpy as np
+
+# software specific classes and modules from flex_extract
+import _config
+from classes.ControlFile import ControlFile
+from classes.UioFiles import UioFiles
+
+font = {'family': 'monospace', 'size': 12}
+matplotlib.rcParams['xtick.major.pad'] = '20'
+matplotlib.rc('font', **font)
+# ------------------------------------------------------------------------------
+# FUNCTION
+# ------------------------------------------------------------------------------
+def main():
+    '''
+    @Description:
+        If plot_retrieved is called from command line, this function controls
+        the program flow and calls the argumentparser function and
+        the plot_retrieved function for plotting the retrieved GRIB data.
+
+    @Input:
+        <nothing>
+
+    @Return:
+        <nothing>
+    '''
+    args, c = get_plot_args()
+    plot_retrieved(c)
+
+    return
+
+def get_basics(ifile, verb=False):
+    """
+    @Description:
+        An example grib file will be opened and basic information will
+        be extracted. These information are important for later use and the
+        initialization of numpy arrays for data storing.
+
+    @Input:
+        ifile: string
+            Contains the full absolute path to the ECMWF grib file.
+
+        verb (opt): bool
+            Is True if there should be extra output in verbose mode.
+            Default value is False.
+
+    @Return:
+        data: dict
+            Contains basic informations of the ECMWF grib files, e.g.
+            'Ni', 'Nj', 'latitudeOfFirstGridPointInDegrees',
+            'longitudeOfFirstGridPointInDegrees',
+            'latitudeOfLastGridPointInDegrees',
+            'longitudeOfLastGridPointInDegrees',
+            'jDirectionIncrementInDegrees',
+            'iDirectionIncrementInDegrees'
+    """
+
+    data = {}
+
+    # --- open file ---
+    print("Opening file for getting information data --- %s" %
+          os.path.basename(ifile))
+
+    with open(ifile) as f:
+
+        # load first message from file
+        gid = codes_grib_new_from_file(f)
+
+        # information needed from grib message
+        keys = ['Ni',
+                'Nj',
+                'latitudeOfFirstGridPointInDegrees',
+                'longitudeOfFirstGridPointInDegrees',
+                'latitudeOfLastGridPointInDegrees',
+                'longitudeOfLastGridPointInDegrees',
+                'jDirectionIncrementInDegrees',
+                'iDirectionIncrementInDegrees']
+
+        if verb:
+            print '\nInformations are: '
+        for key in keys:
+            # Get the value of the key in a grib message.
+            data[key] = codes_get(gid, key)
+            if verb:
+                print "%s = %s" % (key, data[key])
+        if verb:
+            print '\n'
+
+        # Free the memory for the message referred as gribid.
+        codes_release(gid)
+
+    return data
+
+def get_files_per_date(files, datelist):
+    '''
+    @Description:
+        The filenames contain dates which are used to select a list
+        of files for a specific time period specified in datelist.
+
+    @Input:
+        files: instance of UioFiles
+            For description see class documentation.
+            It contains the attribute "files" which is a list of pathes
+            to filenames.
+
+        datelist: list of datetimes
+            Contains the list of dates which should be processed for plotting.
+
+    @Return:
+        filelist: list of strings
+            Contains the selected files for the time period.
+    '''
+
+    filelist = []
+    for filename in files:
+        filedate = filename[-8:]
+        ddate = datetime.datetime.strptime(filedate, '%y%m%d%H')
+        if ddate in datelist:
+            filelist.append(filename)
+
+    return filelist
+
+def plot_retrieved(c):
+    '''
+    @Description:
+        Reads GRIB data from a specified time period, a list of levels
+        and a specified list of parameter.
+
+    @Input:
+        c: instance of class ControlFile
+            Contains all necessary information of a CONTROL file. The parameters
+            are: DAY1, DAY2, DTIME, MAXSTEP, TYPE, TIME, STEP, CLASS, STREAM,
+            NUMBER, EXPVER, GRID, LEFT, LOWER, UPPER, RIGHT, LEVEL, LEVELIST,
+            RESOL, GAUSS, ACCURACY, OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA,
+            SMOOTH, FORMAT, ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS,
+            ECFSDIR, MAILOPS, MAILFAIL, GRIB2FLEXPART, DEBUG, INPUTDIR,
+            OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+            For more information about format and content of the parameter see
+            documentation.
+
+    @Return:
+        <nothing>
+    '''
+    start = datetime.datetime.strptime(c.start_date, '%Y%m%d%H')
+    end = datetime.datetime.strptime(c.end_date, '%Y%m%d%H')
+
+    # create datelist between start and end date
+    datelist = [start] # initialise datelist with first date
+    run_date = start
+    while run_date < end:
+        run_date += datetime.timedelta(hours=int(c.dtime))
+        datelist.append(run_date)
+
+    print 'datelist: ', datelist
+
+    c.paramIds = np.asarray(c.paramIds, dtype='int')
+    c.levels = np.asarray(c.levels, dtype='int')
+    c.area = np.asarray(c.area)
+
+    files = UioFiles(c.inputdir, c.prefix+'*')
+    ifiles = get_files_per_date(files.files, datelist)
+    ifiles.sort()
+
+    gdict = get_basics(ifiles[0], verb=False)
+
+    fdict = dict()
+    fmeta = dict()
+    fstamp = dict()
+    for p in c.paramIds:
+        for l in c.levels:
+            key = '{:0>3}_{:0>3}'.format(p, l)
+            fdict[key] = []
+            fmeta[key] = []
+            fstamp[key] = []
+
+    for filename in ifiles:
+        f = open(filename)
+        print "Opening file for reading data --- %s" % filename
+        fdate = datetime.datetime.strptime(filename[-8:], "%y%m%d%H")
+
+        # Load in memory a grib message from a file.
+        gid = codes_grib_new_from_file(f)
+        while gid is not None:
+            gtype = codes_get(gid, 'type')
+            paramId = codes_get(gid, 'paramId')
+            parameterName = codes_get(gid, 'parameterName')
+            level = codes_get(gid, 'level')
+
+            if paramId in c.paramIds and level in c.levels:
+                key = '{:0>3}_{:0>3}'.format(paramId, level)
+                print 'key: ', key
+                if fstamp[key]:
+                    for i in range(len(fstamp[key])):
+                        if fdate < fstamp[key][i]:
+                            fstamp[key].insert(i, fdate)
+                            fmeta[key].insert(i, [paramId, parameterName, gtype,
+                                                  fdate, level])
+                            fdict[key].insert(i, np.flipud(np.reshape(
+                                codes_get_values(gid),
+                                [gdict['Nj'], gdict['Ni']])))
+                            break
+                        elif fdate > fstamp[key][i] and i == len(fstamp[key])-1:
+                            fstamp[key].append(fdate)
+                            fmeta[key].append([paramId, parameterName, gtype,
+                                               fdate, level])
+                            fdict[key].append(np.flipud(np.reshape(
+                                codes_get_values(gid),
+                                [gdict['Nj'], gdict['Ni']])))
+                            break
+                        elif fdate > fstamp[key][i] and i != len(fstamp[key])-1 \
+                             and fdate < fstamp[key][i+1]:
+                            fstamp[key].insert(i, fdate)
+                            fmeta[key].insert(i, [paramId, parameterName, gtype,
+                                                  fdate, level])
+                            fdict[key].insert(i, np.flipud(np.reshape(
+                                codes_get_values(gid),
+                                [gdict['Nj'], gdict['Ni']])))
+                            break
+                        else:
+                            pass
+                else:
+                    fstamp[key].append(fdate)
+                    fmeta[key].append((paramId, parameterName, gtype,
+                                       fdate, level))
+                    fdict[key].append(np.flipud(np.reshape(
+                        codes_get_values(gid), [gdict['Nj'], gdict['Ni']])))
+
+            codes_release(gid)
+
+            # Load in memory a grib message from a file.
+            gid = codes_grib_new_from_file(f)
+
+        f.close()
+
+    for k in fdict.iterkeys():
+        print 'fmeta: ', len(fmeta), fmeta
+        fml = fmeta[k]
+        fdl = fdict[k]
+        print 'fm1: ', len(fml), fml
+        for fd, fm in zip(fdl, fml):
+            print fm
+            ftitle = fm[1] + ' {} '.format(fm[-1]) + \
+                datetime.datetime.strftime(fm[3], '%Y%m%d%H')
+            pname = '_'.join(fm[1].split()) + '_{}_'.format(fm[-1]) + \
+                datetime.datetime.strftime(fm[3], '%Y%m%d%H')
+            plot_map(c, fd, fm, gdict, ftitle, pname, 'png')
+
+    for k in fdict.iterkeys():
+        fml = fmeta[k]
+        fdl = fdict[k]
+        fsl = fstamp[k]
+        if fdl:
+            fm = fml[0]
+            fd = fdl[0]
+            ftitle = fm[1] + ' {} '.format(fm[-1]) + \
+                datetime.datetime.strftime(fm[3], '%Y%m%d%H')
+            pname = '_'.join(fm[1].split()) + '_{}_'.format(fm[-1]) + \
+                datetime.datetime.strftime(fm[3], '%Y%m%d%H')
+            lat = -20.
+            lon = 20.
+            plot_timeseries(c, fdl, fml, fsl, lat, lon, gdict,
+                            ftitle, pname, 'png')
+
+    return
+
+def plot_timeseries(c, flist, fmetalist, ftimestamps, lat, lon,
+                    gdict, ftitle, filename, fending, show=False):
+    '''
+    @Description:
+        Creates a timeseries plot for a given lat/lon position.
+
+    @Input:
+        c: instance of class ControlFile
+            Contains all necessary information of a CONTROL file. The parameters
+            are: DAY1, DAY2, DTIME, MAXSTEP, TYPE, TIME, STEP, CLASS, STREAM,
+            NUMBER, EXPVER, GRID, LEFT, LOWER, UPPER, RIGHT, LEVEL, LEVELIST,
+            RESOL, GAUSS, ACCURACY, OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA,
+            SMOOTH, FORMAT, ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS,
+            ECFSDIR, MAILOPS, MAILFAIL, GRIB2FLEXPART, DEBUG, INPUTDIR,
+            OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+            For more information about format and content of the parameter see
+            documentation.
+
+        flist: numpy array, 2d
+            The actual data values to be plotted from the grib messages.
+
+        fmetalist: list of strings
+            Contains some meta date for the data field to be plotted:
+            parameter id, parameter Name, grid type, datetime, level
+
+        ftimestamps: list of datetime
+            Contains the time stamps.
+
+        lat: float
+            The latitude for which the timeseries should be plotted.
+
+        lon: float
+            The longitude for which the timeseries should be plotted.
+
+        gdict: dict
+            Contains basic informations of the ECMWF grib files, e.g.
+            'Ni', 'Nj', 'latitudeOfFirstGridPointInDegrees',
+            'longitudeOfFirstGridPointInDegrees',
+            'latitudeOfLastGridPointInDegrees',
+            'longitudeOfLastGridPointInDegrees',
+            'jDirectionIncrementInDegrees',
+            'iDirectionIncrementInDegrees'
+
+        ftitle: string
+            The title of the timeseries.
+
+        filename: string
+            The time series is stored in a file with this name.
+
+        fending: string
+            Contains the type of plot, e.g. pdf or png
+
+        show: boolean
+            Decides if the plot is shown after plotting or hidden.
+
+    @Return:
+        <nothing>
+    '''
+    print 'plotting timeseries'
+
+    t1 = time.time()
+
+    #llx = gdict['longitudeOfFirstGridPointInDegrees']
+    #if llx > 180. :
+    #    llx -= 360.
+    #lly = gdict['latitudeOfLastGridPointInDegrees']
+    #dxout = gdict['iDirectionIncrementInDegrees']
+    #dyout = gdict['jDirectionIncrementInDegrees']
+    #urx = gdict['longitudeOfLastGridPointInDegrees']
+    #ury = gdict['latitudeOfFirstGridPointInDegrees']
+    #numxgrid = gdict['Ni']
+    #numygrid = gdict['Nj']
+
+    farr = np.asarray(flist)
+    #(time, lat, lon)
+
+    #lonindex = linspace(llx, urx, numxgrid)
+    #latindex = linspace(lly, ury, numygrid)
+
+    ts = farr[:, 0, 0]
+
+    fig = plt.figure(figsize=(12, 6.7))
+
+    plt.plot(ftimestamps, ts)
+    plt.title(ftitle)
+
+    plt.savefig(c.outputdir + '/' + filename + '_TS.' + fending,
+                facecolor=fig.get_facecolor(),
+                edgecolor='none',
+                format=fending)
+    print 'created ', c.outputdir + '/' + filename
+    if show:
+        plt.show()
+    fig.clf()
+    plt.close(fig)
+
+    print time.time() - t1, 's'
+
+    return
+
+def plot_map(c, flist, fmetalist, gdict, ftitle, filename, fending, show=False):
+    '''
+    @Description:
+        Creates a basemap plot with imshow for a given data field.
+
+    @Input:
+        c: instance of class ControlFile
+            Contains all necessary information of a CONTROL file. The parameters
+            are: DAY1, DAY2, DTIME, MAXSTEP, TYPE, TIME, STEP, CLASS, STREAM,
+            NUMBER, EXPVER, GRID, LEFT, LOWER, UPPER, RIGHT, LEVEL, LEVELIST,
+            RESOL, GAUSS, ACCURACY, OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA,
+            SMOOTH, FORMAT, ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS,
+            ECFSDIR, MAILOPS, MAILFAIL, GRIB2FLEXPART, DEBUG, INPUTDIR,
+            OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+            For more information about format and content of the parameter see
+            documentation.
+
+        flist: numpy array, 2d
+            The actual data values to be plotted from the grib messages.
+
+        fmetalist: list of strings
+            Contains some meta date for the data field to be plotted:
+            parameter id, parameter Name, grid type, datetime, level
+
+        gdict: dict
+            Contains basic informations of the ECMWF grib files, e.g.
+            'Ni', 'Nj', 'latitudeOfFirstGridPointInDegrees',
+            'longitudeOfFirstGridPointInDegrees',
+            'latitudeOfLastGridPointInDegrees',
+            'longitudeOfLastGridPointInDegrees',
+            'jDirectionIncrementInDegrees',
+            'iDirectionIncrementInDegrees'
+
+        ftitle: string
+            The titel of the plot.
+
+        filename: string
+            The plot is stored in a file with this name.
+
+        fending: string
+            Contains the type of plot, e.g. pdf or png
+
+        show: boolean
+            Decides if the plot is shown after plotting or hidden.
+
+    @Return:
+        <nothing>
+    '''
+    print 'plotting map'
+
+    t1 = time.time()
+
+    fig = plt.figure(figsize=(12, 6.7))
+    #mbaxes = fig.add_axes([0.05, 0.15, 0.8, 0.7])
+
+    llx = gdict['longitudeOfFirstGridPointInDegrees'] #- 360
+    if llx > 180.:
+        llx -= 360.
+    lly = gdict['latitudeOfLastGridPointInDegrees']
+    #dxout = gdict['iDirectionIncrementInDegrees']
+    #dyout = gdict['jDirectionIncrementInDegrees']
+    urx = gdict['longitudeOfLastGridPointInDegrees']
+    ury = gdict['latitudeOfFirstGridPointInDegrees']
+    #numxgrid = gdict['Ni']
+    #numygrid = gdict['Nj']
+
+    m = Basemap(projection='cyl', llcrnrlon=llx, llcrnrlat=lly,
+                urcrnrlon=urx, urcrnrlat=ury, resolution='i')
+
+    #lw = 0.5
+    m.drawmapboundary()
+    #x = linspace(llx, urx, numxgrid)
+    #y = linspace(lly, ury, numygrid)
+
+    #xx, yy = m(*meshgrid(x, y))
+
+    #s = m.contourf(xx, yy, flist)
+
+    s = plt.imshow(flist.T,
+                   extent=(llx, urx, lly, ury),
+                   alpha=1.0,
+                   interpolation='nearest'
+                   #vmin=vn,
+                   #vmax=vx,
+                   #cmap=my_cmap,
+                   #levels=levels,
+                   #cmap=my_cmap,
+                   #norm=LogNorm(vn,vx)
+                  )
+
+    plt.title(ftitle, y=1.08)
+    cb = m.colorbar(s, location="right", pad="10%")
+    cb.set_label('label', size=14)
+
+    thickline = np.arange(lly, ury+1, 10.)
+    thinline = np.arange(lly, ury+1, 5.)
+    m.drawparallels(thickline,
+                    color='gray',
+                    dashes=[1, 1],
+                    linewidth=0.5,
+                    labels=[1, 1, 1, 1],
+                    xoffset=1.)
+    m.drawparallels(np.setdiff1d(thinline, thickline),
+                    color='lightgray',
+                    dashes=[1, 1],
+                    linewidth=0.5,
+                    labels=[0, 0, 0, 0])
+
+    thickline = np.arange(llx, urx+1, 10.)
+    thinline = np.arange(llx, urx+1, 5.)
+    m.drawmeridians(thickline,
+                    color='gray',
+                    dashes=[1, 1],
+                    linewidth=0.5,
+                    labels=[1, 1, 1, 1],
+                    yoffset=1.)
+    m.drawmeridians(np.setdiff1d(thinline, thickline),
+                    color='lightgray',
+                    dashes=[1, 1],
+                    linewidth=0.5,
+                    labels=[0, 0, 0, 0])
+
+    m.drawcoastlines()
+    m.drawcountries()
+
+    plt.savefig(c.outputdir + '/' + filename + '_MAP.' + fending,
+                facecolor=fig.get_facecolor(),
+                edgecolor='none',
+                format=fending)
+    print 'created ', c.outputdir + '/' + filename
+    if show:
+        plt.show()
+    fig.clf()
+    plt.close(fig)
+
+    print time.time() - t1, 's'
+
+    return
+
+def get_plot_args():
+    '''
+    @Description:
+        Assigns the command line arguments and reads CONTROL file
+        content. Apply default values for non mentioned arguments.
+
+    @Input:
+        <nothing>
+
+    @Return:
+        args: instance of ArgumentParser
+            Contains the commandline arguments from script/program call.
+
+        c: instance of class ControlFile
+            Contains all necessary information of a CONTROL file. The parameters
+            are: DAY1, DAY2, DTIME, MAXSTEP, TYPE, TIME, STEP, CLASS, STREAM,
+            NUMBER, EXPVER, GRID, LEFT, LOWER, UPPER, RIGHT, LEVEL, LEVELIST,
+            RESOL, GAUSS, ACCURACY, OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA,
+            SMOOTH, FORMAT, ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS,
+            ECFSDIR, MAILOPS, MAILFAIL, GRIB2FLEXPART, DEBUG, INPUTDIR,
+            OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+            For more information about format and content of the parameter see
+            documentation.
+    '''
+    parser = ArgumentParser(description='Plot retrieved GRIB data from ' + \
+                            'ECMWF MARS archive',
+                            formatter_class=ArgumentDefaultsHelpFormatter)
+
+# the most important arguments
+    parser.add_argument("--start_date", dest="start_date",
+                        help="start date YYYYMMDD")
+    parser.add_argument("--end_date", dest="end_date",
+                        help="end_date YYYYMMDD")
+
+    parser.add_argument("--start_step", dest="start_step",
+                        help="start step in hours")
+    parser.add_argument("--end_step", dest="end_step",
+                        help="end step in hours")
+
+# some arguments that override the default in the CONTROL file
+    parser.add_argument("--levelist", dest="levelist",
+                        help="vertical levels to be retrieved, e.g. 30/to/60")
+    parser.add_argument("--area", dest="area",
+                        help="area defined as north/west/south/east")
+    parser.add_argument("--paramIds", dest="paramIds",
+                        help="parameter IDs")
+    parser.add_argument("--prefix", dest="prefix", default='EN',
+                        help="output file name prefix")
+
+# set the working directories
+    parser.add_argument("--inputdir", dest="inputdir", default=None,
+                        help="root directory for storing intermediate files")
+    parser.add_argument("--outputdir", dest="outputdir", default=None,
+                        help="root directory for storing output files")
+    parser.add_argument("--flexpart_root_scripts", dest="flexpart_root_scripts",
+                        help="FLEXPART root directory (to find \
+                        'grib2flexpart and COMMAND file)\n \
+                        Normally flex_extract resides in the scripts directory \
+                        of the FLEXPART distribution")
+
+    parser.add_argument("--controlfile", dest="controlfile",
+                        default='CONTROL.temp',
+                        help="file with CONTROL parameters")
+    args = parser.parse_args()
+
+    try:
+        c = ControlFile(args.controlfile)
+    except IOError:
+        try:
+            c = ControlFile(LOCAL_PYTHON_PATH + args.controlfile)
+        except IOError:
+            print 'Could not read CONTROL file "' + args.controlfile + '"'
+            print 'Either it does not exist or its syntax is wrong.'
+            print 'Try "' + sys.argv[0].split('/')[-1] + \
+                  ' -h" to print usage information'
+            exit(1)
+
+    if args.levelist:
+        c.levels = args.levelist.split('/')
+    else:
+        c.levels = [0]
+
+    if args.area:
+        c.area = args.area.split('/')
+    else:
+        c.area = '[0,0]'
+
+    c.paramIds = args.paramIds.split('/')
+
+    if args.start_step:
+        c.start_step = int(args.start_step)
+    else:
+        c.start_step = 0
+
+    if args.end_step:
+        c.end_step = int(args.end_step)
+    else:
+        c.end_step = 0
+
+    c.start_date = args.start_date
+    c.end_date = args.end_date
+
+    c.prefix = args.prefix
+
+    c.inputdir = args.inputdir
+
+    if args.outputdir:
+        c.outputdir = args.outputdir
+    else:
+        c.outputdir = c.inputdir
+
+    return args, c
+
+if __name__ == "__main__":
+    main()
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/python/mods/prepare_flexpart.py b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/mods/prepare_flexpart.py
new file mode 100755
index 0000000000000000000000000000000000000000..4ac0af8fe37d7f4be3e7d4f7975f6b91e033470d
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/mods/prepare_flexpart.py
@@ -0,0 +1,196 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#*******************************************************************************
+# @Author: Anne Fouilloux (University of Oslo)
+#
+# @Date: October 2014
+#
+# @Change History:
+#
+#    November 2015 - Leopold Haimberger (University of Vienna):
+#        - using the WebAPI also for general MARS retrievals
+#        - job submission on ecgate and cca
+#        - job templates suitable for twice daily operational dissemination
+#        - dividing retrievals of longer periods into digestable chunks
+#        - retrieve also longer term forecasts, not only analyses and
+#          short term forecast data
+#        - conversion into GRIB2
+#        - conversion into .fp format for faster execution of FLEXPART
+#
+#    February 2018 - Anne Philipp (University of Vienna):
+#        - applied PEP8 style guide
+#        - added documentation
+#        - minor changes in programming style for consistence
+#        - BUG: removed call of clean_up-Function after call of
+#               prepareFlexpart in main since it is already called in
+#               prepareFlexpart at the end!
+#        - created function main and moved the two function calls for
+#          arguments and prepare_flexpart into it
+#
+# @License:
+#    (C) Copyright 2014-2018.
+#
+#    This software is licensed under the terms of the Apache Licence Version 2.0
+#    which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+#
+# @Program Functionality:
+#    This program prepares the final version of the grib files which are
+#    then used by FLEXPART. It converts the bunch of grib files extracted
+#    via get_mars_data by doing for example the necessary conversion to get
+#    consistent grids or the disaggregation of flux data. Finally, the
+#    program combines the data fields in files per available hour with the
+#    naming convention xxYYMMDDHH, where xx should be 2 arbitrary letters
+#    (mostly xx is chosen to be "EN").
+#
+# @Program Content:
+#    - main
+#    - prepare_flexpart
+#
+#*******************************************************************************
+
+# ------------------------------------------------------------------------------
+# MODULES
+# ------------------------------------------------------------------------------
+import datetime
+import os
+import inspect
+import sys
+import socket
+
+# software specific classes and modules from flex_extract
+import _config
+from classes.UioFiles import UioFiles
+from tools import clean_up, get_cmdline_arguments, read_ecenv
+from classes.EcFlexpart import EcFlexpart
+
+ecapi = 'ecmwf' not in socket.gethostname()
+try:
+    if ecapi:
+        import ecmwfapi
+except ImportError:
+    ecapi = False
+
+# ------------------------------------------------------------------------------
+# FUNCTION
+# ------------------------------------------------------------------------------
+def main():
+    '''
+    @Description:
+        If prepare_flexpart is called from command line, this function controls
+        the program flow and calls the argumentparser function and
+        the prepare_flexpart function for preparation of GRIB data for FLEXPART.
+
+    @Input:
+        <nothing>
+
+    @Return:
+        <nothing>
+    '''
+
+    args = get_cmdline_arguments()
+
+    try:
+        c = ControlFile(args.controlfile)
+    except IOError:
+        print('Could not read CONTROL file "' + args.controlfile + '"')
+        print('Either it does not exist or its syntax is wrong.')
+        print('Try "' + sys.argv[0].split('/')[-1] + \
+              ' -h" to print usage information')
+        sys.exit(1)
+
+    env_parameter = read_ecenv(_config.PATH_ECMWF_ENV)
+    c.assign_args_to_control(args, env_parameter)
+    c.assign_envs_to_control(env_parameter)
+    c.check_conditions(args.queue)
+    prepare_flexpart(args.ppid, c)
+
+    return
+
+def prepare_flexpart(ppid, c):
+    '''
+    @Description:
+        Lists all grib files retrieved from MARS with get_mars_data and
+        uses prepares data for the use in FLEXPART. Specific data fields
+        are converted to a different grid and the flux data are going to be
+        disaggregated. The data fields are collected by hour and stored in
+        a file with a specific FLEXPART relevant naming convention.
+
+    @Input:
+        ppid: int
+            Contains the ppid number of the current ECMWF job. If it is called
+            from this script, it is "None".
+
+        c: instance of class ControlFile
+            Contains all the parameters of CONTROL file, which are e.g.:
+            DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
+            STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
+            LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
+            OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
+            ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
+            MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
+            DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+
+            For more information about format and content of the parameter
+            see documentation.
+
+    @Return:
+        <nothing>
+    '''
+
+    if not ppid:
+        c.ppid = str(os.getppid())
+    else:
+        c.ppid = ppid
+
+    c.ecapi = ecapi
+
+    # create the start and end date
+    start = datetime.date(year=int(c.start_date[:4]),
+                          month=int(c.start_date[4:6]),
+                          day=int(c.start_date[6:]))
+
+    end = datetime.date(year=int(c.end_date[:4]),
+                        month=int(c.end_date[4:6]),
+                        day=int(c.end_date[6:]))
+
+    # assign starting date minus 1 day
+    # since for basetime 00 we need the 12 hours upfront
+    # (the day before from 12 UTC to current day 00 UTC)
+    if c.basetime == '00':
+        start = start - datetime.timedelta(days=1)
+
+    print('Prepare ' + start.strftime("%Y%m%d") +
+           "/to/" + end.strftime("%Y%m%d"))
+
+    # create output dir if necessary
+    if not os.path.exists(c.outputdir):
+        os.makedirs(c.outputdir)
+
+    # get all files with flux data to be deaccumulated
+    inputfiles = UioFiles(c.inputdir, '*OG_acc_SL*.' + c.ppid + '.*')
+
+    # deaccumulate the flux data
+    flexpart = EcFlexpart(c, fluxes=True)
+    flexpart.write_namelist(c, _config.FILE_NAMELIST)
+    flexpart.deacc_fluxes(inputfiles, c)
+
+    # get a list of all files from the root inputdir
+    inputfiles = UioFiles(c.inputdir, '????__??.*' + c.ppid + '.*')
+
+    # produce FLEXPART-ready GRIB files and process them -
+    # copy/transfer/interpolate them or make them GRIB2
+    flexpart = EcFlexpart(c, fluxes=False)
+    flexpart.create(inputfiles, c)
+    flexpart.process_output(c)
+
+    # check if in debugging mode, then store all files
+    # otherwise delete temporary files
+    if int(c.debug) != 0:
+        print('\nTemporary files left intact')
+    else:
+        clean_up(c)
+
+    return
+
+if __name__ == "__main__":
+    main()
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/python/mods/profiling.py b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/mods/profiling.py
new file mode 100644
index 0000000000000000000000000000000000000000..a20cad6d0c0c51b5868b045e9e56c74c80b88d11
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/mods/profiling.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#************************************************************************
+# ToDo AP
+# - check license of book content
+#************************************************************************
+#*******************************************************************************
+#
+# @Author: Anne Philipp (University of Vienna)
+#
+# @Date: March 2018
+#
+# @License:
+#    (C) Copyright 2018.
+#
+#    This software is licensed under the terms of the Apache Licence Version 2.0
+#    which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+#
+# @Program functionality:
+#    This module is not part of flex_extract. It is just used for testing and
+#    performance analysis of some functions.
+#
+# @Program Content:
+#    - timefn
+#
+#*******************************************************************************
+
+# ------------------------------------------------------------------------------
+# MODULES
+# ------------------------------------------------------------------------------
+from functools import wraps
+import time
+
+# ------------------------------------------------------------------------------
+# FUNCTION
+# ------------------------------------------------------------------------------
+def timefn(fn):
+    '''
+    @Description:
+        Decorator function. It takes the inner function as an argument.
+    '''
+    @wraps(fn)
+    def measure_time(*args, **kwargs):
+        '''
+        @Descripton:
+            Passes the arguments through fn for execution. Around the
+            execution of fn the time is captured to execute the fn function
+            and prints the result along with the function name.
+
+            This is taken from the book "High Performance Python" from
+            Micha Gorelick and Ian Ozsvald, O'Reilly publisher, 2014,
+            ISBN: 978-1-449-36159-4
+
+        @Input:
+            *args: undefined
+                A variable number of positional arguments.
+
+            **kwargs: undefined
+                A variable number of key/value arguments.
+
+        @Return:
+            <nothing>
+        '''
+
+        t1 = time.time()
+        result = fn(*args, **kwargs)
+        t2 = time.time()
+        print("@timefn:" + fn.func_name + " took " + str(t2 - t1) + " seconds")
+
+        return result
+
+    return measure_time
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/python/mods/tools.py b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/mods/tools.py
new file mode 100644
index 0000000000000000000000000000000000000000..b2cd1dc33dfcadd2dbf20a908998b87d12a2472a
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/mods/tools.py
@@ -0,0 +1,533 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#*******************************************************************************
+# @Author: Anne Philipp (University of Vienna)
+#
+# @Date: May 2018
+#
+# @Change History:
+#    October 2014 - Anne Fouilloux (University of Oslo)
+#        - created functions silent_remove and product (taken from ECMWF)
+#
+#    November 2015 - Leopold Haimberger (University of Vienna)
+#        - created functions: interpret_args_and_control, clean_up
+#          my_error, normal_exit, init128, to_param_id
+#
+#    April 2018 - Anne Philipp (University of Vienna):
+#        - applied PEP8 style guide
+#        - added documentation
+#        - moved all functions from file Flexparttools to this file tools
+#        - added function get_list_as_string
+#        - seperated args and control interpretation
+#
+# @License:
+#    (C) Copyright 2014-2018.
+#
+#    This software is licensed under the terms of the Apache Licence Version 2.0
+#    which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+#
+# @Modul Description:
+#    This module contains a couple of helpful functions which are
+#    used in different places in flex_extract.
+#
+# @Module Content:
+#    - get_cmdline_arguments
+#    - clean_up
+#    - my_error
+#    - normal_exit
+#    - product
+#    - silent_remove
+#    - init128
+#    - to_param_id
+#    - get_list_as_string
+#    - make_dir
+#
+#*******************************************************************************
+
+# ------------------------------------------------------------------------------
+# MODULES
+# ------------------------------------------------------------------------------
+import os
+import errno
+import sys
+import glob
+import subprocess
+import traceback
+from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
+
+# ------------------------------------------------------------------------------
+# FUNCTIONS
+# ------------------------------------------------------------------------------
+
+def get_cmdline_arguments():
+    '''
+    @Description:
+        Decomposes the command line arguments and assigns them to variables.
+        Apply default values for non mentioned arguments.
+
+    @Input:
+        <nothing>
+
+    @Return:
+        args: instance of ArgumentParser
+            Contains the commandline arguments from script/program call.
+    '''
+
+    parser = ArgumentParser(description='Retrieve FLEXPART input from \
+                                ECMWF MARS archive',
+                            formatter_class=ArgumentDefaultsHelpFormatter)
+
+    # the most important arguments
+    parser.add_argument("--start_date", dest="start_date", default=None,
+                        help="start date YYYYMMDD")
+    parser.add_argument("--end_date", dest="end_date", default=None,
+                        help="end_date YYYYMMDD")
+    parser.add_argument("--date_chunk", dest="date_chunk", default=None,
+                        help="# of days to be retrieved at once")
+
+    # some arguments that override the default in the CONTROL file
+    parser.add_argument("--basetime", dest="basetime", default=None,
+                        help="base such as 00/12 (for half day retrievals)")
+    parser.add_argument("--step", dest="step", default=None,
+                        help="steps such as 00/to/48")
+    parser.add_argument("--levelist", dest="levelist", default=None,
+                        help="Vertical levels to be retrieved, e.g. 30/to/60")
+    parser.add_argument("--area", dest="area", default=None,
+                        help="area defined as north/west/south/east")
+
+    # set the working directories
+    parser.add_argument("--inputdir", dest="inputdir", default=None,
+                        help="root directory for storing intermediate files")
+    parser.add_argument("--outputdir", dest="outputdir", default=None,
+                        help="root directory for storing output files")
+    parser.add_argument("--flexpart_root_scripts", dest="flexpart_root_scripts",
+                        default=None,
+                        help="FLEXPART root directory (to find grib2flexpart \
+                        and COMMAND file)\n Normally flex_extract resides in \
+                        the scripts directory of the FLEXPART distribution")
+
+    # this is only used by prepare_flexpart.py to rerun a postprocessing step
+    parser.add_argument("--ppid", dest="ppid", default=None,
+                        help="specify parent process id for \
+                        rerun of prepare_flexpart")
+
+    # arguments for job submission to ECMWF, only needed by submit.py
+    parser.add_argument("--job_template", dest='job_template',
+                        default="job.temp",
+                        help="job template file for submission to ECMWF")
+    parser.add_argument("--queue", dest="queue", default=None,
+                        help="queue for submission to ECMWF \
+                        (e.g. ecgate or cca )")
+    parser.add_argument("--controlfile", dest="controlfile",
+                        default='CONTROL.temp',
+                        help="file with CONTROL parameters")
+    parser.add_argument("--debug", dest="debug", default=None,
+                        help="debug mode - leave temporary files intact")
+    parser.add_argument("--request", dest="request", default=None,
+                        help="list all mars request in file mars_requests.dat \
+                        and skip submission to mars")
+
+    args = parser.parse_args()
+
+    return args
+
+def read_ecenv(filename):
+    '''
+    @Description:
+        Reads the file into a dictionary where the key values are the parameter
+        names.
+
+    @Input:
+        filename: string
+            Path to file where the ECMWV environment parameters are stored.
+
+    @Return:
+        envs: dict
+            Contains the environment parameter ecuid, ecgid, gateway
+            and destination for ECMWF server environments.
+    '''
+    envs= {}
+
+    with open(filename, 'r') as f:
+        for line in f:
+            data = line.strip().split()
+            envs[str(data[0])] = str(data[1])
+
+    return envs
+
+def clean_up(c):
+    '''
+    @Description:
+        Remove all files from intermediate directory
+        (inputdir from CONTROL file).
+
+    @Input:
+        c: instance of class ControlFile
+            Contains all the parameters of CONTROL file, which are e.g.:
+            DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
+            STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
+            LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
+            OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
+            ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
+            MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
+            DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+
+            For more information about format and content of the parameter
+            see documentation.
+
+    @Return:
+        <nothing>
+    '''
+
+    print("clean_up")
+
+    cleanlist = glob.glob(c.inputdir + "/*")
+    for clist in cleanlist:
+        if c.prefix not in clist:
+            silent_remove(clist)
+        if c.ecapi is False and (c.ectrans == '1' or c.ecstorage == '1'):
+            silent_remove(clist)
+
+    print("Done")
+
+    return
+
+
+def my_error(users, message='ERROR'):
+    '''
+    @Description:
+        Prints a specified error message which can be passed to the function
+        before exiting the program.
+
+    @Input:
+        user: list of strings
+            Contains all email addresses which should be notified.
+            It might also contain just the ecmwf user name which wil trigger
+            mailing to the associated email address for this user.
+
+        message: string, optional
+            Error message. Default value is "ERROR".
+
+    @Return:
+        <nothing>
+    '''
+
+    print(message)
+
+    # comment if user does not want email notification directly from python
+    for user in users:
+        if '${USER}' in user:
+            user = os.getenv('USER')
+        try:
+            p = subprocess.Popen(['mail', '-s flex_extract_v7.1 ERROR',
+                                  os.path.expandvars(user)],
+                                 stdin=subprocess.PIPE,
+                                 stdout=subprocess.PIPE,
+                                 stderr=subprocess.PIPE,
+                                 bufsize=1)
+            trace = '\n'.join(traceback.format_stack())
+            pout = p.communicate(input=message + '\n\n' + trace)[0]
+        except ValueError as e:
+            print('ERROR: ', e)
+            sys.exit('Email could not be sent!')
+        else:
+            print('Email sent to ' + os.path.expandvars(user) + ' ' +
+                  pout.decode())
+
+    sys.exit(1)
+
+    return
+
+
+def normal_exit(users, message='Done!'):
+    '''
+    @Description:
+        Prints a specific exit message which can be passed to the function.
+
+    @Input:
+        user: list of strings
+            Contains all email addresses which should be notified.
+            It might also contain just the ecmwf user name which wil trigger
+            mailing to the associated email address for this user.
+
+        message: string, optional
+            Message for exiting program. Default value is "Done!".
+
+    @Return:
+        <nothing>
+
+    '''
+    print(message)
+
+    # comment if user does not want notification directly from python
+    for user in users:
+        if '${USER}' in user:
+            user = os.getenv('USER')
+        try:
+            p = subprocess.Popen(['mail', '-s flex_extract_v7.1 normal exit',
+                                  os.path.expandvars(user)],
+                                 stdin=subprocess.PIPE,
+                                 stdout=subprocess.PIPE,
+                                 stderr=subprocess.PIPE,
+                                 bufsize=1)
+            pout = p.communicate(input=message+'\n\n')[0]
+        except ValueError as e:
+            print('ERROR: ', e)
+            print('Email could not be sent!')
+        else:
+            print('Email sent to ' + os.path.expandvars(user) + ' ' +
+                  pout.decode())
+
+    return
+
+
+def product(*args, **kwds):
+    '''
+    @Description:
+        This method is taken from an example at the ECMWF wiki website.
+        https://software.ecmwf.int/wiki/display/GRIB/index.py; 2018-03-16
+
+        This method combines the single characters of the passed arguments
+        with each other. So that each character of each argument value
+        will be combined with each character of the other arguments as a tuple.
+
+        Example:
+        product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
+        product(range(2), repeat = 3) --> 000 001 010 011 100 101 110 111
+
+    @Input:
+        *args: tuple
+            Positional arguments (arbitrary number).
+
+        **kwds: dictionary
+            Contains all the keyword arguments from *args.
+
+    @Return:
+        prod: tuple
+            Return will be done with "yield". A tuple of combined arguments.
+            See example in description above.
+    '''
+    pools = map(tuple, args) * kwds.get('repeat', 1)
+    result = [[]]
+    for pool in pools:
+        result = [x + [y] for x in result for y in pool]
+    for prod in result:
+        yield tuple(prod)
+
+    return
+
+
+def silent_remove(filename):
+    '''
+    @Description:
+        Remove file if it exists.
+        The function does not fail if the file does not exist.
+
+    @Input:
+        filename: string
+            The name of the file to be removed without notification.
+
+    @Return:
+        <nothing>
+    '''
+    try:
+        os.remove(filename)
+    except OSError as e:
+        if e.errno != errno.ENOENT:
+            # errno.ENOENT  =  no such file or directory
+            raise  # re-raise exception if a different error occured
+
+    return
+
+
+def init128(filepath):
+    '''
+    @Description:
+        Opens and reads the grib file with table 128 information.
+
+    @Input:
+        filepath: string
+            Path to file of ECMWF grib table number 128.
+
+    @Return:
+        table128: dictionary
+            Contains the ECMWF grib table 128 information.
+            The key is the parameter number and the value is the
+            short name of the parameter.
+    '''
+    table128 = dict()
+    with open(filepath) as f:
+        fdata = f.read().split('\n')
+    for data in fdata:
+        if data[0] != '!':
+            table128[data[0:3]] = data[59:64].strip()
+
+    return table128
+
+
+def to_param_id(pars, table):
+    '''
+    @Description:
+        Transform parameter names to parameter ids
+        with ECMWF grib table 128.
+
+    @Input:
+        pars: string
+            Addpar argument from CONTROL file in the format of
+            parameter names instead of ids. The parameter short
+            names are sepearted with "/" and they are passed as
+            one single string.
+
+        table: dictionary
+            Contains the ECMWF grib table 128 information.
+            The key is the parameter number and the value is the
+            short name of the parameter.
+
+    @Return:
+        ipar: list of integer
+            List of addpar parameters from CONTROL file transformed to
+            parameter ids in the format of integer.
+    '''
+    cpar = pars.upper().split('/')
+    ipar = []
+    for par in cpar:
+        for k, v in table.iteritems():
+            if par == k or par == v:
+                ipar.append(int(k))
+                break
+        else:
+            print('Warning: par ' + par + ' not found in table 128')
+
+    return ipar
+
+def get_list_as_string(list_obj, concatenate_sign=', '):
+    '''
+    @Description:
+        Converts a list of arbitrary content into a single string.
+
+    @Input:
+        list_obj: list
+            A list with arbitrary content.
+
+        concatenate_sign: string, optional
+            A string which is used to concatenate the single
+            list elements. Default value is ", ".
+
+    @Return:
+        str_of_list: string
+            The content of the list as a single string.
+    '''
+
+    str_of_list = concatenate_sign.join(str(l) for l in list_obj)
+
+    return str_of_list
+
+def make_dir(directory):
+    '''
+    @Description:
+        Creates a directory and gives a warning if the directory
+        already exists. The program stops only if there is another problem.
+
+    @Input:
+        directory: string
+            The directory name including the path which should be created.
+
+    @Return:
+        <nothing>
+    '''
+    try:
+        os.makedirs(directory)
+    except OSError as e:
+        if e.errno != errno.EEXIST:
+            # errno.EEXIST = directory already exists
+            raise # re-raise exception if a different error occured
+        else:
+            print('WARNING: Directory {0} already exists!'.format(directory))
+
+    return
+
+def put_file_to_ecserver(ecd, filename, target, ecuid, ecgid):
+    '''
+    @Description:
+        Uses the ecaccess-file-put command to send a file to the ECMWF servers.
+
+        NOTE:
+        The return value is just for testing reasons. It does not have
+        to be used from the calling function since the whole error handling
+        is done in here.
+
+    @Input:
+        ecd: string
+            The path were the file is stored.
+
+        filename: string
+            The name of the file to send to the ECMWF server.
+
+        target: string
+            The target queue where the file should be sent to.
+
+        ecuid: string
+            The user id on ECMWF server.
+
+        ecgid: string
+            The group id on ECMWF server.
+
+    @Return:
+        rcode: string
+            Resulting code of command execution. If successful the string
+            will be empty.
+    '''
+
+    try:
+        rcode = subprocess.check_output(['ecaccess-file-put',
+                                          ecd + '/' + filename,
+                                          target + ':/home/ms/' +
+                                          ecgid + '/' + ecuid +
+                                          '/' + filename],
+                                         stderr=subprocess.STDOUT)
+    except subprocess.CalledProcessError as e:
+        print('... ERROR CODE:\n ... ' + str(e.returncode))
+        print('... ERROR MESSAGE:\n ... ' + str(e))
+
+        print('\n... Do you have a valid ecaccess certification key?')
+        sys.exit('... ECACCESS-FILE-PUT FAILED!')
+
+    return rcode
+
+def submit_job_to_ecserver(target, jobname):
+    '''
+    @Description:
+        Uses ecaccess-job-submit command to submit a job to the ECMWF server.
+
+        NOTE:
+        The return value is just for testing reasons. It does not have
+        to be used from the calling function since the whole error handling
+        is done in here.
+
+    @Input:
+        target: string
+            The target where the file should be sent to, e.g. the queue.
+
+        jobname: string
+            The name of the jobfile to be submitted to the ECMWF server.
+
+    @Return:
+        rcode: string
+            Resulting code of command execution. If successful the string
+            will contain an integer number, representing the id of the job
+            at the ecmwf server.
+    '''
+
+    try:
+        rcode = subprocess.check_output(['ecaccess-job-submit',
+                                         '-queueName', target,
+                                         jobname])
+    except subprocess.CalledProcessError as e:
+        print('... ERROR CODE:\n ... ' + str(e.returncode))
+        print('... ERROR MESSAGE:\n ... ' + str(e))
+
+
+        print('\n... Do you have a valid ecaccess certification key?')
+        sys.exit('... ECACCESS-JOB-SUBMIT FAILED!')
+
+    return rcode
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/source/python/submit.py b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/submit.py
new file mode 100755
index 0000000000000000000000000000000000000000..9819583fe2d42f975612fb724a20ac1850cfe9c6
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/source/python/submit.py
@@ -0,0 +1,201 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#*******************************************************************************
+# @Author: Anne Fouilloux (University of Oslo)
+#
+# @Date: October 2014
+#
+# @Change History:
+#
+#    November 2015 - Leopold Haimberger (University of Vienna):
+#        - job submission on ecgate and cca
+#        - job templates suitable for twice daily operational dissemination
+#
+#    February 2018 - Anne Philipp (University of Vienna):
+#        - applied PEP8 style guide
+#        - added documentation
+#        - minor changes in programming style (for consistence)
+#        - changed path names to variables from config file
+#        - added option for writing mars requests to extra file
+#          additionally,as option without submitting the mars jobs
+#
+# @License:
+#    (C) Copyright 2014-2018.
+#
+#    This software is licensed under the terms of the Apache Licence Version 2.0
+#    which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
+#
+# @Program Functionality:
+#    This program is the main program of flex_extract and controls the
+#    program flow.
+#    If it is supposed to work locally then it works through the necessary
+#    functions get_mars_data and prepareFlexpart. Otherwise it prepares
+#    a shell job script which will do the necessary work on the
+#    ECMWF server and is submitted via ecaccess-job-submit.
+#
+# @Program Content:
+#    - main
+#    - submit
+#
+#*******************************************************************************
+
+# ------------------------------------------------------------------------------
+# MODULES
+# ------------------------------------------------------------------------------
+import os
+import sys
+import subprocess
+import inspect
+import collections
+
+# software specific classes and modules from flex_extract
+import _config
+from mods.tools import (normal_exit, get_cmdline_arguments,
+                        submit_job_to_ecserver, read_ecenv)
+from mods.get_mars_data import get_mars_data
+from mods.prepare_flexpart import prepare_flexpart
+from classes.ControlFile import ControlFile
+
+# ------------------------------------------------------------------------------
+# FUNCTIONS
+# ------------------------------------------------------------------------------
+
+def main():
+    '''
+    @Description:
+        Get the arguments from script call and from CONTROL file.
+        Decides from the argument "queue" if the local version
+        is done "queue=None" or the gateway version with "queue=ecgate"
+        or "queue=cca".
+
+    @Input:
+        <nothing>
+
+    @Return:
+        <nothing>
+    '''
+
+    args = get_cmdline_arguments()
+
+    try:
+        c = ControlFile(args.controlfile)
+    except IOError:
+        print('Could not read CONTROL file "' + args.controlfile + '"')
+        print('Either it does not exist or its syntax is wrong.')
+        print('Try "' + sys.argv[0].split('/')[-1] + \
+              ' -h" to print usage information')
+        sys.exit(1)
+
+    env_parameter = read_ecenv(_config.PATH_ECMWF_ENV)
+    c.assign_args_to_control(args)
+    c.assign_envs_to_control(env_parameter)
+    c.check_conditions(args.queue)
+
+    # on local side
+    # on ECMWF server this would also be the local side
+    called_from_dir = os.getcwd()
+    if args.queue is None:
+        if c.inputdir[0] != '/':
+            c.inputdir = os.path.join(called_from_dir, c.inputdir)
+        if c.outputdir[0] != '/':
+            c.outputdir = os.path.join(called_from_dir, c.outputdir)
+        get_mars_data(c)
+        if c.request == 0 or c.request == 2:
+            prepare_flexpart(args.ppid, c)
+            normal_exit(c.mailfail, 'FLEX_EXTRACT IS DONE!')
+        else:
+            normal_exit(c.mailfail, 'PRINTING MARS_REQUESTS DONE!')
+    # send files to ECMWF server and install there
+    else:
+        submit(args.job_template, c, args.queue)
+
+    return
+
+def submit(jtemplate, c, queue):
+    '''
+    @Description:
+        Prepares the job script and submit it to the specified queue.
+
+    @Input:
+        jtemplate: string
+            Job template file from sub-directory "_templates" for
+            submission to ECMWF. It contains all necessary
+            module and variable settings for the ECMWF environment as well as
+            the job call and mail report instructions.
+            Default is "job.temp".
+
+        c: instance of class ControlFile
+            Contains all the parameters of CONTROL file, which are e.g.:
+            DAY1(start_date), DAY2(end_date), DTIME, MAXSTEP, TYPE, TIME,
+            STEP, CLASS(marsclass), STREAM, NUMBER, EXPVER, GRID, LEFT,
+            LOWER, UPPER, RIGHT, LEVEL, LEVELIST, RESOL, GAUSS, ACCURACY,
+            OMEGA, OMEGADIFF, ETA, ETADIFF, DPDETA, SMOOTH, FORMAT,
+            ADDPAR, WRF, CWC, PREFIX, ECSTORAGE, ECTRANS, ECFSDIR,
+            MAILOPS, MAILFAIL, GRIB2FLEXPART, FLEXPARTDIR, BASETIME
+            DATE_CHUNK, DEBUG, INPUTDIR, OUTPUTDIR, FLEXPART_ROOT_SCRIPTS
+
+            For more information about format and content of the parameter
+            see documentation.
+
+        queue: string
+            Name of queue for submission to ECMWF (e.g. ecgate or cca )
+
+    @Return:
+        <nothing>
+    '''
+
+    # read template file and get index for CONTROL input
+    with open(os.path.join(_config.PATH_TEMPLATES, jtemplate)) as f:
+        lftext = f.read().split('\n')
+    insert_point = lftext.index('EOF')
+
+    if not c.basetime:
+    # --------- create on demand job script ------------------------------------
+        if c.maxstep > 24:
+            print('---- Pure forecast mode! ----')
+        else:
+            print('---- On-demand mode! ----')
+        job_file = os.path.join(_config.PATH_JOBSCRIPTS,
+                                jtemplate[:-4] + 'ksh')
+        clist = c.to_list()
+
+        lftextondemand = lftext[:insert_point] + clist + lftext[insert_point:]
+
+        with open(job_file, 'w') as f:
+            f.write('\n'.join(lftextondemand))
+
+        submit_job_to_ecserver(queue, job_file)
+
+    else:
+    # --------- create operational job script ----------------------------------
+        print('---- Operational mode! ----')
+        job_file = os.path.join(_config.PATH_JOBSCRIPTS,
+                                jtemplate[:-5] + 'oper.ksh')
+
+        if c.maxstep:
+            mt = int(c.maxstep)
+        else:
+            mt = 0
+
+        c.start_date = '${MSJ_YEAR}${MSJ_MONTH}${MSJ_DAY}'
+        c.end_date = '${MSJ_YEAR}${MSJ_MONTH}${MSJ_DAY}'
+        c.base_time = '${MSJ_BASETIME}'
+        if mt > 24:
+            c.time = '${MSJ_BASETIME} {MSJ_BASETIME}'
+
+        colist = c.to_list()
+
+        lftextoper = lftext[:insert_point] + colist + lftext[insert_point + 2:]
+
+        with open(job_file, 'w') as f:
+            f.write('\n'.join(lftextoper))
+
+        submit_job_to_ecserver(queue, job_file)
+
+    # --------------------------------------------------------------------------
+    print('You should get an email with subject flex.hostname.pid')
+
+    return
+
+if __name__ == "__main__":
+    main()
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/templates/compilejob.temp b/test/InstallTar/flex_extract_v7.1_ecgate/templates/compilejob.temp
new file mode 100644
index 0000000000000000000000000000000000000000..715308b3d361e2b0f5c088b344ecde539d74243e
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/templates/compilejob.temp
@@ -0,0 +1,77 @@
+#!/bin/ksh
+
+# ON ECGB:
+# start with ecaccess-job-submit -queueName ecgb NAME_OF_THIS_FILE  on gateway server
+# start with sbatch NAME_OF_THIS_FILE directly on machine
+
+#SBATCH --workdir=/scratch/ms/spatlh00/lh0
+#SBATCH --qos=normal
+#SBATCH --job-name=flex_ecmwf
+#SBATCH --output=flex_ecmwf.%j.out
+#SBATCH --error=flex_ecmwf.%j.out
+#SBATCH --mail-type=FAIL
+#SBATCH --time=12:00:00
+
+## CRAY specific batch requests
+##PBS -N flex_ecmwf
+##PBS -q ns
+##PBS -S /usr/bin/ksh
+# -o /scratch/ms/no/sbc/flex_ecmwf.$Jobname.$Job_ID.out
+# job output is in .ecaccess_DO_NOT_REMOVE
+##PBS -j oe
+##PBS -V
+##PBS -l EC_threads_per_task=1
+##PBS -l EC_memory_per_task=3200MB
+
+set -x
+export VERSION=7.1
+case $HOST in
+  *ecg*)
+  module load python
+  module unload grib_api
+  module unload emos
+  module load grib_api/1.14.5
+  module load emos/437-r64
+  export FLEXPART_ROOT_SCRIPTS=
+  export MAKEFILE=Makefile.gfortran
+  ;;
+  *cca*)
+  module switch PrgEnv-cray PrgEnv-intel
+  module load grib_api
+  module load emos
+  module load python
+  echo ${GROUP}
+  echo ${HOME}
+  echo $HOME | awk -F / '{print $1, $2, $3, $4}'
+  export GROUP=`echo $HOME | awk -F / '{print $4}'`
+  export SCRATCH=/scratch/ms/${GROUP}/${USER}
+  export FLEXPART_ROOT_SCRIPTS=
+  export MAKEFILE=Makefile.CRAY
+  ;;
+esac
+
+mkdir -p $FLEXPART_ROOT_SCRIPTS/flex_extract_v$VERSION
+cd $FLEXPART_ROOT_SCRIPTS/flex_extract_v$VERSION   # if FLEXPART_ROOT is not set this means cd to the home directory
+tar -xvf $HOME/flex_extract_v$VERSION.tar
+cd src
+\rm *.o *.mod CONVERT2
+make -f $MAKEFILE >flexcompile 2>flexcompile
+
+ls -l CONVERT2 >>flexcompile
+if [ $? -eq 0 ]; then
+  echo 'SUCCESS!' >>flexcompile
+  mail -s flexcompile.$HOST.$$ $USER <flexcompile
+else
+  echo Environment: >>flexcompile
+  env >> flexcompile
+  mail -s "ERROR! flexcompile.$HOST.$$" $USER <flexcompile
+fi
+
+
+
+
+
+
+
+
+
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/templates/ecmwf_grib1_table_128 b/test/InstallTar/flex_extract_v7.1_ecgate/templates/ecmwf_grib1_table_128
new file mode 100644
index 0000000000000000000000000000000000000000..b14d7afb69fd6f687840d2c406698f56f3d696d8
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/templates/ecmwf_grib1_table_128
@@ -0,0 +1,197 @@
+! 
+! ECMWFGRIB128.TBL -- GRIB 2 parameter conversion table version 128 
+!
+!ID# NAME                             UNITS                GNAM         SCALE   MISSING 
+!
+001 Stream function                   m**2 s**-1           STRF             0  -9999.00
+002 Velocity potential                m**2 s**-1           VPOT             0  -9999.00
+003 Potential temperature             K                    THTA             0  -9999.00
+004 Equivalent potential temperature  K                    THTE             0  -9999.00
+005 Saturated eq. pot. temperature    K                    STHE             0  -9999.00
+!006-010 Reserved for Metview
+011 U component of divergent wind     m s**-1              UDVW             0  -9999.00
+012 V component of divergent wind     m s**-1              VDVW             0  -9999.00
+013 U component of rotational wind    m s**-1              URTW             0  -9999.00
+014 V component of rotational wind    m s**-1              VRTW             0  -9999.00
+!015-020 Reserved for Metview
+021 Unbalanced component of temp.     K                    UCTP             0  -9999.00
+022 Unbal. comp. of log surface pres  ln(Pa)               UCLN             0  -9999.00
+023 Unbal. comp. of divergence        s**-1                UCDV             0  -9999.00
+024 Reserved for future unbal. comp.  -                    X                0  -9999.00
+023 Reserved for future unbal. comp.  -                    X                0  -9999.00
+026 Lake cover (0-1)                  fraction             CL               0  -9999.00
+027 Low vegetation cover (0-1)        fraction             CVL              0  -9999.00
+028 High vegetation cover (0-1)       fraction             CVH              0  -9999.00
+029 Type of low vegetation            type                 TVL              0  -9999.00
+030 Type of high vegetation           type                 TVH              0  -9999.00
+031 Sea-ice cover (0-1)               fraction             CI               0  -9999.00
+032 Snow albedo (0-1)                 fraction             ASN              0  -9999.00
+033 Snow density                      kg m**-3             RSN              0  -9999.00
+034 Sea surface temperature           K                    SST              0  -9999.00
+035 Ice surface temperature layer 1   K                    ISTL1            0  -9999.00
+036 Ice surface temperature layer 2   K                    ISTL2            0  -9999.00
+037 Ice surface temperature layer 3   K                    ISTL3            0  -9999.00
+038 Ice surface temperature layer 4   K                    ISTL4            0  -9999.00
+039 Volumetric soil water layer 1     m**3 m**3            SWVL1            0  -9999.00
+040 Volumetric soil water layer 2     m**3 m**3            SWVL2            0  -9999.00
+041 Volumetric soil water layer 3     m**3 m**3            SWVL3            0  -9999.00
+042 Volumetric soil water layer 4     m**3 m**3            SWVL4            0  -9999.00
+043 Soil type                         type                 SLT              0  -9999.00
+044 Snow evaporation                  m (H2O)              ES               0  -9999.00
+045 Snowmelt                          m (H2)               SMLT             0  -9999.00
+046 Solar duration                    s                    SDUR             0  -9999.00
+047 Direct solar radiation            W m**-2              DSRP             0  -9999.00
+048 Magnitude of surface stress       N m**-2 s            MAGSS            0  -9999.00
+049 10 metre wind gust                m s**-1              10FG             0  -9999.00
+050 Large-scale precip. fraction      s                    SLPF             0  -9999.00
+051 Maximum 2 metre temperature       K                    MX2T24           0  -9999.00
+052 Minimum 2 metre temperature       K                    MN2T24           0  -9999.00
+053 Montgomery potential              m**2 s**-2           MONT             0  -9999.00
+054 Pressure                          Pa                   PRES             0  -9999.00
+055 Mean 2m temp.in past 24 hours     K                    MN2T24           0  -9999.00
+056 Mean 2m dewpt. temp. in past 24h  K                    MN2D24           0  -9999.00
+057 Downward UV radiation at sfc.     W m**-2 s            UVB              0  -9999.00
+058 Photo. active rad. at sfc.        W m**-2 s            PAR              0  -9999.00
+059 Convective available pot. energy  J kg**-1             CAPE             0  -9999.00
+060 Potential vorticity               K m**2 kg**-1 s**-1  PVOR             0  -9999.00
+061 Total precipitation from obs.     mm*100+Nobs          TPO              0  -9999.00
+062 Observation count                 count                OBCT             0  -9999.00
+063 Start time for skin temp. diff.   s                    TSDIFS           0  -9999.00
+064 Finish time for skin temp. diff.  s                    TSDIFE           0  -9999.00
+065 Skin temperature difference       K                    TSDIF            0  -9999.00
+!66 to 77 Unused
+078 Total column liquid water         kg m**-2             TCLW             0  -9999.00
+079 Total column ice water            kg m**-2             TCIW             0  -9999.00
+!80 to 120 Experimental products (contents may vary)
+!121 to 124 Unused
+125 Vert. integrated tot. energy      J m**-2              COLENR           0  -9999.00
+126 Param. for sensitive area pred.   -                    SENPRM           0  -9999.00
+127 Atmospheric tide                  -                    AT               0  -9999.00
+128 Budget values                     -                    BV               0  -9999.00
+129 Geopotential                      m**2 s**-2           Z                0  -9999.00
+130 Temperature                       K                    T                0  -9999.00
+131 U velocity                        m s**-1              U                0  -9999.00
+132 V velocity                        m s**-1              V                0  -9999.00
+133 Specific humidity                 kg (H2O) kg**1       Q                0  -9999.00
+134 Surface pressure                  Pa                   SP              -2  -9999.00
+135 Vertical velocity                 Pa s**-1             W               -2  -9999.00
+136 Total column water                kg m**-2             TCW              0  -9999.00
+137 Total column water vapour         kg m**-2             TCWV             0  -9999.00
+138 Vorticity (relative)              s**-1                VO               0  -9999.00
+139 Soil temperature level 1          K                    STL1             0  -9999.00
+140 Soil wetness level 1              m (H2O)              SWL1             0  -9999.00
+141 Snow depth                        m (H2O)              SD               0  -9999.00
+142 Large scale precipitation         m                    LSP              0  -9999.00
+143 Convective precipitation          m                    CP               0  -9999.00
+144 Snowfall (conv. + strat.)         m (H2O)              SF               0  -9999.00
+145 Boundary layer dissipation        W m**-2 s            BLD              0  -9999.00
+146 Surface sensible heat flux        W m**-2 s            SSHF             0  -9999.00
+147 Surface latent heat flux          W m**-2 s            SLHF             0  -9999.00
+148 Charnock                          -                    CHNK             0  -9999.00
+149 Surface net radiation             W m**-2 s            SNR              0  -9999.00
+150 Top net radiation                 W m**-2 s            TNR              0  -9999.00
+151 Mean sea level pressure           Pa                   MSLP             0  -9999.00
+152 Logarithm of surface pressure     ln(Pa)               LNSP             0  -9999.00
+153 Short-wave heating rate           K                    SWHR             0  -9999.00
+154 Long-wave heating rate            K                    LWHR             0  -9999.00
+155 Divergence                        s**-1                D                0  -9999.00
+156 Height                            m                    HGHT             0  -9999.00
+157 Relative humidity                 %                    RELH             0  -9999.00
+158 Tendency of surface pressure      Pa s**-1             PTND            -2  -9999.00
+159 Boundary layer height             m                    ZPBL             0  -9999.00
+160 Standard deviation of orography   m                    SDOR             0  -9999.00
+161 Anisotropy of sub-gridscale oro.  -                    ISOR             0  -9999.00
+162 Angle of sub-gridscale orography  rad                  ANOR             0  -9999.00
+163 Slope of sub-gridscale orography  -                    SLOR             0  -9999.00
+164 Total cloud cover (0-1)           fraction             TCC              0  -9999.00
+165 10 metre U wind component         m s**-1              10U              0  -9999.00
+166 10 metre V wind component         m s**-1              10V              0  -9999.00
+167 2 metre temperature               K                    2T               0  -9999.00
+168 2 metre dewpoint temperature      K                    2D               0  -9999.00
+169 Surface solar radiation downwards W m**-2 s            SSRD             0  -9999.00
+170 Soil temperature level 2          K                    STL2             0  -9999.00
+171 Soil wetness level 2              m (H2O)              SWL2             0  -9999.00
+172 Land-sea mask (0,1)               logical              LSM              0  -9999.00
+173 Surface roughness                 m                    SR               0  -9999.00
+174 Albedo (0-1)                      fraction             ALBD             0  -9999.00
+175 Surface thermal radiation down    W m**-2 s            STRD             0  -9999.00
+176 Surface solar radiation           W m**-2 s            SSR              0  -9999.00
+177 Surface thermal radiation         W m**-2 s            STR              0  -9999.00
+178 Top solar radiation               W m**-2 s            TSR              0  -9999.00
+179 Top thermal radiation             W m**-2 s            TTR              0  -9999.00
+180 East-West surface stress          N m**-2 s            EWSS             0  -9999.00
+181 North-South surface stress        N m**-2 s            NSSS             0  -9999.00
+182 Evaporation                       m (H2O)              EVAP             0  -9999.00
+183 Soil temperature level 3          K                    STL3             0  -9999.00
+184 Soil wetness level 3              m (H2O)              SWL3             0  -9999.00
+185 Convective cloud cover (0-1)      fraction             CCC              0  -9999.00
+186 Low cloud cover (0-1)             fraction             LCC              0  -9999.00
+187 Medium cloud cover (0-1)          fraction             MCC              0  -9999.00
+188 High cloud cover (0-1)            fraction             HCC              0  -9999.00
+189 Sunshine duration                 s                    SUND             0  -9999.00
+190 E-W comp. of subgrid oro. var.    m**2                 EWOV             0  -9999.00
+191 N-S comp. of subgrid oro. var.    m**2                 NSOV             0  -9999.00
+192 NW-SE comp. of subgrid oro. var.  m**2                 NWOV             0  -9999.00
+193 NE-SW comp. of subgrid oro. var.  m**2                 NEOV             0  -9999.00
+194 Brightness temperature            K                    BTMP             0  -9999.00
+195 Lat. comp. of gravity wave stress N m**-2 s            LGWS             0  -9999.00
+196 Mer. comp. of gravity wave stress N m**-2 s            MGWS             0  -9999.00
+197 Gravity wave dissipation          W m**-2 s            GWD              0  -9999.00
+198 Skin reservoir content            m (H2O)              SRC              0  -9999.00
+199 Vegetation fraction (0-1)         fraction             VEG              0  -9999.00
+200 Variance of subgrid orography     m**2                 VSO              0  -9999.00
+201 Max. 2m temp. since post-process. K                    MX2T             0  -9999.00
+202 Min. 2m temp. since post-process. K                    MN2T             0  -9999.00
+203 Ozone mass mixing ratio           kg (O3) kg**-1       OZMR             0  -9999.00
+204 Precipiation analysis weights     -                    PAW              0  -9999.00
+205 Runoff                            m                    RO               0  -9999.00
+206 Total column ozone                kg m**-2             TOZO             0  -9999.00
+207 10 metre wind speed               m s**-1              10SI             0  -9999.00
+208 Top net solar rad., clear sky     W m**-2 s            TSRC             0  -9999.00
+209 Top net thermal rad., clear sky   W m**-2 s            TTRC             0  -9999.00
+210 Surface net solar rad., clear sky W m**-2 s            SSRC             0  -9999.00
+211 Sfc. net thermal rad., clear sky  W m**-2 s            STRC             0  -9999.00
+212 Solar insolation                  W m**-2 s            SI               0  -9999.00
+213 Unused
+214 Diabatic heating by radiation     K                    DHR              0  -9999.00
+215 Diab. heating by vert. diffusion  K                    DHVD             0  -9999.00
+216 Diab. heating by cumulus convec.  K                    DHCC             0  -9999.00
+217 Diab. heating resolved conden.    K                    DHLC             0  -9999.00
+218 Vertical diffusion of zonal wind  m s**-1              VDZW             0  -9999.00
+219 Vertical diffusion of mer.. wind  m s**-1              VDMW             0  -9999.00
+220 E-W gravity wave drag tendency    m s**-1              EWGD             0  -9999.00
+221 N-S gravity wave drag tendency    m s**-1              NSGD             0  -9999.00
+222 Convective tendency of zonal wind m s**-1              CTZW             0  -9999.00
+223 Convective tendency of mer. wind  m s**-1              CTMW             0  -9999.00
+224 Vertical diffusion of humidity    kg (H2O) kg**-1      VDH              0  -9999.00
+225 Humid. tend. by cumulus convec.   kg (H2O) kg**-1      HTCC             0  -9999.00
+226 Humid. tend. by resolved conden.  kg (H2O) kg**-1      HTLC             0  -9999.00
+227 Change from removing neg. humid.  kg (H2O) kg**-1      CRNH             0  -9999.00
+228 Total precipitation               m                    P--M             0  -9999.00
+229 Instantaneous X surface stress    N m**-2              IEWS             0  -9999.00
+230 Instantaneous Y surface stress    N m**-2              INSS             0  -9999.00
+231 Instantaneous surface heat flux   W m**-2              ISHF             0  -9999.00
+232 Instantaneous moisture flux       kg m**-2 s           IE               0  -9999.00
+233 Apparent surface humidity         kg (H2O) kg**-1      ASQ              0  -9999.00
+234 Log of sfc. rough. length (heat)  ln(m)                LSRH             0  -9999.00
+235 Skin temperature                  K                    SKT              0  -9999.00
+236 Soil temperature level 4          K                    STL4             0  -9999.00
+237 Soil wetness level 4              m (H2O)              SWL4             0  -9999.00
+238 Temperature of snow layer         K                    TSN              0  -9999.00
+239 Convective snowfall               m (H2O)              CSF              0  -9999.00
+240 Large-scale snowfall              m (H2O)              LSF              0  -9999.00
+241 Accum. cloud frac. tend. (-1 - 1) fraction             ACF              0  -9999.00
+242 Accum liquid water tend. (-1 - 1) fraction             ALW              0  -9999.00
+243 Forecast albedo (0-1)             fraction             FAL              0  -9999.00
+244 Forecast surface roughness        m                    FSR              0  -9999.00
+245 Fcst. log of src. rough. (heat)   log(m)               FLSR             0  -9999.00
+246 Cloud liquid water content        kg (H2O) kg**-1      CLWC             0  -9999.00
+247 Cloud ice water content           kg kg**-1            CIWC             0  -9999.00
+248 Cloud cover (0-1)                 fraction             CC               0  -9999.00
+249 Accum. ice water tend. (-1 - 1)   fraction             AIW              0  -9999.00
+250 Ice age (1,0) 0-first 1-multi     logical              ICE              0  -9999.00
+251 Adiabatic tendency of temperature K                    ATTE             0  -9999.00
+252 Adiabatic tendency of humidity    kg (H2O) kg**-1      ATHE             0  -9999.00
+253 Adiabatic tendency of zonal wind  m s**-1              ATZE             0  -9999.00
+254 Adiabatic tendency of mer. wind   m s**-1              ATMW             0  -9999.00
+255 Indicates a missing value         -                    MISS             0  -9999.00
\ No newline at end of file
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/templates/job.temp b/test/InstallTar/flex_extract_v7.1_ecgate/templates/job.temp
new file mode 100644
index 0000000000000000000000000000000000000000..43becc4fd06f4aa513688b7a579e56daff3c276c
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/templates/job.temp
@@ -0,0 +1,76 @@
+#!/bin/ksh
+
+# ON ECGB:
+# start with ecaccess-job-submit -queueName ecgb NAME_OF_THIS_FILE  on gateway server
+# start with sbatch NAME_OF_THIS_FILE directly on machine
+
+#SBATCH --workdir=/scratch/ms/at/km4a
+#SBATCH --qos=normal
+#SBATCH --job-name=flex_ecmwf
+#SBATCH --output=flex_ecmwf.%j.out
+#SBATCH --error=flex_ecmwf.%j.out
+#SBATCH --mail-type=FAIL
+#SBATCH --time=12:00:00
+
+## CRAY specific batch requests
+##PBS -N flex_ecmwf
+##PBS -q np
+##PBS -S /usr/bin/ksh
+## -o /scratch/ms/spatlh00/lh0/flex_ecmwf.$PBS_JOBID.out
+## job output is in .ecaccess_DO_NOT_REMOVE
+##PBS -j oe
+##PBS -V
+##PBS -l EC_threads_per_task=24
+##PBS -l EC_memory_per_task=32000MB
+
+set -x
+export VERSION=7.1
+case $HOST in
+  *ecg*)
+  module load python
+  module unload grib_api
+  module unload emos
+  module load grib_api/1.14.5
+  module load emos/437-r64
+  export PATH=${PATH}:${HOME}/flex_extract_v7.1/source/python
+  ;;
+  *cca*)
+  module switch PrgEnv-cray PrgEnv-intel
+  module load grib_api
+  module load emos
+  module load python
+  export SCRATCH=$TMPDIR
+  export PATH=${PATH}:${HOME}/flex_extract_v7.1/source/python
+  ;;
+esac
+
+cd $SCRATCH
+mkdir -p python$$
+cd python$$
+
+export CONTROL=CONTROL
+
+cat >$CONTROL<<EOF
+EOF
+
+
+submit.py --controlfile=$CONTROL --inputdir=./work --outputdir=./work 1> prot 2>&1
+
+if [ $? -eq 0 ] ; then
+  l=0
+  for muser in `grep -i MAILOPS $CONTROL`; do
+      if [ $l -gt 0 ] ; then 
+         mail -s flex.${HOST}.$$ $muser <prot
+      fi
+      l=$(($l+1))
+  done
+else
+  l=0
+  for muser in `grep -i MAILFAIL $CONTROL`; do
+      if [ $l -gt 0 ] ; then 
+         mail -s "ERROR! flex.${HOST}.$$" $muser <prot
+      fi
+      l=$(($l+1))
+  done
+fi
+
diff --git a/test/InstallTar/flex_extract_v7.1_ecgate/templates/job.temp.o b/test/InstallTar/flex_extract_v7.1_ecgate/templates/job.temp.o
new file mode 100644
index 0000000000000000000000000000000000000000..fbdbd81aa1ea7100a84ac0858ed29804526e98a5
--- /dev/null
+++ b/test/InstallTar/flex_extract_v7.1_ecgate/templates/job.temp.o
@@ -0,0 +1,75 @@
+#!/bin/ksh
+
+# ON ECGB:
+# start with ecaccess-job-submit -queueName ecgb NAME_OF_THIS_FILE  on gateway server
+# start with sbatch NAME_OF_THIS_FILE directly on machine
+
+#SBATCH --workdir=/scratch/ms/spatlh00/lh0
+#SBATCH --qos=normal
+#SBATCH --job-name=flex_ecmwf
+#SBATCH --output=flex_ecmwf.%j.out
+#SBATCH --error=flex_ecmwf.%j.out
+#SBATCH --mail-type=FAIL
+#SBATCH --time=12:00:00
+
+## CRAY specific batch requests
+##PBS -N flex_ecmwf
+##PBS -q np
+##PBS -S /usr/bin/ksh
+## -o /scratch/ms/spatlh00/lh0/flex_ecmwf.$PBS_JOBID.out
+## job output is in .ecaccess_DO_NOT_REMOVE
+##PBS -j oe
+##PBS -V
+##PBS -l EC_threads_per_task=24
+##PBS -l EC_memory_per_task=32000MB
+
+set -x
+export VERSION=7.1
+case $HOST in
+  *ecg*)
+  module load python
+  module unload grib_api
+  module unload emos
+  module load grib_api/1.14.5
+  module load emos/437-r64
+  export PATH=${PATH}:
+  ;;
+  *cca*)
+  module switch PrgEnv-cray PrgEnv-intel
+  module load grib_api
+  module load emos
+  module load python
+  export SCRATCH=$TMPDIR
+  export PATH=${PATH}:
+  ;;
+esac
+
+cd $SCRATCH
+mkdir -p python$$
+cd python$$
+
+export CONTROL=CONTROL
+
+cat >$CONTROL<<EOF
+EOF
+
+
+submit.py --controlfile=$CONTROL --inputdir=./work --outputdir=./work 1> prot 2>&1
+
+if [ $? -eq 0 ] ; then
+  l=0
+  for muser in `grep -i MAILOPS $CONTROL`; do
+      if [ $l -gt 0 ] ; then 
+         mail -s flex.${HOST}.$$ $muser <prot
+      fi
+      l=$(($l+1))
+  done
+else
+  l=0
+  for muser in `grep -i MAILFAIL $CONTROL`; do
+      if [ $l -gt 0 ] ; then 
+         mail -s "ERROR! flex.${HOST}.$$" $muser <prot
+      fi
+      l=$(($l+1))
+  done
+fi
diff --git a/test/Testfiles/ECMWF_ENV.test b/test/Testfiles/ECMWF_ENV.test
new file mode 100644
index 0000000000000000000000000000000000000000..dc258a940b6cacb52706c196b6ea9a5f609cc72c
--- /dev/null
+++ b/test/Testfiles/ECMWF_ENV.test
@@ -0,0 +1,4 @@
+ECUID testuser
+ECGID testgroup
+GATEWAY gateway.test.ac.at
+DESTINATION user@destination
diff --git a/test/Testfiles/test_put_to_ecserver.txt b/test/Testfiles/test_put_to_ecserver.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f28a7b5dee1644a76232d820e59c2dcca24615bc
--- /dev/null
+++ b/test/Testfiles/test_put_to_ecserver.txt
@@ -0,0 +1,2 @@
+#This file is just for testing the submission of files to an ecserver. 
+ls -l