class ImmutableProject extends ImmutableDocument implements Project {

    private final boolean enabled;
    private final String id;
    private final String name;
    private final String companyName;
    private final String packageName;
    private final String packageLocation;
    private final Path configPath;
    
    private final List<Dbms> dbmses;
    private final Map<String, ImmutableTable> tablesByName;

    public ImmutableProject(Map<String, Object> project) {
        super(project);
        final Project prototype = Project.create(project);
        this.enabled         = prototype.isEnabled();
        this.id              = prototype.getId();
        this.name            = prototype.getName();
        this.companyName     = prototype.getCompanyName();
        this.packageName     = prototype.getPackageName().orElse(null);
        this.packageLocation = prototype.getPackageLocation();
        this.configPath      = prototype.getConfigPath().orElse(null);
        this.dbmses = unmodifiableList(super.children(DBMSES, ImmutableDbms::new).collect(toList()));

        this.tablesByName = DocumentDbUtil.traverseOver(this, ImmutableTable.class)
            .collect(toMap(
                table -> DocumentUtil.relativeName(table, Dbms.class, DATABASE_NAME),
                Function.identity()
            ));
    }

    @Override
    public boolean isEnabled() {
        return enabled;
    }

    @Override
    public String getId() {
        return id;
    }
    
    @Override
    public String getName() {
        return name;
    }

    @Override
    public String getCompanyName() {
        return companyName;
    }

    @Override
    public Optional<String> getPackageName() {
        return Optional.ofNullable(packageName);
    }

    @Override
    public String getPackageLocation() {
        return packageLocation;
    }

    @Override
    public Optional<Path> getConfigPath() {
        return Optional.ofNullable(configPath);
    }

    @Override
    public Stream<Dbms> dbmses() {
        return dbmses.stream();
    }

    @Override
    public ImmutableTable findTableByName(String fullName) {<FILL_FUNCTION_BODY>}

}

        final ImmutableTable table = tablesByName.get(fullName);
        
        if (table == null) {
            throw new SpeedmentConfigException(
                "Unable to find table '" + 
                fullName + 
                "' in immutable config model."
            );
        }
        
        return table;
    
<methods>public Stream<T> children(java.lang.String, BiFunction<P,Map<java.lang.String,java.lang.Object>,T>) ,public final Map<java.lang.String,java.lang.Object> getData() ,public final void put(java.lang.String, java.lang.Object) ,public java.lang.String toString() ,public static com.speedment.runtime.config.internal.immutable.ImmutableDocument wrap(com.speedment.runtime.config.Document) <variables>private final non-sealed Map<java.lang.String,List<com.speedment.runtime.config.Document>> children