class ImmutableForeignKeyColumn extends ImmutableDocument implements ForeignKeyColumn {

    private final String id;
    private final String name;
    private final int ordinalPosition;
    private final String foreignColumnName;
    private final String foreignTableName;
    
    private final AtomicReference<ImmutableColumn> foreignColumn;
    private final AtomicReference<ImmutableTable> foreignTable;
    private final AtomicReference<ImmutableColumn> column;
  
    ImmutableForeignKeyColumn(ImmutableForeignKey parent, Map<String, Object> fkc) {
        super(parent, requireKeys(fkc, ForeignKeyColumnUtil.FOREIGN_COLUMN_NAME, ForeignKeyColumnUtil.FOREIGN_TABLE_NAME));
        
        final ForeignKeyColumn prototype = new ForeignKeyColumnImpl(parent, fkc);
    
        this.id                = prototype.getId();
        this.name              = prototype.getName();
        this.ordinalPosition   = prototype.getOrdinalPosition();
        this.foreignTableName  = prototype.getForeignTableName();
        this.foreignColumnName = prototype.getForeignColumnName();
        
        this.foreignTable      = new AtomicReference<>();
        this.foreignColumn     = new AtomicReference<>();
        this.column            = new AtomicReference<>();
    }

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

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

    @Override
    public int getOrdinalPosition() {
        return ordinalPosition;
    }

    @Override
    public String getForeignColumnName() {
        return foreignColumnName;
    }

    @Override
    public String getForeignTableName() {
        return foreignTableName;
    }

    @Override
    public Optional<ImmutableColumn> findForeignColumn() {
        if (foreignColumn.get() == null) {
            foreignColumn.set(ForeignKeyColumn.super.findForeignColumn().map(ImmutableColumn.class::cast).orElse(null));
        }
        return Optional.ofNullable(foreignColumn.get());
    }

    @Override
    public Optional<ImmutableTable> findForeignTable() {<FILL_FUNCTION_BODY>}

    @Override
    public Optional<ImmutableColumn> findColumn() {
        if (column.get() == null) {
            column.set(ForeignKeyColumn.super.findColumn()
                .map(ImmutableColumn.class::cast).orElse(null));
        }
        return Optional.ofNullable(column.get());
    }
    
    @Override
    public Optional<ForeignKey> getParent() {
        return super.getParent().map(ForeignKey.class::cast);
    }
    
    @Override
    public String toString() {
        return toStringHelper(this);
    }
}

        if (foreignTable.get() == null) {
            foreignTable.set(ForeignKeyColumn.super.findForeignTable().map(ImmutableTable.class::cast).orElse(null));
        }
        return Optional.ofNullable(foreignTable.get());
    
<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