in a particular direction (e.g. traverse from employee to their manager(s)) go N steps in sequence, where each step can be any traversal specification go N steps in parallel, and unify the resulting set select a subset of the found nodes based on some criteria, etc. The FirstStep example shows some simple traversals.And just for simplicity, InfoGrid also allows traversals starting from a set of start nodes, not just one. So we can say things like this:MeshObject me = ...;MeshObjectSet myParents = me.traverse( childToParents );MeshObjectSet myGrandParents = myParents.traverse( childToParents );In our experience, working with sets makes complex traversals very easily understandable. Operations on a Graph Database (Part 7 - Sets)Sets are a core concept of most databases. For example, any SQL SELECT statement in a relational database produces a set. Sets apply to Graph Databases just as well and are just as useful:The most frequently encountered set of nodes in a Graph Database is the result of a traversal. For example, in InfoGrid, all traversal operations result in a set like this:MeshObject startNode = ...; // some start nodeMeshObjectSet neighborNodes = startNode.traverseToNeighbors();We might as well have returned an array, or an Iterator over the members of the set, were it not for the fact that there are well-understood set operations that often make our jobs as developers much simpler: like set unification, intersection and so forth.For example, in a social bookmarking application we might want to find out which sites both you and I have bookmarked. Code might look like this:MeshObject me = ...; // node representing meMeshObject you = ...; // node representing youTraversalSpecification ME_TO_BOOKMARKS_SPEC = ...; // how to get from a person to their bookmarks, see post on traversalsMeshObjectSet myBookmarks = me.traverse( ME_TO_BOOKMARKS_SPEC );MeshObjectSet yourBookmarks = you.traverse( ME_TO_BOOKMARKS_SPEC );// Bookmarks that you and I shareMeshObjectSet sharedBookmarks = myBookmarks.intersect( yourBookmarks );Notice how simple this code is to understand? One of the powers of sets. Or, if you know what a minus operation is on a set, this is immediately obvious:// Bookmarks unique to meMeshObjectSet myUniqueBookmarks = myBookmarks.minus( yourBookmarks );This is clearly much simpler than writing imperative code which would have lots of loops and if/then/elses and comparisons and perhaps indexes in it. (And seeing this might put some concerns to rest that NoSQL databases are primitive because they dont have a SQL-like query language. Id argue its less the language but the power of sets, and if you have sets you have a lot of power at your fingertips.)To check out sets in InfoGrid, try package org.infogrid.mesh.set. Clearly much more can be done than we have so far in InfoGrid, but its a very useful start in our experience. Operations on a Graph Database (Part 8 - Events)The database industry is not used to databases that can generate events. The closest the relational database has to events are stored procedures, but they never reach out back to the application, so their usefulness is limited. But events are quite natural for graph databases. Broadly speaking, they occur in two places: Events on the graph database itself (example: tell me when a