public void ReaderTests()
        {
            var node = this.ReadNode(EmptyDataStore, isDataStoreJson: true);
            Assert.True(object.ReferenceEquals(DataStoreTests.EmptyDataStore, node));

            node = this.ReadNode(TextValueRoot, isDataStoreJson: true);
            Assert.True(DataStoreTests.TextValueRoot.Equals(node));

            node = this.ReadNode(EmptyObjectRoot, isDataStoreJson: true);
            Assert.True(DataStoreTests.EmptyObjectRoot.Equals(node));

            node = this.ReadNode(EmptyValueRoot, isDataStoreJson: true);
            Assert.True(DataStoreTests.EmptyValueRoot.Equals(node));

            node = this.ReadNode(SimpleRoot, isDataStoreJson: true);
            Assert.True(DataStoreTests.SimpleRoot.Equals(node));


            node = this.ReadNode(EmptyDataStore, isDataStoreJson: false);
            IDataStoreNode expectedNode = new DataStoreObject("root");
            Assert.True(expectedNode.Equals(node));

            node = this.ReadNode(TextValueRoot, isDataStoreJson: false);
            expectedNode = new DataStoreObject(
                "root",
                new DataStoreTextValue("textRoot", "abc"));
            Assert.True(expectedNode.Equals(node));

            node = this.ReadNode(EmptyObjectRoot, isDataStoreJson: false);
            expectedNode = new DataStoreObject(
                "root",
                new DataStoreObject("objectRoot"));
            Assert.True(expectedNode.Equals(node));
        }
        /// <summary>
        /// Writes an ObjectStart, ObjectEnd, or a value.
        /// </summary>
        /// <param name="name">The data store name to use; or <c>null</c> for the ObjectEnd token.</param>
        /// <param name="isObjectStart"><c>true</c> if an ObjectStart token is to be written, <c>false</c> for ObjectEnd, and <c>null</c> for a binary or text value.</param>
        /// <returns>A value determining whether the value to be written is binary or not. <c>null</c> if an object was written.</returns>
        protected override bool? Write( string name, bool? isObjectStart )
        {
            try
            {
                if( isObjectStart != false
                 && !DataStore.IsValidName(name) )
                    throw new ArgumentException("Invalid data store name!").StoreFileLine();

                bool? isBinary;
                if( isObjectStart.HasValue )
                {
                    if( isObjectStart.Value )
                    {
                        var node = new DataStoreObject(name);
                        this.parents.Add(node);
                    }
                    else
                    {
                        var index = this.parents.Count - 1;
                        var node = this.parents[index];
                        this.parents.RemoveAt(index);
                        this.AddChild(node);
                    }

                    isBinary = null;
                }
                else
                {
                    this.currentValueNodeName = name;
                    isBinary = this.IsBinary;
                }

                return isBinary;
            }
            catch( Exception ex )
            {
                ex.StoreFileLine();
                ex.Store("name", name);
                ex.Store("isObjectStart", isObjectStart);
                throw;
            }
        }
        private IDataStoreObject CreateDirectoryRecursively( string dataStorePath )
        {
            var node = this.GetNodeAt(dataStorePath);
            if( node.NotNullReference() )
            {
                var objectNode = node as IDataStoreObject;
                if( objectNode.NullReference() )
                    throw new FileNotFoundException("File system entry already exists, but isn't a directory!").Store("filePath", dataStorePath);
                else
                    return objectNode;
            }

            IList<IDataStoreNode> parentNodes;
            var parentPath = DataStore.GetParentPath(dataStorePath);
            if( parentPath.NullOrEmpty() )
                parentNodes = this.rootNodes;
            else
                parentNodes = this.CreateDirectoryRecursively(parentPath).Nodes;

            // we know the parent does not have a child with the same name
            var newObject = new DataStoreObject(DataStore.GetNodeName(dataStorePath));
            parentNodes.Add(newObject);
            return newObject;
        }