diff --git a/R/read_in_utils.R b/R/read_in_utils.R
index 725048e1cd6f58cbc579efad134769a67dfb0772..c0e541162d8b365fbd97efb543746a6e7a798338 100644
--- a/R/read_in_utils.R
+++ b/R/read_in_utils.R
@@ -25,21 +25,17 @@ validate_read_in_xml <- function(path){
 }
 
 
-has_ambiguous_representation <- function(tag_name) {
+is_actually_subclass <- function(tag_name, xpath_expr) {
+
+    is_subclass <- TRUE
+
     ambiguous_tags <- c("material_property",
                         "fluid",
                         "porous_medium",
                         "relative_permeability",
                         "capillary_pressure")
 
-    return(invisible(tag_name %in% ambiguous_tags))
-}
-
-
-check_could_be_subclass <- function(tag_name, xpath_expr) {
-    could_be_subclass <- TRUE
-
-    if(has_ambiguous_representation(tag_name)){
+    if(tag_name %in% ambiguous_tags){
 
         non_subclass_paths <-
             c("constitutive_relation/material_properties/material_property",
@@ -60,17 +56,14 @@ check_could_be_subclass <- function(tag_name, xpath_expr) {
                 unlist(strsplit(xpath_expr, "/", fixed = TRUE))
             regex_friendly_xpth <- paste(split_xpth, collapse = "  ")
 
-            # cat("\n", regex_friendly_ncp, "\n")
-            # cat("\n", regex_friendly_xpth, "\n")
-
             if(grepl(paste0(regex_friendly_ncp, "$"), regex_friendly_xpth)){
-                could_be_subclass <- FALSE
+                is_subclass <- FALSE
                 break
             }
         }
     }
 
-    return(invisible(could_be_subclass))
+    return(invisible(is_subclass))
 }
 
 
@@ -109,12 +102,11 @@ read_in <- function(ogs6_obj,
     #Parse all children
     for (i in seq_len(length(nodes))) {
 
-        r2ogs6_obj <- node_to_r2ogs6_obj(nodes[[i]],
-                                         xpath_expr,
-                                         subclasses_names)
+        r2ogs6_obj <- node_to_r2ogs6_class_object(nodes[[i]],
+                                                  xpath_expr,
+                                                  subclasses_names)
 
         #Add r2ogs6_obj with code snippet
-        # cat("\n", add_call, "\n")
         eval(parse(text = add_call))
     }
 
@@ -122,27 +114,20 @@ read_in <- function(ogs6_obj,
 }
 
 
-#'node_to_r2ogs6_obj
+#'node_to_r2ogs6_class_object
 #'@description Takes an XML node and turns it into a class object
-#'@param xml_node An XML node (of class xml2::xml_node)
-#'@param xpath_expr An XPath expression (for subclass differentiation)
-#'@param subclasses_names Optional: A character vector containing the names of
-#' r2ogs6 subclasses (r2ogs6 classes without a method for input_add)
-node_to_r2ogs6_obj <- function(xml_node,
-                               xpath_expr,
-                               subclasses_names = character()){
+#'@param xml_node xml2::xml_node: XML node
+#'@param xpath_expr string: XPath expression (for subclass differentiation)
+#'@param subclasses_names character: Optional: Names of r2ogs6 subclasses
+#' (r2ogs6 classes without a method for input_add)
+node_to_r2ogs6_class_object <- function(xml_node,
+                                        xpath_expr,
+                                        subclasses_names = character()){
 
     assertthat::assert_that(class(xml_node) == "xml_node")
 
     parameter_nodes <- xml2::xml_children(xml_node)
-
-    parameters <- list()
-
-    init_prefix <- ""
-
-    if(length(xml2::xml_attrs(xml_node)) != 0){
-        parameters <- c(parameters, xml2::xml_attrs(xml_node))
-    }
+    parameters <- c(list(), xml2::xml_attrs(xml_node))
 
     for(i in seq_len(length(parameter_nodes))){
 
@@ -151,43 +136,32 @@ node_to_r2ogs6_obj <- function(xml_node,
                              xml2::xml_name(parameter_nodes[[i]]))
 
         #Guess R representation of node, add it to parameter list
-        parameters <- c(parameters, list(guess_structure(parameter_nodes[[i]],
-                                                         new_xpath_expr,
-                                                         subclasses_names)))
+        parameters <- c(parameters, list(node_to_object(parameter_nodes[[i]],
+                                                        new_xpath_expr,
+                                                        subclasses_names)))
 
         #Name parameter after the xml_node child name
         names(parameters)[[length(parameters)]] <-
             xml2::xml_name(parameter_nodes[[i]])
     }
 
-    class_name <- ""
     tag_name <- xml2::xml_name(xml_node)
 
     #If node represented by subclass, get class name
-    if(tag_name %in% names(subclasses_names)){
-        class_name <- select_fitting_subclass(xpath_expr, subclasses_names)
-
-    #Else assume class name is r2ogs6_ + node name
-    }else{
-        class_name <- get_tag_class_name(tag_name)
-    }
-
-    #If it's an R6 class, we need to alter constructor syntax a bit
-    if(grepl("OGS6", class_name)){
-        init_prefix <- "$new"
-    }
+    class_name <- ifelse(tag_name %in% names(subclasses_names),
+                         select_fitting_subclass(xpath_expr, subclasses_names),
+                         get_tag_class_name(tag_name))
 
     ordered_parameters <- order_parameters(parameters, class_name)
 
     param_call_strs <- lapply(names(parameters), function(x){
-        call_str <- paste0("parameters[[\"", x, "\"]]")
-        return(call_str)
+        return(invisible(paste0("parameters[[\"", x, "\"]]")))
     })
 
     #Construct the call to the r2ogs6_object helper
     class_constructor_call <-
         paste0(class_name,
-               init_prefix,
+               ifelse(grepl("OGS6", class_name), "$new", ""),
                "(",
                paste(
                    names(parameters),
@@ -204,17 +178,96 @@ node_to_r2ogs6_obj <- function(xml_node,
 }
 
 
-get_class_args <- function(class_name){
 
-    assertthat::assert_that(assertthat::is.string(class_name))
+#'node_to_object
+#'@description Returns representation of an XML node. This is a recursive
+#' function.
+#'ASSUMPTIONS:
+#'1) Leaf nodes will have EITHER a value OR attributes (and will not be missing
+#' both, e.g. '<a/>').
+#'2) Leaf nodes will never be r2ogs6_* objects
+#'3) If there are multiple occurrences of r2ogs6_* class (and subclass)
+#' elements on the same level, they have a wrapper node as their parent
+#' (e.g. <processes>, <properties>) which  will contain ONLY elements of this
+#' type
+#'4) Wrapper nodes are represented as lists
+#'5) Parent nodes whose children have no children are represented as lists
+#'@param xml_node xml2::xml_node: XML node
+#'@param xpath_expr string: XPath expression (for subclass differentiation)
+#'@param subclasses_names character: Optional: Names of `r2ogs6` subclasses
+#' (`r2ogs6` classes without a OGS6$add method)
+node_to_object <- function(xml_node,
+                           xpath_expr,
+                           subclasses_names = character()){
 
-    formals_call <- class_name
+    assertthat::assert_that("xml_node" %in% class(xml_node))
+    assertthat::assert_that(assertthat::is.string(xpath_expr))
+
+    node_name <- xml2::xml_name(xml_node)
+
+    #Node is leaf
+    if(length(xml2::xml_children(xml_node)) == 0){
+        if(xml2::xml_text(xml_node) != ""){
+            return(invisible(xml2::xml_text(xml_node)))
+        }else{
+            return(invisible(xml2::xml_attrs(xml_node)))
+        }
+    }
 
-    if(grepl("OGS6", class_name, fixed = TRUE)){
-        formals_call <- paste0(class_name,
-                               "$public_methods$initialize")
+    #Node is represented by subclass
+    if(node_name %in% names(subclasses_names) &&
+       is_actually_subclass(node_name, xpath_expr)){
+        return(invisible(node_to_r2ogs6_class_object(xml_node,
+                                                     xpath_expr,
+                                                     subclasses_names)))
     }
 
+    #Node has children but is not represented by subclass
+    wrapper_list <- list()
+
+    for (i in seq_len(length((xml2::xml_children(xml_node))))) {
+        child_node <- xml2::xml_children(xml_node)[[i]]
+        child_name <- xml2::xml_name(child_node)
+
+        list_content <- NULL
+
+        new_xpath_expr <- paste0(xpath_expr,
+                                 "/",
+                                 child_name)
+
+        if (child_name %in% names(subclasses_names) &&
+            is_actually_subclass(child_name, new_xpath_expr)) {
+            list_content <- node_to_r2ogs6_class_object(child_node,
+                                                        new_xpath_expr,
+                                                        subclasses_names)
+        } else{
+            list_content <- node_to_object(child_node,
+                                           new_xpath_expr,
+                                           subclasses_names)
+        }
+
+        wrapper_list <- c(wrapper_list, list(list_content))
+        names(wrapper_list)[[length(wrapper_list)]] <-
+            child_name
+    }
+
+    return(invisible(wrapper_list))
+}
+
+
+#'get_class_args
+#'@description Gets class arguments
+#'@param class_name string: The name of a class
+#'@return character: Named vector of class arguments
+get_class_args <- function(class_name){
+
+    assertthat::assert_that(assertthat::is.string(class_name))
+
+    formals_call <- ifelse(grepl("OGS6", class_name, fixed = TRUE),
+                           paste0(class_name,
+                                  "$public_methods$initialize"),
+                           class_name)
+
     class_args <- names(as.list(formals(eval(parse(text = formals_call)))))
 
     return(invisible(class_args))
@@ -226,6 +279,7 @@ get_class_args <- function(class_name){
 #' of a class
 #'@param parameters list: Parameters
 #'@param class_name string: The name of a class
+#'@return list: Parameters ordered by argument order of class
 order_parameters <- function(parameters, class_name){
 
     assertthat::assert_that(is.list(parameters))
@@ -273,129 +327,3 @@ order_parameters <- function(parameters, class_name){
     return(invisible(ordered_parameters))
 }
 
-
-#===== GUESS STRUCTURE FUNCTIONALITY =====
-
-
-#'guess_structure
-#'@description Guesses the R representation of an XML node and adds it to
-#' parameter list. This is a recursive function.
-#'ASSUMPTIONS:
-#'1) Leaf nodes will have EITHER a value OR attributes (and will not be missing
-#' both, e.g. '<a/>').
-#'2) Leaf nodes will never be r2ogs6_* objects
-#'3) If there are multiple occurrences of r2ogs6_* class (and subclass)
-#' elements on the same level, they have a wrapper node as their parent
-#' (e.g. <processes>, <properties>) which  will contain ONLY elements of this
-#' type
-#'4) Wrapper nodes are represented as lists
-#'5) Parent nodes whose children have no children are represented as lists
-#'@param xml_node xml2::xml_node: XML node
-#'@param xpath_expr string: XPath expression (for subclass differentiation)
-#'@param subclasses_names Optional: character: Names of r2ogs6 subclasses
-#' (r2ogs6 classes without a OGS6$add method)
-guess_structure <- function(xml_node,
-                            xpath_expr,
-                            subclasses_names = character()){
-
-    assertthat::assert_that("xml_node" %in% class(xml_node))
-    assertthat::assert_that(assertthat::is.string(xpath_expr))
-
-    node_name <- xml2::xml_name(xml_node)
-    # cat("\n", xpath_expr, check_could_be_subclass(node_name, xpath_expr), "\n")
-
-    #Node is leaf
-    if(length(xml2::xml_children(xml_node)) == 0){
-        if(xml2::xml_text(xml_node) != ""){
-            return(invisible(xml2::xml_text(xml_node)))
-        }else{
-            return(invisible(xml2::xml_attrs(xml_node)))
-        }
-
-    #Node is represented by subclass
-    }else if(node_name %in% names(subclasses_names) &&
-             check_could_be_subclass(node_name, xpath_expr)){
-        return(invisible(node_to_r2ogs6_obj(xml_node,
-                                            xpath_expr,
-                                            subclasses_names)))
-
-    #Node has children but is not represented by subclass
-    }else{
-
-        wrapper_list <- list()
-
-        for (i in seq_len(length((xml2::xml_children(xml_node))))) {
-            child_node <- xml2::xml_children(xml_node)[[i]]
-            child_name <- xml2::xml_name(child_node)
-
-            list_content <- NULL
-
-            new_xpath_expr <- paste0(xpath_expr,
-                                     "/",
-                                     child_name)
-
-            if (child_name %in% names(subclasses_names) &&
-                check_could_be_subclass(child_name, new_xpath_expr)) {
-                list_content <- node_to_r2ogs6_obj(child_node,
-                                                   new_xpath_expr,
-                                                   subclasses_names)
-            }else{
-                list_content <- guess_structure(child_node,
-                                                new_xpath_expr,
-                                                subclasses_names)
-            }
-
-            wrapper_list <- c(wrapper_list, list(list_content))
-            names(wrapper_list)[[length(wrapper_list)]] <- child_name
-
-        }
-
-        return(invisible(wrapper_list))
-    }
-}
-
-
-#===== RECURSIVE IMPORT (WIP)  =====
-
-
-#
-# to_object <- function(xml_node,
-#                       xpath_expr,
-#                       subclasses_names = character()){
-#
-#
-#
-#
-# }
-
-
-#===== FILE HANDLING UTILITY  =====
-
-
-#'check_file_extension
-#'@description Helper function to check the extension of a file
-#'@param file A file
-#'@param expected_extension The expected file extension
-check_file_extension <- function(file, expected_extension){
-
-    assertthat::assert_that(assertthat::is.string(file))
-    assertthat::assert_that(assertthat::is.string(expected_extension))
-
-    if(tools::file_ext(file) != expected_extension){
-        stop(paste("File must have extension", expected_extension),
-             call. = FALSE)
-    }
-}
-
-
-#Source: https://stackoverflow.com/questions/48218491/os-independent-way-to-
-# select-directory-interactively-in-r/48296736
-#Helper function for choosing a directory (platform independent!)
-choose_directory = function(ini_dir = getwd(),
-                            caption = 'Select data directory') {
-    if (exists('utils::choose.dir')) {
-        utils::choose.dir(default = ini_dir, caption = caption)
-    } else {
-        tcltk::tk_choose.dir(default = ini_dir, caption = caption)
-    }
-}
\ No newline at end of file