diff --git a/src/file/format/ini.rs b/src/file/format/ini.rs
index 9295e60e..f7a25a5c 100644
--- a/src/file/format/ini.rs
+++ b/src/file/format/ini.rs
@@ -3,35 +3,46 @@ use std::error::Error;
 use ini::Ini;
 
 use crate::map::Map;
-use crate::value::{Value, ValueKind};
+use crate::value::{Table, Value, ValueKind};
 
 pub fn parse(
     uri: Option<&String>,
     text: &str,
 ) -> Result<Map<String, Value>, Box<dyn Error + Send + Sync>> {
-    let mut map: Map<String, Value> = Map::new();
-    let i = Ini::load_from_str(text)?;
-    for (sec, prop) in i.iter() {
-        match sec {
-            Some(sec) => {
-                let mut sec_map: Map<String, Value> = Map::new();
-                for (k, v) in prop.iter() {
-                    sec_map.insert(
-                        k.to_owned(),
-                        Value::new(uri, ValueKind::String(v.to_owned())),
-                    );
-                }
-                map.insert(sec.to_owned(), Value::new(uri, ValueKind::Table(sec_map)));
-            }
-            None => {
-                for (k, v) in prop.iter() {
-                    map.insert(
-                        k.to_owned(),
-                        Value::new(uri, ValueKind::String(v.to_owned())),
-                    );
-                }
-            }
-        }
+    let value = from_ini(uri, Ini::load_from_str(text)?);
+
+    match value.kind {
+        ValueKind::Table(map) => Ok(map),
+
+        _ => Ok(Map::new()),
     }
-    Ok(map)
+}
+
+fn from_ini(
+    uri: Option<&String>,
+    data: Ini,
+) -> Value {
+    let mut map = Map::<String, Value>::new();
+
+    let mut sections: Map<Option<&str>, Table> = data.into_iter().map(|(section, props)| {
+        let key = section;
+        let value = props.iter().map(|(k, v)| {
+            let key = k.to_owned();
+            let value = Value::new(uri, ValueKind::String(v.to_owned()));
+            (key, value)
+        }).collect();
+        (key, value)
+    }).collect();
+
+    // Hoist (optional) sectionless properties to the top-level, alongside sections:
+    map.extend(sections.remove(&None).unwrap_or_default());
+
+    // Wrap each section Table into Value for merging into `map`:
+    map.extend(sections.into_iter().map(|(k,v)| {
+        let key = k.unwrap_or_default().to_owned();
+        let value = Value::new(uri, ValueKind::Table(v));
+        (key , value)
+    }));
+
+    Value::new(uri, ValueKind::Table(map))
 }