git subrepo clone https://github.com/mailcow/mailcow-dockerized.git mailcow/src/mailcow-dockerized

subrepo: subdir:   "mailcow/src/mailcow-dockerized"
  merged:   "a832becb"
upstream: origin:   "https://github.com/mailcow/mailcow-dockerized.git"
  branch:   "master"
  commit:   "a832becb"
git-subrepo: version:  "0.4.3"
  origin:   "???"
  commit:   "???"
Change-Id: If5be2d621a211e164c9b6577adaa7884449f16b5
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/.gitignore b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/.gitignore
new file mode 100644
index 0000000..e5294f4
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/.gitignore
@@ -0,0 +1,3 @@
+vendor
+composer.lock
+.DS_Store
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/COPYING b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/COPYING
new file mode 100644
index 0000000..8e7ddbc
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/COPYING
@@ -0,0 +1,21 @@
+The MIT License
+
+Copyright (c) 2011 Vladimir Andersen
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/README.md b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/README.md
new file mode 100644
index 0000000..1ebbdc5
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/README.md
@@ -0,0 +1,30 @@
+**Spyc** is a YAML loader/dumper written in pure PHP. Given a YAML document, Spyc will return an array that
+you can use however you see fit. Given an array, Spyc will return a string which contains a YAML document 
+built from your data.
+
+**YAML** is an amazingly human friendly and strikingly versatile data serialization language which can be used 
+for log files, config files, custom protocols, the works. For more information, see http://www.yaml.org.
+
+Spyc supports YAML 1.0 specification.
+
+## Using Spyc
+
+Using Spyc is trivial:
+
+```php
+<?php
+require_once "spyc.php";
+$Data = Spyc::YAMLLoad('spyc.yaml');
+```
+
+or (if you prefer functional syntax)
+
+```php
+<?php
+require_once "spyc.php";
+$Data = spyc_load_file('spyc.yaml');
+```
+
+## Donations, anyone?
+
+If you find Spyc useful, I'm accepting Bitcoin donations (who doesn't these days?) at 193bEkLP7zMrNLZm9UdUet4puGD5mQiLai
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/Spyc.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/Spyc.php
new file mode 100644
index 0000000..3fe0f62
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/Spyc.php
@@ -0,0 +1,1186 @@
+<?php
+/**
+   * Spyc -- A Simple PHP YAML Class
+   * @version 0.6.2
+   * @author Vlad Andersen <vlad.andersen@gmail.com>
+   * @author Chris Wanstrath <chris@ozmm.org>
+   * @link https://github.com/mustangostang/spyc/
+   * @copyright Copyright 2005-2006 Chris Wanstrath, 2006-2011 Vlad Andersen
+   * @license http://www.opensource.org/licenses/mit-license.php MIT License
+   * @package Spyc
+   */
+
+if (!function_exists('spyc_load')) {
+  /**
+   * Parses YAML to array.
+   * @param string $string YAML string.
+   * @return array
+   */
+  function spyc_load ($string) {
+    return Spyc::YAMLLoadString($string);
+  }
+}
+
+if (!function_exists('spyc_load_file')) {
+  /**
+   * Parses YAML to array.
+   * @param string $file Path to YAML file.
+   * @return array
+   */
+  function spyc_load_file ($file) {
+    return Spyc::YAMLLoad($file);
+  }
+}
+
+if (!function_exists('spyc_dump')) {
+  /**
+   * Dumps array to YAML.
+   * @param array $data Array.
+   * @return string
+   */
+  function spyc_dump ($data) {
+    return Spyc::YAMLDump($data, false, false, true);
+  }
+}
+
+if (!class_exists('Spyc')) {
+
+/**
+   * The Simple PHP YAML Class.
+   *
+   * This class can be used to read a YAML file and convert its contents
+   * into a PHP array.  It currently supports a very limited subsection of
+   * the YAML spec.
+   *
+   * Usage:
+   * <code>
+   *   $Spyc  = new Spyc;
+   *   $array = $Spyc->load($file);
+   * </code>
+   * or:
+   * <code>
+   *   $array = Spyc::YAMLLoad($file);
+   * </code>
+   * or:
+   * <code>
+   *   $array = spyc_load_file($file);
+   * </code>
+   * @package Spyc
+   */
+class Spyc {
+
+  // SETTINGS
+
+  const REMPTY = "\0\0\0\0\0";
+
+  /**
+   * Setting this to true will force YAMLDump to enclose any string value in
+   * quotes.  False by default.
+   *
+   * @var bool
+   */
+  public $setting_dump_force_quotes = false;
+
+  /**
+   * Setting this to true will forse YAMLLoad to use syck_load function when
+   * possible. False by default.
+   * @var bool
+   */
+  public $setting_use_syck_is_possible = false;
+
+  /**
+   * Setting this to true will forse YAMLLoad to use syck_load function when
+   * possible. False by default.
+   * @var bool
+   */
+  public $setting_empty_hash_as_object = false;
+
+
+  /**#@+
+  * @access private
+  * @var mixed
+  */
+  private $_dumpIndent;
+  private $_dumpWordWrap;
+  private $_containsGroupAnchor = false;
+  private $_containsGroupAlias = false;
+  private $path;
+  private $result;
+  private $LiteralPlaceHolder = '___YAML_Literal_Block___';
+  private $SavedGroups = array();
+  private $indent;
+  /**
+   * Path modifier that should be applied after adding current element.
+   * @var array
+   */
+  private $delayedPath = array();
+
+  /**#@+
+  * @access public
+  * @var mixed
+  */
+  public $_nodeId;
+
+/**
+ * Load a valid YAML string to Spyc.
+ * @param string $input
+ * @return array
+ */
+  public function load ($input) {
+    return $this->_loadString($input);
+  }
+
+ /**
+ * Load a valid YAML file to Spyc.
+ * @param string $file
+ * @return array
+ */
+  public function loadFile ($file) {
+    return $this->_load($file);
+  }
+
+  /**
+     * Load YAML into a PHP array statically
+     *
+     * The load method, when supplied with a YAML stream (string or file),
+     * will do its best to convert YAML in a file into a PHP array.  Pretty
+     * simple.
+     *  Usage:
+     *  <code>
+     *   $array = Spyc::YAMLLoad('lucky.yaml');
+     *   print_r($array);
+     *  </code>
+     * @access public
+     * @return array
+     * @param string $input Path of YAML file or string containing YAML
+     * @param array set options
+     */
+  public static function YAMLLoad($input, $options = []) {
+    $Spyc = new Spyc;
+    foreach ($options as $key => $value) {
+        if (property_exists($Spyc, $key)) {
+            $Spyc->$key = $value;
+        }
+    }
+    return $Spyc->_load($input);
+  }
+
+  /**
+     * Load a string of YAML into a PHP array statically
+     *
+     * The load method, when supplied with a YAML string, will do its best
+     * to convert YAML in a string into a PHP array.  Pretty simple.
+     *
+     * Note: use this function if you don't want files from the file system
+     * loaded and processed as YAML.  This is of interest to people concerned
+     * about security whose input is from a string.
+     *
+     *  Usage:
+     *  <code>
+     *   $array = Spyc::YAMLLoadString("---\n0: hello world\n");
+     *   print_r($array);
+     *  </code>
+     * @access public
+     * @return array
+     * @param string $input String containing YAML
+     * @param array set options
+     */
+  public static function YAMLLoadString($input, $options = []) {
+    $Spyc = new Spyc;
+    foreach ($options as $key => $value) {
+        if (property_exists($Spyc, $key)) {
+            $Spyc->$key = $value;
+        }
+    }
+    return $Spyc->_loadString($input);
+  }
+
+  /**
+     * Dump YAML from PHP array statically
+     *
+     * The dump method, when supplied with an array, will do its best
+     * to convert the array into friendly YAML.  Pretty simple.  Feel free to
+     * save the returned string as nothing.yaml and pass it around.
+     *
+     * Oh, and you can decide how big the indent is and what the wordwrap
+     * for folding is.  Pretty cool -- just pass in 'false' for either if
+     * you want to use the default.
+     *
+     * Indent's default is 2 spaces, wordwrap's default is 40 characters.  And
+     * you can turn off wordwrap by passing in 0.
+     *
+     * @access public
+     * @return string
+     * @param array|\stdClass $array PHP array
+     * @param int $indent Pass in false to use the default, which is 2
+     * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40)
+     * @param bool $no_opening_dashes Do not start YAML file with "---\n"
+     */
+  public static function YAMLDump($array, $indent = false, $wordwrap = false, $no_opening_dashes = false) {
+    $spyc = new Spyc;
+    return $spyc->dump($array, $indent, $wordwrap, $no_opening_dashes);
+  }
+
+
+  /**
+     * Dump PHP array to YAML
+     *
+     * The dump method, when supplied with an array, will do its best
+     * to convert the array into friendly YAML.  Pretty simple.  Feel free to
+     * save the returned string as tasteful.yaml and pass it around.
+     *
+     * Oh, and you can decide how big the indent is and what the wordwrap
+     * for folding is.  Pretty cool -- just pass in 'false' for either if
+     * you want to use the default.
+     *
+     * Indent's default is 2 spaces, wordwrap's default is 40 characters.  And
+     * you can turn off wordwrap by passing in 0.
+     *
+     * @access public
+     * @return string
+     * @param array $array PHP array
+     * @param int $indent Pass in false to use the default, which is 2
+     * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40)
+     */
+  public function dump($array,$indent = false,$wordwrap = false, $no_opening_dashes = false) {
+    // Dumps to some very clean YAML.  We'll have to add some more features
+    // and options soon.  And better support for folding.
+
+    // New features and options.
+    if ($indent === false or !is_numeric($indent)) {
+      $this->_dumpIndent = 2;
+    } else {
+      $this->_dumpIndent = $indent;
+    }
+
+    if ($wordwrap === false or !is_numeric($wordwrap)) {
+      $this->_dumpWordWrap = 40;
+    } else {
+      $this->_dumpWordWrap = $wordwrap;
+    }
+
+    // New YAML document
+    $string = "";
+    if (!$no_opening_dashes) $string = "---\n";
+
+    // Start at the base of the array and move through it.
+    if ($array) {
+      $array = (array)$array;
+      $previous_key = -1;
+      foreach ($array as $key => $value) {
+        if (!isset($first_key)) $first_key = $key;
+        $string .= $this->_yamlize($key,$value,0,$previous_key, $first_key, $array);
+        $previous_key = $key;
+      }
+    }
+    return $string;
+  }
+
+  /**
+     * Attempts to convert a key / value array item to YAML
+     * @access private
+     * @return string
+     * @param $key The name of the key
+     * @param $value The value of the item
+     * @param $indent The indent of the current node
+     */
+  private function _yamlize($key,$value,$indent, $previous_key = -1, $first_key = 0, $source_array = null) {
+    if(is_object($value)) $value = (array)$value;
+    if (is_array($value)) {
+      if (empty ($value))
+        return $this->_dumpNode($key, array(), $indent, $previous_key, $first_key, $source_array);
+      // It has children.  What to do?
+      // Make it the right kind of item
+      $string = $this->_dumpNode($key, self::REMPTY, $indent, $previous_key, $first_key, $source_array);
+      // Add the indent
+      $indent += $this->_dumpIndent;
+      // Yamlize the array
+      $string .= $this->_yamlizeArray($value,$indent);
+    } elseif (!is_array($value)) {
+      // It doesn't have children.  Yip.
+      $string = $this->_dumpNode($key, $value, $indent, $previous_key, $first_key, $source_array);
+    }
+    return $string;
+  }
+
+  /**
+     * Attempts to convert an array to YAML
+     * @access private
+     * @return string
+     * @param $array The array you want to convert
+     * @param $indent The indent of the current level
+     */
+  private function _yamlizeArray($array,$indent) {
+    if (is_array($array)) {
+      $string = '';
+      $previous_key = -1;
+      foreach ($array as $key => $value) {
+        if (!isset($first_key)) $first_key = $key;
+        $string .= $this->_yamlize($key, $value, $indent, $previous_key, $first_key, $array);
+        $previous_key = $key;
+      }
+      return $string;
+    } else {
+      return false;
+    }
+  }
+
+  /**
+     * Returns YAML from a key and a value
+     * @access private
+     * @return string
+     * @param $key The name of the key
+     * @param $value The value of the item
+     * @param $indent The indent of the current node
+     */
+  private function _dumpNode($key, $value, $indent, $previous_key = -1, $first_key = 0, $source_array = null) {
+    // do some folding here, for blocks
+    if (is_string ($value) && ((strpos($value,"\n") !== false || strpos($value,": ") !== false || strpos($value,"- ") !== false ||
+      strpos($value,"*") !== false || strpos($value,"#") !== false || strpos($value,"<") !== false || strpos($value,">") !== false || strpos ($value, '%') !== false || strpos ($value, '  ') !== false ||
+      strpos($value,"[") !== false || strpos($value,"]") !== false || strpos($value,"{") !== false || strpos($value,"}") !== false) || strpos($value,"&") !== false || strpos($value, "'") !== false || strpos($value, "!") === 0 ||
+      substr ($value, -1, 1) == ':')
+    ) {
+      $value = $this->_doLiteralBlock($value,$indent);
+    } else {
+      $value  = $this->_doFolding($value,$indent);
+    }
+
+    if ($value === array()) $value = '[ ]';
+    if ($value === "") $value = '""';
+    if (self::isTranslationWord($value)) {
+      $value = $this->_doLiteralBlock($value, $indent);
+    }
+    if (trim ($value) != $value)
+       $value = $this->_doLiteralBlock($value,$indent);
+
+    if (is_bool($value)) {
+       $value = $value ? "true" : "false";
+    }
+
+    if ($value === null) $value = 'null';
+    if ($value === "'" . self::REMPTY . "'") $value = null;
+
+    $spaces = str_repeat(' ',$indent);
+
+    //if (is_int($key) && $key - 1 == $previous_key && $first_key===0) {
+    if (is_array ($source_array) && array_keys($source_array) === range(0, count($source_array) - 1)) {
+      // It's a sequence
+      $string = $spaces.'- '.$value."\n";
+    } else {
+      // if ($first_key===0)  throw new Exception('Keys are all screwy.  The first one was zero, now it\'s "'. $key .'"');
+      // It's mapped
+      if (strpos($key, ":") !== false || strpos($key, "#") !== false) { $key = '"' . $key . '"'; }
+      $string = rtrim ($spaces.$key.': '.$value)."\n";
+    }
+    return $string;
+  }
+
+  /**
+     * Creates a literal block for dumping
+     * @access private
+     * @return string
+     * @param $value
+     * @param $indent int The value of the indent
+     */
+  private function _doLiteralBlock($value,$indent) {
+    if ($value === "\n") return '\n';
+    if (strpos($value, "\n") === false && strpos($value, "'") === false) {
+      return sprintf ("'%s'", $value);
+    }
+    if (strpos($value, "\n") === false && strpos($value, '"') === false) {
+      return sprintf ('"%s"', $value);
+    }
+    $exploded = explode("\n",$value);
+    $newValue = '|';
+    if (isset($exploded[0]) && ($exploded[0] == "|" || $exploded[0] == "|-" || $exploded[0] == ">")) {
+        $newValue = $exploded[0];
+        unset($exploded[0]);
+    }
+    $indent += $this->_dumpIndent;
+    $spaces   = str_repeat(' ',$indent);
+    foreach ($exploded as $line) {
+      $line = trim($line);
+      if (strpos($line, '"') === 0 && strrpos($line, '"') == (strlen($line)-1) || strpos($line, "'") === 0 && strrpos($line, "'") == (strlen($line)-1)) {
+        $line = substr($line, 1, -1);
+      }
+      $newValue .= "\n" . $spaces . ($line);
+    }
+    return $newValue;
+  }
+
+  /**
+     * Folds a string of text, if necessary
+     * @access private
+     * @return string
+     * @param $value The string you wish to fold
+     */
+  private function _doFolding($value,$indent) {
+    // Don't do anything if wordwrap is set to 0
+
+    if ($this->_dumpWordWrap !== 0 && is_string ($value) && strlen($value) > $this->_dumpWordWrap) {
+      $indent += $this->_dumpIndent;
+      $indent = str_repeat(' ',$indent);
+      $wrapped = wordwrap($value,$this->_dumpWordWrap,"\n$indent");
+      $value   = ">\n".$indent.$wrapped;
+    } else {
+      if ($this->setting_dump_force_quotes && is_string ($value) && $value !== self::REMPTY)
+        $value = '"' . $value . '"';
+      if (is_numeric($value) && is_string($value))
+        $value = '"' . $value . '"';
+    }
+
+
+    return $value;
+  }
+
+  private function isTrueWord($value) {
+    $words = self::getTranslations(array('true', 'on', 'yes', 'y'));
+    return in_array($value, $words, true);
+  }
+
+  private function isFalseWord($value) {
+    $words = self::getTranslations(array('false', 'off', 'no', 'n'));
+    return in_array($value, $words, true);
+  }
+
+  private function isNullWord($value) {
+    $words = self::getTranslations(array('null', '~'));
+    return in_array($value, $words, true);
+  }
+
+  private function isTranslationWord($value) {
+    return (
+      self::isTrueWord($value)  ||
+      self::isFalseWord($value) ||
+      self::isNullWord($value)
+    );
+  }
+
+  /**
+     * Coerce a string into a native type
+     * Reference: http://yaml.org/type/bool.html
+     * TODO: Use only words from the YAML spec.
+     * @access private
+     * @param $value The value to coerce
+     */
+  private function coerceValue(&$value) {
+    if (self::isTrueWord($value)) {
+      $value = true;
+    } else if (self::isFalseWord($value)) {
+      $value = false;
+    } else if (self::isNullWord($value)) {
+      $value = null;
+    }
+  }
+
+  /**
+     * Given a set of words, perform the appropriate translations on them to
+     * match the YAML 1.1 specification for type coercing.
+     * @param $words The words to translate
+     * @access private
+     */
+  private static function getTranslations(array $words) {
+    $result = array();
+    foreach ($words as $i) {
+      $result = array_merge($result, array(ucfirst($i), strtoupper($i), strtolower($i)));
+    }
+    return $result;
+  }
+
+// LOADING FUNCTIONS
+
+  private function _load($input) {
+    $Source = $this->loadFromSource($input);
+    return $this->loadWithSource($Source);
+  }
+
+  private function _loadString($input) {
+    $Source = $this->loadFromString($input);
+    return $this->loadWithSource($Source);
+  }
+
+  private function loadWithSource($Source) {
+    if (empty ($Source)) return array();
+    if ($this->setting_use_syck_is_possible && function_exists ('syck_load')) {
+      $array = syck_load (implode ("\n", $Source));
+      return is_array($array) ? $array : array();
+    }
+
+    $this->path = array();
+    $this->result = array();
+
+    $cnt = count($Source);
+    for ($i = 0; $i < $cnt; $i++) {
+      $line = $Source[$i];
+
+      $this->indent = strlen($line) - strlen(ltrim($line));
+      $tempPath = $this->getParentPathByIndent($this->indent);
+      $line = self::stripIndent($line, $this->indent);
+      if (self::isComment($line)) continue;
+      if (self::isEmpty($line)) continue;
+      $this->path = $tempPath;
+
+      $literalBlockStyle = self::startsLiteralBlock($line);
+      if ($literalBlockStyle) {
+        $line = rtrim ($line, $literalBlockStyle . " \n");
+        $literalBlock = '';
+        $line .= ' '.$this->LiteralPlaceHolder;
+        $literal_block_indent = strlen($Source[$i+1]) - strlen(ltrim($Source[$i+1]));
+        while (++$i < $cnt && $this->literalBlockContinues($Source[$i], $this->indent)) {
+          $literalBlock = $this->addLiteralLine($literalBlock, $Source[$i], $literalBlockStyle, $literal_block_indent);
+        }
+        $i--;
+      }
+
+      // Strip out comments
+      if (strpos ($line, '#')) {
+          $line = preg_replace('/\s*#([^"\']+)$/','',$line);
+      }
+
+      while (++$i < $cnt && self::greedilyNeedNextLine($line)) {
+        $line = rtrim ($line, " \n\t\r") . ' ' . ltrim ($Source[$i], " \t");
+      }
+      $i--;
+
+      $lineArray = $this->_parseLine($line);
+
+      if ($literalBlockStyle)
+        $lineArray = $this->revertLiteralPlaceHolder ($lineArray, $literalBlock);
+
+      $this->addArray($lineArray, $this->indent);
+
+      foreach ($this->delayedPath as $indent => $delayedPath)
+        $this->path[$indent] = $delayedPath;
+
+      $this->delayedPath = array();
+
+    }
+    return $this->result;
+  }
+
+  private function loadFromSource ($input) {
+    if (!empty($input) && strpos($input, "\n") === false && file_exists($input))
+      $input = file_get_contents($input);
+
+    return $this->loadFromString($input);
+  }
+
+  private function loadFromString ($input) {
+    $lines = explode("\n",$input);
+    foreach ($lines as $k => $_) {
+      $lines[$k] = rtrim ($_, "\r");
+    }
+    return $lines;
+  }
+
+  /**
+     * Parses YAML code and returns an array for a node
+     * @access private
+     * @return array
+     * @param string $line A line from the YAML file
+     */
+  private function _parseLine($line) {
+    if (!$line) return array();
+    $line = trim($line);
+    if (!$line) return array();
+
+    $array = array();
+
+    $group = $this->nodeContainsGroup($line);
+    if ($group) {
+      $this->addGroup($line, $group);
+      $line = $this->stripGroup ($line, $group);
+    }
+
+    if ($this->startsMappedSequence($line)) {
+      return $this->returnMappedSequence($line);
+    }
+
+    if ($this->startsMappedValue($line)) {
+      return $this->returnMappedValue($line);
+    }
+
+    if ($this->isArrayElement($line))
+      return $this->returnArrayElement($line);
+
+    if ($this->isPlainArray($line))
+     return $this->returnPlainArray($line);
+
+    return $this->returnKeyValuePair($line);
+
+  }
+
+  /**
+     * Finds the type of the passed value, returns the value as the new type.
+     * @access private
+     * @param string $value
+     * @return mixed
+     */
+  private function _toType($value) {
+    if ($value === '') return "";
+
+    if ($this->setting_empty_hash_as_object && $value === '{}') {
+      return new stdClass();
+    }
+
+    $first_character = $value[0];
+    $last_character = substr($value, -1, 1);
+
+    $is_quoted = false;
+    do {
+      if (!$value) break;
+      if ($first_character != '"' && $first_character != "'") break;
+      if ($last_character != '"' && $last_character != "'") break;
+      $is_quoted = true;
+    } while (0);
+
+    if ($is_quoted) {
+      $value = str_replace('\n', "\n", $value);
+      if ($first_character == "'")
+        return strtr(substr ($value, 1, -1), array ('\'\'' => '\'', '\\\''=> '\''));
+      return strtr(substr ($value, 1, -1), array ('\\"' => '"', '\\\''=> '\''));
+    }
+
+    if (strpos($value, ' #') !== false && !$is_quoted)
+      $value = preg_replace('/\s+#(.+)$/','',$value);
+
+    if ($first_character == '[' && $last_character == ']') {
+      // Take out strings sequences and mappings
+      $innerValue = trim(substr ($value, 1, -1));
+      if ($innerValue === '') return array();
+      $explode = $this->_inlineEscape($innerValue);
+      // Propagate value array
+      $value  = array();
+      foreach ($explode as $v) {
+        $value[] = $this->_toType($v);
+      }
+      return $value;
+    }
+
+    if (strpos($value,': ')!==false && $first_character != '{') {
+      $array = explode(': ',$value);
+      $key   = trim($array[0]);
+      array_shift($array);
+      $value = trim(implode(': ',$array));
+      $value = $this->_toType($value);
+      return array($key => $value);
+    }
+
+    if ($first_character == '{' && $last_character == '}') {
+      $innerValue = trim(substr ($value, 1, -1));
+      if ($innerValue === '') return array();
+      // Inline Mapping
+      // Take out strings sequences and mappings
+      $explode = $this->_inlineEscape($innerValue);
+      // Propagate value array
+      $array = array();
+      foreach ($explode as $v) {
+        $SubArr = $this->_toType($v);
+        if (empty($SubArr)) continue;
+        if (is_array ($SubArr)) {
+          $array[key($SubArr)] = $SubArr[key($SubArr)]; continue;
+        }
+        $array[] = $SubArr;
+      }
+      return $array;
+    }
+
+    if ($value == 'null' || $value == 'NULL' || $value == 'Null' || $value == '' || $value == '~') {
+      return null;
+    }
+
+    if ( is_numeric($value) && preg_match ('/^(-|)[1-9]+[0-9]*$/', $value) ){
+      $intvalue = (int)$value;
+      if ($intvalue != PHP_INT_MAX && $intvalue != ~PHP_INT_MAX)
+        $value = $intvalue;
+      return $value;
+    }
+
+    if ( is_string($value) && preg_match('/^0[xX][0-9a-fA-F]+$/', $value)) {
+      // Hexadecimal value.
+      return hexdec($value);
+    }
+
+    $this->coerceValue($value);
+
+    if (is_numeric($value)) {
+      if ($value === '0') return 0;
+      if (rtrim ($value, 0) === $value)
+        $value = (float)$value;
+      return $value;
+    }
+
+    return $value;
+  }
+
+  /**
+     * Used in inlines to check for more inlines or quoted strings
+     * @access private
+     * @return array
+     */
+  private function _inlineEscape($inline) {
+    // There's gotta be a cleaner way to do this...
+    // While pure sequences seem to be nesting just fine,
+    // pure mappings and mappings with sequences inside can't go very
+    // deep.  This needs to be fixed.
+
+    $seqs = array();
+    $maps = array();
+    $saved_strings = array();
+    $saved_empties = array();
+
+    // Check for empty strings
+    $regex = '/("")|(\'\')/';
+    if (preg_match_all($regex,$inline,$strings)) {
+      $saved_empties = $strings[0];
+      $inline  = preg_replace($regex,'YAMLEmpty',$inline);
+    }
+    unset($regex);
+
+    // Check for strings
+    $regex = '/(?:(")|(?:\'))((?(1)[^"]+|[^\']+))(?(1)"|\')/';
+    if (preg_match_all($regex,$inline,$strings)) {
+      $saved_strings = $strings[0];
+      $inline  = preg_replace($regex,'YAMLString',$inline);
+    }
+    unset($regex);
+
+    // echo $inline;
+
+    $i = 0;
+    do {
+
+    // Check for sequences
+    while (preg_match('/\[([^{}\[\]]+)\]/U',$inline,$matchseqs)) {
+      $seqs[] = $matchseqs[0];
+      $inline = preg_replace('/\[([^{}\[\]]+)\]/U', ('YAMLSeq' . (count($seqs) - 1) . 's'), $inline, 1);
+    }
+
+    // Check for mappings
+    while (preg_match('/{([^\[\]{}]+)}/U',$inline,$matchmaps)) {
+      $maps[] = $matchmaps[0];
+      $inline = preg_replace('/{([^\[\]{}]+)}/U', ('YAMLMap' . (count($maps) - 1) . 's'), $inline, 1);
+    }
+
+    if ($i++ >= 10) break;
+
+    } while (strpos ($inline, '[') !== false || strpos ($inline, '{') !== false);
+
+    $explode = explode(',',$inline);
+    $explode = array_map('trim', $explode);
+    $stringi = 0; $i = 0;
+
+    while (1) {
+
+    // Re-add the sequences
+    if (!empty($seqs)) {
+      foreach ($explode as $key => $value) {
+        if (strpos($value,'YAMLSeq') !== false) {
+          foreach ($seqs as $seqk => $seq) {
+            $explode[$key] = str_replace(('YAMLSeq'.$seqk.'s'),$seq,$value);
+            $value = $explode[$key];
+          }
+        }
+      }
+    }
+
+    // Re-add the mappings
+    if (!empty($maps)) {
+      foreach ($explode as $key => $value) {
+        if (strpos($value,'YAMLMap') !== false) {
+          foreach ($maps as $mapk => $map) {
+            $explode[$key] = str_replace(('YAMLMap'.$mapk.'s'), $map, $value);
+            $value = $explode[$key];
+          }
+        }
+      }
+    }
+
+
+    // Re-add the strings
+    if (!empty($saved_strings)) {
+      foreach ($explode as $key => $value) {
+        while (strpos($value,'YAMLString') !== false) {
+          $explode[$key] = preg_replace('/YAMLString/',$saved_strings[$stringi],$value, 1);
+          unset($saved_strings[$stringi]);
+          ++$stringi;
+          $value = $explode[$key];
+        }
+      }
+    }
+
+
+    // Re-add the empties
+    if (!empty($saved_empties)) {
+      foreach ($explode as $key => $value) {
+        while (strpos($value,'YAMLEmpty') !== false) {
+          $explode[$key] = preg_replace('/YAMLEmpty/', '', $value, 1);
+          $value = $explode[$key];
+        }
+      }
+    }
+
+    $finished = true;
+    foreach ($explode as $key => $value) {
+      if (strpos($value,'YAMLSeq') !== false) {
+        $finished = false; break;
+      }
+      if (strpos($value,'YAMLMap') !== false) {
+        $finished = false; break;
+      }
+      if (strpos($value,'YAMLString') !== false) {
+        $finished = false; break;
+      }
+      if (strpos($value,'YAMLEmpty') !== false) {
+        $finished = false; break;
+      }
+    }
+    if ($finished) break;
+
+    $i++;
+    if ($i > 10)
+      break; // Prevent infinite loops.
+    }
+
+
+    return $explode;
+  }
+
+  private function literalBlockContinues ($line, $lineIndent) {
+    if (!trim($line)) return true;
+    if (strlen($line) - strlen(ltrim($line)) > $lineIndent) return true;
+    return false;
+  }
+
+  private function referenceContentsByAlias ($alias) {
+    do {
+      if (!isset($this->SavedGroups[$alias])) { echo "Bad group name: $alias."; break; }
+      $groupPath = $this->SavedGroups[$alias];
+      $value = $this->result;
+      foreach ($groupPath as $k) {
+        $value = $value[$k];
+      }
+    } while (false);
+    return $value;
+  }
+
+  private function addArrayInline ($array, $indent) {
+      $CommonGroupPath = $this->path;
+      if (empty ($array)) return false;
+
+      foreach ($array as $k => $_) {
+        $this->addArray(array($k => $_), $indent);
+        $this->path = $CommonGroupPath;
+      }
+      return true;
+  }
+
+  private function addArray ($incoming_data, $incoming_indent) {
+
+   // print_r ($incoming_data);
+
+    if (count ($incoming_data) > 1)
+      return $this->addArrayInline ($incoming_data, $incoming_indent);
+
+    $key = key ($incoming_data);
+    $value = isset($incoming_data[$key]) ? $incoming_data[$key] : null;
+    if ($key === '__!YAMLZero') $key = '0';
+
+    if ($incoming_indent == 0 && !$this->_containsGroupAlias && !$this->_containsGroupAnchor) { // Shortcut for root-level values.
+      if ($key || $key === '' || $key === '0') {
+        $this->result[$key] = $value;
+      } else {
+        $this->result[] = $value; end ($this->result); $key = key ($this->result);
+      }
+      $this->path[$incoming_indent] = $key;
+      return;
+    }
+
+
+
+    $history = array();
+    // Unfolding inner array tree.
+    $history[] = $_arr = $this->result;
+    foreach ($this->path as $k) {
+      $history[] = $_arr = $_arr[$k];
+    }
+
+    if ($this->_containsGroupAlias) {
+      $value = $this->referenceContentsByAlias($this->_containsGroupAlias);
+      $this->_containsGroupAlias = false;
+    }
+
+
+    // Adding string or numeric key to the innermost level or $this->arr.
+    if (is_string($key) && $key == '<<') {
+      if (!is_array ($_arr)) { $_arr = array (); }
+
+      $_arr = array_merge ($_arr, $value);
+    } else if ($key || $key === '' || $key === '0') {
+      if (!is_array ($_arr))
+        $_arr = array ($key=>$value);
+      else
+        $_arr[$key] = $value;
+    } else {
+      if (!is_array ($_arr)) { $_arr = array ($value); $key = 0; }
+      else { $_arr[] = $value; end ($_arr); $key = key ($_arr); }
+    }
+
+    $reverse_path = array_reverse($this->path);
+    $reverse_history = array_reverse ($history);
+    $reverse_history[0] = $_arr;
+    $cnt = count($reverse_history) - 1;
+    for ($i = 0; $i < $cnt; $i++) {
+      $reverse_history[$i+1][$reverse_path[$i]] = $reverse_history[$i];
+    }
+    $this->result = $reverse_history[$cnt];
+
+    $this->path[$incoming_indent] = $key;
+
+    if ($this->_containsGroupAnchor) {
+      $this->SavedGroups[$this->_containsGroupAnchor] = $this->path;
+      if (is_array ($value)) {
+        $k = key ($value);
+        if (!is_int ($k)) {
+          $this->SavedGroups[$this->_containsGroupAnchor][$incoming_indent + 2] = $k;
+        }
+      }
+      $this->_containsGroupAnchor = false;
+    }
+
+  }
+
+  private static function startsLiteralBlock ($line) {
+    $lastChar = substr (trim($line), -1);
+    if ($lastChar != '>' && $lastChar != '|') return false;
+    if ($lastChar == '|') return $lastChar;
+    // HTML tags should not be counted as literal blocks.
+    if (preg_match ('#<.*?>$#', $line)) return false;
+    return $lastChar;
+  }
+
+  private static function greedilyNeedNextLine($line) {
+    $line = trim ($line);
+    if (!strlen($line)) return false;
+    if (substr ($line, -1, 1) == ']') return false;
+    if ($line[0] == '[') return true;
+    if (preg_match ('#^[^:]+?:\s*\[#', $line)) return true;
+    return false;
+  }
+
+  private function addLiteralLine ($literalBlock, $line, $literalBlockStyle, $indent = -1) {
+    $line = self::stripIndent($line, $indent);
+    if ($literalBlockStyle !== '|') {
+        $line = self::stripIndent($line);
+    }
+    $line = rtrim ($line, "\r\n\t ") . "\n";
+    if ($literalBlockStyle == '|') {
+      return $literalBlock . $line;
+    }
+    if (strlen($line) == 0)
+      return rtrim($literalBlock, ' ') . "\n";
+    if ($line == "\n" && $literalBlockStyle == '>') {
+      return rtrim ($literalBlock, " \t") . "\n";
+    }
+    if ($line != "\n")
+      $line = trim ($line, "\r\n ") . " ";
+    return $literalBlock . $line;
+  }
+
+   function revertLiteralPlaceHolder ($lineArray, $literalBlock) {
+     foreach ($lineArray as $k => $_) {
+      if (is_array($_))
+        $lineArray[$k] = $this->revertLiteralPlaceHolder ($_, $literalBlock);
+      else if (substr($_, -1 * strlen ($this->LiteralPlaceHolder)) == $this->LiteralPlaceHolder)
+	       $lineArray[$k] = rtrim ($literalBlock, " \r\n");
+     }
+     return $lineArray;
+   }
+
+  private static function stripIndent ($line, $indent = -1) {
+    if ($indent == -1) $indent = strlen($line) - strlen(ltrim($line));
+    return substr ($line, $indent);
+  }
+
+  private function getParentPathByIndent ($indent) {
+    if ($indent == 0) return array();
+    $linePath = $this->path;
+    do {
+      end($linePath); $lastIndentInParentPath = key($linePath);
+      if ($indent <= $lastIndentInParentPath) array_pop ($linePath);
+    } while ($indent <= $lastIndentInParentPath);
+    return $linePath;
+  }
+
+
+  private function clearBiggerPathValues ($indent) {
+
+
+    if ($indent == 0) $this->path = array();
+    if (empty ($this->path)) return true;
+
+    foreach ($this->path as $k => $_) {
+      if ($k > $indent) unset ($this->path[$k]);
+    }
+
+    return true;
+  }
+
+
+  private static function isComment ($line) {
+    if (!$line) return false;
+    if ($line[0] == '#') return true;
+    if (trim($line, " \r\n\t") == '---') return true;
+    return false;
+  }
+
+  private static function isEmpty ($line) {
+    return (trim ($line) === '');
+  }
+
+
+  private function isArrayElement ($line) {
+    if (!$line || !is_scalar($line)) return false;
+    if (substr($line, 0, 2) != '- ') return false;
+    if (strlen ($line) > 3)
+      if (substr($line,0,3) == '---') return false;
+
+    return true;
+  }
+
+  private function isHashElement ($line) {
+    return strpos($line, ':');
+  }
+
+  private function isLiteral ($line) {
+    if ($this->isArrayElement($line)) return false;
+    if ($this->isHashElement($line)) return false;
+    return true;
+  }
+
+
+  private static function unquote ($value) {
+    if (!$value) return $value;
+    if (!is_string($value)) return $value;
+    if ($value[0] == '\'') return trim ($value, '\'');
+    if ($value[0] == '"') return trim ($value, '"');
+    return $value;
+  }
+
+  private function startsMappedSequence ($line) {
+    return (substr($line, 0, 2) == '- ' && substr ($line, -1, 1) == ':');
+  }
+
+  private function returnMappedSequence ($line) {
+    $array = array();
+    $key         = self::unquote(trim(substr($line,1,-1)));
+    $array[$key] = array();
+    $this->delayedPath = array(strpos ($line, $key) + $this->indent => $key);
+    return array($array);
+  }
+
+  private function checkKeysInValue($value) {
+    if (strchr('[{"\'', $value[0]) === false) {
+      if (strchr($value, ': ') !== false) {
+          throw new Exception('Too many keys: '.$value);
+      }
+    }
+  }
+
+  private function returnMappedValue ($line) {
+    $this->checkKeysInValue($line);
+    $array = array();
+    $key         = self::unquote (trim(substr($line,0,-1)));
+    $array[$key] = '';
+    return $array;
+  }
+
+  private function startsMappedValue ($line) {
+    return (substr ($line, -1, 1) == ':');
+  }
+
+  private function isPlainArray ($line) {
+    return ($line[0] == '[' && substr ($line, -1, 1) == ']');
+  }
+
+  private function returnPlainArray ($line) {
+    return $this->_toType($line);
+  }
+
+  private function returnKeyValuePair ($line) {
+    $array = array();
+    $key = '';
+    if (strpos ($line, ': ')) {
+      // It's a key/value pair most likely
+      // If the key is in double quotes pull it out
+      if (($line[0] == '"' || $line[0] == "'") && preg_match('/^(["\'](.*)["\'](\s)*:)/',$line,$matches)) {
+        $value = trim(str_replace($matches[1],'',$line));
+        $key   = $matches[2];
+      } else {
+        // Do some guesswork as to the key and the value
+        $explode = explode(': ', $line);
+        $key     = trim(array_shift($explode));
+        $value   = trim(implode(': ', $explode));
+        $this->checkKeysInValue($value);
+      }
+      // Set the type of the value.  Int, string, etc
+      $value = $this->_toType($value);
+
+      if ($key === '0') $key = '__!YAMLZero';
+      $array[$key] = $value;
+    } else {
+      $array = array ($line);
+    }
+    return $array;
+
+  }
+
+
+  private function returnArrayElement ($line) {
+     if (strlen($line) <= 1) return array(array()); // Weird %)
+     $array = array();
+     $value   = trim(substr($line,1));
+     $value   = $this->_toType($value);
+     if ($this->isArrayElement($value)) {
+       $value = $this->returnArrayElement($value);
+     }
+     $array[] = $value;
+     return $array;
+  }
+
+
+  private function nodeContainsGroup ($line) {
+    $symbolsForReference = 'A-z0-9_\-';
+    if (strpos($line, '&') === false && strpos($line, '*') === false) return false; // Please die fast ;-)
+    if ($line[0] == '&' && preg_match('/^(&['.$symbolsForReference.']+)/', $line, $matches)) return $matches[1];
+    if ($line[0] == '*' && preg_match('/^(\*['.$symbolsForReference.']+)/', $line, $matches)) return $matches[1];
+    if (preg_match('/(&['.$symbolsForReference.']+)$/', $line, $matches)) return $matches[1];
+    if (preg_match('/(\*['.$symbolsForReference.']+$)/', $line, $matches)) return $matches[1];
+    if (preg_match ('#^\s*<<\s*:\s*(\*[^\s]+).*$#', $line, $matches)) return $matches[1];
+    return false;
+
+  }
+
+  private function addGroup ($line, $group) {
+    if ($group[0] == '&') $this->_containsGroupAnchor = substr ($group, 1);
+    if ($group[0] == '*') $this->_containsGroupAlias = substr ($group, 1);
+    //print_r ($this->path);
+  }
+
+  private function stripGroup ($line, $group) {
+    $line = trim(str_replace($group, '', $line));
+    return $line;
+  }
+}
+}
+
+// Enable use of Spyc from command line
+// The syntax is the following: php Spyc.php spyc.yaml
+
+do {
+  if (PHP_SAPI != 'cli') break;
+  if (empty ($_SERVER['argc']) || $_SERVER['argc'] < 2) break;
+  if (empty ($_SERVER['PHP_SELF']) || FALSE === strpos ($_SERVER['PHP_SELF'], 'Spyc.php') ) break;
+  $file = $argv[1];
+  echo json_encode (spyc_load_file ($file));
+} while (0);
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/composer.json b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/composer.json
new file mode 100644
index 0000000..e5ab776
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/composer.json
@@ -0,0 +1,30 @@
+{
+    "name": "mustangostang/spyc",
+    "description": "A simple YAML loader/dumper class for PHP",
+    "type": "library",
+    "keywords": [
+        "spyc",
+        "yaml",
+        "yml"
+    ],
+    "homepage": "https://github.com/mustangostang/spyc/",
+    "authors" : [{
+        "name": "mustangostang",
+        "email": "vlad.andersen@gmail.com"
+    }],
+    "license": "MIT",
+    "require": {
+        "php": ">=5.3.1"
+    },
+    "autoload": {
+        "files": [ "Spyc.php" ]
+    },
+    "require-dev": {
+        "phpunit/phpunit": "4.3.*@dev"
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "0.5.x-dev"
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/examples/yaml-dump.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/examples/yaml-dump.php
new file mode 100644
index 0000000..9d2160a
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/examples/yaml-dump.php
@@ -0,0 +1,25 @@
+<?php
+
+#
+#    S P Y C
+#      a simple php yaml class
+#
+# Feel free to dump an array to YAML, and then to load that YAML back into an
+# array.  This is a good way to test the limitations of the parser and maybe
+# learn some basic YAML.
+#
+
+include('../Spyc.php');
+
+$array[] = 'Sequence item';
+$array['The Key'] = 'Mapped value';
+$array[] = array('A sequence','of a sequence');
+$array[] = array('first' => 'A sequence','second' => 'of mapped values');
+$array['Mapped'] = array('A sequence','which is mapped');
+$array['A Note'] = 'What if your text is too long?';
+$array['Another Note'] = 'If that is the case, the dumper will probably fold your text by using a block.  Kinda like this.';
+$array['The trick?'] = 'The trick is that we overrode the default indent, 2, to 4 and the default wordwrap, 40, to 60.';
+$array['Old Dog'] = "And if you want\n to preserve line breaks, \ngo ahead!";
+$array['key:withcolon'] = "Should support this to";
+
+$yaml = Spyc::YAMLDump($array,4,60);
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/examples/yaml-load.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/examples/yaml-load.php
new file mode 100644
index 0000000..9e457e1
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/examples/yaml-load.php
@@ -0,0 +1,21 @@
+<?php
+
+#
+#    S P Y C
+#      a simple php yaml class
+#
+# license: [MIT License, http://www.opensource.org/licenses/mit-license.php]
+#
+
+include('../Spyc.php');
+
+$array = Spyc::YAMLLoad('../spyc.yaml');
+
+echo '<pre><a href="spyc.yaml">spyc.yaml</a> loaded into PHP:<br/>';
+print_r($array);
+echo '</pre>';
+
+
+echo '<pre>YAML Data dumped back:<br/>';
+echo Spyc::YAMLDump($array);
+echo '</pre>';
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/php4/5to4.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/php4/5to4.php
new file mode 100644
index 0000000..5a48694
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/php4/5to4.php
@@ -0,0 +1,17 @@
+<?php
+
+php5to4 ("../spyc.php", 'spyc-latest.php4');
+
+function php5to4 ($src, $dest) {
+  $code = file_get_contents ($src);
+  $code = preg_replace ('#(public|private|protected)\s+\$#i', 'var \$', $code);
+  $code = preg_replace ('#(public|private|protected)\s+static\s+\$#i', 'var \$', $code);
+  $code = preg_replace ('#(public|private|protected)\s+function#i', 'function', $code);
+  $code = preg_replace ('#(public|private|protected)\s+static\s+function#i', 'function', $code);
+  $code = preg_replace ('#throw new Exception\\(([^)]*)\\)#i', 'trigger_error($1,E_USER_ERROR)', $code);
+  $code = str_replace ('self::', '$this->', $code);
+  $f = fopen ($dest, 'w');
+  fwrite($f, $code);
+  fclose ($f);
+  print "Written to $dest.\n";
+}
\ No newline at end of file
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/php4/spyc.php4 b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/php4/spyc.php4
new file mode 100644
index 0000000..73f08cc
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/php4/spyc.php4
@@ -0,0 +1,1023 @@
+<?php
+/**
+   * Spyc -- A Simple PHP YAML Class
+   * @version 0.4.5
+   * @author Vlad Andersen <vlad.andersen@gmail.com>
+   * @author Chris Wanstrath <chris@ozmm.org>
+   * @link http://code.google.com/p/spyc/
+   * @copyright Copyright 2005-2006 Chris Wanstrath, 2006-2009 Vlad Andersen
+   * @license http://www.opensource.org/licenses/mit-license.php MIT License
+   * @package Spyc
+   */
+
+if (!function_exists('spyc_load')) {
+  /**
+   * Parses YAML to array.
+   * @param string $string YAML string.
+   * @return array
+   */
+  function spyc_load ($string) {
+    return Spyc::YAMLLoadString($string);
+  }
+}
+
+if (!function_exists('spyc_load_file')) {
+  /**
+   * Parses YAML to array.
+   * @param string $file Path to YAML file.
+   * @return array
+   */
+  function spyc_load_file ($file) {
+    return Spyc::YAMLLoad($file);
+  }
+}
+
+/**
+   * The Simple PHP YAML Class.
+   *
+   * This class can be used to read a YAML file and convert its contents
+   * into a PHP array.  It currently supports a very limited subsection of
+   * the YAML spec.
+   *
+   * Usage:
+   * <code>
+   *   $Spyc  = new Spyc;
+   *   $array = $Spyc->load($file);
+   * </code>
+   * or:
+   * <code>
+   *   $array = Spyc::YAMLLoad($file);
+   * </code>
+   * or:
+   * <code>
+   *   $array = spyc_load_file($file);
+   * </code>
+   * @package Spyc
+   */
+class Spyc {
+
+  // SETTINGS
+
+  /**
+   * Setting this to true will force YAMLDump to enclose any string value in
+   * quotes.  False by default.
+   * 
+   * @var bool
+   */
+  var $setting_dump_force_quotes = false;
+
+  /**
+   * Setting this to true will forse YAMLLoad to use syck_load function when
+   * possible. False by default.
+   * @var bool
+   */
+  var $setting_use_syck_is_possible = false;
+
+
+
+  /**#@+
+  * @access private
+  * @var mixed
+  */
+  var $_dumpIndent;
+  var $_dumpWordWrap;
+  var $_containsGroupAnchor = false;
+  var $_containsGroupAlias = false;
+  var $path;
+  var $result;
+  var $LiteralPlaceHolder = '___YAML_Literal_Block___';
+  var $SavedGroups = array();
+  var $indent;
+  /**
+   * Path modifier that should be applied after adding current element.
+   * @var array
+   */
+  var $delayedPath = array();
+
+  /**#@+
+  * @access public
+  * @var mixed
+  */
+  var $_nodeId;
+
+/**
+ * Load a valid YAML string to Spyc.
+ * @param string $input
+ * @return array
+ */
+  function load ($input) {
+    return $this->__loadString($input);
+  }
+
+ /**
+ * Load a valid YAML file to Spyc.
+ * @param string $file
+ * @return array
+ */
+  function loadFile ($file) {
+    return $this->__load($file);
+  }
+
+  /**
+     * Load YAML into a PHP array statically
+     *
+     * The load method, when supplied with a YAML stream (string or file),
+     * will do its best to convert YAML in a file into a PHP array.  Pretty
+     * simple.
+     *  Usage:
+     *  <code>
+     *   $array = Spyc::YAMLLoad('lucky.yaml');
+     *   print_r($array);
+     *  </code>
+     * @access public
+     * @return array
+     * @param string $input Path of YAML file or string containing YAML
+     */
+  function YAMLLoad($input) {
+    $Spyc = new Spyc;
+    return $Spyc->__load($input);
+  }
+
+  /**
+     * Load a string of YAML into a PHP array statically
+     *
+     * The load method, when supplied with a YAML string, will do its best 
+     * to convert YAML in a string into a PHP array.  Pretty simple.
+     *
+     * Note: use this function if you don't want files from the file system
+     * loaded and processed as YAML.  This is of interest to people concerned
+     * about security whose input is from a string.
+     *
+     *  Usage:
+     *  <code>
+     *   $array = Spyc::YAMLLoadString("---\n0: hello world\n");
+     *   print_r($array);
+     *  </code>
+     * @access public
+     * @return array
+     * @param string $input String containing YAML
+     */
+  function YAMLLoadString($input) {
+    $Spyc = new Spyc;
+    return $Spyc->__loadString($input);
+  }
+
+  /**
+     * Dump YAML from PHP array statically
+     *
+     * The dump method, when supplied with an array, will do its best
+     * to convert the array into friendly YAML.  Pretty simple.  Feel free to
+     * save the returned string as nothing.yaml and pass it around.
+     *
+     * Oh, and you can decide how big the indent is and what the wordwrap
+     * for folding is.  Pretty cool -- just pass in 'false' for either if
+     * you want to use the default.
+     *
+     * Indent's default is 2 spaces, wordwrap's default is 40 characters.  And
+     * you can turn off wordwrap by passing in 0.
+     *
+     * @access public
+     * @return string
+     * @param array $array PHP array
+     * @param int $indent Pass in false to use the default, which is 2
+     * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40)
+     */
+  function YAMLDump($array,$indent = false,$wordwrap = false) {
+    $spyc = new Spyc;
+    return $spyc->dump($array,$indent,$wordwrap);
+  }
+
+
+  /**
+     * Dump PHP array to YAML
+     *
+     * The dump method, when supplied with an array, will do its best
+     * to convert the array into friendly YAML.  Pretty simple.  Feel free to
+     * save the returned string as tasteful.yaml and pass it around.
+     *
+     * Oh, and you can decide how big the indent is and what the wordwrap
+     * for folding is.  Pretty cool -- just pass in 'false' for either if
+     * you want to use the default.
+     *
+     * Indent's default is 2 spaces, wordwrap's default is 40 characters.  And
+     * you can turn off wordwrap by passing in 0.
+     *
+     * @access public
+     * @return string
+     * @param array $array PHP array
+     * @param int $indent Pass in false to use the default, which is 2
+     * @param int $wordwrap Pass in 0 for no wordwrap, false for default (40)
+     */
+  function dump($array,$indent = false,$wordwrap = false) {
+    // Dumps to some very clean YAML.  We'll have to add some more features
+    // and options soon.  And better support for folding.
+
+    // New features and options.
+    if ($indent === false or !is_numeric($indent)) {
+      $this->_dumpIndent = 2;
+    } else {
+      $this->_dumpIndent = $indent;
+    }
+
+    if ($wordwrap === false or !is_numeric($wordwrap)) {
+      $this->_dumpWordWrap = 40;
+    } else {
+      $this->_dumpWordWrap = $wordwrap;
+    }
+
+    // New YAML document
+    $string = "---\n";
+
+    // Start at the base of the array and move through it.
+    if ($array) {
+      $array = (array)$array;
+      $first_key = key($array);
+      
+      $previous_key = -1;
+      foreach ($array as $key => $value) {
+        $string .= $this->_yamlize($key,$value,0,$previous_key, $first_key);
+        $previous_key = $key;
+      }
+    }
+    return $string;
+  }
+
+  /**
+     * Attempts to convert a key / value array item to YAML
+     * @access private
+     * @return string
+     * @param $key The name of the key
+     * @param $value The value of the item
+     * @param $indent The indent of the current node
+     */
+  function _yamlize($key,$value,$indent, $previous_key = -1, $first_key = 0) {
+    if (is_array($value)) {
+      if (empty ($value))
+        return $this->_dumpNode($key, array(), $indent, $previous_key, $first_key);
+      // It has children.  What to do?
+      // Make it the right kind of item
+      $string = $this->_dumpNode($key, NULL, $indent, $previous_key, $first_key);
+      // Add the indent
+      $indent += $this->_dumpIndent;
+      // Yamlize the array
+      $string .= $this->_yamlizeArray($value,$indent);
+    } elseif (!is_array($value)) {
+      // It doesn't have children.  Yip.
+      $string = $this->_dumpNode($key, $value, $indent, $previous_key, $first_key);
+    }
+    return $string;
+  }
+
+  /**
+     * Attempts to convert an array to YAML
+     * @access private
+     * @return string
+     * @param $array The array you want to convert
+     * @param $indent The indent of the current level
+     */
+  function _yamlizeArray($array,$indent) {
+    if (is_array($array)) {
+      $string = '';
+      $previous_key = -1;
+      $first_key = key($array);
+      foreach ($array as $key => $value) {
+        $string .= $this->_yamlize($key, $value, $indent, $previous_key, $first_key);
+        $previous_key = $key;
+      }
+      return $string;
+    } else {
+      return false;
+    }
+  }
+
+  /**
+     * Returns YAML from a key and a value
+     * @access private
+     * @return string
+     * @param $key The name of the key
+     * @param $value The value of the item
+     * @param $indent The indent of the current node
+     */
+  function _dumpNode($key, $value, $indent, $previous_key = -1, $first_key = 0) {
+    // do some folding here, for blocks
+    if (is_string ($value) && ((strpos($value,"\n") !== false || strpos($value,": ") !== false || strpos($value,"- ") !== false ||
+      strpos($value,"*") !== false || strpos($value,"#") !== false || strpos($value,"<") !== false || strpos($value,">") !== false ||
+      strpos($value,"[") !== false || strpos($value,"]") !== false || strpos($value,"{") !== false || strpos($value,"}") !== false) || substr ($value, -1, 1) == ':')) {
+      $value = $this->_doLiteralBlock($value,$indent);
+    } else {
+      $value  = $this->_doFolding($value,$indent);
+      if (is_bool($value)) {
+        $value = ($value) ? "true" : "false";
+      }
+    }
+
+    if ($value === array()) $value = '[ ]';
+
+    $spaces = str_repeat(' ',$indent);
+
+    if (is_int($key) && $key - 1 == $previous_key && $first_key===0) {
+      // It's a sequence
+      $string = $spaces.'- '.$value."\n";
+    } else {
+      if ($first_key===0)  throw new Exception('Keys are all screwy.  The first one was zero, now it\'s "'. $key .'"');
+      // It's mapped
+      if (strpos($key, ":") !== false) { $key = '"' . $key . '"'; }
+      $string = $spaces.$key.': '.$value."\n";
+    }
+    return $string;
+  }
+
+  /**
+     * Creates a literal block for dumping
+     * @access private
+     * @return string
+     * @param $value
+     * @param $indent int The value of the indent
+     */
+  function _doLiteralBlock($value,$indent) {
+    if (strpos($value, "\n") === false && strpos($value, "'") === false) {
+      return sprintf ("'%s'", $value);
+    }
+    if (strpos($value, "\n") === false && strpos($value, '"') === false) {
+      return sprintf ('"%s"', $value);
+    }
+    $exploded = explode("\n",$value);
+    $newValue = '|';
+    $indent  += $this->_dumpIndent;
+    $spaces   = str_repeat(' ',$indent);
+    foreach ($exploded as $line) {
+      $newValue .= "\n" . $spaces . trim($line);
+    }
+    return $newValue;
+  }
+
+  /**
+     * Folds a string of text, if necessary
+     * @access private
+     * @return string
+     * @param $value The string you wish to fold
+     */
+  function _doFolding($value,$indent) {
+    // Don't do anything if wordwrap is set to 0
+
+    if ($this->_dumpWordWrap !== 0 && is_string ($value) && strlen($value) > $this->_dumpWordWrap) {
+      $indent += $this->_dumpIndent;
+      $indent = str_repeat(' ',$indent);
+      $wrapped = wordwrap($value,$this->_dumpWordWrap,"\n$indent");
+      $value   = ">\n".$indent.$wrapped;
+    } else {
+      if ($this->setting_dump_force_quotes && is_string ($value))
+        $value = '"' . $value . '"';
+    }
+
+
+    return $value;
+  }
+
+// LOADING FUNCTIONS
+
+  function __load($input) {
+    $Source = $this->loadFromSource($input);
+    return $this->loadWithSource($Source);
+  }
+
+  function __loadString($input) {
+    $Source = $this->loadFromString($input);
+    return $this->loadWithSource($Source);
+  }
+
+  function loadWithSource($Source) {
+    if (empty ($Source)) return array();
+    if ($this->setting_use_syck_is_possible && function_exists ('syck_load')) {
+      $array = syck_load (implode ('', $Source));
+      return is_array($array) ? $array : array();
+    }
+
+    $this->path = array();
+    $this->result = array();
+
+    $cnt = count($Source);
+    for ($i = 0; $i < $cnt; $i++) {
+      $line = $Source[$i];
+      
+      $this->indent = strlen($line) - strlen(ltrim($line));
+      $tempPath = $this->getParentPathByIndent($this->indent);
+      $line = $this->stripIndent($line, $this->indent);
+      if ($this->isComment($line)) continue;
+      if ($this->isEmpty($line)) continue;
+      $this->path = $tempPath;
+
+      $literalBlockStyle = $this->startsLiteralBlock($line);
+      if ($literalBlockStyle) {
+        $line = rtrim ($line, $literalBlockStyle . " \n");
+        $literalBlock = '';
+        $line .= $this->LiteralPlaceHolder;
+
+        while (++$i < $cnt && $this->literalBlockContinues($Source[$i], $this->indent)) {
+          $literalBlock = $this->addLiteralLine($literalBlock, $Source[$i], $literalBlockStyle);
+        }
+        $i--;
+      }
+
+      while (++$i < $cnt && $this->greedilyNeedNextLine($line)) {
+        $line = rtrim ($line, " \n\t\r") . ' ' . ltrim ($Source[$i], " \t");
+      }
+      $i--;
+
+
+
+      if (strpos ($line, '#')) {
+        if (strpos ($line, '"') === false && strpos ($line, "'") === false)
+          $line = preg_replace('/\s+#(.+)$/','',$line);
+      }
+
+      $lineArray = $this->_parseLine($line);
+
+      if ($literalBlockStyle)
+        $lineArray = $this->revertLiteralPlaceHolder ($lineArray, $literalBlock);
+
+      $this->addArray($lineArray, $this->indent);
+
+      foreach ($this->delayedPath as $indent => $delayedPath)
+        $this->path[$indent] = $delayedPath;
+
+      $this->delayedPath = array();
+
+    }
+    return $this->result;
+  }
+
+  function loadFromSource ($input) {
+    if (!empty($input) && strpos($input, "\n") === false && file_exists($input))
+    return file($input);
+
+    return $this->loadFromString($input);
+  }
+
+  function loadFromString ($input) {
+    $lines = explode("\n",$input);
+    foreach ($lines as $k => $_) {
+      $lines[$k] = rtrim ($_, "\r");
+    }
+    return $lines;
+  }
+
+  /**
+     * Parses YAML code and returns an array for a node
+     * @access private
+     * @return array
+     * @param string $line A line from the YAML file
+     */
+  function _parseLine($line) {
+    if (!$line) return array();
+    $line = trim($line);
+
+    if (!$line) return array();
+    $array = array();
+
+    $group = $this->nodeContainsGroup($line);
+    if ($group) {
+      $this->addGroup($line, $group);
+      $line = $this->stripGroup ($line, $group);
+    }
+
+    if ($this->startsMappedSequence($line))
+      return $this->returnMappedSequence($line);
+
+    if ($this->startsMappedValue($line))
+      return $this->returnMappedValue($line);
+
+    if ($this->isArrayElement($line))
+     return $this->returnArrayElement($line);
+
+    if ($this->isPlainArray($line))
+     return $this->returnPlainArray($line); 
+     
+     
+    return $this->returnKeyValuePair($line);
+
+  }
+
+  /**
+     * Finds the type of the passed value, returns the value as the new type.
+     * @access private
+     * @param string $value
+     * @return mixed
+     */
+  function _toType($value) {
+    if ($value === '') return null;
+    $first_character = $value[0];
+    $last_character = substr($value, -1, 1);
+
+    $is_quoted = false;
+    do {
+      if (!$value) break;
+      if ($first_character != '"' && $first_character != "'") break;
+      if ($last_character != '"' && $last_character != "'") break;
+      $is_quoted = true;
+    } while (0);
+
+    if ($is_quoted)
+      return strtr(substr ($value, 1, -1), array ('\\"' => '"', '\'\'' => '\'', '\\\'' => '\''));
+    
+    if (strpos($value, ' #') !== false)
+      $value = preg_replace('/\s+#(.+)$/','',$value);
+
+    if ($first_character == '[' && $last_character == ']') {
+      // Take out strings sequences and mappings
+      $innerValue = trim(substr ($value, 1, -1));
+      if ($innerValue === '') return array();
+      $explode = $this->_inlineEscape($innerValue);
+      // Propagate value array
+      $value  = array();
+      foreach ($explode as $v) {
+        $value[] = $this->_toType($v);
+      }
+      return $value;
+    }
+
+    if (strpos($value,': ')!==false && $first_character != '{') {
+      $array = explode(': ',$value);
+      $key   = trim($array[0]);
+      array_shift($array);
+      $value = trim(implode(': ',$array));
+      $value = $this->_toType($value);
+      return array($key => $value);
+    }
+    
+    if ($first_character == '{' && $last_character == '}') {
+      $innerValue = trim(substr ($value, 1, -1));
+      if ($innerValue === '') return array();
+      // Inline Mapping
+      // Take out strings sequences and mappings
+      $explode = $this->_inlineEscape($innerValue);
+      // Propagate value array
+      $array = array();
+      foreach ($explode as $v) {
+        $SubArr = $this->_toType($v);
+        if (empty($SubArr)) continue;
+        if (is_array ($SubArr)) {
+          $array[key($SubArr)] = $SubArr[key($SubArr)]; continue;
+        }
+        $array[] = $SubArr;
+      }
+      return $array;
+    }
+
+    if ($value == 'null' || $value == 'NULL' || $value == 'Null' || $value == '' || $value == '~') {
+      return null;
+    }
+
+    if (intval($first_character) > 0 && preg_match ('/^[1-9]+[0-9]*$/', $value)) {
+      $intvalue = (int)$value;
+      if ($intvalue != PHP_INT_MAX)
+        $value = $intvalue;
+      return $value;
+    }
+
+    if (in_array($value,
+                 array('true', 'on', '+', 'yes', 'y', 'True', 'TRUE', 'On', 'ON', 'YES', 'Yes', 'Y'))) {
+      return true;
+    }
+
+    if (in_array(strtolower($value),
+                 array('false', 'off', '-', 'no', 'n'))) {
+      return false;
+    }
+
+    if (is_numeric($value)) {
+      if ($value === '0') return 0;
+      if (trim ($value, 0) === $value)
+        $value = (float)$value;
+      return $value;
+    }
+    
+    return $value;
+  }
+
+  /**
+     * Used in inlines to check for more inlines or quoted strings
+     * @access private
+     * @return array
+     */
+  function _inlineEscape($inline) {
+    // There's gotta be a cleaner way to do this...
+    // While pure sequences seem to be nesting just fine,
+    // pure mappings and mappings with sequences inside can't go very
+    // deep.  This needs to be fixed.
+
+    $seqs = array();
+    $maps = array();
+    $saved_strings = array();
+
+    // Check for strings
+    $regex = '/(?:(")|(?:\'))((?(1)[^"]+|[^\']+))(?(1)"|\')/';
+    if (preg_match_all($regex,$inline,$strings)) {
+      $saved_strings = $strings[0];
+      $inline  = preg_replace($regex,'YAMLString',$inline);
+    }
+    unset($regex);
+
+    $i = 0;
+    do {
+
+    // Check for sequences
+    while (preg_match('/\[([^{}\[\]]+)\]/U',$inline,$matchseqs)) {
+      $seqs[] = $matchseqs[0];
+      $inline = preg_replace('/\[([^{}\[\]]+)\]/U', ('YAMLSeq' . (count($seqs) - 1) . 's'), $inline, 1);
+    }
+
+    // Check for mappings
+    while (preg_match('/{([^\[\]{}]+)}/U',$inline,$matchmaps)) {
+      $maps[] = $matchmaps[0];
+      $inline = preg_replace('/{([^\[\]{}]+)}/U', ('YAMLMap' . (count($maps) - 1) . 's'), $inline, 1);
+    }
+
+    if ($i++ >= 10) break;
+
+    } while (strpos ($inline, '[') !== false || strpos ($inline, '{') !== false);
+
+    $explode = explode(', ',$inline);
+    $stringi = 0; $i = 0;
+
+    while (1) {
+
+    // Re-add the sequences
+    if (!empty($seqs)) {
+      foreach ($explode as $key => $value) {
+        if (strpos($value,'YAMLSeq') !== false) {
+          foreach ($seqs as $seqk => $seq) {
+            $explode[$key] = str_replace(('YAMLSeq'.$seqk.'s'),$seq,$value);
+            $value = $explode[$key];
+          }
+        }
+      }
+    }
+
+    // Re-add the mappings
+    if (!empty($maps)) {
+      foreach ($explode as $key => $value) {
+        if (strpos($value,'YAMLMap') !== false) {
+          foreach ($maps as $mapk => $map) {
+            $explode[$key] = str_replace(('YAMLMap'.$mapk.'s'), $map, $value);
+            $value = $explode[$key];
+          }
+        }
+      }
+    }
+
+
+    // Re-add the strings
+    if (!empty($saved_strings)) {
+      foreach ($explode as $key => $value) {
+        while (strpos($value,'YAMLString') !== false) {
+          $explode[$key] = preg_replace('/YAMLString/',$saved_strings[$stringi],$value, 1);
+          unset($saved_strings[$stringi]);
+          ++$stringi;
+          $value = $explode[$key];
+        }
+      }
+    }
+
+    $finished = true;
+    foreach ($explode as $key => $value) {
+      if (strpos($value,'YAMLSeq') !== false) {
+        $finished = false; break;
+      }
+      if (strpos($value,'YAMLMap') !== false) {
+        $finished = false; break;
+      }
+      if (strpos($value,'YAMLString') !== false) {
+        $finished = false; break;
+      }
+    }
+    if ($finished) break;
+
+    $i++;
+    if ($i > 10) 
+      break; // Prevent infinite loops.
+    }
+
+    return $explode;
+  }
+
+  function literalBlockContinues ($line, $lineIndent) {
+    if (!trim($line)) return true;
+    if (strlen($line) - strlen(ltrim($line)) > $lineIndent) return true;
+    return false;
+  }
+
+  function referenceContentsByAlias ($alias) {
+    do {
+      if (!isset($this->SavedGroups[$alias])) { echo "Bad group name: $alias."; break; }
+      $groupPath = $this->SavedGroups[$alias];
+      $value = $this->result;
+      foreach ($groupPath as $k) {
+        $value = $value[$k];
+      }
+    } while (false);
+    return $value;
+  }
+
+  function addArrayInline ($array, $indent) {
+      $CommonGroupPath = $this->path;
+      if (empty ($array)) return false;
+      
+      foreach ($array as $k => $_) {
+        $this->addArray(array($k => $_), $indent);
+        $this->path = $CommonGroupPath;
+      }
+      return true;
+  }
+
+  function addArray ($incoming_data, $incoming_indent) {
+
+   // print_r ($incoming_data);
+
+    if (count ($incoming_data) > 1)
+      return $this->addArrayInline ($incoming_data, $incoming_indent);
+    
+    $key = key ($incoming_data);
+    $value = isset($incoming_data[$key]) ? $incoming_data[$key] : null;
+    if ($key === '__!YAMLZero') $key = '0';
+
+    if ($incoming_indent == 0 && !$this->_containsGroupAlias && !$this->_containsGroupAnchor) { // Shortcut for root-level values.
+      if ($key || $key === '' || $key === '0') {
+        $this->result[$key] = $value;
+      } else {
+        $this->result[] = $value; end ($this->result); $key = key ($this->result);
+      }
+      $this->path[$incoming_indent] = $key;
+      return;
+    }
+
+
+    
+    $history = array();
+    // Unfolding inner array tree.
+    $history[] = $_arr = $this->result;
+    foreach ($this->path as $k) {
+      $history[] = $_arr = $_arr[$k];
+    }
+
+    if ($this->_containsGroupAlias) {
+      $value = $this->referenceContentsByAlias($this->_containsGroupAlias);
+      $this->_containsGroupAlias = false;
+    }
+
+
+    // Adding string or numeric key to the innermost level or $this->arr.
+    if (is_string($key) && $key == '<<') {
+      if (!is_array ($_arr)) { $_arr = array (); }
+      $_arr = array_merge ($_arr, $value);
+    } else if ($key || $key === '' || $key === '0') {
+      $_arr[$key] = $value;
+    } else {
+      if (!is_array ($_arr)) { $_arr = array ($value); $key = 0; }
+      else { $_arr[] = $value; end ($_arr); $key = key ($_arr); }
+    }
+
+    $reverse_path = array_reverse($this->path);
+    $reverse_history = array_reverse ($history);
+    $reverse_history[0] = $_arr;
+    $cnt = count($reverse_history) - 1;
+    for ($i = 0; $i < $cnt; $i++) {
+      $reverse_history[$i+1][$reverse_path[$i]] = $reverse_history[$i];
+    }
+    $this->result = $reverse_history[$cnt];
+
+    $this->path[$incoming_indent] = $key;
+
+    if ($this->_containsGroupAnchor) {
+      $this->SavedGroups[$this->_containsGroupAnchor] = $this->path;
+      if (is_array ($value)) {
+        $k = key ($value);
+        if (!is_int ($k)) {
+          $this->SavedGroups[$this->_containsGroupAnchor][$incoming_indent + 2] = $k;
+        }
+      }
+      $this->_containsGroupAnchor = false;
+    }
+
+  }
+
+  function startsLiteralBlock ($line) {
+    $lastChar = substr (trim($line), -1);
+    if ($lastChar != '>' && $lastChar != '|') return false;
+    if ($lastChar == '|') return $lastChar;
+    // HTML tags should not be counted as literal blocks.
+    if (preg_match ('#<.*?>$#', $line)) return false;
+    return $lastChar;
+  }
+
+  function greedilyNeedNextLine($line) {
+    $line = trim ($line);
+    if (!strlen($line)) return false;
+    if (substr ($line, -1, 1) == ']') return false;
+    if ($line[0] == '[') return true;
+    if (preg_match ('#^[^:]+?:\s*\[#', $line)) return true;
+    return false;
+  }
+
+  function addLiteralLine ($literalBlock, $line, $literalBlockStyle) {
+    $line = $this->stripIndent($line);
+    $line = rtrim ($line, "\r\n\t ") . "\n";
+    if ($literalBlockStyle == '|') {
+      return $literalBlock . $line;
+    }
+    if (strlen($line) == 0)
+      return rtrim($literalBlock, ' ') . "\n";
+    if ($line == "\n" && $literalBlockStyle == '>') {
+      return rtrim ($literalBlock, " \t") . "\n";
+    }
+    if ($line != "\n")
+      $line = trim ($line, "\r\n ") . " ";
+    return $literalBlock . $line;
+  }
+
+   function revertLiteralPlaceHolder ($lineArray, $literalBlock) {
+     foreach ($lineArray as $k => $_) {
+      if (is_array($_))
+        $lineArray[$k] = $this->revertLiteralPlaceHolder ($_, $literalBlock);
+      else if (substr($_, -1 * strlen ($this->LiteralPlaceHolder)) == $this->LiteralPlaceHolder)
+	       $lineArray[$k] = rtrim ($literalBlock, " \r\n");
+     }
+     return $lineArray;
+   }
+
+  function stripIndent ($line, $indent = -1) {
+    if ($indent == -1) $indent = strlen($line) - strlen(ltrim($line));
+    return substr ($line, $indent);
+  }
+
+  function getParentPathByIndent ($indent) {
+    if ($indent == 0) return array();
+    $linePath = $this->path;
+    do {
+      end($linePath); $lastIndentInParentPath = key($linePath);
+      if ($indent <= $lastIndentInParentPath) array_pop ($linePath);
+    } while ($indent <= $lastIndentInParentPath);
+    return $linePath;
+  }
+
+
+  function clearBiggerPathValues ($indent) {
+
+
+    if ($indent == 0) $this->path = array();
+    if (empty ($this->path)) return true;
+
+    foreach ($this->path as $k => $_) {
+      if ($k > $indent) unset ($this->path[$k]);
+    }
+
+    return true;
+  }
+
+
+  function isComment ($line) {
+    if (!$line) return false;
+    if ($line[0] == '#') return true;
+    if (trim($line, " \r\n\t") == '---') return true;
+    return false;
+  }
+
+  function isEmpty ($line) {
+    return (trim ($line) === '');
+  }
+
+
+  function isArrayElement ($line) {
+    if (!$line) return false;
+    if ($line[0] != '-') return false;
+    if (strlen ($line) > 3)
+      if (substr($line,0,3) == '---') return false;
+    
+    return true;
+  }
+
+  function isHashElement ($line) {
+    return strpos($line, ':');
+  }
+
+  function isLiteral ($line) {
+    if ($this->isArrayElement($line)) return false;
+    if ($this->isHashElement($line)) return false;
+    return true;
+  }
+
+
+  function unquote ($value) {
+    if (!$value) return $value;
+    if (!is_string($value)) return $value;
+    if ($value[0] == '\'') return trim ($value, '\'');
+    if ($value[0] == '"') return trim ($value, '"');
+    return $value;
+  }
+
+  function startsMappedSequence ($line) {
+    return ($line[0] == '-' && substr ($line, -1, 1) == ':');
+  }
+
+  function returnMappedSequence ($line) {
+    $array = array();
+    $key         = $this->unquote(trim(substr($line,1,-1)));
+    $array[$key] = array();
+    $this->delayedPath = array(strpos ($line, $key) + $this->indent => $key);
+    return array($array);
+  }
+
+  function returnMappedValue ($line) {
+    $array = array();
+    $key         = $this->unquote (trim(substr($line,0,-1)));
+    $array[$key] = '';
+    return $array;
+  }
+
+  function startsMappedValue ($line) {
+    return (substr ($line, -1, 1) == ':');
+  }
+  
+  function isPlainArray ($line) {
+    return ($line[0] == '[' && substr ($line, -1, 1) == ']');
+  }
+  
+  function returnPlainArray ($line) {
+    return $this->_toType($line); 
+  }  
+
+  function returnKeyValuePair ($line) {
+    $array = array();
+    $key = '';
+    if (strpos ($line, ':')) {
+      // It's a key/value pair most likely
+      // If the key is in double quotes pull it out
+      if (($line[0] == '"' || $line[0] == "'") && preg_match('/^(["\'](.*)["\'](\s)*:)/',$line,$matches)) {
+        $value = trim(str_replace($matches[1],'',$line));
+        $key   = $matches[2];
+      } else {
+        // Do some guesswork as to the key and the value
+        $explode = explode(':',$line);
+        $key     = trim($explode[0]);
+        array_shift($explode);
+        $value   = trim(implode(':',$explode));
+      }
+      // Set the type of the value.  Int, string, etc
+      $value = $this->_toType($value);
+      if ($key === '0') $key = '__!YAMLZero';
+      $array[$key] = $value;
+    } else {
+      $array = array ($line);
+    }
+    return $array;
+
+  }
+
+
+  function returnArrayElement ($line) {
+     if (strlen($line) <= 1) return array(array()); // Weird %)
+     $array = array();
+     $value   = trim(substr($line,1));
+     $value   = $this->_toType($value);
+     $array[] = $value;
+     return $array;
+  }
+
+
+  function nodeContainsGroup ($line) {    
+    $symbolsForReference = 'A-z0-9_\-';
+    if (strpos($line, '&') === false && strpos($line, '*') === false) return false; // Please die fast ;-)
+    if ($line[0] == '&' && preg_match('/^(&['.$symbolsForReference.']+)/', $line, $matches)) return $matches[1];
+    if ($line[0] == '*' && preg_match('/^(\*['.$symbolsForReference.']+)/', $line, $matches)) return $matches[1];
+    if (preg_match('/(&['.$symbolsForReference.']+)$/', $line, $matches)) return $matches[1];
+    if (preg_match('/(\*['.$symbolsForReference.']+$)/', $line, $matches)) return $matches[1];
+    if (preg_match ('#^\s*<<\s*:\s*(\*[^\s]+).*$#', $line, $matches)) return $matches[1];
+    return false;
+
+  }
+
+  function addGroup ($line, $group) {
+    if ($group[0] == '&') $this->_containsGroupAnchor = substr ($group, 1);
+    if ($group[0] == '*') $this->_containsGroupAlias = substr ($group, 1);
+    //print_r ($this->path);
+  }
+
+  function stripGroup ($line, $group) {
+    $line = trim(str_replace($group, '', $line));
+    return $line;
+  }
+}
+
+// Enable use of Spyc from command line
+// The syntax is the following: php spyc.php spyc.yaml
+
+define ('SPYC_FROM_COMMAND_LINE', false);
+
+do {
+  if (!SPYC_FROM_COMMAND_LINE) break;
+  if (empty ($_SERVER['argc']) || $_SERVER['argc'] < 2) break;
+  if (empty ($_SERVER['PHP_SELF']) || $_SERVER['PHP_SELF'] != 'spyc.php') break;
+  $file = $argv[1];
+  printf ("Spyc loading file: %s\n", $file);
+  print_r (spyc_load_file ($file));
+} while (0);
\ No newline at end of file
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/php4/test.php4 b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/php4/test.php4
new file mode 100644
index 0000000..315f501
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/php4/test.php4
@@ -0,0 +1,162 @@
+<?php
+#
+#    S P Y C
+#      a simple php yaml class
+#   v0.3
+#
+# author: [chris wanstrath, chris@ozmm.org]
+# websites: [http://www.yaml.org, http://spyc.sourceforge.net/]
+# license: [MIT License, http://www.opensource.org/licenses/mit-license.php]
+# copyright: (c) 2005-2006 Chris Wanstrath
+#
+# We're gonna load a file into memory and see if we get what we expect.
+# If not, we're gonna complain.
+#
+# Pretty lo-fi.  Let's see if we can't get some unit testing going in the next,
+# I dunno, 20 months?  Alright.  Go team.
+#
+
+error_reporting(E_ALL);
+
+include('spyc.php4');
+
+$yaml = Spyc::YAMLLoad('../spyc.yaml');
+
+// print_r ($yaml);
+
+# Added in .2
+if ($yaml[1040] != "Ooo, a numeric key!")
+	die('Key: 1040 failed');
+
+# Test mappings / types
+if ($yaml['String'] != "Anyone's name, really.")
+	die('Key: String failed');
+
+if ($yaml['Int'] !== 13)
+	die('Key: Int failed');
+
+if ($yaml['True'] !== true)
+	die('Key: True failed');
+
+if ($yaml['False'] !== false)
+	die('Key: False failed');
+
+if ($yaml['Zero'] !== 0)
+	die('Key: Zero failed');
+
+if (isset($yaml['Null']))
+	die('Key: Null failed');
+
+if ($yaml['Float'] !== 5.34)
+	die('Key: Float failed');
+
+
+# Test sequences
+if ($yaml[0] != "PHP Class")
+	die('Sequence 0 failed');
+
+if ($yaml[1] != "Basic YAML Loader")
+	die('Sequence 1 failed');
+
+if ($yaml[2] != "Very Basic YAML Dumper")
+	die('Sequence 2 failed');
+
+# A sequence of a sequence
+if ($yaml[3] != array("YAML is so easy to learn.",
+											"Your config files will never be the same."))
+	die('Sequence 3 failed');
+
+# Sequence of mappings
+if ($yaml[4] != array("cpu" => "1.5ghz", "ram" => "1 gig",
+											"os" => "os x 10.4.1"))
+	die('Sequence 4 failed');
+
+# Mapped sequence
+if ($yaml['domains'] != array("yaml.org", "php.net"))
+	die("Key: 'domains' failed");
+
+# A sequence like this.
+if ($yaml[5] != array("program" => "Adium", "platform" => "OS X",
+											"type" => "Chat Client"))
+	die('Sequence 5 failed');
+
+# A folded block as a mapped value
+if ($yaml['no time'] != "There isn't any time for your tricks!\nDo you understand?")
+	die("Key: 'no time' failed");
+
+# A literal block as a mapped value
+if ($yaml['some time'] != "There is nothing but time\nfor your tricks.")
+	die("Key: 'some time' failed");
+
+# Crazy combinations
+if ($yaml['databases'] != array( array("name" => "spartan", "notes" =>
+																			array( "Needs to be backed up",
+																						 "Needs to be normalized" ),
+																			 "type" => "mysql" )))
+  die("Key: 'databases' failed");
+
+# You can be a bit tricky
+if ($yaml["if: you'd"] != "like")
+	die("Key: 'if: you\'d' failed");
+
+# Inline sequences
+if ($yaml[6] != array("One", "Two", "Three", "Four"))
+	die("Sequence 6 failed");
+
+# Nested Inline Sequences
+if ($yaml[7] != array("One", array("Two", "And", "Three"), "Four", "Five"))
+	die("Sequence 7 failed");
+
+# Nested Nested Inline Sequences
+if ($yaml[8] != array( "This", array("Is", "Getting", array("Ridiculous", "Guys")),
+									"Seriously", array("Show", "Mercy")))
+	die("Sequence 8 failed");
+
+# Inline mappings
+if ($yaml[9] != array("name" => "chris", "age" => "young", "brand" => "lucky strike"))
+	die("Sequence 9 failed");
+
+# Nested inline mappings
+if ($yaml[10] != array("name" => "mark", "age" => "older than chris",
+											 "brand" => array("marlboro", "lucky strike")))
+	die("Sequence 10 failed");
+
+# References -- they're shaky, but functional
+if ($yaml['dynamic languages'] != array('Perl', 'Python', 'PHP', 'Ruby'))
+	die("Key: 'dynamic languages' failed");
+
+if ($yaml['compiled languages'] != array('C/C++', 'Java'))
+	die("Key: 'compiled languages' failed");
+
+if ($yaml['all languages'] != array(
+																		array('Perl', 'Python', 'PHP', 'Ruby'),
+																		array('C/C++', 'Java')
+																	 ))
+	die("Key: 'all languages' failed");
+
+# Added in .2.2: Escaped quotes
+if ($yaml[11] != "you know, this shouldn't work.  but it does.")
+	die("Sequence 11 failed.");
+
+if ($yaml[12] != "that's my value.")
+	die("Sequence 12 failed.");
+
+if ($yaml[13] != "again, that's my value.")
+	die("Sequence 13 failed.");
+
+if ($yaml[14] != "here's to \"quotes\", boss.")
+	die("Sequence 14 failed.");
+
+if ($yaml[15] != array( 'name' => "Foo, Bar's", 'age' => 20))
+	die("Sequence 15 failed.");
+
+if ($yaml[16] != array( 0 => "a", 1 => array (0 => 1, 1 => 2), 2 => "b"))
+	die("Sequence 16 failed.");
+
+if ($yaml['endloop'] != "Does this line in the end indeed make Spyc go to an infinite loop?")
+	die("[endloop] failed.");
+
+
+print "spyc.yaml parsed correctly\n";
+
+?>
\ No newline at end of file
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/phpunit.xml b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/phpunit.xml
new file mode 100644
index 0000000..a6151af
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/phpunit.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit colors="true" bootstrap="vendor/autoload.php">
+    <testsuites>
+        <testsuite name="all">
+            <directory suffix="Test.php">tests/</directory>
+        </testsuite>
+    </testsuites>
+</phpunit>
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/spyc.yaml b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/spyc.yaml
new file mode 100644
index 0000000..489f28c
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/spyc.yaml
@@ -0,0 +1,219 @@
+#
+#    S P Y C
+#      a simple php yaml class
+#
+# authors: [vlad andersen (vlad.andersen@gmail.com), chris wanstrath (chris@ozmm.org)]
+# websites: [http://www.yaml.org, http://spyc.sourceforge.net/]
+# license: [MIT License, http://www.opensource.org/licenses/mit-license.php]
+# copyright: (c) 2005-2006 Chris Wanstrath, 2006-2014 Vlad Andersen
+#
+# spyc.yaml - A file containing the YAML that Spyc understands.
+
+---
+
+# Mappings - with proper types
+String: Anyone's name, really.
+Int: 13
+BadHex: f0xf3
+Hex: 0xf3
+True: true
+False: false
+Zero: 0
+Null: NULL
+NotNull: 'null'
+NotTrue: 'y'
+NotBoolTrue: 'true'
+NotInt: '5'
+Float: 5.34
+Negative: -90
+SmallFloat: 0.7
+NewLine: \n
+QuotedNewLine: "\n"
+
+# A sequence
+- PHP Class
+- Basic YAML Loader
+- Very Basic YAML Dumper
+
+# A sequence of a sequence
+-
+  - YAML is so easy to learn.
+  - Your config files will never be the same.
+
+# Sequence of mappings
+-
+  cpu: 1.5ghz
+  ram: 1 gig
+  os : os x 10.4.1
+
+# Mapped sequence
+domains:
+  - yaml.org
+  - php.net
+
+# A sequence like this.
+- program: Adium
+  platform: OS X
+  type: Chat Client
+
+# A folded block as a mapped value
+no time: >
+  There isn't any time
+  for your tricks!
+
+  Do you understand?
+
+# A literal block as a mapped value
+some time: |
+  There is nothing but time
+  for your tricks.
+
+# Crazy combinations
+databases:
+  - name: spartan
+    notes:
+      - Needs to be backed up
+      - Needs to be normalized
+    type: mysql
+
+# You can be a bit tricky
+"if: you'd": like
+
+# Inline sequences
+- [One, Two, Three, Four]
+
+# Nested Inline Sequences
+- [One, [Two, And, Three], Four, Five]
+
+# Nested Nested Inline Sequences
+- [This, [Is, Getting, [Ridiculous, Guys]], Seriously, [Show, Mercy]]
+
+# Inline mappings
+- {name: chris, age: young, brand: lucky strike}
+
+# Nested inline mappings
+- {name: mark, age: older than chris, brand: [marlboro, lucky strike]}
+
+# References -- they're shaky, but functional
+dynamic languages: &DLANGS
+  - Perl
+  - Python
+  - PHP
+  - Ruby
+compiled languages: &CLANGS
+  - C/C++
+  - Java
+all languages:
+  - *DLANGS
+  - *CLANGS
+
+# Added in .2.2: Escaped quotes
+- you know, this shouldn't work.  but it does.
+- 'that''s my value.'
+- 'again, that\'s my value.'
+- "here's to \"quotes\", boss."
+
+# added in .2.3
+- {name: "Foo, Bar's", age: 20}
+
+# Added in .2.4: bug [ 1418193 ] Quote Values in Nested Arrays
+- [a, ['1', "2"], b]
+
+# Add in .5.2: Quoted new line values.
+- "First line\nSecond line\nThird line"
+
+# Added in .2.4: malformed YAML
+all
+  javascripts:     [dom1.js, dom.js]
+
+# Added in .2
+1040: Ooo, a numeric key! # And working comments? Wow! Colons in comments: a menace (0.3).
+
+hash_1: Hash #and a comment
+hash_2: "Hash #and a comment"
+"hash#3": "Hash (#) can appear in key too"
+
+float_test: 1.0
+float_test_with_quotes: '1.0'
+float_inverse_test: 001
+
+a_really_large_number: 115792089237316195423570985008687907853269984665640564039457584007913129639936 # 2^256
+
+int array: [ 1, 2, 3 ]
+
+array on several lines:
+  [ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
+    10, 11, 12, 13, 14, 15, 16, 17, 18, 19 ]
+
+morelesskey: "<value>"
+
+array_of_zero: [0]
+sophisticated_array_of_zero: {rx: {tx: [0]} }
+
+switches:
+  - { row: 0, col: 0, func: {tx: [0, 1]} }
+
+empty_sequence: [ ]
+empty_hash: { }
+
+special_characters: "[{]]{{]]"
+
+asterisks: "*"
+
+empty_key:
+  :
+    key: value
+
+trailing_colon: "foo:"
+
+multiline_items:
+  - type: SomeItem
+    values: [blah, blah, blah,
+      blah]
+    ints: [2, 54, 12,
+      2143]
+
+many_lines: |
+  A quick
+  fox
+
+
+  jumped
+  over
+
+
+
+
+
+  a lazy
+
+
+
+  dog
+
+
+werte:
+  1: nummer 1
+  0: Stunde 0
+
+noindent_records:
+- record1: value1
+- record2: value2
+
+"a:1": [1000]
+"a:2":
+  - 2000
+a:3: [3000]
+
+complex_unquoted_key:
+  a:b:''test': value
+
+array with commas:
+  ["0","1"]
+
+invoice: ["Something", "", '', "Something else"]
+quotes: ['Something', "Nothing", 'Anything', "Thing"]
+
+# [Endloop]
+endloop: |
+  Does this line in the end indeed make Spyc go to an infinite loop?
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/DumpTest.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/DumpTest.php
new file mode 100644
index 0000000..ceb5c8e
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/DumpTest.php
@@ -0,0 +1,194 @@
+<?php
+
+class DumpTest extends PHPUnit_Framework_TestCase {
+
+    private $files_to_test = array();
+
+    public function setUp() {
+      $this->files_to_test = array (__DIR__.'/../spyc.yaml', 'failing1.yaml', 'indent_1.yaml', 'quotes.yaml');
+    }
+
+    public function testShortSyntax() {
+      $dump = spyc_dump(array ('item1', 'item2', 'item3'));
+      $awaiting = "- item1\n- item2\n- item3\n";
+      $this->assertEquals ($awaiting, $dump);
+    }
+
+    public function testDump() {
+      foreach ($this->files_to_test as $file) {
+        $yaml = spyc_load(file_get_contents($file));
+        $dump = Spyc::YAMLDump ($yaml);
+        $yaml_after_dump = Spyc::YAMLLoad ($dump);
+        $this->assertEquals ($yaml, $yaml_after_dump);
+      }
+    }
+
+    public function testDumpWithQuotes() {
+      $Spyc = new Spyc();
+      $Spyc->setting_dump_force_quotes = true;
+      foreach ($this->files_to_test as $file) {
+        $yaml = $Spyc->load(file_get_contents($file));
+        $dump = $Spyc->dump ($yaml);
+        $yaml_after_dump = Spyc::YAMLLoad ($dump);
+        $this->assertEquals ($yaml, $yaml_after_dump);
+      }
+    }
+
+    public function testDumpArrays() {
+      $dump = Spyc::YAMLDump(array ('item1', 'item2', 'item3'));
+      $awaiting = "---\n- item1\n- item2\n- item3\n";
+      $this->assertEquals ($awaiting, $dump);
+    }
+
+    public function testNull() {
+        $dump = Spyc::YAMLDump(array('a' => 1, 'b' => null, 'c' => 3));
+        $awaiting = "---\na: 1\nb: null\nc: 3\n";
+        $this->assertEquals ($awaiting, $dump);
+    }
+
+    public function testNext() {
+        $array = array("aaa", "bbb", "ccc");
+        #set arrays internal pointer to next element
+        next($array);
+        $dump = Spyc::YAMLDump($array);
+        $awaiting = "---\n- aaa\n- bbb\n- ccc\n";
+        $this->assertEquals ($awaiting, $dump);
+    }
+
+    public function testDumpingMixedArrays() {
+        $array = array();
+        $array[] = 'Sequence item';
+        $array['The Key'] = 'Mapped value';
+        $array[] = array('A sequence','of a sequence');
+        $array[] = array('first' => 'A sequence','second' => 'of mapped values');
+        $array['Mapped'] = array('A sequence','which is mapped');
+        $array['A Note'] = 'What if your text is too long?';
+        $array['Another Note'] = 'If that is the case, the dumper will probably fold your text by using a block.  Kinda like this.';
+        $array['The trick?'] = 'The trick is that we overrode the default indent, 2, to 4 and the default wordwrap, 40, to 60.';
+        $array['Old Dog'] = "And if you want\n to preserve line breaks, \ngo ahead!";
+        $array['key:withcolon'] = "Should support this to";
+
+        $yaml = Spyc::YAMLDump($array,4,60);
+    }
+
+    public function testMixed() {
+        $dump = Spyc::YAMLDump(array(0 => 1, 'b' => 2, 1 => 3));
+        $awaiting = "---\n0: 1\nb: 2\n1: 3\n";
+        $this->assertEquals ($awaiting, $dump);
+    }
+
+    public function testDumpNumerics() {
+      $dump = Spyc::YAMLDump(array ('404', '405', '500'));
+      $awaiting = "---\n- \"404\"\n- \"405\"\n- \"500\"\n";
+      $this->assertEquals ($awaiting, $dump);
+    }
+
+    public function testDumpAsterisks() {
+      $dump = Spyc::YAMLDump(array ('*'));
+      $awaiting = "---\n- '*'\n";
+      $this->assertEquals ($awaiting, $dump);
+    }
+
+    public function testDumpAmpersands() {
+      $dump = Spyc::YAMLDump(array ('some' => '&foo'));
+      $awaiting = "---\nsome: '&foo'\n";
+      $this->assertEquals ($awaiting, $dump);
+    }
+
+    public function testDumpExclamations() {
+      $dump = Spyc::YAMLDump(array ('some' => '!foo'));
+      $awaiting = "---\nsome: '!foo'\n";
+      $this->assertEquals ($awaiting, $dump);
+    }
+
+    public function testDumpExclamations2() {
+      $dump = Spyc::YAMLDump(array ('some' => 'foo!'));
+      $awaiting = "---\nsome: foo!\n";
+      $this->assertEquals ($awaiting, $dump);
+    }
+
+    public function testDumpApostrophes() {
+      $dump = Spyc::YAMLDump(array ('some' => "'Biz' pimpt bedrijventerreinen"));
+      $awaiting = "---\nsome: \"'Biz' pimpt bedrijventerreinen\"\n";
+      $this->assertEquals ($awaiting, $dump);
+    }
+
+    public function testDumpNumericHashes() {
+      $dump = Spyc::YAMLDump(array ("titel"=> array("0" => "", 1 => "Dr.", 5 => "Prof.", 6 => "Prof. Dr.")));
+      $awaiting = "---\ntitel:\n  0: \"\"\n  1: Dr.\n  5: Prof.\n  6: Prof. Dr.\n";
+      $this->assertEquals ($awaiting, $dump);
+    }
+
+    public function testEmpty() {
+      $dump = Spyc::YAMLDump(array("foo" => array()));
+      $awaiting = "---\nfoo: [ ]\n";
+      $this->assertEquals ($awaiting, $dump);
+    }
+
+    public function testHashesInKeys() {
+      $dump = Spyc::YAMLDump(array ('#color' => '#ffffff'));
+      $awaiting = "---\n\"#color\": '#ffffff'\n";
+      $this->assertEquals ($awaiting, $dump);
+    }
+
+    public function testParagraph() {
+      $dump = Spyc::YAMLDump(array ('key' => "|\n  value"));
+      $awaiting = "---\nkey: |\n  value\n";
+      $this->assertEquals ($awaiting, $dump);
+    }
+
+    public function testParagraphTwo() {
+      $dump = Spyc::YAMLDump(array ('key' => 'Congrats, pimpt bedrijventerreinen pimpt bedrijventerreinen pimpt bedrijventerreinen!'));
+      $awaiting = "---\nkey: >\n  Congrats, pimpt bedrijventerreinen pimpt\n  bedrijventerreinen pimpt\n  bedrijventerreinen!\n";
+      $this->assertEquals ($awaiting, $dump);
+    }
+
+    public function testString() {
+      $dump = Spyc::YAMLDump(array ('key' => array('key_one' => 'Congrats, pimpt bedrijventerreinen!')));
+      $awaiting = "---\nkey:\n  key_one: Congrats, pimpt bedrijventerreinen!\n";
+      $this->assertEquals ($awaiting, $dump);
+    }
+
+    public function testStringLong() {
+      $dump = Spyc::YAMLDump(array ('key' => array('key_one' => 'Congrats, pimpt bedrijventerreinen pimpt bedrijventerreinen pimpt bedrijventerreinen!')));
+      $awaiting = "---\nkey:\n  key_one: >\n    Congrats, pimpt bedrijventerreinen pimpt\n    bedrijventerreinen pimpt\n    bedrijventerreinen!\n";
+      $this->assertEquals ($awaiting, $dump);
+    }
+
+    public function testStringDoubleQuote() {
+      $dump = Spyc::YAMLDump(array ('key' => array('key_one' =>  array('key_two' => '"Système d\'e-réservation"'))));
+      $awaiting = "---\nkey:\n  key_one:\n    key_two: |\n      Système d'e-réservation\n";
+      $this->assertEquals ($awaiting, $dump);
+    }
+
+    public function testLongStringDoubleQuote() {
+      $dump = Spyc::YAMLDump(array ('key' => array('key_one' =>  array('key_two' => '"Système d\'e-réservation bedrijventerreinen pimpt" bedrijventerreinen!'))));
+      $awaiting = "---\nkey:\n  key_one:\n    key_two: |\n      \"Système d'e-réservation bedrijventerreinen pimpt\" bedrijventerreinen!\n";
+      $this->assertEquals ($awaiting, $dump);
+    }
+
+    public function testStringStartingWithSpace() {
+      $dump = Spyc::YAMLDump(array ('key' => array('key_one' => "    Congrats, pimpt bedrijventerreinen \n    pimpt bedrijventerreinen pimpt bedrijventerreinen!")));
+      $awaiting = "---\nkey:\n  key_one: |\n    Congrats, pimpt bedrijventerreinen\n    pimpt bedrijventerreinen pimpt bedrijventerreinen!\n";
+      $this->assertEquals ($awaiting, $dump);
+    }
+
+    public function testPerCentOne() {
+      $dump = Spyc::YAMLDump(array ('key' => "%name%, pimpts bedrijventerreinen!"));
+      $awaiting = "---\nkey: '%name%, pimpts bedrijventerreinen!'\n";
+      $this->assertEquals ($awaiting, $dump);
+    }
+
+    public function testPerCentAndSimpleQuote() {
+      $dump = Spyc::YAMLDump(array ('key' => "%name%, pimpt's bedrijventerreinen!"));
+      $awaiting = "---\nkey: \"%name%, pimpt's bedrijventerreinen!\"\n";
+      $this->assertEquals ($awaiting, $dump);
+    }
+
+    public function testPerCentAndDoubleQuote() {
+      $dump = Spyc::YAMLDump(array ('key' => '%name%, pimpt\'s "bed"rijventerreinen!'));
+      $awaiting = "---\nkey: |\n  %name%, pimpt's \"bed\"rijventerreinen!\n";
+      $this->assertEquals ($awaiting, $dump);
+    }
+
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/IndentTest.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/IndentTest.php
new file mode 100644
index 0000000..b7cdcab
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/IndentTest.php
@@ -0,0 +1,68 @@
+<?php
+
+class IndentTest extends PHPUnit_Framework_TestCase {
+
+    protected $Y;
+
+    protected function setUp() {
+        $this->Y = Spyc::YAMLLoad(__DIR__."/indent_1.yaml");
+    }
+
+    public function testIndent_1() {
+        $this->assertEquals (array ('child_1' => 2, 'child_2' => 0, 'child_3' => 1), $this->Y['root']);
+    }
+
+    public function testIndent_2() {
+        $this->assertEquals (array ('child_1' => 1, 'child_2' => 2), $this->Y['root2']);
+    }
+
+    public function testIndent_3() {
+        $this->assertEquals (array (array ('resolutions' => array (1024 => 768, 1920 => 1200), 'producer' => 'Nec')), $this->Y['display']);
+    }
+
+    public function testIndent_4() {
+        $this->assertEquals (array (
+            array ('resolutions' => array (1024 => 768)),
+            array ('resolutions' => array (1920 => 1200)),
+        ), $this->Y['displays']);
+    }
+
+    public function testIndent_5() {
+        $this->assertEquals (array (array (
+            'row' => 0,
+            'col' => 0,
+            'headsets_affected' => array (
+                array (
+                    'ports' => array (0),
+                    'side' => 'left',
+                )
+            ),
+            'switch_function' => array (
+                'ics_ptt' => true
+            )
+        )), $this->Y['nested_hashes_and_seqs']);
+    }
+
+    public function testIndent_6() {
+        $this->assertEquals (array (
+            'h' => array (
+                array ('a' => 'b', 'a1' => 'b1'),
+                array ('c' => 'd')
+            )
+        ), $this->Y['easier_nest']);
+    }
+
+    public function testIndent_space() {
+        $this->assertEquals ("By four\n  spaces", $this->Y['one_space']);
+    }
+
+    public function testListAndComment() {
+        $this->assertEquals (array ('one', 'two', 'three'), $this->Y['list_and_comment']);
+    }
+
+    public function testAnchorAndAlias() {
+        $this->assertEquals (array ('database' => 'rails_dev', 'adapter' => 'mysql', 'host' => 'localhost'), $this->Y['development']);
+        $this->assertEquals (array (1 => 'abc'), $this->Y['zzz']);
+    }
+
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/LoadTest.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/LoadTest.php
new file mode 100644
index 0000000..a25d36f
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/LoadTest.php
@@ -0,0 +1,17 @@
+<?php
+
+class LoadTest extends PHPUnit_Framework_TestCase {
+    public function testQuotes() {
+        $test_values = array(
+            "adjacent '''' \"\"\"\" quotes.",
+            "adjacent '''' quotes.",
+            "adjacent \"\"\"\" quotes.",
+        );
+        foreach($test_values as $value) {
+            $yaml = array($value);
+            $dump = Spyc::YAMLDump ($yaml);
+            $yaml_loaded = Spyc::YAMLLoad ($dump);
+            $this->assertEquals ($yaml, $yaml_loaded);
+        }
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/ParseTest.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/ParseTest.php
new file mode 100644
index 0000000..2ce77ca
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/ParseTest.php
@@ -0,0 +1,413 @@
+<?php
+
+class ParseTest extends PHPUnit_Framework_TestCase {
+
+    protected $yaml;
+
+    protected function setUp() {
+      $this->yaml = spyc_load_file(__DIR__.'/../spyc.yaml');
+    }
+
+    public function testMergeHashKeys() {
+      $Expected =  array (
+        array ('step' => array('instrument' => 'Lasik 2000', 'pulseEnergy' => 5.4, 'pulseDuration' => 12, 'repetition' => 1000, 'spotSize' => '1mm')),
+        array ('step' => array('instrument' => 'Lasik 2000', 'pulseEnergy' => 5.4, 'pulseDuration' => 12, 'repetition' => 1000, 'spotSize' => '2mm')),
+      );
+      $Actual = spyc_load_file (__DIR__.'/indent_1.yaml');
+      $this->assertEquals ($Expected, $Actual['steps']);
+    }
+
+    public function testDeathMasks() {
+      $Expected = array ('sad' => 2, 'magnificent' => 4);
+      $Actual = spyc_load_file (__DIR__.'/indent_1.yaml');
+      $this->assertEquals ($Expected, $Actual['death masks are']);
+    }
+
+    public function testDevDb() {
+      $Expected = array ('adapter' => 'mysql', 'host' => 'localhost', 'database' => 'rails_dev');
+      $Actual = spyc_load_file (__DIR__.'/indent_1.yaml');
+      $this->assertEquals ($Expected, $Actual['development']);
+    }
+
+    public function testNumericKey() {
+      $this->assertEquals ("Ooo, a numeric key!", $this->yaml[1040]);
+    }
+
+    public function testMappingsString() {
+      $this->assertEquals ("Anyone's name, really.", $this->yaml['String']);
+    }
+
+    public function testMappingsInt() {
+      $this->assertSame (13, $this->yaml['Int']);
+    }
+
+    public function testMappingsHex() {
+      $this->assertSame (243, $this->yaml['Hex']);
+      $this->assertSame ('f0xf3', $this->yaml['BadHex']);
+    }
+
+    public function testMappingsBooleanTrue() {
+      $this->assertSame (true, $this->yaml['True']);
+    }
+
+    public function testMappingsBooleanFalse() {
+      $this->assertSame (false, $this->yaml['False']);
+    }
+
+    public function testMappingsZero() {
+      $this->assertSame (0, $this->yaml['Zero']);
+    }
+
+    public function testMappingsNull() {
+      $this->assertSame (null, $this->yaml['Null']);
+    }
+
+    public function testMappingsNotNull() {
+      $this->assertSame ('null', $this->yaml['NotNull']);
+    }
+
+    public function testMappingsFloat() {
+      $this->assertSame (5.34, $this->yaml['Float']);
+    }
+
+    public function testMappingsNegative() {
+      $this->assertSame (-90, $this->yaml['Negative']);
+    }
+
+    public function testMappingsSmallFloat() {
+      $this->assertSame (0.7, $this->yaml['SmallFloat']);
+    }
+
+    public function testNewline() {
+      $this->assertSame ('\n', $this->yaml['NewLine']);
+    }
+
+    public function testQuotedNewline() {
+      $this->assertSame ("\n", $this->yaml['QuotedNewLine']);
+    }
+
+    public function testSeq0() {
+      $this->assertEquals ("PHP Class", $this->yaml[0]);
+    }
+
+    public function testSeq1() {
+      $this->assertEquals ("Basic YAML Loader", $this->yaml[1]);
+    }
+
+    public function testSeq2() {
+      $this->assertEquals ("Very Basic YAML Dumper", $this->yaml[2]);
+    }
+
+    public function testSeq3() {
+      $this->assertEquals (array("YAML is so easy to learn.",
+											"Your config files will never be the same."), $this->yaml[3]);
+    }
+
+    public function testSeqMap() {
+      $this->assertEquals (array("cpu" => "1.5ghz", "ram" => "1 gig",
+											"os" => "os x 10.4.1"), $this->yaml[4]);
+    }
+
+    public function testMappedSequence() {
+      $this->assertEquals (array("yaml.org", "php.net"), $this->yaml['domains']);
+    }
+
+    public function testAnotherSequence() {
+      $this->assertEquals (array("program" => "Adium", "platform" => "OS X",
+											"type" => "Chat Client"), $this->yaml[5]);
+    }
+
+    public function testFoldedBlock() {
+      $this->assertEquals ("There isn't any time for your tricks!\nDo you understand?", $this->yaml['no time']);
+    }
+
+    public function testLiteralAsMapped() {
+      $this->assertEquals ("There is nothing but time\nfor your tricks.", $this->yaml['some time']);
+    }
+
+    public function testCrazy() {
+      $this->assertEquals (array( array("name" => "spartan", "notes" =>
+																			array( "Needs to be backed up",
+																						 "Needs to be normalized" ),
+																			 "type" => "mysql" )), $this->yaml['databases']);
+    }
+
+    public function testColons() {
+      $this->assertEquals ("like", $this->yaml["if: you'd"]);
+    }
+
+    public function testInline() {
+      $this->assertEquals (array("One", "Two", "Three", "Four"), $this->yaml[6]);
+    }
+
+    public function testNestedInline() {
+      $this->assertEquals (array("One", array("Two", "And", "Three"), "Four", "Five"), $this->yaml[7]);
+    }
+
+    public function testNestedNestedInline() {
+      $this->assertEquals (array( "This", array("Is", "Getting", array("Ridiculous", "Guys")),
+									"Seriously", array("Show", "Mercy")), $this->yaml[8]);
+    }
+
+    public function testInlineMappings() {
+      $this->assertEquals (array("name" => "chris", "age" => "young", "brand" => "lucky strike"), $this->yaml[9]);
+    }
+
+    public function testNestedInlineMappings() {
+      $this->assertEquals (array("name" => "mark", "age" => "older than chris",
+											 "brand" => array("marlboro", "lucky strike")), $this->yaml[10]);
+    }
+
+    public function testReferences() {
+      $this->assertEquals (array('Perl', 'Python', 'PHP', 'Ruby'), $this->yaml['dynamic languages']);
+    }
+
+    public function testReferences2() {
+      $this->assertEquals (array('C/C++', 'Java'), $this->yaml['compiled languages']);
+    }
+
+    public function testReferences3() {
+      $this->assertEquals (array(
+																		array('Perl', 'Python', 'PHP', 'Ruby'),
+																		array('C/C++', 'Java')
+																	 ), $this->yaml['all languages']);
+    }
+
+    public function testEscapedQuotes() {
+      $this->assertEquals ("you know, this shouldn't work.  but it does.", $this->yaml[11]);
+    }
+
+    public function testEscapedQuotes_2() {
+      $this->assertEquals ( "that's my value.", $this->yaml[12]);
+    }
+
+    public function testEscapedQuotes_3() {
+      $this->assertEquals ("again, that's my value.", $this->yaml[13]);
+    }
+
+    public function testQuotes() {
+      $this->assertEquals ("here's to \"quotes\", boss.", $this->yaml[14]);
+    }
+
+    public function testQuoteSequence() {
+      $this->assertEquals ( array( 'name' => "Foo, Bar's", 'age' => 20), $this->yaml[15]);
+    }
+
+    public function testShortSequence() {
+      $this->assertEquals (array( 0 => "a", 1 => array (0 => 1, 1 => 2), 2 => "b"), $this->yaml[16]);
+    }
+
+    public function testQuotedNewlines() {
+      $this->assertEquals ("First line\nSecond line\nThird line", $this->yaml[17]);
+    }
+
+    public function testHash_1() {
+      $this->assertEquals ("Hash", $this->yaml['hash_1']);
+    }
+
+    public function testHash_2() {
+      $this->assertEquals ('Hash #and a comment', $this->yaml['hash_2']);
+    }
+
+    public function testHash_3() {
+      $this->assertEquals ('Hash (#) can appear in key too', $this->yaml['hash#3']);
+    }
+
+    public function testEndloop() {
+      $this->assertEquals ("Does this line in the end indeed make Spyc go to an infinite loop?", $this->yaml['endloop']);
+    }
+
+    public function testReallyLargeNumber() {
+      $this->assertEquals ('115792089237316195423570985008687907853269984665640564039457584007913129639936', $this->yaml['a_really_large_number']);
+    }
+
+    public function testFloatWithZeros() {
+      $this->assertSame ('1.0', $this->yaml['float_test']);
+    }
+
+    public function testFloatWithQuotes() {
+      $this->assertSame ('1.0', $this->yaml['float_test_with_quotes']);
+    }
+
+    public function testFloatInverse() {
+      $this->assertEquals ('001', $this->yaml['float_inverse_test']);
+    }
+
+    public function testIntArray() {
+      $this->assertEquals (array (1, 2, 3), $this->yaml['int array']);
+    }
+
+    public function testArrayOnSeveralLines() {
+      $this->assertEquals (array (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19), $this->yaml['array on several lines']);
+    }
+
+    public function testArrayWithCommas() {
+      $this->assertEquals(array (0, 1), $this->yaml['array with commas']);
+    }
+
+    public function testmoreLessKey() {
+      $this->assertEquals ('<value>', $this->yaml['morelesskey']);
+    }
+
+    public function testArrayOfZero() {
+      $this->assertSame (array(0), $this->yaml['array_of_zero']);
+    }
+
+    public function testSophisticatedArrayOfZero() {
+      $this->assertSame (array('rx' => array ('tx' => array (0))), $this->yaml['sophisticated_array_of_zero']);
+    }
+
+    public function testSwitches() {
+      $this->assertEquals (array (array ('row' => 0, 'col' => 0, 'func' => array ('tx' => array(0, 1)))), $this->yaml['switches']);
+    }
+
+    public function testEmptySequence() {
+      $this->assertSame (array(), $this->yaml['empty_sequence']);
+    }
+
+    public function testEmptyHash() {
+      $this->assertSame (array(), $this->yaml['empty_hash']);
+    }
+
+    public function testEmptykey() {
+      $this->assertSame (array('' => array ('key' => 'value')), $this->yaml['empty_key']);
+    }
+
+    public function testMultilines() {
+      $this->assertSame (array(array('type' => 'SomeItem', 'values' => array ('blah', 'blah', 'blah', 'blah'), 'ints' => array(2, 54, 12, 2143))), $this->yaml['multiline_items']);
+    }
+
+    public function testManyNewlines() {
+      $this->assertSame ('A quick
+fox
+
+
+jumped
+over
+
+
+
+
+
+a lazy
+
+
+
+dog', $this->yaml['many_lines']);
+    }
+
+    public function testWerte() {
+      $this->assertSame (array ('1' => 'nummer 1', '0' => 'Stunde 0'), $this->yaml['werte']);
+    }
+
+    /* public function testNoIndent() {
+      $this->assertSame (array(
+        array ('record1'=>'value1'),
+        array ('record2'=>'value2')
+      )
+      , $this->yaml['noindent_records']);
+    } */
+
+    public function testColonsInKeys() {
+      $this->assertSame (array (1000), $this->yaml['a:1']);
+    }
+
+    public function testColonsInKeys2() {
+      $this->assertSame (array (2000), $this->yaml['a:2']);
+    }
+
+    public function testUnquotedColonsInKeys() {
+        $this->assertSame (array (3000), $this->yaml['a:3']);
+    }
+
+    public function testComplicatedKeyWithColon() {
+        $this->assertSame(array("a:b:''test'" => 'value'), $this->yaml['complex_unquoted_key']);
+    }
+
+    public function testKeysInMappedValueException() {
+        $this->setExpectedException('Exception');
+        Spyc::YAMLLoad('x: y: z:');
+    }
+
+    public function testKeysInValueException() {
+        $this->setExpectedException('Exception');
+        Spyc::YAMLLoad('x: y: z');
+    }
+
+    public function testSpecialCharacters() {
+      $this->assertSame ('[{]]{{]]', $this->yaml['special_characters']);
+    }
+
+    public function testAngleQuotes() {
+      $Quotes = Spyc::YAMLLoad(__DIR__.'/quotes.yaml');
+      $this->assertEquals (array ('html_tags' => array ('<br>', '<p>'), 'html_content' => array ('<p>hello world</p>', 'hello<br>world'), 'text_content' => array ('hello world')),
+          $Quotes);
+    }
+
+    public function testFailingColons() {
+      $Failing = Spyc::YAMLLoad(__DIR__.'/failing1.yaml');
+      $this->assertSame (array ('MyObject' => array ('Prop1' => array ('key1:val1'))),
+          $Failing);
+    }
+
+    public function testQuotesWithComments() {
+      $Expected = 'bar';
+      $Actual = spyc_load_file (__DIR__.'/comments.yaml');
+      $this->assertEquals ($Expected, $Actual['foo']);
+    }
+
+    public function testArrayWithComments() {
+      $Expected = array ('x', 'y', 'z');
+      $Actual = spyc_load_file (__DIR__.'/comments.yaml');
+      $this->assertEquals ($Expected, $Actual['arr']);
+    }
+
+    public function testAfterArrayWithKittens() {
+      $Expected = 'kittens';
+      $Actual = spyc_load_file (__DIR__.'/comments.yaml');
+      $this->assertEquals ($Expected, $Actual['bar']);
+    }
+
+    // Plain characters http://www.yaml.org/spec/1.2/spec.html#id2789510
+    public function testKai() {
+      $Expected = array('-example' => 'value');
+      $Actual = spyc_load_file (__DIR__.'/indent_1.yaml');
+      $this->assertEquals ($Expected, $Actual['kai']);
+    }
+
+    public function testKaiList() {
+      $Expected = array ('-item', '-item', '-item');
+      $Actual = spyc_load_file (__DIR__.'/indent_1.yaml');
+      $this->assertEquals ($Expected, $Actual['kai_list_of_items']);
+    }
+
+    public function testDifferentQuoteTypes() {
+      $expected = array ('Something', "", "", "Something else");
+      $this->assertSame ($expected, $this->yaml['invoice']);
+    }
+
+    public function testDifferentQuoteTypes2() {
+      $expected = array ('Something', "Nothing", "Anything", "Thing");
+      $this->assertSame ($expected, $this->yaml['quotes']);
+    }
+
+    // Separation spaces http://www.yaml.org/spec/1.2/spec.html#id2778394
+    public function testMultipleArrays() {
+      $expected = array(array(array('x')));
+      $this->assertSame($expected, Spyc::YAMLLoad("- - - x"));
+    }
+
+    public function testElementWithEmptyHash()
+    {
+        $element = "hash: {}\narray: []";
+        $yaml = Spyc::YAMLLoadString($element);
+        $this->assertEquals($yaml['hash'], []);
+        $this->assertEquals($yaml['array'], []);
+
+        $yaml = Spyc::YAMLLoadString($element, [
+            'setting_empty_hash_as_object' => true
+        ]);
+        $this->assertInstanceOf(stdClass::class, $yaml['hash']);
+        $this->assertEquals($yaml['array'], []);
+    }
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/RoundTripTest.php b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/RoundTripTest.php
new file mode 100644
index 0000000..3e707df
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/RoundTripTest.php
@@ -0,0 +1,76 @@
+<?php
+
+function roundTrip($a) { return Spyc::YAMLLoad(Spyc::YAMLDump(array('x' => $a))); }
+
+
+class RoundTripTest extends PHPUnit_Framework_TestCase {
+
+    protected function setUp() {
+    }
+
+    public function testNull() {
+      $this->assertEquals (array ('x' => null), roundTrip (null));
+    }
+
+    public function testY() {
+      $this->assertEquals (array ('x' => 'y'), roundTrip ('y'));
+    }
+    
+    public function testExclam() {
+      $this->assertEquals (array ('x' => '!yeah'), roundTrip ('!yeah'));
+    }
+
+    public function test5() {
+      $this->assertEquals (array ('x' => '5'), roundTrip ('5'));
+    }
+
+    public function testSpaces() {
+      $this->assertEquals (array ('x' => 'x '), roundTrip ('x '));
+    }
+    
+    public function testApostrophes() {
+      $this->assertEquals (array ('x' => "'biz'"), roundTrip ("'biz'"));
+    }
+
+    public function testNewLines() {
+      $this->assertEquals (array ('x' => "\n"), roundTrip ("\n"));
+    }
+
+    public function testHashes() {
+      $this->assertEquals (array ('x' => array ("#color" => '#fff')), roundTrip (array ("#color" => '#fff')));
+    }
+
+    public function testPreserveString() {
+      $result1 = roundTrip ('0');
+      $result2 = roundTrip ('true');
+      $this->assertTrue (is_string ($result1['x']));
+      $this->assertTrue (is_string ($result2['x']));
+    }
+
+    public function testPreserveBool() {
+      $result = roundTrip (true);
+      $this->assertTrue (is_bool ($result['x']));
+    }
+
+    public function testPreserveInteger() {
+      $result = roundTrip (0);
+      $this->assertTrue (is_int ($result['x']));
+    }
+
+    public function testWordWrap() {
+      $this->assertEquals (array ('x' => "aaaaaaaaaaaaaaaaaaaaaaaaaaaa  bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"), roundTrip ("aaaaaaaaaaaaaaaaaaaaaaaaaaaa  bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
+    }
+
+    public function testABCD() {
+      $this->assertEquals (array ('a', 'b', 'c', 'd'), Spyc::YAMLLoad(Spyc::YAMLDump(array('a', 'b', 'c', 'd'))));
+    }
+    
+    public function testABCD2() {
+        $a = array('a', 'b', 'c', 'd'); // Create a simple list
+        $b = Spyc::YAMLDump($a);        // Dump the list as YAML
+        $c = Spyc::YAMLLoad($b);        // Load the dumped YAML
+        $d = Spyc::YAMLDump($c);        // Re-dump the data
+        $this->assertSame($b, $d);
+    }
+   
+}
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/comments.yaml b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/comments.yaml
new file mode 100644
index 0000000..c05012f
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/comments.yaml
@@ -0,0 +1,3 @@
+foo: 'bar' #Comment
+arr: ['x', 'y', 'z'] # Comment here
+bar: kittens
\ No newline at end of file
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/failing1.yaml b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/failing1.yaml
new file mode 100644
index 0000000..6906a51
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/failing1.yaml
@@ -0,0 +1,2 @@
+MyObject:
+  Prop1: {key1:val1}
\ No newline at end of file
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/indent_1.yaml b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/indent_1.yaml
new file mode 100644
index 0000000..62d6ece
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/indent_1.yaml
@@ -0,0 +1,70 @@
+root:
+  child_1: 2
+
+  child_2: 0
+  child_3: 1
+
+root2:
+  child_1: 1
+# A comment
+  child_2: 2
+
+displays:
+  - resolutions:
+      1024: 768
+  - resolutions:
+      1920: 1200
+
+display:
+  - resolutions:
+      1024: 768
+      1920: 1200
+    producer: "Nec"
+
+nested_hashes_and_seqs:
+ - { row: 0, col: 0, headsets_affected: [{ports: [0], side: left}], switch_function: {ics_ptt: true} }
+
+easier_nest: { h: [{a: b, a1: b1}, {c: d}] }
+
+one_space: |
+    By four
+      spaces
+
+steps:
+  - step: &id001
+      instrument:      Lasik 2000
+      pulseEnergy:     5.4
+      pulseDuration:   12
+      repetition:      1000
+      spotSize:        1mm
+  - step:
+      <<: *id001
+      spotSize:       2mm
+
+death masks are:
+   sad: 2
+   <<: {magnificent: 4}
+
+login: &login
+   adapter: mysql
+   host: localhost
+
+development:
+   database: rails_dev
+   <<: *login
+
+"key": "value:"
+colon_only: ":"
+
+list_and_comment: [one, two, three] # comment
+kai:
+  -example: value
+kai_list_of_items:
+  - -item
+  - '-item'
+  -item
+
+&foo bar:
+  1: "abc"
+
+zzz: *foo
diff --git a/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/quotes.yaml b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/quotes.yaml
new file mode 100644
index 0000000..2ceea86
--- /dev/null
+++ b/mailcow/src/mailcow-dockerized/data/web/inc/lib/vendor/mustangostang/spyc/tests/quotes.yaml
@@ -0,0 +1,8 @@
+html_tags:
+  - <br>
+  - <p>
+html_content:
+  - <p>hello world</p>
+  - hello<br>world
+text_content:
+  - hello world
\ No newline at end of file