src/main/java/com/aoindustries/dbc/meta/Catalog.java
public SymmetricGraph<Table,Edge<Table>,SQLException> getForeignKeyGraph(final Set<String> tableTypes) {
		return new SymmetricGraph<Table, Edge<Table>, SQLException>() {

			@Override
			public Set<Table> getVertices() throws SQLException {
				Set<Table> vertices = new LinkedHashSet<>();
				for(Schema schema : getSchemas().values()) {
					for(Table table : schema.getTables().values()) {
						if(tableTypes==null || tableTypes.contains(table.getTableType())) vertices.add(table);
					}
				}
				return AoCollections.optimalUnmodifiableSet(vertices);
			}

			@Override
			public Set<Edge<Table>> getEdgesFrom(Table from) throws SQLException {
				Set<? extends Table> tos = from.getImportedTables();
				Set<Edge<Table>> edges = new LinkedHashSet<>(tos.size()*4/3+1);
				for(Table to : tos) {
					if(
						tableTypes==null
						|| tableTypes.contains(from.getTableType())
						|| tableTypes.contains(to.getTableType())
					) edges.add(new Edge<>(from, to));
				}
				return AoCollections.optimalUnmodifiableSet(edges);
			}

			@Override
			public Set<Edge<Table>> getEdgesTo(Table to) throws SQLException {
				Set<? extends Table> froms = to.getExportedTables();
				Set<Edge<Table>> edges = new LinkedHashSet<>(froms.size()*4/3+1);
				for(Table from : froms) {
					if(
						tableTypes==null
						|| tableTypes.contains(from.getTableType())
						|| tableTypes.contains(to.getTableType())
					) edges.add(new Edge<>(from, to));
				}
				return AoCollections.optimalUnmodifiableSet(edges);
			}
		};
	}
public SymmetricGraph<Table,Edge<Table>,SQLException> getForeignKeyGraph(final Set<String> tableTypes) {
		return new SymmetricGraph<Table, Edge<Table>, SQLException>() {

			@Override
			public Set<Table> getVertices() throws SQLException {
				Set<Table> vertices = new LinkedHashSet<>();
				for(Schema schema : getSchemas().values()) {
					for(Table table : schema.getTables().values()) {
						if(tableTypes==null || tableTypes.contains(table.getTableType())) vertices.add(table);
					}
				}
				return AoCollections.optimalUnmodifiableSet(vertices);
			}

			@Override
			public Set<Edge<Table>> getEdgesFrom(Table from) throws SQLException {
				Set<? extends Table> tos = from.getImportedTables();
				Set<Edge<Table>> edges = new LinkedHashSet<>(tos.size()*4/3+1);
				for(Table to : tos) {
					if(
						tableTypes==null
						|| tableTypes.contains(from.getTableType())
						|| tableTypes.contains(to.getTableType())
					) edges.add(new Edge<>(from, to));
				}
				return AoCollections.optimalUnmodifiableSet(edges);
			}

			@Override
			public Set<Edge<Table>> getEdgesTo(Table to) throws SQLException {
				Set<? extends Table> froms = to.getExportedTables();
				Set<Edge<Table>> edges = new LinkedHashSet<>(froms.size()*4/3+1);
				for(Table from : froms) {
					if(
						tableTypes==null
						|| tableTypes.contains(from.getTableType())
						|| tableTypes.contains(to.getTableType())
					) edges.add(new Edge<>(from, to));
				}
				return AoCollections.optimalUnmodifiableSet(edges);
			}
		};
	}
Gets a graph view of the imported/exported table relationships within this catalog.

TODO: Check is symmetric in JUnit test

@param the set of tables types or <code>null</code> for all types