@Override
    protected void fetchAsync(List<byte[]> refs, AsyncCallback<Object[]> objects) {
        Object[] result = new Object[refs.size()];

        for (int i = 0; i < result.length; i++) {
            result[i] = _reader.read(refs.get(i));
            _reader.readVersions();
            _reader.importVersions();
        }

        objects.onSuccess(result);
    }
        @Override
        protected void checkedRun() {
            if (Debug.THREADS) {
                ThreadAssert.resume(this, false);
                ThreadAssert.exchangeTake(this);
            }

            Exception ex;

            try {
                onRunStarting();
                runTasks();

                //

                while (_inserts.size() > 0)
                    _refs.add(writeObject(_inserts.poll()));

                //

                if (Debug.ENABLED)
                    Debug.assertion(!_writer.interrupted());

                for (;;) {
                    BinaryStore.this.run(_writer);

                    if (!_writer.interrupted())
                        break;

                    _writer.grow();
                }

                _writer.writeSnapshots();

                //

                Exception wrongStore = null;
                int toremove;

                if (_writer.getWrongStore() == null)
                    _jdbm.commit();
                else {
                    _jdbm.rollback();
                    wrongStore = new RuntimeException(Strings.WRONG_STORE + _writer.getWrongStore());
                }

                while (_processed.size() > 0) {
                    Transaction branch = _processed.pollPartOfClear();
                    byte interception = _processedInterceptions[_processed.size()];

                    if (wrongStore == null)
                        Interceptor.ack(branch, interception, true);
                    else
                        Interceptor.nack(branch, null, wrongStore);
                }

                if (wrongStore != null) {
                    if (Debug.ENABLED) {
                        // Assert old records have been restored on rollback
                        for (int i = 0; i < _updatedVersions.size(); i++) {
                            Version shared = _updatedVersions.get(i);
                            Debug.assertion(_jdbm.fetch(shared.getRecord()) != null);
                        }
                    }

                    _updatedVersions.clear();
                    _updatedSessions.clear();
                } else {
                    while (_updatedVersions.size() > 0) {
                        Version shared = _updatedVersions.pollPartOfClear();
                        long record = _updatedVersionsRecords[_updatedVersions.size()];
                        shared.setRecord(record);
                    }

                    while (_updatedSessions.size() > 0) {
                        Session session = _updatedSessions.pollPartOfClear();
                        long records = _updatedSessionsRecords[_updatedSessions.size()];
                        session.setRecords(records);
                    }
                }

                //

                while (_callbacks.size() > 0) {
                    AsyncCallback<byte[]> callback = _callbacks.poll();
                    byte[] ref = _refs.poll();

                    if (wrongStore == null)
                        callback.onSuccess(ref);
                    else
                        callback.onFailure(wrongStore);
                }

                //

                _writer.resetWrongStore();

                if (Debug.THREADS)
                    ThreadAssert.suspend(this);

                setFlushes();
                onRunEnded();
                return;
            } catch (Exception e) {
                ex = e;
            }

            while (_callbacks.size() > 0)
                _callbacks.poll().onFailure(ex);

            // Only in case of exception (can be closing)
            onException(ex);
        }