///////////////////////////////////////////////////////////////////////////////
// DeleteChildArray
///////////////////////////////////////////////////////////////////////////////
void cHierDatabaseIter::DeleteChildArray() //throw (eArchive, eHierDatabase)
{
    ASSERT( ! Done() );
    ASSERT( CanDescend() );
    cDebug d("cHierDatabaseIter::DeleteChildArray");

    if( Done() )
    {
        d.TraceDetail("Attempt to DeleteChildArray() when Done() == true; returning\n");
        return;
    }
    if( ! CanDescend() )
    {
        d.TraceDetail("Attempt to DeleteChildArray() when none exists; returning\n");
        return;
    }
    //
    // make sure that the child index is empty...
    //
    if( ! ChildArrayEmpty() )
    {
        ASSERT( false );
        throw eHierDatabase( _T("Attempt to delete a child array that still has entries") );
    }
    //
    // ok, no we can remove it...
    //
    mpDb->RemoveItem( cBlockRecordFile::tAddr( mIter->mChild.mBlockNum, mIter->mChild.mIndex ) );
    mIter->mChild = cHierAddr();
    util_RewriteObject( mpDb, &(*mIter), GetCurrentAddr() );
}
///////////////////////////////////////////////////////////////////////////////
// CreateChildArray
///////////////////////////////////////////////////////////////////////////////
void cHierDatabaseIter::CreateChildArray() //throw (eArchive, eHierDatabase)
{
    ASSERT( ! Done() );
    ASSERT( ! CanDescend() );
    if( Done() )
    {
        throw eHierDatabase( _T("Attempt to call iter::CreateChildArray() when done is true"));
    }
    if( CanDescend() )
    {
        throw eHierDatabase( _T("Attempt to call iter::CreateChildArray() when child already exists"));
    }
        
    cHierArrayInfo  newInfo;
    cHierAddr       infoAddr;

    // write the new info
    newInfo.mParent = mInfoAddr;
    infoAddr        = util_WriteObject( mpDb, &newInfo );
    mIter->mChild   = infoAddr;
    //
    // rewrite the current object, since its child info just changed
    //
    util_RewriteObject( mpDb, &(*mIter), GetCurrentAddr() );
}
///////////////////////////////////////////////////////////////////////////////
// AddChildArray
///////////////////////////////////////////////////////////////////////////////
void cDbDataSourceIter::AddChildArray() //throw (eError)
{
	ASSERT( ! Done() );
	ASSERT( ! CanDescend() );

	mDbIter.CreateChildArray();
}
///////////////////////////////////////////////////////////////////////////////
// CanDeleteChildArray
///////////////////////////////////////////////////////////////////////////////
bool cHierDatabaseIter::ChildArrayEmpty()
{
    ASSERT( ! Done() );
    ASSERT( CanDescend() );

    cHierArrayInfo  info;
    util_ReadObject ( mpDb, &info, mIter->mChild );
    return          ( info.mArray.IsNull() );
}
///////////////////////////////////////////////////////////////////////////////
// DeleteEntry
///////////////////////////////////////////////////////////////////////////////
void cHierDatabaseIter::DeleteEntry() //throw (eArchive, eHierDatabase)
{
    ASSERT( ! Done() );
    ASSERT( ! CanDescend() ); // this node can't have any children.
    cDebug d("cHierDatabaseIter::DeleteEntry");

    if( Done() )
    {
        d.TraceDetail("Attempt to DeleteEntry() when Done() == true; returning\n");
        return;
    }
    if( CanDescend() )
    {
        throw eHierDatabase( _T("Attempt to delete an entry that still has children.\n"));
    }
    
    //
    // first, we should set the previous node's next pointer...
    //
    cHierAddr curAddr = GetCurrentAddr();
    if( mIter == mEntries.begin() )
    {
        // we are changing the info's mArray pointer
        //
        mInfo.mArray = mIter->mNext;
        util_RewriteObject( mpDb, &mInfo, mInfoAddr );
    }
    else
    {
        // altering the previous node...
        //
        mIter--;
        mIter->mNext = (mIter+1)->mNext;
        util_RewriteObject( mpDb, &(*mIter), GetCurrentAddr() );
        mIter++;
    }
    //
    // now, delete the node from the file and from our array...
    //
    mpDb->RemoveItem( cBlockRecordFile::tAddr( curAddr.mBlockNum, curAddr.mIndex ) );
    mIter = mEntries.erase(mIter);

}
///////////////////////////////////////////////////////////////////////////////
// Descend
///////////////////////////////////////////////////////////////////////////////
void cHierDatabaseIter::Descend()
{
    ASSERT( CanDescend() );
    // 
    // alter the cwd...
    //
    mCurPath.Push( mIter->mName );

    LoadArrayAt ( mIter->mChild );
}