diff --git a/src/FusionDirectory/Cli/Application.php b/src/FusionDirectory/Cli/Application.php
index 653e21dbea3d4c9f45e1d462c76d61989a069f6e..2c2d4d04c36a44c7c6aac97398fe9b75c6b2f5a7 100644
--- a/src/FusionDirectory/Cli/Application.php
+++ b/src/FusionDirectory/Cli/Application.php
@@ -28,19 +28,19 @@ class Application
 {
   /**
    * @var array<string,array>
-   * Options this application supports. Should be filled in constructor.
+   * Options this application supports. Should be filled in constructor's child.
    */
-  protected $options  = [];
+  protected $options = [];
   /**
    * @var array<string,array>
-   * Arguments this application supports. Should be filled in constructor.
+   * Arguments this application supports. Should be filled in constructor's child.
    */
-  protected $args     = [];
+  protected array $args = [];
   /**
    * @var array<string,mixed>
-   * Result of options parsing
+   * Result of options parsing.
    */
-  protected $getopt   = [];
+  protected array $getopt = [];
 
   public function __construct ()
   {
@@ -52,29 +52,34 @@ class Application
    */
   protected function usage (array $argv): void
   {
-    echo 'Usage: '.$argv[0].' --'.str_replace(':', ' VALUE', implode(' --', array_keys($this->options))).' '.strtoupper(implode(' ', array_keys($this->args)))."\n\n";
+    echo 'Usage: ' . $argv[0] . ' --' . str_replace(':', ' VALUE', implode(' --', array_keys($this->options))) . ' ' . strtoupper(implode(' ', array_keys($this->args))) . "\n\n";
+
     foreach ($this->options as $opt => $infos) {
-      printf("\t--%-25s\t%s\n", $opt.(isset($infos['short']) ? ', -'.$infos['short'] : ''), $infos['help']);
+      printf("\t--%-25s\t%s\n", $opt . (isset($infos['short']) ? ', -' . $infos['short'] : ''), $infos['help']);
     }
+
     foreach ($this->args as $arg => $infos) {
       printf("\t%-25s:\t%s\n", strtoupper($arg), $infos['help']);
     }
+
     exit(1);
   }
 
   /**
-   * Parse arguments
-   * @param array<string> $argv
+   * @param array $argv
+   * @param int $optind
+   * @return void
    */
   protected function parseArgs (array $argv, int $optind): void
   {
+    // optind comes from setopt method, counting the matches in existing options and arguments passed. If not equals, print usage.
     if ((count($argv) - $optind) != count($this->args)) {
       $this->usage($argv);
     }
 
     $argv = array_slice($argv, $optind);
 
-    foreach ($this->args as $arg => &$infos) {
+    foreach ($this->args as &$infos) {
       if ($infos['handler'] == '…') {
         /* All the last args */
         $infos['value'] = $argv;
@@ -88,20 +93,17 @@ class Application
   }
 
   /**
-   * Parse options and arguments from $argv
-   * @param array<string> $argv
-   *
-   * @return array<string,mixed>
+   * @return string
+   * Note : This method is used to format the available options in children applications. Create short formats.
+   * This class is responsible to output the helpers info and thus receive options from children.
    */
-  protected function parseOptionsAndArgs (array $argv): array
+  protected function generateShortOptions (): string
   {
-    /* Parse options */
-    $shortOptions = implode('', array_map(
-      function (string $key, array $infos): string
-      {
+    return implode('', array_map(
+      function (string $key, array $infos): string {
         if (isset($infos['short'])) {
           if (substr($key, -1) === ':') {
-            return $infos['short'].':';
+            return $infos['short'] . ':';
           } else {
             return $infos['short'];
           }
@@ -112,73 +114,154 @@ class Application
       array_keys($this->options),
       array_values($this->options)
     ));
-    $getopt = getopt($shortOptions, array_keys($this->options), $optind);
+  }
+
+  /**
+   *  Note : Simply output usage if required after verifying existing potential invalid arguments
+   *  Receive option index (returned by getopt method) and the arguments passed to the script
+   */
+  protected function verifyArguments ($optind, $argv, $shortOptions)
+  {
     for ($i = 0; $i < $optind; $i++) {
+
       if (($argv[$i][0] === '-') && ($argv[$i] !== '--')) {
         if (preg_match('/^--(.+)$/', $argv[$i], $m)) {
-          if (!isset($this->options[$m[1]]) && !isset($this->options[$m[1].':'])) {
-            echo 'Unrecognized option '.$argv[$i]."\n";
+          if (!isset($this->options[$m[1]]) && !isset($this->options[$m[1] . ':'])) {
+
+            echo 'Unrecognized option ' . $argv[$i] . "\n";
             $this->usage($argv);
           }
         } elseif (preg_match('/^-(.+)$/', $argv[$i], $m)) {
           $shorts = str_split($m[1]);
+
           foreach ($shorts as $short) {
             if (strpos($shortOptions, $short) === FALSE) {
-              echo 'Unrecognized option -'.$short."\n";
+              echo 'Unrecognized option -' . $short . "\n";
+
               $this->usage($argv);
             }
           }
         } else {
-          echo 'Failed to parse option '.$argv[$i]."\n";
+          echo 'Failed to parse option ' . $argv[$i] . "\n";
+
           $this->usage($argv);
         }
       }
     }
-    foreach ($this->options as $key => $option) {
-      if (substr($key, -1) !== ':') {
-        if (isset($getopt[$key])) {
-          if (is_array($getopt[$key])) {
-            $getopt[$key] = count($getopt[$key]);
-          } else {
-            $getopt[$key] = 1;
-          }
-        } else {
-          $getopt[$key] = 0;
-        }
-        if (isset($option['short']) && isset($getopt[$option['short']])) {
-          if (is_array($getopt[$option['short']])) {
-            $getopt[$key] += count($getopt[$option['short']]);
-          } else {
-            $getopt[$key]++;
-          }
-          unset($getopt[$option['short']]);
-        }
+  }
+
+  /**
+   * @return void
+   * Logic is that every options that are matched by an arguments will have an incremental int increased from zero.
+   * This allows to have a final array of arguments (validated) on which we can work on to execute related functions.
+   */
+  private function handleShortOptions ($key, $option, &$getopt): void
+  {
+    if (isset($option['short']) && isset($getopt[$option['short']])) {
+      if (is_array($getopt[$option['short']])) {
+        $getopt[$key] += count($getopt[$option['short']]);
+
       } else {
-        $key = substr($key, 0, -1);
-        if (isset($option['short']) && isset($getopt[$option['short']])) {
-          if (!isset($getopt[$key])) {
-            $getopt[$key] = $getopt[$option['short']];
-          } else {
-            if (is_string($getopt[$key])) {
-              $getopt[$key] = [$getopt[$key]];
-            }
-            if (is_array($getopt[$option['short']])) {
-              $getopt[$key] = array_merge($getopt[$key], $getopt[$option['short']]);
-            } else {
-              $getopt[$key][] = $getopt[$option['short']];
-            }
-          }
-        }
+        $getopt[$key]++;
       }
-      if (isset($getopt[$key])) {
+
+      unset($getopt[$option['short']]);
+    }
+  }
+
+  /**
+   * @return void
+   * Note : This method, like the handleShortOptions - incremented the integer. Arguments requiring data.
+   */
+  private function processNonValueOption ($key, $option, &$getopt): void
+  {
+    if (!isset($getopt[$key])) {
+      $getopt[$key] = 0;
+    } elseif (is_array($getopt[$key])) {
+      $getopt[$key] = count($getopt[$key]);
+    } else {
+      $getopt[$key] = 1;
+    }
+
+    // Simply handle the short options
+    $this->handleShortOptions($key, $option, $getopt);
+  }
+
+  /**
+   * @return void
+   * Note : Method which process arguments requiring data input. (See processNonValueOption for non data arguments).
+   */
+  private function processValueOption ($key, $option, &$getopt): void
+  {
+    $key = substr($key, 0, -1);
+
+    // Simply handle short option with value below
+    if (isset($option['short']) && isset($getopt[$option['short']])) {
+      if (!isset($getopt[$key])) {
+
+        $getopt[$key] = $getopt[$option['short']];
+      } else {
+
         if (is_string($getopt[$key])) {
           $getopt[$key] = [$getopt[$key]];
         }
-        if (isset($option['handler'])) {
-          $getopt[$key] = $option['handler']($getopt[$key]);
+
+        if (is_array($getopt[$option['short']])) {
+          $getopt[$key] = array_merge($getopt[$key], $getopt[$option['short']]);
+        } else {
+
+          $getopt[$key][] = $getopt[$option['short']];
         }
       }
     }
+  }
+
+  /**
+   * @return void
+   * Note: We are putting a numerical value on arguments allowing better error handling.
+   * Note 2: getopt is passed by reference. Keep this function private.
+   */
+  private function processOptions ($key, $option, &$getopt): void
+  {
+    if (substr($key, -1) !== ':') {
+      // Process non-value options (No added path or file or options to the arguments set).
+      $this->processNonValueOption($key, $option, $getopt);
+    } else {
+      // Process value options (argument provided + data).
+      $this->processValueOption($key, $option, $getopt);
+    }
+
+    if (isset($getopt[$key])) {
+      if (is_string($getopt[$key])) {
+        $getopt[$key] = [$getopt[$key]];
+      }
+      if (isset($option['handler'])) {
+        $getopt[$key] = $option['handler']($getopt[$key]);
+      }
+    }
+  }
+
+  /**
+   * @param array $argv
+   * @return array
+   * Note : This is the main method to verify arguments passed and generated a final array which summarize valid arguments
+   * passed.
+   */
+  protected function parseOptionsAndArgs (array $argv): array
+  {
+    // Parse into a short format, options received by children applications.
+    $shortOptions = $this->generateShortOptions();
+
+    // using getopt method, arguments passed are matched to existing preset long/short options.
+    $getopt = getopt($shortOptions, array_keys($this->options), $optind);
+
+    // getopt does not return wrong arguments passed, therefore below verification allows to indicate it.
+    $this->verifyArguments($optind, $argv, $shortOptions);
+
+    foreach ($this->options as $key => $option) {
+      // process each options retrieved by getopt
+      $this->processOptions($key, $option, $getopt);
+    }
 
     /* Parse arguments */
     $this->parseArgs($argv, $optind);
@@ -193,16 +276,18 @@ class Application
   {
     foreach ($this->getopt as $key => $value) {
       if (isset($this->options[$key]['command']) && ($value > 0)) {
+
         call_user_func([$this, $this->options[$key]['command']]);
-      } elseif (isset($this->options[$key.':']['command'])) {
-        call_user_func([$this, $this->options[$key.':']['command']], $value);
+      } elseif (isset($this->options[$key . ':']['command'])) {
+
+        call_user_func([$this, $this->options[$key . ':']['command']], $value);
       }
     }
   }
 
   /**
    * Main function.
-   * By default only parse options and arguments, and print help if needed.
+   * By default, only parse options and arguments, and print help if needed.
    * Extend if you want to call runCommands.
    * @param array<string> $argv
    */
@@ -230,10 +315,10 @@ class Application
       /* Remove the \n at the end of $input */
       $line = trim($line);
 
-      if (in_array(strtolower($line), ['yes','y'])) {
+      if (in_array(strtolower($line), ['yes', 'y'])) {
         $return = TRUE;
         break;
-      } elseif (in_array(strtolower($line), ['no','n'])) {
+      } elseif (in_array(strtolower($line), ['no', 'n'])) {
         $return = FALSE;
         break;
       }
@@ -249,7 +334,7 @@ class Application
     if ($defaultAnswer != '') {
       $thingToAsk .= " [$defaultAnswer]";
     }
-    echo $thingToAsk.":\n";
+    echo $thingToAsk . ":\n";
 
     if ($hidden) {
       /* FIXME maybe find a better way */
diff --git a/src/FusionDirectory/Cli/FusionDirectory.php b/src/FusionDirectory/Cli/FusionDirectory.php
new file mode 100644
index 0000000000000000000000000000000000000000..47c8a0f863b81c1a916536a683b710375f625a70
--- /dev/null
+++ b/src/FusionDirectory/Cli/FusionDirectory.php
@@ -0,0 +1,229 @@
+<?php
+/*
+  This code is part of ldap-config-manager (https://www.fusiondirectory.org/)
+
+  Copyright (C) 2020-2024  FusionDirectory
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+namespace FusionDirectory\Cli;
+
+use Exception;
+use SimpleXMLElement;
+use SodiumException;
+
+/**
+ * Base class for interacting with FusionDirectory specifics
+ */
+class FusionDirectory extends Application
+{
+  /**
+   * Current values of variables
+   * @var array<string,string>
+   */
+  protected $vars;
+  protected $configFilePath;
+  /**
+   * @var string path to the FusionDirectory secrets file containing the key to decrypt passwords
+   */
+  protected string $secretsFilePath;
+
+  public function __construct ()
+  {
+    parent::__construct();
+
+    // Variables to be set during script calling.
+    $this->vars = [
+      'fd_home'          => '/usr/share/fusiondirectory',
+      'fd_config_dir'    => '/etc/fusiondirectory',
+      'config_file'      => 'fusiondirectory.conf',
+      'secrets_file'     => 'fusiondirectory.secrets',
+      'fd_cache'         => '/var/cache/fusiondirectory',
+      'fd_smarty_path'   => '/usr/share/php/smarty3/Smarty.class.php',
+      'fd_spool_dir'     => '/var/spool/fusiondirectory',
+      'locale_dir'       => 'locale',
+      'class_cache'      => 'class.cache',
+      'locale_cache_dir' => 'locale',
+      'tmp_dir'          => 'tmp',
+      'fai_log_dir'      => 'fai',
+      'template_dir'     => 'template'
+    ];
+  }
+
+  /**
+   * @return array[]
+   */
+  public function getVarOptions (): array
+  {
+    return [
+      'list-vars' => [
+        'help'    => 'List an example of a possible var to give to --set-var followed by --write-vars',
+        'command' => 'cmdListVars',
+      ],
+      'set-var:'  => [
+        'help'    => 'Set the variable value',
+        'command' => 'cmdSetVar',
+      ],
+    ];
+  }
+
+
+  /**
+   * Read variables.inc file from FusionDirectory and update variables accordingly
+   */
+  protected function readFusionDirectoryVariablesFile (): void
+  {
+    if ($this->verbose()) {
+      printf('Reading vars from %s' . "\n", $this->vars['fd_home'] . '/include/variables.inc');
+    }
+    require_once($this->vars['fd_home'] . '/include/variables.inc');
+
+    $fd_cache  = $this->removeFinalSlash(CACHE_DIR);
+    $varsToSet = [
+      'fd_config_dir'    => $this->removeFinalSlash(CONFIG_DIR),
+      'config_file'      => $this->removeFinalSlash(CONFIG_FILE),
+      'fd_smarty_path'   => $this->removeFinalSlash(SMARTY),
+      'fd_spool_dir'     => $this->removeFinalSlash(SPOOL_DIR),
+      'fd_cache'         => $fd_cache,
+      'locale_cache_dir' => $this->removeFinalSlash(str_replace($fd_cache . '/', '', LOCALE_DIR)),
+      'tmp_dir'          => $this->removeFinalSlash(str_replace($fd_cache . '/', '', TEMP_DIR)),
+      'template_dir'     => $this->removeFinalSlash(str_replace($fd_cache . '/', '', CONFIG_TEMPLATE_DIR)),
+      'fai_log_dir'      => $this->removeFinalSlash(str_replace($fd_cache . '/', '', FAI_LOG_DIR)),
+      'class_cache'      => $this->removeFinalSlash(CLASS_CACHE),
+    ];
+    foreach ($varsToSet as $var => $value) {
+      if (isset($this->vars[$var])) {
+        $this->vars[$var] = $value;
+      }
+    }
+  }
+
+
+  /**
+   * @return void
+   * Only print an example of variables that can be changed.
+   */
+  protected function cmdListVars (): void
+  {
+    foreach ($this->vars as $key => $value) {
+      printf("%-20s [%s]\n", $key, $value);
+    }
+  }
+
+
+  /**
+   * @param string $var
+   * @return void
+   * @throws Exception
+   * Note : This allows to set var in the variables.php file in FD.
+   * This method needs rework as multiple variables are not received, only a string.
+   * (logic of multiple should be defined in parent class)
+   */
+  protected function cmdSetVar (string $var): void
+  {
+    $varsToSet = [];
+    if (preg_match('/^([^=]+)=(.+)$/', $var, $m)) {
+      if (isset($this->vars[strtolower($m[1])])) {
+        $varsToSet[strtolower($m[1])] = $m[2];
+      } else {
+        throw new Exception('Var "' . $m[1] . '" does not exists. Use --list-vars to get the list of vars.');
+      }
+    } else {
+      throw new Exception('Incorrect syntax for --set-var: "' . $var . '". Use var=value');
+    }
+
+    if (isset($varsToSet['fd_home'])) {
+      if ($this->verbose()) {
+        printf('Setting var %s to "%s"' . "\n", 'fd_home', $this->removeFinalSlash($varsToSet['fd_home']));
+      }
+      $this->vars['fd_home'] = $this->removeFinalSlash($varsToSet['fd_home']);
+    }
+    $this->readFusionDirectoryVariablesFile();
+    unset($varsToSet['fd_home']);
+    foreach ($varsToSet as $var => $value) {
+      if ($this->verbose()) {
+        printf('Setting var %s to "%s"' . "\n", $var, $value);
+      }
+      $this->vars[$var] = $value;
+    }
+  }
+
+  /**
+   * Load locations information from FusionDirectory configuration file
+   * @return array<array{tls: bool, uri: string, base: string, bind_dn: string, bind_pwd: string}> locations
+   * @throws SodiumException
+   * @throws Exception
+   */
+  protected function loadFusionDirectoryConfigurationFile (): array
+  {
+    if ($this->verbose()) {
+      printf('Loading configuration file from %s' . "\n", $this->configFilePath);
+    }
+
+    $secret = NULL;
+    if (file_exists($this->secretsFilePath)) {
+      if ($this->verbose()) {
+        printf('Using secrets file %s' . "\n", $this->secretsFilePath);
+      }
+      $lines = file($this->secretsFilePath, FILE_SKIP_EMPTY_LINES);
+      if ($lines === FALSE) {
+        throw new Exception('Could not open "' . $this->secretsFilePath . '"');
+      }
+      foreach ($lines as $line) {
+        if (preg_match('/RequestHeader set FDKEY ([^ \n]+)\n/', $line, $m)) {
+          $secret = sodium_base642bin($m[1], SODIUM_BASE64_VARIANT_ORIGINAL, '');
+          break;
+        }
+      }
+    }
+
+    // Note: this function is case sensitive with xml tags and attributes, FD is not
+    $xml       = new SimpleXMLElement($this->configFilePath, 0, TRUE);
+    $locations = [];
+    foreach ($xml->main->location as $loc) {
+      $ref      = $loc->referral[0];
+      $location = [
+        'tls'      => (isset($loc['ldapTLS']) && (strcasecmp((string)$loc['ldapTLS'], 'TRUE') === 0)),
+        'uri'      => (string)$ref['URI'],
+        'base'     => (string)($ref['base'] ?? $loc['base'] ?? ''),
+        'bind_dn'  => (string)$ref['adminDn'],
+        'bind_pwd' => (string)$ref['adminPassword'],
+      ];
+      if ($location['base'] === '') {
+        if (preg_match('|^(.*)/([^/]+)$|', $location['uri'], $m)) {
+          /* Format from FD<1.3 */
+          $location['uri']  = $m[1];
+          $location['base'] = $m[2];
+        } else {
+          throw new Exception('"' . $location['uri'] . '" does not contain any base!');
+        }
+      }
+      if ($secret !== NULL) {
+        $location['bind_pwd'] = SecretBox::decrypt($location['bind_pwd'], $secret);
+      }
+      $locations[(string)$loc['name']] = $location;
+      if ($this->verbose()) {
+        printf('Found location %s (%s)' . "\n", (string)$loc['name'], $location['uri']);
+      }
+    }
+    if (count($locations) < 1) {
+      throw new Exception('No location found in configuration file');
+    }
+
+    return $locations;
+  }
+
+}
\ No newline at end of file
diff --git a/src/FusionDirectory/Cli/LdapApplication.php b/src/FusionDirectory/Cli/LdapApplication.php
index 875640f76152b7525e6f5eda9e1c846a080a2561..a6cc067f3ddd6e2e52265a1ac1643b23de925b42 100644
--- a/src/FusionDirectory/Cli/LdapApplication.php
+++ b/src/FusionDirectory/Cli/LdapApplication.php
@@ -21,32 +21,33 @@
 
 namespace FusionDirectory\Cli;
 
-use \FusionDirectory\Ldap;
+use FusionDirectory\Ldap;
+use SodiumException;
 
 /**
  * Base class for cli applications that needs an LDAP connection from fusiondirectory configuration file
  */
-class LdapApplication extends Application
+class LdapApplication extends FusionDirectory
 {
   /**
    * @var Ldap\Link|null
    */
-  protected $ldap = NULL;
+  protected ?Ldap\Link $ldap = NULL;
 
   /**
    * @var string Ldap tree base
    */
-  protected $base;
+  protected string $base;
 
-  /**
-   * @var string path to the FusionDirectory configuration file
-   */
-  protected $configFilePath;
+  //  /**
+  //   * @var string path to the FusionDirectory configuration file
+  //   */
+  //  protected string $configFilePath;
 
-  /**
-   * @var string path to the FusionDirectory secrets file containing the key to decrypt passwords
-   */
-  protected $secretsFilePath;
+  //  /**
+  //   * @var string path to the FusionDirectory secrets file containing the key to decrypt passwords
+  //   */
+  //  protected string $secretsFilePath;
 
   /**
    * May not be needed once SecretBox situation clears up
@@ -58,36 +59,36 @@ class LdapApplication extends Application
   {
     parent::__construct();
 
-    $this->options  = [
-      'ldapuri:'  => [
-        'help'        => 'URI to connect to, defaults to configuration file value',
+    $this->options = [
+      'ldapuri:'     => [
+        'help' => 'URI to connect to, defaults to configuration file value',
       ],
-      'binddn:'  => [
-        'help'        => 'DN to bind with, defaults to configuration file value',
+      'binddn:'      => [
+        'help' => 'DN to bind with, defaults to configuration file value',
       ],
-      'bindpwd:'  => [
-        'help'        => 'Password to bind with, defaults to configuration file value',
+      'bindpwd:'     => [
+        'help' => 'Password to bind with, defaults to configuration file value',
       ],
-      'saslmech:'  => [
-        'help'        => 'SASL mech, activates SASL if specified',
+      'saslmech:'    => [
+        'help' => 'SASL mech, activates SASL if specified',
       ],
-      'saslrealm:'  => [
-        'help'        => 'SASL realm',
+      'saslrealm:'   => [
+        'help' => 'SASL realm',
       ],
-      'saslauthcid:'  => [
-        'help'        => 'SASL authcid',
+      'saslauthcid:' => [
+        'help' => 'SASL authcid',
       ],
-      'saslauthzid:'  => [
-        'help'        => 'SASL authzid',
+      'saslauthzid:' => [
+        'help' => 'SASL authzid',
       ],
-      'yes'           => [
-        'help'        => 'Answer yes to all questions',
+      'yes'          => [
+        'help' => 'Answer yes to all questions',
       ],
-      'verbose'       => [
-        'help'        => 'Verbose output',
+      'verbose'      => [
+        'help' => 'Verbose output',
       ],
-      'help'          => [
-        'help'        => 'Show this help',
+      'help'         => [
+        'help' => 'Show this help',
       ],
     ];
   }
@@ -95,6 +96,8 @@ class LdapApplication extends Application
   /**
    * Read FusionDirectory configuration file, and open a connection to the LDAP server
    * If there already is a connection opened, do nothing
+   * @throws Ldap\Exception
+   * @throws SodiumException
    */
   protected function readFusionDirectoryConfigurationFileAndConnectToLdap (): void
   {
@@ -102,11 +105,11 @@ class LdapApplication extends Application
       return;
     }
 
-    $locations  = $this->loadFusionDirectoryConfigurationFile();
-    $location   = (string)key($locations);
+    $locations = $this->loadFusionDirectoryConfigurationFile();
+    $location  = (string)key($locations);
     if (count($locations) > 1) {
       /* Give the choice between locations to user */
-      $question = 'There are several locations in your config file, which one should be used: ('.implode(',', array_keys($locations)).')';
+      $question = 'There are several locations in your config file, which one should be used: (' . implode(',', array_keys($locations)) . ')';
       do {
         $answer = $this->askUserInput($question, $location);
       } while (!isset($locations[$answer]));
@@ -115,7 +118,7 @@ class LdapApplication extends Application
     $config = $locations[$location];
 
     if ($this->verbose()) {
-      printf('Connecting to LDAP at %s'."\n", $this->getopt['ldapuri'][0] ?? $config['uri']);
+      printf('Connecting to LDAP at %s' . "\n", $this->getopt['ldapuri'][0] ?? $config['uri']);
     }
     $this->ldap = new Ldap\Link($this->getopt['ldapuri'][0] ?? $config['uri']);
     if (($this->getopt['saslmech'][0] ?? '') === '') {
@@ -133,71 +136,4 @@ class LdapApplication extends Application
 
     $this->base = $config['base'];
   }
-
-  /**
-   * Load locations information from FusionDirectory configuration file
-   * @return array<array{tls: bool, uri: string, base: string, bind_dn: string, bind_pwd: string}> locations
-   */
-  protected function loadFusionDirectoryConfigurationFile (): array
-  {
-    if ($this->verbose()) {
-      printf('Loading configuration file from %s'."\n", $this->configFilePath);
-    }
-
-    $secret = NULL;
-    if (file_exists($this->secretsFilePath)) {
-      if ($this->verbose()) {
-        printf('Using secrets file %s'."\n", $this->secretsFilePath);
-      }
-      $lines = file($this->secretsFilePath, FILE_SKIP_EMPTY_LINES);
-      if ($lines === FALSE) {
-        throw new \Exception('Could not open "'.$this->secretsFilePath.'"');
-      }
-      foreach ($lines as $line) {
-        if (preg_match('/RequestHeader set FDKEY ([^ \n]+)\n/', $line, $m)) {
-          $secret = \sodium_base642bin($m[1], SODIUM_BASE64_VARIANT_ORIGINAL);
-          break;
-        }
-      }
-    }
-
-    // FIXME this function is case sensitive with xml tags and attributes, FD is not
-    $xml = new \SimpleXMLElement($this->configFilePath, 0, TRUE);
-    $locations = [];
-    foreach ($xml->main->location as $loc) {
-      $ref = $loc->referral[0];
-      $location = [
-        'tls'       => (isset($loc['ldapTLS']) && (strcasecmp((string)$loc['ldapTLS'], 'TRUE') === 0)),
-        'uri'       => (string)$ref['URI'],
-        'base'      => (string)($ref['base'] ?? $loc['base'] ?? '' ),
-        'bind_dn'   => (string)$ref['adminDn'],
-        'bind_pwd'  => (string)$ref['adminPassword'],
-      ];
-      if ($location['base'] === '') {
-        if (preg_match('|^(.*)/([^/]+)$|', $location['uri'], $m)) {
-          /* Format from FD<1.3 */
-          $location['uri']   = $m[1];
-          $location['base']  = $m[2];
-        } else {
-          throw new \Exception('"'.$location['uri'].'" does not contain any base!');
-        }
-      }
-      if ($secret !== NULL) {
-        if (!class_exists('SecretBox')) {
-          /* Temporary hack waiting for core namespace/autoload refactor */
-          require_once($this->vars['fd_home'].'/include/SecretBox.inc');
-        }
-        $location['bind_pwd'] = SecretBox::decrypt($location['bind_pwd'], $secret);
-      }
-      $locations[(string)$loc['name']] = $location;
-      if ($this->verbose()) {
-        printf('Found location %s (%s)'."\n", (string)$loc['name'], $location['uri']);
-      }
-    }
-    if (count($locations) < 1) {
-      throw new \Exception('No location found in configuration file');
-    }
-
-    return $locations;
-  }
 }
diff --git a/src/FusionDirectory/Cli/SecretBox.php b/src/FusionDirectory/Cli/SecretBox.php
index d795c04a6fd365df997b3e56dec0decdf8484ec3..0f2608be7dedfe3750ca37da14165f62532d5556 100644
--- a/src/FusionDirectory/Cli/SecretBox.php
+++ b/src/FusionDirectory/Cli/SecretBox.php
@@ -21,6 +21,18 @@
 
 namespace FusionDirectory\Cli;
 
+use Exception;
+use SodiumException;
+use function random_bytes;
+use function sodium_base642bin;
+use function sodium_bin2base64;
+use function sodium_crypto_secretbox;
+use function sodium_crypto_secretbox_keygen;
+use function sodium_crypto_secretbox_open;
+use function sodium_memzero;
+use function sodium_pad;
+use function sodium_unpad;
+
 class SecretBox
 {
   /**
@@ -32,7 +44,7 @@ class SecretBox
    */
   public static function generateSecretKey (): string
   {
-    return \sodium_crypto_secretbox_keygen();
+    return sodium_crypto_secretbox_keygen();
   }
 
   /**
@@ -43,23 +55,23 @@ class SecretBox
    * @param string $message - message to encrypt
    * @param string $secret_key - encryption key
    * @param int $block_size - pad the message by $block_size byte chunks to conceal encrypted data size. must match between encrypt/decrypt!
-   * @see decrypt()
    * @see https://github.com/jedisct1/libsodium/issues/392
+   * @see decrypt()
    */
   public static function encrypt (string $message, string $secret_key, int $block_size = 1): string
   {
     /* Create a nonce for this operation. it will be stored and recovered in the message itself */
-    $nonce = \random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
+    $nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
 
     /* Pad to $block_size byte chunks (enforce 512 byte limit) */
-    $padded_message = \sodium_pad($message, $block_size <= 512 ? $block_size : 512);
+    $padded_message = sodium_pad($message, min($block_size, 512));
 
     /* Encrypt message and combine with nonce */
-    $cipher = \sodium_bin2base64($nonce . \sodium_crypto_secretbox($padded_message, $nonce, $secret_key), SODIUM_BASE64_VARIANT_ORIGINAL);
+    $cipher = sodium_bin2base64($nonce . sodium_crypto_secretbox($padded_message, $nonce, $secret_key), SODIUM_BASE64_VARIANT_ORIGINAL);
 
     /* Cleanup */
-    \sodium_memzero($message);
-    \sodium_memzero($secret_key);
+    sodium_memzero($message);
+    sodium_memzero($secret_key);
 
     return $cipher;
   }
@@ -70,16 +82,18 @@ class SecretBox
    * Use libsodium to decrypt an encrypted string
    *
    * @param int $block_size - pad the message by $block_size byte chunks to conceal encrypted data size. must match between encrypt/decrypt!
-   * @see encrypt()
+   * @throws SodiumException
+   * @throws Exception
    * @see https://github.com/jedisct1/libsodium/issues/392
+   * @see encrypt()
    */
   public static function decrypt (string $encrypted, string $secret_key, int $block_size = 1): string
   {
     /* Unpack base64 message */
-    $decoded = \sodium_base642bin($encrypted, SODIUM_BASE64_VARIANT_ORIGINAL);
+    $decoded = sodium_base642bin($encrypted, SODIUM_BASE64_VARIANT_ORIGINAL, '');
 
     if (mb_strlen($decoded, '8bit') < (SODIUM_CRYPTO_SECRETBOX_NONCEBYTES + SODIUM_CRYPTO_SECRETBOX_MACBYTES)) {
-      throw new \Exception('The message was truncated');
+      throw new Exception('The message was truncated');
     }
 
     /* Pull nonce and ciphertext out of unpacked message */
@@ -87,18 +101,18 @@ class SecretBox
     $ciphertext = mb_substr($decoded, SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, NULL, '8bit');
 
     /* Decrypt it and account for extra padding from $block_size (enforce 512 byte limit) */
-    $decrypted_padded_message = \sodium_crypto_secretbox_open($ciphertext, $nonce, $secret_key);
+    $decrypted_padded_message = sodium_crypto_secretbox_open($ciphertext, $nonce, $secret_key);
 
     /* Check for encryption failures */
     if ($decrypted_padded_message === FALSE) {
-      throw new \Exception('The message was tampered with in transit');
+      throw new Exception('The message was tampered with in transit');
     }
 
-    $message = \sodium_unpad($decrypted_padded_message, $block_size <= 512 ? $block_size : 512);
+    $message = sodium_unpad($decrypted_padded_message, min($block_size, 512));
 
     /* Cleanup */
-    \sodium_memzero($encrypted);
-    \sodium_memzero($secret_key);
+    sodium_memzero($encrypted);
+    sodium_memzero($secret_key);
 
     return $message;
   }
diff --git a/src/FusionDirectory/Cli/VarHandling.php b/src/FusionDirectory/Cli/VarHandling.php
deleted file mode 100644
index d5fb5634e6dd39f9329926d46ce5d39c1183857a..0000000000000000000000000000000000000000
--- a/src/FusionDirectory/Cli/VarHandling.php
+++ /dev/null
@@ -1,129 +0,0 @@
-<?php
-/*
-  This code is part of FusionDirectory (https://www.fusiondirectory.org/)
-
-  Copyright (C) 2020-2021 FusionDirectory
-
-  This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program; if not, write to the Free Software
-  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-*/
-
-namespace FusionDirectory\Cli;
-
-/**
- * Trait for cli tools using a variable system through their options
- */
-trait VarHandling
-{
-  /**
-   * Current values of variables
-   * @var array<string,string>
-   */
-  protected $vars;
-
-  /**
-   * Get the options related to variables handling
-   * @return array<string,array<string,string>>
-   */
-  protected function getVarOptions (): array
-  {
-    return [
-      'list-vars' => [
-        'help'    => 'List possible vars to give --set-var',
-        'command' => 'cmdListVars',
-      ],
-      'set-var:' => [
-        'help'    => 'Set the variable value',
-        'command' => 'cmdSetVar',
-      ],
-    ];
-  }
-
-  abstract protected function verbose (): bool;
-
-  /**
-   * Read variables.inc file from FusionDirectory and update variables accordingly
-   */
-  protected function readFusionDirectoryVariablesFile (): void
-  {
-    if ($this->verbose()) {
-      printf('Reading vars from %s'."\n", $this->vars['fd_home'].'/include/variables.inc');
-    }
-    require_once($this->vars['fd_home'].'/include/variables.inc');
-
-    $fd_cache = LdapApplication::removeFinalSlash(CACHE_DIR);
-    $varsToSet = [
-      'fd_config_dir'    => LdapApplication::removeFinalSlash(CONFIG_DIR),
-      'config_file'      => LdapApplication::removeFinalSlash(CONFIG_FILE),
-      'fd_smarty_path'   => LdapApplication::removeFinalSlash(SMARTY),
-      'fd_spool_dir'     => LdapApplication::removeFinalSlash(SPOOL_DIR),
-      'fd_cache'         => $fd_cache,
-      'locale_cache_dir' => LdapApplication::removeFinalSlash(str_replace($fd_cache.'/', '', LOCALE_DIR)),
-      'tmp_dir'          => LdapApplication::removeFinalSlash(str_replace($fd_cache.'/', '', TEMP_DIR)),
-      'template_dir'     => LdapApplication::removeFinalSlash(str_replace($fd_cache.'/', '', CONFIG_TEMPLATE_DIR)),
-      'fai_log_dir'      => LdapApplication::removeFinalSlash(str_replace($fd_cache.'/', '', FAI_LOG_DIR)),
-      'class_cache'      => LdapApplication::removeFinalSlash(CLASS_CACHE),
-    ];
-    foreach ($varsToSet as $var => $value) {
-      if (isset($this->vars[$var])) {
-        $this->vars[$var] = $value;
-      }
-    }
-  }
-
-  /**
-   * Output variables and their current values
-   */
-  protected function cmdListVars (): void
-  {
-    foreach ($this->vars as $key => $value) {
-      printf("%-20s [%s]\n", $key, $value);
-    }
-  }
-
-  /**
-   * Set variables values
-   * @param array<string> $vars
-   */
-  protected function cmdSetVar (array $vars): void
-  {
-    $varsToSet = [];
-    foreach ($vars as $var) {
-      if (preg_match('/^([^=]+)=(.+)$/', $var, $m)) {
-        if (isset($this->vars[strtolower($m[1])])) {
-          $varsToSet[strtolower($m[1])] = $m[2];
-        } else {
-          throw new \Exception('Var "'.$m[1].'" does not exists. Use --list-vars to get the list of vars.');
-        }
-      } else {
-        throw new \Exception('Incorrect syntax for --set-var: "'.$var.'". Use var=value');
-      }
-    }
-
-    if (isset($varsToSet['fd_home'])) {
-      if ($this->verbose()) {
-        printf('Setting var %s to "%s"'."\n", 'fd_home', LdapApplication::removeFinalSlash($varsToSet['fd_home']));
-      }
-      $this->vars['fd_home'] = LdapApplication::removeFinalSlash($varsToSet['fd_home']);
-    }
-    $this->readFusionDirectoryVariablesFile();
-    unset($varsToSet['fd_home']);
-    foreach ($varsToSet as $var => $value) {
-      if ($this->verbose()) {
-        printf('Setting var %s to "%s"'."\n", $var, $value);
-      }
-      $this->vars[$var] = $value;
-    }
-  }
-}
diff --git a/src/FusionDirectory/Rest/WebServiceCall.php b/src/FusionDirectory/Rest/WebServiceCall.php
index 047023d522956209ff2ad4763e89c8fbd39b8a6b..fcc48e9881c558bae2bdbe908cfa90afae3834df 100644
--- a/src/FusionDirectory/Rest/WebServiceCall.php
+++ b/src/FusionDirectory/Rest/WebServiceCall.php
@@ -1,5 +1,6 @@
 <?php
 
+namespace FusionDirectory\Rest;
 class WebServiceCall
 {
   private $URL, $method, $token; //String