diff --git a/SearchBox-CLI/Program.cs b/SearchBox-CLI/Program.cs
index f56688d..e8f5619 100644
--- a/SearchBox-CLI/Program.cs
+++ b/SearchBox-CLI/Program.cs
@@ -6,6 +6,7 @@ using Newtonsoft.Json;
 
 using LibSearchBox;
 using System.Text.RegularExpressions;
+using Newtonsoft.Json.Serialization;
 
 namespace SearchBoxCLI
 {
diff --git a/SearchBox/IdMap.cs b/SearchBox/IdMap.cs
index 958157f..05b572a 100644
--- a/SearchBox/IdMap.cs
+++ b/SearchBox/IdMap.cs
@@ -1,5 +1,6 @@
 ﻿using System;
 using System.Collections.Generic;
+using System.Linq;
 using System.Text;
 using Newtonsoft.Json;
 using Stackoverflow.Utilities;
@@ -8,32 +9,39 @@ namespace LibSearchBox
 {
 	public class IdNotFoundException : Exception { public IdNotFoundException(string message) : base(message) {  } }
 
-	[JsonObject(MemberSerialization.OptIn)]
 	public class IdMap
 	{
-		[JsonProperty]
 		private int nextId = 0;
 		public BiDictionary<int, string> map = new BiDictionary<int, string>();
 
-		[JsonProperty]
-		public Dictionary<int, string> Map {
+		public Dictionary<int, string> MapOut {
 			get {
 				Dictionary<int, string> result = new Dictionary<int, string>();
 				foreach (BiDictionary<int, string>.Pair pair in map)
 					result.Add(pair.First, pair.Second);
 				return result;
 			}
-			set {
-				map.Clear();
-				foreach (KeyValuePair<int, string> pair in value)
-					map.Add(pair.Key, pair.Value);
-			}
 		}
 
 		public IdMap()
 		{
 		}
 
+
+		public void Import(Dictionary<int, string> inMap, bool clearOld = true) {
+			// Clear out the old map, if any
+			if(clearOld) map.Clear();
+
+			// Import the new records
+			foreach (KeyValuePair<int, string> pair in inMap)
+				map.Add(pair.Key, pair.Value);
+
+			// Calculate the next id
+			// FUTURE: Store & retrieve this via JSON
+			nextId = map.Max((pair) => pair.First) + 1;
+		}
+
+
 		public int GetId(string pageName)
 		{
 			// Perform unicode normalization
diff --git a/SearchBox/InvertedIndex.cs b/SearchBox/InvertedIndex.cs
index 195dddb..ca4e7b7 100644
--- a/SearchBox/InvertedIndex.cs
+++ b/SearchBox/InvertedIndex.cs
@@ -29,8 +29,7 @@ namespace LibSearchBox
 
 		public bool RemoveIndex(int pageId, Index oldIndex)
 		{
-			foreach (string token in oldIndex.Tokens())
-			{
+			foreach (string token in oldIndex.Tokens()) {
 				if (!invertedIndex.ContainsKey(token) || !invertedIndex[token].ContainsKey(pageId)) continue;
 
 				if (!invertedIndex[token].TryRemove(pageId, out List<int> noop))
@@ -52,6 +51,8 @@ namespace LibSearchBox
 				if (!pair.Value.ContainsKey(pageId)) continue;
 				if (!pair.Value.TryRemove(pageId, out List<int> noop))
 					return false;
+				if (pair.Value.Count == 0 && !invertedIndex.TryRemove(pair.Key, out var noopAgain))
+					return false;
 			}
 			return true;
 		}
diff --git a/SearchBox/SearchBox.cs b/SearchBox/SearchBox.cs
index c256d31..04eb84f 100644
--- a/SearchBox/SearchBox.cs
+++ b/SearchBox/SearchBox.cs
@@ -7,11 +7,28 @@ namespace LibSearchBox
 {
 	public class SearchBoxException : Exception { public SearchBoxException(string message) : base(message) {  } }
 
+	[JsonObject(MemberSerialization.OptIn)]
 	public class SearchBox
 	{
-		public IdMap idMap = new IdMap();
-		public InvertedIndex index = new InvertedIndex();
+		private IdMap idMap = new IdMap();
+
+		[JsonProperty("ids")]
+		public Dictionary<int, string> IdMap {
+			get {
+				Dictionary<int, string> result = idMap.MapOut;
+				if (result.Count == 0) return null;
+				return result;
+			}
+			set {
+				if (value == null) return;
+				idMap.Import(value);
+			}
+		}
+
+		[JsonProperty]
 		public ConcurrentDictionary<int, DocumentMeta> metaTable = new ConcurrentDictionary<int, DocumentMeta>();
+		[JsonProperty]
+		public InvertedIndex index = new InvertedIndex();
 
 		public SearchBox()
 		{
@@ -22,6 +39,7 @@ namespace LibSearchBox
 		{
 			DocumentMeta info = new DocumentMeta(title, tags);
 			int id = idMap.GetId(info.Title);
+			metaTable.AddOrUpdate(id, info, (key, oldValue) => info);
 			Index upsideIndex = new Index(content);
 			index.AddIndex(id, upsideIndex);
 		}
@@ -34,7 +52,7 @@ namespace LibSearchBox
 
 			Index oldIndex = new Index(oldContent), newIndex = new Index(newContent);
 			if (!index.ReplaceIndex(id, oldIndex, newIndex))
-				throw new Exception($"Error: Failed to replace index for document with title {title}.");
+				throw new SearchBoxException($"Error: Failed to replace index for document with title {title}.");
 		}
 
 		public void RemoveDocument(string title)
