Agreed about only disallowing the path separator; I made that change.

As far as where to put the logic, I want to make sure I have it right. The way I understand the code, there are four scenarios where a node name is used to create a document path:

1. When a document is newly created
2. When a document is moved by assignment (e.g. the value of the NodeName field changes)
3. When a document's child is newly created via cascade
4. When a document's child is renamed (but not moved; moving by assignment here throws an exception)

The first, second, and fourth of those scenarios happen within `UnitOfWork::computeChangeSet()`, while the third one happens in `UnitOfWork::computeChildChanges()`.

I updated the commit with better tests that cover this. They are:

*`BasicCrudTest::testIllegalNodename()`*
* If a name with a slash is provided, e.g. "bad/name", the code in `UnitOfWork::computeChangeSet()` (specifically the call to `PathHelper::getParentPath($id)`) will fail as it attempts to look up "/previous/parent/bad"
* Today: Throws "PHPCR\ItemNotFoundException: HTTP 404 Path Not Found: GET"

*`BasicCrudTest::testIllegalNodenameMove()`*
* If a name with a slash is provided, e.g. "bad/name", the `$targetPath` in `UnitOfWork::executeMoves()` will have a new value of "/previous/parent/bad/name", and thus will fail as it attempts to look up "/previous/parent/bad"
* Today: Throws "PHPCR\ItemNotFoundException: HTTP 404 Path Not Found: GET"

*`ParentTest::testIllegalNameNewChild()`*
* If a name with a slash is provided, e.g. "bad/name", the code in `UnitOfWork::executeInserts()` (specifically the call to `PathHelper::getParentPath($id)`) will fail as it attempts to look up "/previous/parent/bad"
* Today: Throws "PHPCR\PathNotFoundException: HTTP 404 Path Not Found: GET"
 
*`ParentTest::testIllegalNameExistingChild()`*
* If a name with a slash is provided, e.g. "bad/name", the code in `UnitOfWork::computeChildChanges()` will note that the node's parent path (e.g. "/previous/parent") and new parent path (e.g. "/previous/parent/bad") are not the same, so it thinks we are trying to move the child
* Today: Throws "Doctrine\ODM\PHPCR\PHPCRException: Cannot move/copy children by assignment as it would be ambiguous. Please use the DocumentManager::move() or PHPCR\Session::copy() operations for this: Doctrine\Tests\ODM\PHPCR\Functional\ParentTestNamedChildObj@0000000075781c8c00000000321dcb1f (/functional/ExistingParent/bad/name)" 

So, if we move the name check into `ParentIdGenerator`, it only covers two of the four above scenarios, and we'd still need a check in `UnitOfWork::computeChangeSet()` to handle #2 above. In either strategy we still need a check in `UnitOfWork::computeChildChanges()` since that code explicity appends the name to the parent's path to create a new ID.

The code path can be observed by commenting out the checks in `computeChangeSet` and `computeChildChanges`, and removing the `@expectedException` annotations from the tests and then running them.

I can add that logic to `ParentIdGenerator` but I am unsure of how to handle the other cases then.

(Sorry about the lengthy response, it is quite possible I am just missing something in the code so I want to make sure I've got it right!)