diff --git a/include/core/utils/converter.h b/include/core/utils/converter.h
index 36d59e759018377bb81266932a57d7a5d827b318..85b47613e435facc904fa086550512297e40d79b 100644
--- a/include/core/utils/converter.h
+++ b/include/core/utils/converter.h
@@ -8,6 +8,8 @@
 #include <iostream>
 #include <array>
 
+#include "core/common/wolf.h"
+
 /**
    @file
  */
@@ -35,7 +37,7 @@ namespace utils{
     /** @Brief Returns all the substrings of @val that match @exp
      * @param val String to be matched
      * @param exp Regular expression
-    * @return <b>{std::vector<std::string>}</b> Collection of matching subtrings
+     * @return <b>{std::vector<std::string>}</b> Collection of matching substrings
     */
     static inline std::vector<std::string> getMatches(std::string val, std::regex exp){
         std::smatch res;
@@ -91,6 +93,55 @@ namespace utils{
         }
         return result;
     }
+    static inline std::vector<std::string> parseList(std::string val){
+        std::stack<char> limiters;
+        std::stack<std::string> word_stack;
+        std::string current_word;
+        std::vector<std::string> words;
+        std::vector<char> chars(val.begin(), val.end());
+        for(const char &current : chars){
+          if(current == '['){
+            limiters.push(current);
+            word_stack.push(current_word);
+            current_word = "";
+          }else if(current == ']'){
+            if(limiters.empty()) throw std::runtime_error("Unmatched delimiter");
+            if(limiters.top() == '[') {
+              if(limiters.size() > 1) {
+                if(word_stack.empty()) word_stack.push("");
+                current_word = word_stack.top() + "[" + current_word + "]";
+                word_stack.pop();
+              }else if(limiters.size() == 1 and current_word != "") words.push_back(current_word);
+              else current_word += current;
+              limiters.pop();
+            }else throw std::runtime_error("Unmatched delimiter");
+          }else if(current == '{'){
+            limiters.push(current);
+            word_stack.push(current_word);
+            current_word = "";
+          }else if(current == '}'){
+            if(limiters.top() == '{') {
+              if(limiters.size() > 1) {
+                if(word_stack.empty()) word_stack.push("");
+                current_word = word_stack.top() + "{" + current_word + "}";
+                word_stack.pop();
+              }else if(limiters.size() == 1) words.push_back(current_word);
+              else current_word += current;
+              limiters.pop();
+            }else throw std::runtime_error("Unmatched delimiter");
+          }else if(current == ',') {
+            if(limiters.size() == 1 and current_word != "") {
+              words.push_back(current_word);
+              current_word = "";
+            }else if(limiters.size() > 1) current_word += current;
+          }else {
+            if(limiters.empty()) throw std::runtime_error("Found non-delimited text");
+            current_word += current;
+          }
+        }
+        if(not limiters.empty()) throw std::runtime_error("Unclosed delimiter [] or {}");
+        return words;
+    }
 }
 namespace wolf{
 
@@ -102,14 +153,16 @@ struct converter{
 };
 template<typename A>
 struct converter<utils::list<A>>{
-    static utils::list<A> convert(std::string val){
+  static utils::list<A> convert(std::string val){
         std::regex rgxP("\\[([^,]+)?(,[^,]+)*\\]");
         utils::list<A> result = utils::list<A>();
         if(std::regex_match(val, rgxP)) {
-            std::string aux = val.substr(1,val.size()-2);
-            auto l = utils::getMatches(aux, std::regex("([^,]+)"));
+            // std::string aux = val.substr(1,val.size()-2);
+            // auto l = utils::getMatches(aux, std::regex("([^,]+)"));
+            auto l = utils::parseList(val);
             for(auto it : l){
-                result.push_back(converter<A>::convert(it));
+              // WOLF_DEBUG("Asking to convert in list ", it);
+              result.push_back(converter<A>::convert(it));
             }
         } else throw std::runtime_error("Invalid string format representing a list-like structure. Correct format is [(value)?(,value)*]. String provided: " + val);
         return result;
@@ -118,11 +171,11 @@ struct converter<utils::list<A>>{
         std::string aux = "";
         bool first = true;
         for(auto it : val){
-            if(not first) aux += "," + it;
-            else{
-                first = false;
-                aux = it;
-            }
+          if(not first) aux += "," + converter<A>::convert(it);
+          else{
+            first = false;
+            aux = converter<A>::convert(it);
+          }
         }
         return "[" + aux + "]";
     }
@@ -264,8 +317,11 @@ struct converter<Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCo
 template<typename A>
 struct converter<std::map<std::string,A>>{
     static std::map<std::string,A> convert(std::string val){
-        auto str_map = utils::splitMapStringRepresentation(val);
-        auto v = utils::pairSplitter(str_map);
+        std::regex rgxM("\\[((?:(?:\\{[^\\{:]+:[^:\\}]+\\}),?)*)\\]");
+        if(not std::regex_match(val, rgxM))
+          throw std::runtime_error("Invalid string representation of a Map. Correct format is [({id:value})?(,{id:value})*]. String provided: " + val);
+
+        auto v = utils::parseList(val);
         auto map = std::map<std::string, A>();
         for(auto it : v){
             auto p = converter<std::pair<std::string, A>>::convert(it);
diff --git a/include/core/yaml/parser_yaml.hpp b/include/core/yaml/parser_yaml.hpp
index 3af5c1630da3e1bbeba9ec0ec4c6cc8ab5c63cfb..1ec675756ec1b3d59946a21f1be5c01eef16979a 100644
--- a/include/core/yaml/parser_yaml.hpp
+++ b/include/core/yaml/parser_yaml.hpp
@@ -14,52 +14,67 @@
 #include <numeric>
 
 namespace {
-    /** @Brief Generates a std::string [v1,v2,v3,...] representing the YAML sequence node
-    * @param n a vector of YAML::Node where each node should be of type YAML::Node::Scalar
-    * @return <b>{std::string}</b> [v1,v2,v3,...]
-    */
-  std::string fromSequenceToString(std::vector<YAML::Node> n){
-    std::string aux = "[";
-    bool first = true;
-    for(auto it : n){
-      assert(it.Type() == YAML::NodeType::Scalar && "fromSequenceToString requires that the sequence be a sequence of Scalars");
-      if(first) {
-        aux = aux + it.Scalar();
-        first = false;
-      }else{
-        aux = aux + "," + it.Scalar();
-      }
-    }
-    aux = aux + "]";
-    return aux;
-  }
-  /** @Brief Generates a std::string representing a YAML sequence. The sequence is assumed to be scalar or at most be a sequence of sequences of scalars.
-   * @param n a vector of YAML::Node that represents a YAML::Sequence
-   * @return <b>{std::string}</b> representing the YAML sequence
-   */
-  std::string parseScalarSequence(std::vector<YAML::Node> n){
-        std::string aux = "[";
-        bool first = true;
-        std::string separator = "";
-        for(auto it : n){
-              if(it.Type() == YAML::NodeType::Scalar) aux = aux + separator + it.Scalar();
-              else {
-                auto seq = std::vector<YAML::Node>();
-                for(auto itt : it){
-                  //I'm going to assume that the node is a sequence of scalars
-                  assert(itt.Type() == YAML::NodeType::Scalar && "The sequence should be a sequence of Scalars");
-                  seq.push_back(itt);
-                }
-                aux = aux + separator + fromSequenceToString(seq);
-              }
-              if(first){
-                separator = ",";
-                first = false;
-              }
+  //====== START OF FORWARD DECLARATION ========
+  std::string parseAtomicNode(YAML::Node);
+  std::string fetchMapEntry(YAML::Node);
+  std::string mapToString(std::map<std::string,std::string>);
+  //====== END OF FORWARD DECLARATION ========
+
+/** @Brief Interprets a map as being atomic and thus parses it as a single entity. We assume that the map has as values only scalars and sequences.
+ *  @param n the node representing a map
+ *  @return std::map<std::string, std::string> populated with the key,value pairs in n
+ */
+std::map<std::string, std::string> fetchAsMap(YAML::Node n){
+    assert(n.Type() == YAML::NodeType::Map && "trying to fetch as Map a non-Map node");
+    auto m = std::map<std::string, std::string>();
+    for(const auto& kv : n){
+        std::string key = kv.first.as<std::string>();
+        switch (kv.second.Type()) {
+        case YAML::NodeType::Scalar : {
+            std::string value = kv.second.Scalar();
+            m.insert(std::pair<std::string,std::string>(key, value));
+            break;
+        }
+        case YAML::NodeType::Sequence : {
+            std::string aux = parseAtomicNode(kv.second);
+            m.insert(std::pair<std::string,std::string>(key, aux));
+            break;
+        }
+        case YAML::NodeType::Map : {
+          std::string value = fetchMapEntry(kv.second);
+          std::regex r("^\\$.*");
+          if (std::regex_match(key, r)) key = key.substr(1,key.size()-1);
+          m.insert(std::pair<std::string,std::string>(key, value));
+          break;
         }
-        aux = aux + "]";
-        return aux;
+        default:
+            assert(1 == 0 && "Unsupported node Type at fetchAsMap");
+            break;
+        }
+    }
+    return m;
+}
+  std::string fetchMapEntry(YAML::Node n){
+    switch (n.Type()) {
+    case YAML::NodeType::Scalar: {
+      return n.Scalar();
+      break;
+    }
+    case YAML::NodeType::Sequence: {
+      return parseAtomicNode(n);
+      break;
+    }
+    case YAML::NodeType::Map: {
+      return mapToString(fetchAsMap(n));
+      break;
+    }
+    default: {
+      assert(1 == 0 && "Unsupported node Type at fetchMapEntry");
+      return "";
+      break;
+    }
     }
+  }
     /** @Brief Transforms a std::map<std::string,std::string> to its std::string representation [{k1:v1},{k2:v2},{k3:v3},...]
     * @param _map just a std::map<std::string,std::string>
     * @return <b>{std::string}</b> [{k1:v1},{k2:v2},{k3:v3},...]
@@ -77,6 +92,76 @@ namespace {
         else accumulated = "";
         return "[" + accumulated + "]";
     }
+    /** @Brief Generates a std::string representing a YAML sequence. The sequence is assumed to be scalar or at most be a sequence of sequences of scalars.
+    * @param n a vector of YAML::Node that represents a YAML::Sequence
+    * @return <b>{std::string}</b> representing the YAML sequence
+    */
+    std::string parseAtomicNode(YAML::Node n){
+      std::string aux = "";
+      bool first = true;
+      std::string separator = "";
+      switch(n.Type()){
+      case YAML::NodeType::Scalar:
+        return n.Scalar();
+        break;
+      case YAML::NodeType::Sequence:
+        for(auto it : n){
+          aux += separator + parseAtomicNode(it);
+          if(first){
+            separator = ",";
+            first = false;
+          }
+        }
+        return "[" + aux + "]";
+        break;
+      case YAML::NodeType::Map:
+        return mapToString(fetchAsMap(n));
+        break;
+      default:
+        return "";
+        break;
+      }
+    }
+
+    /** @Brief checks if a node of the YAML tree is atomic. Only works if the nodes are of type
+     * Scalar, Sequence or Map.
+     * @param key is the key associated to the node n if n.Type() == YAML::NodeType::Map
+     * @param n node to be test for atomicity
+    */
+    bool isAtomic(std::string key, YAML::Node n){
+      assert(n.Type() != YAML::NodeType::Undefined && n.Type() != YAML::NodeType::Null && "Cannot determine atomicity of Undefined/Null node");
+      std::regex r("^\\$.*");
+      bool is_atomic = true;
+      switch(n.Type()){
+      case YAML::NodeType::Scalar:
+        return true;
+        break;
+      case YAML::NodeType::Sequence:
+        for(auto it : n) {
+          switch(it.Type()){
+          case YAML::NodeType::Map:
+            for(const auto& kv : it){
+              is_atomic = is_atomic and isAtomic(kv.first.as<std::string>(), it);
+            }
+            break;
+          default:
+            is_atomic = is_atomic and isAtomic("", it);
+            break;
+          }
+        }
+        return is_atomic;
+        break;
+      case YAML::NodeType::Map:
+        is_atomic = std::regex_match(key, r);
+        return is_atomic;
+        break;
+      default:
+        throw std::runtime_error("Cannot determine atomicity of node type " + std::to_string(n.Type()));
+        return false;
+        break;
+      }
+      return false;
+    }
 }
 class ParserYAML {
     struct ParamsInitSensor{
@@ -158,7 +243,6 @@ public:
     std::vector<std::array<std::string, 2>> getProblem();
     std::map<std::string,std::string> getParams();
     void parse();
-    std::map<std::string, std::string> fetchAsMap(YAML::Node);
 };
 std::string ParserYAML::generatePath(std::string path){
     std::regex r("^/.*");
@@ -193,7 +277,7 @@ void ParserYAML::walkTree(std::string file, std::vector<std::string>& tags, std:
     n = YAML::LoadFile(generatePath(file));
     walkTreeR(n, tags, hdr);
 }
-/** @Brief Recursively walks the YAML tree while filling a map with the values oarsed from the file
+/** @Brief Recursively walks the YAML tree while filling a map with the values parsed from the file
 * @param YAML node to be parsed
 * @param tags represents the path from the root of the YAML tree to the current node
 * @param hdr is the name of the current YAML node
@@ -211,67 +295,59 @@ void ParserYAML::walkTreeR(YAML::Node n, std::vector<std::string>& tags, std::st
         break;
     }
     case YAML::NodeType::Sequence : {
-        std::vector<YAML::Node> scalar_and_seqs;
-        std::vector<YAML::Node> maps;
-        for(const auto& kv : n){
-          if(kv.Type() == YAML::NodeType::Scalar or kv.Type() == YAML::NodeType::Sequence) scalar_and_seqs.push_back(kv);
-          else if(kv.Type() == YAML::NodeType::Map) maps.push_back(kv);
-        }
-        assert(scalar_and_seqs.size() * maps.size() == 0);
-        if(scalar_and_seqs.size() > 0 and maps.size() == 0){
-          _params.insert(std::pair<std::string,std::string>(hdr, parseScalarSequence(scalar_and_seqs)));
-        }else if(scalar_and_seqs.size() == 0 and maps.size() > 0){
-          for(const auto& kv : maps){
+      if(isAtomic("", n)){
+          _params.insert(std::pair<std::string,std::string>(hdr, parseAtomicNode(n)));
+        }else{
+          for(const auto& kv : n){
             walkTreeR(kv, tags, hdr);
           }
         }
         break;
     }
     case YAML::NodeType::Map : {
-        for(const auto& kv : n){
-            //If the key's value starts with a $ (i.e. $key) then its value is parsed as an atomic map,
-            //otherwise the parser recursively parses the map.
-            std::regex r("^\\$.*");
-            if(not std::regex_match(kv.first.as<std::string>(), r)){
-                /*
-                If key=="follow" then the parser will assume that the value is a path and will parse
-                the (expected) yaml file at the specified path. Note that this does not increase the header depth.
-                The following example shows how the header remains unafected:
-                @my_main_config                |  @some_path
-                - cov_det: 1                   |  - my_value : 23
-                - follow: "@some_path"         |
-                - var: 1.2                     |
-                Resulting map:
-                   cov_det -> 1
-                   my_value-> 23
-                   var: 1.2
-                 Instead of:
-                 cov_det -> 1
-                 follow/my_value-> 23
-                 var: 1.2
-                 Which would result from the following yaml files
-                 @my_main_config                |  @some_path
-                 - cov_det: 1                   |  - my_value : 23
-                 - $follow: "@some_path"        |
-                 - var: 1.2                     |
-                */
-                std::regex rr("follow");
-                if(not std::regex_match(kv.first.as<std::string>(), rr)) {
-                    tags.push_back(kv.first.as<std::string>());
-                    if(tags.size() == 2) this->updateActiveName(kv.first.as<std::string>());
-                    walkTreeR(kv.second, tags, hdr +"/"+ kv.first.as<std::string>());
-                    tags.pop_back();
-                    if(tags.size() == 1) this->updateActiveName("");
-                }else{
-                    walkTree(kv.second.as<std::string>(), tags, hdr);
-                }
-            }else{
-                std::string key = kv.first.as<std::string>();
-                key = key.substr(1,key.size() - 1);
-                auto fm = fetchAsMap(kv.second);
-                _params.insert(std::pair<std::string,std::string>(hdr + "/" + key, mapToString(fm)));
-            }
-        }
+      for(const auto& kv : n){
+        if(isAtomic(kv.first.as<std::string>(), n)){
+          std::string key = kv.first.as<std::string>();
+          //WOLF_DEBUG("KEY IN MAP ATOMIC ", hdr + "/" + key);
+          key = key.substr(1,key.size() - 1);
+          _params.insert(std::pair<std::string,std::string>(hdr + "/" + key, parseAtomicNode(kv.second)));
+      }else{
+            /*
+              If key=="follow" then the parser will assume that the value is a path and will parse
+              the (expected) yaml file at the specified path. Note that this does not increase the header depth.
+              The following example shows how the header remains unafected:
+              @my_main_config                |  @some_path
+              - cov_det: 1                   |  - my_value : 23
+              - follow: "@some_path"         |
+              - var: 1.2                     |
+              Resulting map:
+              cov_det -> 1
+              my_value-> 23
+              var: 1.2
+              Instead of:
+              cov_det -> 1
+              follow/my_value-> 23
+              var: 1.2
+              Which would result from the following yaml files
+              @my_main_config                |  @some_path
+              - cov_det: 1                   |  - my_value : 23
+              - $follow: "@some_path"        |
+              - var: 1.2                     |
+            */
+          std::string key = kv.first.as<std::string>();
+          //WOLF_DEBUG("KEY IN MAP NON ATOMIC ", key);
+          std::regex rr("follow");
+          if(not std::regex_match(kv.first.as<std::string>(), rr)) {
+            tags.push_back(kv.first.as<std::string>());
+            if(tags.size() == 2) this->updateActiveName(kv.first.as<std::string>());
+            walkTreeR(kv.second, tags, hdr +"/"+ kv.first.as<std::string>());
+            tags.pop_back();
+            if(tags.size() == 1) this->updateActiveName("");
+          }else{
+            walkTree(kv.second.as<std::string>(), tags, hdr);
+          }
+      }
+      }
         break;
     }
     default:
@@ -350,65 +426,4 @@ void ParserYAML::parse(){
         this->walkTreeR(it.n , tags , it._name);
     }
 }
-
-std::string fetchMapEntry(YAML::Node n){
-  switch (n.Type()) {
-  case YAML::NodeType::Scalar : {
-    return n.Scalar();
-    break;
-  }
-  case YAML::NodeType::Sequence : {
-    std::vector<YAML::Node> nodes;
-    for(auto it : n){
-      nodes.push_back(it);
-    }
-    return parseScalarSequence(nodes);
-    break;
-  }
-  default: {
-    assert(1 == 0 && "Unsupported node Type at fetchMapEntry");
-    return "";
-    break;
-  }
-  }
-}
-/** @Brief Interprets a map as being atomic and thus parses it as a single entity. We assume that the map has as values only scalars and sequences.
- *  @param n the node representing a map
- *  @return std::map<std::string, std::string> populated with the key,value pairs in n
- */
-std::map<std::string, std::string> ParserYAML::fetchAsMap(YAML::Node n){
-    assert(n.Type() == YAML::NodeType::Map && "trying to fetch as Map a non-Map node");
-    auto m = std::map<std::string, std::string>();
-    for(const auto& kv : n){
-        std::string key = kv.first.as<std::string>();
-        switch (kv.second.Type()) {
-        case YAML::NodeType::Scalar : {
-            std::string value = kv.second.Scalar();
-            m.insert(std::pair<std::string,std::string>(key, value));
-            break;
-        }
-        case YAML::NodeType::Sequence : {
-            std::vector<YAML::Node> scalars;
-            std::vector<YAML::Node> non_scalars;
-            for(const auto& kvv : kv.second){
-              if(kvv.Type() == YAML::NodeType::Scalar or kvv.Type() == YAML::NodeType::Sequence) scalars.push_back(kvv);
-              else non_scalars.push_back(kvv);
-            }
-            if(non_scalars.size() > 0) WOLF_WARN("Ignoring non-scalar members of sequence in atomic map...");
-            std::string aux = parseScalarSequence(scalars);
-            m.insert(std::pair<std::string,std::string>(key, aux));
-            break;
-        }
-        case YAML::NodeType::Map : {
-          std::string value = fetchMapEntry(kv.second);
-          m.insert(std::pair<std::string,std::string>(key, value));
-          break;
-        }
-        default:
-            assert(1 == 0 && "Unsupported node Type at fetchAsMap");
-            break;
-        }
-    }
-    return m;
-}
 #endif
diff --git a/test/gtest_converter.cpp b/test/gtest_converter.cpp
index d36d8665d7c3f9226e945a445ff922c20b8c1e00..d068e024a3f9145f347a8645d7ba52dedd036c38 100644
--- a/test/gtest_converter.cpp
+++ b/test/gtest_converter.cpp
@@ -57,6 +57,19 @@ TEST(Converter, ParseToMap)
     map<string, vector<int>> m = {{"x",vector<int>{1,2}}, {"y",vector<int>{}}, {"z",vector<int>{3}}};
     ASSERT_EQ(converter<string>::convert(m), "[{x:[1,2]},{y:[]},{z:[3]}]");
 }
+TEST(Converter, extraTests)
+{
+  string str = "[{x:1},{y:[[{x:[1,2]},{y:[]},{z:[3]}]]},{z:[1,2,3,4,5]}]";
+  auto v = converter<vector<string>>::convert(str);
+  ASSERT_EQ(v[0], "{x:1}");
+  ASSERT_EQ(v[1], "{y:[[{x:[1,2]},{y:[]},{z:[3]}]]}");
+  ASSERT_EQ(v[2], "{z:[1,2,3,4,5]}");
+
+  string str2 = "[]";
+  auto v2 = converter<vector<string>>::convert(str2);
+  // EXPECT_EQ(v2.size(), 1);
+  EXPECT_TRUE(v2.empty());
+}
 TEST(Converter, noGeneralConvert)
 {
   class DUMMY{};
diff --git a/test/gtest_parser_yaml.cpp b/test/gtest_parser_yaml.cpp
index 5102157d05185f93874e9ec0e89e9141feaf230e..985657de83d5bc1381a488d2ed5b6986c12f8f64 100644
--- a/test/gtest_parser_yaml.cpp
+++ b/test/gtest_parser_yaml.cpp
@@ -28,7 +28,10 @@ TEST(ParserYAML, ParseMap)
 {
   auto parser = parse("test/yaml/params2.yaml", wolf_root);
   auto params = parser.getParams();
+  // for(auto it : params)
+  //   cout << it.first << " %% " << it.second << endl;
   EXPECT_EQ(params["processor1/mymap"], "[{k1:v1},{k2:v2},{k3:[v3,v4,v5]}]");
+  // EXPECT_EQ(params["processor1/$mymap/k1"], "v1");
 }
 TEST(ParserYAML, JumpFile)
 {