- added duplicate(), which creates an 'equivalent' ncube (but all internal IDs are new and different, intentionally).  Not the same as a clone(), as that would create an 'identical' n-cube, even with the internal IDs matching.
- added equals(), and hashCode().  a 'duplicate' n-cube is .equals() to it's duplicate.  And two duplicate n-cubes have the same hash code.
- NCubeManager.  Added new APIs to duplicate, getReferencedNCubes (deep), and new API to change a SNAPSHOT n-cube's version value.
- NCubeManager - cleaned up (and uniformized argument validation).