class GBPTree implements Closeable {

    public static void readHeader( PageCache pageCache, File indexFile, Header.Reader headerReader )
            throws IOException, MetadataMismatchException
    {
        try ( PagedFile pagedFile = openExistingIndexFile( pageCache, indexFile ) )
        {
            Pair<TreeState,TreeState> states = loadStatePages( pagedFile );
            TreeState state = TreeStatePair.selectNewestValidState( states );
            try ( PageCursor cursor = pagedFile.io( state.pageId(), PagedFile.PF_SHARED_READ_LOCK ) )
            {
                PageCursorUtil.goTo( cursor, "header data", state.pageId() );
                doReadHeader( headerReader, cursor );
            }
        }
        catch ( Throwable t )
        {
            // Decorate outgoing exceptions with basic tree information. This is similar to how the constructor
            // appends its information, but the constructor has read more information at that point so this one
            // is a bit more sparse on information.
            withMessage( t, t.getMessage() + " | " + format( "GBPTree[file:%s]", indexFile ) );
            throw t;
        }
    }

    public  GBPTree( PageCache pageCache, File indexFile, Layout<KEY,VALUE> layout, int tentativePageSize,
            Monitor monitor, Header.Reader headerReader, Consumer<PageCursor> headerWriter,
            RecoveryCleanupWorkCollector recoveryCleanupWorkCollector, boolean readOnly );

}