diff --git a/src/Generator/Utils/OrderedSet.cs b/src/Generator/Utils/OrderedSet.cs
new file mode 100644
index 00000000..2e40e833
--- /dev/null
+++ b/src/Generator/Utils/OrderedSet.cs
@@ -0,0 +1,85 @@
+using System.Collections;
+using System.Collections.Generic;
+
+namespace CppSharp.Utils
+{
+ ///
+ /// Works just like an HashSet but preserves insertion order.
+ ///
+ ///
+ public class OrderedSet : ICollection
+ {
+ private readonly IDictionary> dictionary;
+ private readonly LinkedList linkedList;
+
+ public OrderedSet()
+ : this(EqualityComparer.Default)
+ {
+ }
+
+ public OrderedSet(IEqualityComparer comparer)
+ {
+ dictionary = new Dictionary>(comparer);
+ linkedList = new LinkedList();
+ }
+
+ public int Count
+ {
+ get { return dictionary.Count; }
+ }
+
+ public virtual bool IsReadOnly
+ {
+ get { return dictionary.IsReadOnly; }
+ }
+
+ void ICollection.Add(T item)
+ {
+ Add(item);
+ }
+
+ public bool Add(T item)
+ {
+ if (dictionary.ContainsKey(item)) return false;
+ LinkedListNode node = linkedList.AddLast(item);
+ dictionary.Add(item, node);
+ return true;
+ }
+
+ public void Clear()
+ {
+ linkedList.Clear();
+ dictionary.Clear();
+ }
+
+ public bool Remove(T item)
+ {
+ LinkedListNode node;
+ bool found = dictionary.TryGetValue(item, out node);
+ if (!found) return false;
+ dictionary.Remove(item);
+ linkedList.Remove(node);
+ return true;
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return linkedList.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ public bool Contains(T item)
+ {
+ return dictionary.ContainsKey(item);
+ }
+
+ public void CopyTo(T[] array, int arrayIndex)
+ {
+ linkedList.CopyTo(array, arrayIndex);
+ }
+ }
+}