diff --git a/docs/object_mapping.md b/docs/object_mapping.md
new file mode 100644
index 0000000000000000000000000000000000000000..cc867f42a3b5489e2d3b2b8a3c5046785560d029
--- /dev/null
+++ b/docs/object_mapping.md
@@ -0,0 +1,213 @@
+Ferma is an Object-graph Model (OGM). An Object-graph Model is to a Graph Database as an Object-relational Model (ORM)
+is to a Relational Database. That is to say that it maps Java Objects to edges and vertex in a graph database. As a
+natural consequence the Java types become an implied Schema for a Graph Database even if the underlying implementation
+doesnt support the notion of a schema.
+
+The objects associated with the various types of Edges and Vertex in a graph are collectively called the Graph Data
+Model (GDM). Each Java type in the GDM will usually represent a class of Edges or Vertex in underlying graph. All Edges
+in the model will extend from the `EdgeFrame` interface and all vertex will extend from `VertexFrame` interface. The
+individual classes that comprise the GDM are usually simply refered to as Frames.
+
+The methods defined by a Frame will represent interactions with the underlying graph via traversals that are relative, 
+using the current edge or vertex as their starting point.
+
+```java
+public interface Person extends VertexFrame {
+  String getName();
+  List<? extends Person> getCoworkers();
+}
+```
+
+In this example Person represents a vertex in the graph with a property indicating their name, and they are associated
+with other vertex in the graph of the same type that represent their coworkers.
+
+When implementing a vertex as a concrete class you must instead inherit from `VertexFrame`.
+
+```java
+public class Person extends AbstractVertexFrame {
+  public String getName() {
+      return this.getProperty("name");
+  }
+  
+  public List<? extends Person> getCoworkers() {
+      return this.traverse(v -> v.out("coworker")).toList(Person.class);
+  }
+}
+```
+
+It is also possible to do the same with inheritance if you want a class and an interface defined.
+
+```java
+public class PersonImpl extends AbstractVertexFrame implements Person {
+  @Override
+  public String getName() {
+      return this.getProperty("name");
+  }
+  
+  @Override
+  public List<? extends Person> getCoworkers() {
+      return this.traverse(v -> v.out("coworker")).toList(Person.class);
+  }
+}
+```
+
+!!! Note
+    When implementing a Frame a class or abstract class must always extend from either `AbstractEdgeFrame` or
+    `AbstractVertexFrame`.
+
+## Typing
+
+There are two typing modes for ferma and each significantly effect how the user will determine the type of the objects
+pulled from the graph, these modes are called **Typed Mode** and **Untyped Mode**.
+
+When performing a traversal on a Frame there are several methods provided which automatically encapsulate the underlying
+graph element or elements into a framed equivelant such as a `VertexFrame` or a `EdgeFrame`. This may either be a single
+Frame, Iterator, Set, or List of Frames.
+
+In the earlier example we used a traversal to find all the coworkers, we used the `toList()` method to frame all the
+underlying vertex into the `Person` type.
+
+```Java
+this.traverse(v -> v.out("coworker")).toList(Person.class);
+```
+
+Traversals have several different methods availible that each frame and collect the underlying elements in different
+ways, those methods, members of the `Traversable` interface, are the following.
+
+```Java
+<N> N next(Class<N> kind);
+<N> List<? extends N> next(int amount, Class<N> kind);
+<N> N nextOrDefault(Class<N> kind, N defaultValue);
+VertexFrame nextOrAdd();
+<N> N nextOrAdd(ClassInitializer<N> initializer);
+<N> N nextOrAdd(Class<N> kind);
+<N> Iterator<N> frame(Class<N> kind);
+<N> List<? extends N> toList(Class<N> kind);
+<N> Set<? extends N> toSet(Class<N> kind);
+```
+
+!! note
+   Each of these methods also have an equivelant method with the suffix `Explicit`, we will discuss those later as they
+   only become important when we begin to discuss the differences between typed and untyped mode.
+
+Each of these methods has a slightly different behavior. For full details see the Ferma Javadocs for the Traversable
+class. However, in short, the `next(Class)` method returns any one of the matching elements and frames it as the
+specified type. It will throw an exception however if no vertexes match. The `nextOrDefault` varient avoids the
+exception by returning the default value when there are no matches, which can be `0` or `null` for example. Similarly
+`nextOrAdd` will add a new vertex to the underlying graph if the traversal yields no matches. finally `frame(Class)`,
+`toList(Class)`, and `toSet(Class)` will return all elements that match the traversal as either a `Iterator`, `List`, 
+or a `Set`.
+
+The exact type returned from all the aforementioned calls will always be a Class of the type specified in the argument,
+or a subclass thereof. The exact type of the class instantiated will depend on which typing mode is being used.
+
+    
+### Untyped Mode
+ 
+In untyped mode there is never any Java type information encoded into the underlying graph. This means when you take an
+object off the graph there is no way for Ferma to know what Java type it is associated with and the user must select
+the type manually. Since a Frame just defines a set of behaviors and properties exposed for a particular graph
+element it can sometimes be useful to pick which Frame to use to represent an element based on how you need to interact
+with that element rather than a one to one mapping of element to a specific type. In such a scenario Untyped Mode might
+be the ideal choice.
+
+In this mode when framing elements from a traversal the type of the element is determined entierly from the parameters
+passed to the methods invoked on the Traversable class. The following is an example of how to frame a vertex as a
+`Person` class from above.
+
+```Java
+// Open an untyped Framed Graph
+FramedGraph fg = new DelegatingFramedGraph(TinkerGraph.open());
+
+//create a vertex with no type information and a single name property
+VertexFrame vertex = fg.addFramedVertex(VertexFrame.class);
+vertex.setProperty("name", "Jeff");
+
+//retrieve the vertex we just created but this time frame it as a Person
+Person person = fg.traverse(g -> g.V().property("name", "jeff")).nextExplicit(Person.class);
+assert person.getName().equals("Jeff");
+```
+
+!!! note
+    In untyped mode all the `Traversal` methods with the suffix of `Explicit` behave exactly the same as those methods
+    without the suffix. Therefore when working in untyped mode it is suggested you only use explicit methods. This way
+    if you ever decide to migrate over to typed mode it will not change the behavior of your existing code base and will
+    make the migration process much easier. 
+
+## Typed Mode
+
+Typed mode takes things one step further and allows type information about a Data Model class to be encoded as a
+property on vertex and edges in the underlying graph. This behavior is governed by the `PolymorphicTypeResolver` which
+encodes the type in a property name which defaults to the value of `PolymorphicTypeResolver.TYPE_RESOLUTION_KEY` but can
+be explicitly set to any string value of the user's choice. When a class is framed the Type Resolution Key is read and
+the original type is determined, this in turn effects the type used to instantiate the new Frame and may be a specific
+type which is a subclass of the type requested. For example say we have the following model. 
+
+```Java
+public class Person extends AbstractVertexFrame {
+  public String getName() {
+      return this.getProperty("name");
+  }
+
+  public List<? extends Person> getFriends() {
+      return this.traverse(v -> v.out("friend")).toList(Person.class);
+  }
+}
+
+public class Programmer extends Person {
+  @Override
+  public List<? extends Programmer> getFriends() {
+      //Programmers don't have friends :(
+      return Collections.emptyList();
+  }
+}
+```
+
+In this case we can encode a `Programmer` vertex into the graph and even if we try to retrieve and frame that vertex as a
+`VertexFrame` or `Person` in the future the instantiated type will still be `Programmer`. This allows for a truly
+Polymorphic Graph Data Model that leverages method overriding and class inheritance functiuonality in the model. For
+example the following is possible now in Typed Mode.
+
+```Java
+// Open typed Framed Graph
+FramedGraph fg = new DelegatingFramedGraph(TinkerGraph.open(), true, false);
+
+//create a vertex with no type information and a single name property
+Programmer programmer = fg.addFramedVertex(Programmer.class);
+programmer.setName("Jeff");
+
+//retrieve the vertex we just created and check it is instantiated as a Programer
+Person person = fg.traverse(g -> g.V().property("name", "jeff")).next(Person.class);
+assert person instanceof Programmer;
+assert person.getFriends().isEmpty();
+```
+
+The methods with the `Explicit` suffix are particularly meaningful for Typed Mode. In this mode they bypass the encoded
+typing completely and instantiate the frame as the type specified instead. The following code snippet provides an
+example using the same model.
+
+```Java
+// Open typed Framed Graph
+FramedGraph fg = new DelegatingFramedGraph(TinkerGraph.open(), true, false);
+
+//create a vertex with no type information and a single name property
+Programmer programmer = fg.addFramedVertex(Programmer.class);
+programmer.setName("Jeff");
+
+//retrieve the vertex we just created, since we are using an excplicit method the type won't be Programmer this time.
+Person person = fg.traverse(g -> g.V().property("name", "jeff")).nextExplicit(Person.class);
+assert !(person instanceof Programmer);
+```
+
+The following are the list of explicit method types in the Traversable class.
+
+```Java
+<N> N nextExplicit(Class<N> kind);
+<N> List<? extends N> nextExplicit(int amount, Class<N> kind);
+<N> N nextOrDefaultExplicit(Class<N> kind, N defaultValue);
+<N> N nextOrAddExplicit(ClassInitializer<N> initializer);
+<N> N nextOrAddExplicit(Class<N> kind);
+<N> Iterator<? extends N> frameExplicit(Class<N> kind);
+<N> List<? extends N> toListExplicit(Class<N> kind);
+<N> Set<? extends N> toSetExplicit(Class<N> kind);
+```
diff --git a/mkdocs.yml b/mkdocs.yml
index c388349daf2d39f22015ed5a6ea0046087865bf2..861e69fb5a26190a7a5f1f82193e98b2dfc2f966 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -11,7 +11,7 @@ site_url: 'http://syncleus.com/Ferma'
 pages:
     - Home: index.md
     - Getting Started: getting_started.md
-    - Comparing the Alternatives: comparing_the_alternatives.md
+    - Object Mapping: object_mapping.md
     - Core Annotations:
         - Overview: annotations/overview.md
         - '@Adjacency': annotations/adjacency.md
@@ -20,6 +20,7 @@ pages:
         - '@InVertex': annotations/invertex.md
         - '@OutVertex': annotations/outvertex.md
         - '@Property': annotations/property.md
+    - Comparing the Alternatives: comparing_the_alternatives.md
     - Glossary: glossary.md
 extra:
   version: '3.2.1'