@Override
    public CompletableFuture<Project> readSchemaMetadata(
            Dbms dbms, ProgressMeasure progress,
            Predicate<String> filterCriteria) {

        // Create a deep copy of the project document.
        final Project projectCopy = projects.getProject().deepCopy();

        // Make sure there are not multiple dbmses with the same id
        final Set<String> ids = new HashSet<>();
        if (!projectCopy.dbmses().map(Dbms::getId).allMatch(ids::add)) {
            final Set<String> duplicates = new HashSet<>();
            ids.clear();

            projectCopy.dbmses()
                .map(Dbms::getId)
                .forEach(s -> {
                    if (!ids.add(s)) {
                        duplicates.add(s);
                    }
                });

            throw new SpeedmentException(
                "The following dbmses have duplicates in the config document: "
                    + duplicates
            );
        }

        // Locate the dbms in the copy.
        final Dbms dbmsCopy = projectCopy.dbmses()
            .filter(d -> d.getId().equals(dbms.getId()))
            .findAny().orElseThrow(() -> new SpeedmentException(
                "Could not find Dbms document in copy."
            ));

        return readSchemaMetadata(
            projectCopy, dbmsCopy, progress
        ).whenCompleteAsync((project, ex) -> {
            progress.setProgress(ProgressMeasureUtil.DONE);
            if (ex != null) {
                progress.setCurrentAction("Error!");
                throw new SpeedmentException("Unable to read schema metadata.", ex);
            } else {
                progress.setCurrentAction("Done!");
            }
        });
    }
'true' below might speed up metadata retrieval since approximations can
be used. See https://github.com/speedment/speedment-enterprise/issues/168
runtime-parent/runtime-connector-parent/sqlite/src/main/java/com/speedment/runtime/connector/sqlite/internal/SqliteMetadataHandlerImpl.java