diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000000..98f72a30a9d
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,10 @@
+root = true
+
+[*]
+charset = utf-8
+ident_style = space
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.md]
+trim_trailing_whitespace = false
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 00000000000..dad040e494f
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,19 @@
+
+```
+ * JGraphT version:
+ * Java version (java -version)/platform:
+```
+
+**Issue**
+
+
+
+**Steps to reproduce (small coding example)**
+
+
+
+**Expected behaviour**
+
+
+
+**Other information**
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 00000000000..17ea0d63eea
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,13 @@
+
+
+----
+
+- [ ] I read and understood
+- [ ] I read and understood
+- [ ] I added [unit tests](https://github.com/jgrapht/jgrapht/wiki/Unit-testing)
+- [ ] I added [documentation](https://github.com/jgrapht/jgrapht/wiki/How-to-write-documentation)
+- [ ] I followed the [Coding and Style Conventions](https://github.com/jgrapht/jgrapht/wiki/Coding-and-Style-Conventions)
+- [ ] I **have not** modified `HISTORY.md` or `CONTRIBUTORS.md`
+- [ ] I ensured that [the git commit message is a good one](https://github.com/joelparkerhenderson/git_commit_message)
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 00000000000..c9b2105b448
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,10 @@
+version: 2
+updates:
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "weekly"
+ - package-ecosystem: "maven"
+ directory: "/"
+ schedule:
+ interval: "weekly"
diff --git a/.github/workflows/PR-workflow.yaml b/.github/workflows/PR-workflow.yaml
new file mode 100644
index 00000000000..d9a65b88aa2
--- /dev/null
+++ b/.github/workflows/PR-workflow.yaml
@@ -0,0 +1,34 @@
+name: JGrapht Pull Request build
+on:
+ pull_request:
+ types: [opened, synchronize, reopened]
+ branches:
+ - master
+
+jobs:
+ build:
+ strategy:
+ fail-fast: false
+ matrix:
+ os:
+ - name: Windows
+ tag: windows-latest
+ - name: macOS
+ tag: macos-latest
+ - name: Ubuntu
+ tag: ubuntu-latest
+ name: Build (${{ matrix.os.name }})
+ runs-on: ${{ matrix.os.tag }}
+ steps:
+ - uses: actions/checkout@v4
+ - name: Set up JDK 11
+ uses: actions/setup-java@v4
+ with:
+ java-version: 11
+ distribution: 'temurin'
+ cache: 'maven'
+ - name: Build with Maven
+ shell: bash
+ run: |
+ set -e
+ mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V && mvn verify -B && mvn javadoc:aggregate && mvn checkstyle:check -P checkstyle
diff --git a/.github/workflows/master-workflow.yaml b/.github/workflows/master-workflow.yaml
new file mode 100644
index 00000000000..67fcb3fc322
--- /dev/null
+++ b/.github/workflows/master-workflow.yaml
@@ -0,0 +1,83 @@
+name: JGrapht Master build
+on:
+ push:
+ branches:
+ - master
+ paths-ignore:
+ - 'CONTRIBUTORS.md'
+ - 'HISTORY.md'
+
+concurrency:
+ group: ${{ github.workflow }}
+ cancel-in-progress: true
+
+jobs:
+ build:
+ strategy:
+ matrix:
+ os:
+ - name: Windows
+ tag: windows-latest
+ - name: macOS
+ tag: macos-latest
+ - name: Ubuntu
+ tag: ubuntu-latest
+ name: Build (${{ matrix.os.name }})
+ runs-on: ${{ matrix.os.tag }}
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ persist-credentials: false
+
+ - uses: actions/setup-java@v4
+ with:
+ java-version: 11
+ distribution: 'temurin'
+ cache: 'maven'
+
+ - name: Build with Maven
+ shell: bash
+ run: |
+ set -e
+ mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V && mvn verify -B && mvn javadoc:aggregate && mvn checkstyle:check -P checkstyle
+
+ snapshot-publish:
+ name: Publish Snapshot
+ needs: build
+ if: github.repository == 'jgrapht/jgrapht'
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ persist-credentials: false
+ - uses: actions/setup-java@v4
+ with:
+ java-version: 11
+ distribution: 'temurin'
+ cache: 'maven'
+ - run: |
+ set -e
+ mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V && mvn javadoc:aggregate
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 14
+ - run: npm install -g hercule@5.0.0
+
+ - name: Run prepareDocs script
+ run: ./etc/prepareDocs.sh
+ shell: bash
+
+ - name: Deploy snapshot to Sonatype
+ env:
+ CENTRAL_USER: ${{ secrets.CI_DEPLOY_USERNAME }}
+ CENTRAL_PASSWORD: ${{ secrets.CI_DEPLOY_PASSWORD }}
+ run: mvn package org.sonatype.central:central-publishing-maven-plugin:publish -DskipTests=true --settings etc/snapshot-settings.xml
+ shell: bash
+
+ - name: Publish Github Pages
+ uses: JamesIves/github-pages-deploy-action@v4.5.0
+ with:
+ token: ${{ secrets.PAGES_TOKEN }}
+ branch: gh-pages
+ folder: docs
+ clean: true
diff --git a/.gitignore b/.gitignore
index 9c0a3e69cc9..f9321ce628f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,3 +26,14 @@ build
.kdev4
.buildpath
.svn
+.idea/*
+*.iml
+out/*
+**/out/*
+**/bin/*
+pom.xml.releaseBackup
+**/pom.xml.releaseBackup
+**/dependency-reduced-pom.xml
+.classpath
+docs/javadoc*
+docs/_site
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 00000000000..d3e0412f3e6
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,90 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as
+contributors and committers pledge to making participation in our project and
+our community a harassment-free experience for everyone, regardless of age, body
+size, disability, ethnicity, sex characteristics, gender identity and expression,
+level of experience, education, socio-economic status, nationality, personal
+appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment
+include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+* Proactively reading, following, and improving community guidelines
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or
+ advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic
+ address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Our Responsibilities
+
+Project committers are responsible for clarifying the standards of acceptable
+behavior and are expected to take appropriate and fair corrective action in
+response to any instances of unacceptable behavior.
+
+Project committers have the right and responsibility to remove, edit, or
+reject comments, commits, code, wiki edits, issues, and other contributions
+that are not aligned to this Code of Conduct, or to ban temporarily or
+permanently any contributor for other behaviors that they deem inappropriate,
+threatening, offensive, or harmful.
+
+## Contribution Model
+
+In the JGraphT project, we use the term "committers" rather than "maintainers".
+
+This is because other than release management, most project maintenance is done through contributions,
+rather than through work carried out by a dedicated team. Committers
+help contributors carry this out through processes such as issue discussions
+and code review. Committers generally do not even commit their own work directly;
+instead, they wait for another committer to review and merge their contributions.
+
+Understanding and respecting these roles is an important aspect of our
+code of conduct.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces
+when an individual is representing the project or its community. Examples of
+representing a project or community include using an official project e-mail
+address, posting via an official social media account, or acting as an appointed
+representative at an online or offline event. Representation of a project may be
+further defined and clarified by project committers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported by contacting the project team at admin@jgrapht.org. All
+complaints will be reviewed and investigated and will result in a response that
+is deemed necessary and appropriate to the circumstances. The project team is
+obligated to maintain confidentiality with regard to the reporter of an incident.
+Further details of specific enforcement policies may be posted separately.
+
+Project committers who do not follow or enforce the Code of Conduct in good
+faith may face temporary or permanent repercussions as determined by other
+members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
+available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see
+https://www.contributor-covenant.org/faq
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 00000000000..37ec37d6277
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,5 @@
+Thanks for your interest in improving JGraphT.:+1::tada:
+
+Before preparing your first pull request, please take a look at our
+[developer guidelines wiki](https://github.com/jgrapht/jgrapht/wiki#developer-pages) page, and in particular the [how to make your first contribution page](https://github.com/jgrapht/jgrapht/wiki/How-to-make-your-first-%28code%29-contribution). The probability that your PR gets accepted increases exponentially when your submission complies with these guidelines. Please do **not** submit PRs that are partially finished: each time you push new commits we get e-mail notifications. If you want feedback or have a dev question, please post an a message to [jgrapht-dev](https://groups.google.com/forum/#!forum/jgrapht-dev) containing a URL to your branch/repository.
+
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index ef10618e988..0ae33757d40 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -1,9 +1,15 @@
## Contributors ##
+Copyright Notice: The JGraphT project source code is a composite of contributions by multiple authors. The copyright for each contribution is owned by the corresponding author. For details, please see [HISTORY.md](HISTORY.md) as well as the complete git history. All authors have agreed to license their contributions to the public as open source under the specific terms noted in [README.md](README.md).
+
JGraphT wouldn't be the library it is today without the source contributions and suggestions made by the authors:
-- [Barak Naveh](http://sourceforge.net/users/barak_naveh/) (project founder)
-- [John V Sichi](http://sourceforge.net/users/perfecthash/) (current project administrator)
+- [Barak Naveh](https://github.com/baraknaveh) (project founder)
+- [John V Sichi](https://github.com/jsichi) (current project administrator)
+- [Joris Kinable](https://github.com/jkinable) (JGraphtT Project Reviewer/Committer and Release Manager)
+- [Dimitrios Michail](https://github.com/d-michail) (JGraphT Project Reviewer/Committer)
+- [Timofey Chudakov](https://github.com/Toptachamann) (JGraphT Project Reviewer/Committer)
+- [Semen Chudakov](https://github.com/SChudakov) (JGraphT Project Reviewer/Committer)
- [Liviu Rau](http://sourceforge.net/users/liviu_aurelian/)
- [Nathan Fiedler](http://www.bluemarsh.com/personal/index.html)
- [Michael Behrisch](http://sourceforge.net/users/behrisch/)
@@ -21,7 +27,6 @@ JGraphT wouldn't be the library it is today without the source contributions and
- Carl Anderson
- Khanh Vu
- Aaron Harnly
-- Dimitrios Michail
- Welson Sun
- Trevor Harmon
- David Black-Schaffer
@@ -41,15 +46,124 @@ JGraphT wouldn't be the library it is today without the source contributions and
- Tom Conerly
- Michele Mancioppi
- Adrian Marte
-- Assaf Mizrachi
+- [Assaf Mizrachi](https://github.com/assimiz)
- Harshal Vora
- Matt Sarjent
- Robby McKilliam
- Yuriy Nakonechnyy
+- Andreas Schnaiter
+- Owen Jacobson
- Alejandro R. Lopez del Huerto
+- Vladimir Kostyukov
+- Ernst de Ridder
+- Michal Pasieka
+- Alexey Kudinkin
+- Adam Gouge
+- Nikolay Ognyanov
+- Graham Hill (AzrgExplorers)
+- Leo Crawford
+- Isaac Kleinman
+- Sebastian Hubenschmid
+- JeanYves Tinevez
+- [Oliver Kopp](https://github.com/koppor)
+- Javier Gutierrez (javierj)
+- Nicolas Fortin
+- Peter Goldstein
+- Rodrigo López Dato
+- Anders Wallgren
+- Siarhei
+- Jan Altenbernd
+- Andrew Chen
+- Florian Buenzli
+- Thomas Tschager
+- Tomas Hruz
+- Philipp Hoppen
+- Chris Wensel
+- Wil Selwood
+- Mihhail Verhovtsov
+- Fabian Späh
+- Rita Dobler
+- [Szabolcs Besenyei](https://github.com/besza)
+- Luiz Kill
+- Christophe Thiebaud
+- Jon Robinson
+- Thomas Breitbart
+- Sarah Komla-Ebri
+- Graeme Ahokas
+- Christoph Zauner
+- [Andrew Gainer-Dewar](https://github.com/agdphd)
+- Benedikt Waldvogel
+- Victor Mikhaylov
+- Nils Olberg
+- [Daniel Gomez-Sanchez](https://github.com/magicDGS)
+- [Skuratovich Sergey](https://github.com/SSNikolaevich)
+- [Martin Sturm](https://github.com/WorstCase00)
+- [Patrick Sharp](https://github.com/sharpTrick)
+- [Piotr Turski](https://github.com/piotrturski)
+- [Alexandru Văleanu](https://github.com/AlexandruValeanu)
+- [Davide Cavestro](https://github.com/davidecavestro)
+- [Mark Raynsford](https://github.com/io7m)
+- [Mariusz Smykuła](https://github.com/mariuszs)
+- [Pratik Tibrewal](https://github.com/tibrewalpratik17)
+- [Chen Kui](https://github.com/Yimismi)
+- [Konstantinos Karatsenidis](https://github.com/gate2k1)
+- [Kirill Vishnyakov](https://github.com/LightnessOfBeing)
+- [Emilio Cruciani](https://github.com/ioemilio)
+- [Vivek Talreja](https://github.com/Vivek1012)
+- [Gilles Gosuin](https://github.com/gilles-gosuin)
+- [Viktor Volkov](https://github.com/chupacabra007)
+- [Philipp Kaesgen](https://github.com/PhilippKaesgen)
+- [Lukas Harzenetter](https://github.com/lharzenetter)
+- [Christoph Grüne](https://github.com/christophgruene)
+- [Daniel Mock](https://github.com/danielmock)
+- [Oliver Feith](https://github.com/Watercrystal)
+- [Abdallah Atouani](https://github.com/AbdallahAt)
+- [Peter Harman](https://github.com/harmanpa)
+- [Nikhil Sharma](https://github.com/nks1558)
+- [Dennis Fischer](https://github.com/pdelvo)
+- [PHaroZ](https://github.com/PHaroZ)
+- [simlu](https://github.com/simlu)
+- [Karri Sai Satish Kumar Reddy](https://github.com/ksskreddy)
+- [Stephan Schroevers](https://github.com/Stephan202)
+- [Ned Twigg](https://github.com/nedtwigg)
+- [Karri Sai Satish Kumar Reddy](https://github.com/ksskreddy)
+- [Lavish Kothari](https://github.com/LavishKothari)
+- [Andre Immig](https://github.com/Aimmig)
+- [Charul Bhanawat](https://github.com/CharulBhanawat13)
+- [Benjamin Krogh](https://github.com/bkrogh)
+- [Reynaldo Gil Pons](https://github.com/gilcu3)
+- [Sean Hudson](https://github.com/shduke)
+- [Edwin Ouwehand](https://github.com/EdwinOuwehand)
+- [Amr Alhossary](https://github.com/aalhossary)
+- [Volkov Viktor](https://github.com/bingo-soft)
+- [Hannes Wellmann](https://github.com/HannesWell)
+- [Shevek](https://github.com/shevek)
+- [Ritik Goyal](https://github.com/rtkg12)
+- [Johannes M Dieterich](https://github.com/iotamudelta)
+- [Milan Szoszkiewicz](https://github.com/szoszk)
+- [Baljit Singh](https://github.com/singhbaljit)
+- [Sebastiano Vigna](https://github.com/vigna)
+- [Florentin Dörre](https://github.com/FlorentinD)
+- [Rostislav Svoboda](https://github.com/rsvoboda)
+- [Dariusz Dudek](https://github.com/dpdudek)
+- [Kaiichiro Ota](https://github.com/kigh-ota)
+- [Magnus Gunnarsson](https://github.com/EnderCrypt)
+- [Frans van Buul](https://github.com/fransvanbuul)
+- [Sérgio Faria](https://github.com/sergio91pt)
+- [Rene Leonhardt](https://github.com/reneleonhardt)
+- [DelfinSR](https://github.com/DelfinSR)
+- [vab2048](https://github.com/vab2048)
+- [Sung Ho Yoon](https://github.com/syoon2)
+- [Albgarsan](https://github.com/Albgarsan)
+- [J. Alejandro Cornejo-Acosta](https://github.com/alex-cornejo)
+- [Feng Wenhan](https://github.com/fwhdzh)
+- [Yuri Bilyarov](https://github.com/YuriBilyarov)
+- [Antonia Tsiftsi](https://github.com/toniaTsif)
+- Lena Büttel
+- [Kirill A. Korinsky](https://github.com/catap)
-(if we have missed your name on this list, please email us to get it fixed).
+(If we have missed your name on this list, please email us to get it fixed.)
-Other people have also helped in different ways: reporting bugs,requesting features, commenting, and by merely asking very good questions.
+Other people have also helped in different ways: reporting bugs, requesting features, commenting, and by merely asking very good questions.
-Many thanks to all of you.
\ No newline at end of file
+Many thanks to all of you.
diff --git a/HISTORY.md b/HISTORY.md
index c1a6babff50..c985dea25ca 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -2,137 +2,637 @@
Changes to JGraphT in each version:
-- **version 0.8.4** (under development):
- - Move to github for source control, and Apache Maven for build, contributed by Andreas Schnaiter and Owen Jacobson.
- - Add source/target vertices to edge events to fix sf.net bug 3486775, spotted by Frank Mori Hess.
- - Add EdmondsBlossomShrinking algorithm, contributed by Alejandro R. Lopez del Huerto.
+- **version 1.5.3** (Under development)
+ - Updated dependencies (contributed by Joris Kinable and Dimitrios Michail)
+ - Fixed a bug in `DOTExporter` causing graph attributes not to be exported correctly. (contributed by vab2048)
+ - Fixed `DoublyLinkedList` for compatibility with Java 21 (reported by Liam Miller-Cushon, contributed by Sung Ho Yoon)
+ - Fixed a bug in `GmlExporter` to use system line separator consistently (contributed by Sung Ho Yoon)
+ - Migrated to JUnit 5 (contributed by Sung Ho Yoon)
+ - Javadoc, Maven, README, and CI maintenance (contributed by Sung Ho Yoon)
+ - Miscellaneous code maintenance (contributed by Sung Ho Yoon)
+ - Added missing license headers (contributed by Sung Ho Yoon)
+ - Added matrix build (Ubuntu, MacOS, Windows) to CI (contributed by Sung Ho Yoon)
+ - Tidied up logging in `VF2SubgraphIsomorphismState` (contributed by Albgarsan)
+ - Added `FarthestInsertionHeuristicTSP` algorithm (contributed by J. Alejandro Cornejo-Acosta)
+ - Prevent edge weight modification in `AsUnmodifiableGraph` and add tests (contributed by Sung Ho Yoon)
+ - Rename `SorensenIndexLinkPrediction` to remove non-ASCII characters (contributed by Feng Wenhan)
+ - Fixed backslashing interpretation in `DOTEventDrivenImporter` (contributed by Feng Wenhan)
+ - Fixed `SuurballeKDisjointShortestPaths` modified weight calculation (contributed by Yuri Bilyarov)
+ - Added `KouMarkowskyBermanAlgorithm` implementation of `SteinerTreeAlgorithm` (contributed by Lena Büttel and Dimitrios Michail)
+ - Added `GreedyModularityAlgorithm` and `NaiveGreedyModularityAlgorithm` (contributed by Antonia Tsiftsi and Dimitrios Michail)
+ - Improved performance of filtered `AsSubgraph` creation (contributed by Kirill A. Korinsky)
+- **version 1.5.2** (2-May-2023)
+ - Prepared release cycle 1.5.2: removed deprecated code, updated dependencies (contributed by Joris Kinable)
+ - Fixed NPE when no path exists in `DijkstraManyToManyShortestPaths` (contributed by Dimitrios Michail)
+ - Fixed NaN exception in case of a zero displacement in `FRLayoutAlgorithm2D` (contributed by Dimitrios Michail)
+ - Fixed Eclipse warnings in tests (contributed by Hannes Wellmann)
+ - Enforced naming conventions in checkstyle, allowing Latin chars (contributed by Hannes Wellmann)
+ - Bug fix for `TSPLIBImporter` which failed to parse burma14 due to multi-space delimiters (reported by Joris Kinable, contributed by Hannes Wellmann)
+ - Fixed succinct graph constructors in outgoing-only case (contributed by Sebastiano Vigna)
+ - Added support for custom names in vertices/edges collections in JSON I/O (contributed by Dimitrios Michail)
+ - Fixed assertion message in succinct graphs (contributed by Rostislav Svoboda)
+ - Made result ordering predictable in some algorithms (contributed by Dimitrios Michail)
+ - Added user guide for WebGraph and Sux4J adapters (contributed by Sebastiano Vigna)
+ - Github Actions maintenance (contributed by Szabolcs Besenyei)
+ - Added graph specifics strategy parameter for `DirectedAcyclicGraph` (contributed by Dariusz Dudek)
+ - Added explicit `NotDirectedAcyclicGraphException` (contributed by Kaiichiro Ota)
+ - Added explicit `GraphCycleProhibitedException` (contributed by Magnus Gunnarsson)
+ - Support custom vertex types in `DeltaSteppingShortestPath` (contributed by Semen Chudakov)
+ - Added path validation to `AllDirectedPaths` (contributed by Frans van Buul)
+ - Added `ApBetweennessCentrality` using new dependency on apfloat library (contributed by Dimitrios Michail)
+ - Added `UndirectedModularityMeasurer` (contributed by Dimitrios Michail)
+ - Added callback API to `DirectedSimpleCycles` interface (contributed by Sérgio Faria)
+ - Upgraded commons-text to 1.10.0 and antlr4-runtime to 4.10.1 (contributed by Rene Leonhardt)
+ - Centralized dependency version declarations (contributed by Rene Leonhardt)
+ - Updated all dependencies pre-release (contributed by Rene Leonhardt)
+ - Prevented XEE in `SimpleGEXFEventDrivenImporter` (contributed by DelfinSR)
+
+- **version 1.5.1** (18-Mar-2021)
+ - Prepared release cycle 1.5.1: removed deprecated code, updated dependencies (contributed by Joris Kinable)
+ - Fix non-determinism in `BaseKDisjointShortestPathsAlgorithm` (reported by andreamarotta, contributed by Assaf Mizrachi)
+ - Avoid package self-import in MANIFEST.MF (contributed by Hannes Wellmann)
+ - Fixes issue with reverse path weights in `DijkstraManyToManyShortestPath` (contributed by Semen Chudakov)
+ - Added `RescaleLayoutAlgorithm2D` - layout model rescaling algorithm (contributed by Dimitrios Michail)
+ - Bug fix by rewriting algorithmic part of `NaiveLCAFinder` (contributed by Timofey Chudakov)
+ - Added Boykov-Kolmogorov maximum flow algorithm for computer-vision related flow networks (contributed by Timofey Chudakov)
+ - Added `TransitNodeRoutingShortestPathAlgorithm` (contributed by Semen Chudakov)
+ - Added Zachary's karate club named graph (contributed by Dimitrios Michail)
+ - Simplified graph creation in tests (contributed by Timofey Chudakov)
+ - Add `RandomWalkVertexIterator`, replacing `RandomWalkIterator` (contributed by Dimitrios Michail)
+ - Fixed identically-positioned and isolated vertices in`FRLayoutAlgorithm2D` (reported by rlbns, contributed by Dimitrios Michail)
+ - Added Zhang-Shasha tree edit distance (contributed by Semen Chudakov)
+ - `GraphMetrics.naiveCountTriangles` now returns the correct number of triangles when multiple edges are present (reported by FlorentinD, contributed by Dimitrios Michail)
+ - Fixed JSON importer issue with negative integer weights (see #982) (reported by xianfuzheng, contributed by Dimitrios Michail)
+ - Enabled checkstyle for test files (contributed by Szabolcs Besenyei)
+ - Fixed hashCode/equals on weighted graphs (reported by Sebastiano Vigna, contributed by Dimitrios Michail)
+ - Changed hashCode/equals to ignore edge direction on undirected graphs, and made source/target assignment harmonious for EndpointPair in Guava adapter (reported by Sebastiano Vigna, contributed by Dimitrios Michail)
+ - Bring back importer support for supplying attributes at the point where vertex/edge instantiation occurs (reported by Sebastian Goeb, contributed by Dimitrios Michail)
+ - Added `GraphIterables` interface extension for big graph support (suggested by Sebastiano Vigna, contributed by Dimitrios Michail)
+ - Fixed label propagation clustering bug with isolated vertices (contributed by Dimitrios Michail)
+ - Added Bipartite layout drawing algorithm (contributed by Dimitrios Michail)
+ - Fixed addEdge in `AbstractGraphBuilder` (contributed by Baljit Singh)
+ - Added code of conduct (contributed by John Sichi)
+ - Added documentation for graph thread safety and updated graph equality (contributed by John Sichi)
+ - Enhanced and refactored AlphaCentrality to Katz- and Eigenvector-Centrality (contributed by Sebastiano Vigna)
+ - Added overflow strategy in `BetweennessCentrality` (contributed by Dimitrios Michail)
+ - Replaced `VertexDegreeComparator` and `GeneralVertexDegreeComparator` objects with lambda (contributed by Hannes Wellmann)
+ - Improved performance of the weighted `PageRank` algorithm by caching graph adjacency lists (contributed by Florentin Dörre)
+ - Optimized integer to vertex mappings in several algorithms (contributed by Hannes Wellmann)
+ - Added a collection of local algorithms for link prediction (contributed by Dimitrios Michail)
+ - Fixed some linty Integer comparisons (contributed by Dimitrios Michail)
+ - Added `ThreadPoolExecutor` parameter to all parallel algorithms (contributed by Semen Chudakov)
+ - Fixed bug in `DeltaSteppingShortestPath` (see #994) (reported by Andreas Hartung, contributed by Semen Chudakov)
+ - Added NETGEN-style problems generator (contributed by Timofey Chudakov)
+ - Added algorithm for minimum cycle mean (contributed by Semen Chudakov)
+ - Replace Travis CI with Github Actions (contributed by Szabolcs Besenyei)
+ - Added WebGraph adapter (contributed by Sebastiano Vigna with assistance from Dimitrios Michail)
+ - Added support for vertex provider with attributes in `JSONImporter` (contributed by Dimitrios Michail)
+ - Added edge betweenness centrality algorithm (contributed by Dimitrios Michail)
+ - Added Girvan-Newman community detection algorithm (contributed by Dimitrios Michail)
+ - Refactored sparse graphs to allow different backend implementations (contributed by Dimitrios Michail)
+ - Improved `SupplierUtil` and added tests (contributed by Hannes Wellmann)
+ - Added succinct graph implementations using sux4j (contributed by Sebastiano Vigna)
+ - Ensured predictable vertex order in `MaximumCardinalityIterator` (contributed by Dimitrios Michail)
+ - Used -noimport to simplify package self-import exclusion (contributed by Hannes Wellmann)
+ - Reduced intrusive edge map lookups and prevented invalid reuse (contributed by Hannes Wellmann)
+ - Moved exceptions to be public at top level (contributed by Hannes Wellmann)
+ - Improvements to Hamiltonian Cycle algorithms (contributed by Hannes Wellmann)
+ - Improvements to strong connectivity algorithms (contributed by Hannes Wellmann)
+
+- **version 1.5.0** (14-Jun-2020)
+ - Prepared release cycle 1.4.1: removed deprecated code, updated dependencies, upgraded java to version 11 (contributed by Joris Kinable)
+ - Bring back vertex factory in importers (contributed by Dimitrios Michail)
+ - Added `LabelPropagationClustering` algorithm (contributed by Dimitrios Michail)
+ - Make sure `addVertex()` fires listener event (spotted by akirschbaum, contributed by Dimitrios Michail)
+ - Change queue implementation from LinkedList to ArrayDeque (spotted by shevek, contributed by Ritik Goyal)
+ - Added TSPLIB95 graph and tour importer (contributed by Hannes Wellmann)
+ - Fixed issue with inconsistent graph after duplicate edge addition (spotted by Greg Gibeling, contributed by Dimitrios Michail)
+ - Fixed issue with failing `DirectedScaleFreeGraphGenerator` by fixing the tests seed (contributed by Timofey Chudakov)
+ - Fixed corner case issue with `BoyerMyrvoldPlanarityInspector` (spotted by Malcolm Deck, contributed by Timofey Chudakov)
+ - Added tree dynamic connectivity using the Euler tour data structure (contributed by Timofey Chudakov)
+ - `GmlExporter` support for custom attributes (contributed by Dimitrios Michail)
+ - Invoking `addVertex()` on an `AsUnmodifiableGraph` now throws an `UnsupportedOperationException` (contributed by Dimitrios Michail)
+ - Added `PathValidator` functionality to `YenKShortestPath` (contributed by Semen Chudakov)
+ - Optimize debugging in VF2 (contributed by Johannes M Dieterich)
+ - Fix calculation of matching weight in `MaximumWeightBipartiteMatching` (contributed by Dimitrios Michail)
+ - Add GEXF import/export (contributed by Dimitrios Michail)
+ - Change cache array entries from Boolean to byte in `GraphOrdering` (contributed by Johannes M Dieterich)
+ - Cache edge references in `GraphOrdering` (contributed by Johannes M Dieterich)
+ - Fix to make JSON import/export symmetric (contributed by Dimitrios Michail)
+ - Added support for exporting identifiers in DotExporter (contributed by Milan Szoszkiewicz)
+ - Fixed cycle order in `HawickJamesSimpleCycles` (contributed by Dimitrios Michail)
+ - Fixed unreported edge attributes in `SimpleGraphMLImporter` (contributed by Dimitrios Michail)
+ - Optimized `isFeasiblePair` and finalized fields (contributed by Johannes M Dieterich)
+ - Unified TSP algorithms internal implementation (contributed by Hannes Wellmann)
+ - Deprecated `KShortestSimplePaths` due to bug reported in #892 (contributed by Semen Chudakov)
+ - Clean up some docs and tests (contributed by Oliver Kopp)
+ - Add .editorconfig (contributed by Oliver Kopp)
+ - Change assert to mandatory enforcement in `AsWeightedGraph` (contributed by Dimitrios Michail)
+ - Streamline constructors in `VertexToIntegerMapping` (contributed by Hannes Wellmann)
+ - Add explicit module definitions (contributed by Dimitrios Michail)
+ - Enforce warnings (contributed by John Sichi after nudge from Oliver Kopp)
+ - Prevent tabs in XML files (contributed by John Sichi)
+
+- **version 1.4.0** (21-Feb-2020):
+ - Prepared release cycle 1.3.2: removed deprecated code, updated dependencies, etc (contributed by Joris Kinable)
+ - Format code in parallel (contributed by Joris Kinable)
+ - Fix edge reuse bug in KDisjointShortestPaths implementations (contributed by Benjamin Krogh)
+ - Updated Yen's algorithm to operate on pseudo graphs correctly (contributed by Semen Chudakov)
+ - Updated Guava to version 28.0 (contributed by John Sichi)
+ - Fixed bug in `BiconnectivityInspector` which would occasionally return an incorrect set of biconnected components (contributed by Reynaldo Gil Pons)
+ - Allow edge selection to be overridden in `CrossComponentIterator` (contributed by Sean Hudson)
+ - Reuse traversal listener implementation in tests (contributed by Timofey Chudakov)
+ - Fixed bug in `BetweennessCentrality` which occasionally returned in incorrect centrality score for vertices in weighted graphs (contributed by Gil Pons)
+ - Added path length limit to `HawickJamesSimpleCycles` (contributed by Edwin Ouwehand)
+ - Added links in Guava adapater package-info (contributed by John Sichi)
+ - Added Boyer-Myrvold planarity testing algorithm (contributed by Timofey Chudakov)
+ - Added contraction hierarchy precomputation algorithm (contributed by Semen Chudakov)
+ - Enhanced `IntegerComponentNameProvider` to take arbitrary base (contributed by Amr Alhossary)
+ - Fixed a bug in the `GraphWalk.equals()` method which caused a NullpointerException when invoked on an empty walk (contributed by Volkov Viktor)
+ - Added k-spanning-tree clustering algorithm (contributed by Dimitrios Michail)
+ - Added directed scale-free graph generator (contributed by Amr Alhossary)
+ - Enhanced `CompleteGraphGenerator` and `CompleteBipartiteGraphGenerator` to generate edges between existing vertices (contributed by Joris Kinable)
+ - Added efficient bidirectional Dijkstra implementation based on contraction hierarchy (contributed by Semen Chudakov)
+ - Added sparse graphs and event-based importers, and improved numerous algorithms (contributed by Dimitrios Michail)
+ - Added `CollectionUtil` for preallocating maps and sets correctly (contributed by Hannes Wellmann)
+ - Added efficient many-to-many shortest path algorithm based on contraction hierarchy (contributed by Semen Chudakov)
+ - Added greedy, nearest-insertion, nearest-neighbor heuristic for TSP and improved stability in two-opt heuristic (contributed by Peter Harman)
+ - Enhanced `DoublyLinkedList` by implementing the `List` and `Deque` interfaces (contributed by Hannes Wellmann)
+ - Added dedicated class for `ContractionHierarchy` (contributed by Semen Chudakov)
+ - Use try with resources in default implementations of GraphImporter and GraphExporter (contributed by Hannes Wellmann)
+ - Fixed naive lca bug and code cleanup (reported by Shinpei Hayashi, contributed by Timofey Chudakov)
+ - Enhanced Javadoc generation by adding compatibility with newer JDKs (contributed by Dimitrios Michail)
+ - Reflection speedup (suggested by shevek, contributed by Dimitrios Michail)
+ - Added a graph drawing component, including various layout algorithms incl., random, circular, and tree layouts, the Fruchterman and Reingold Force-Directed Placement algorithm, and a variation of the latter augmented with the Barnes-Hut indexing technique (contributed by Dimitrios Michail)
+
+- **version 1.3.1** (3-Jun-2019):
+ - Prepared release cycle 1.3.1: removed deprecated code, updated dependencies, etc (contributed by Joris Kinable)
+ - Added new logo (from 99designs, with site additions by John Sichi and Joris Kinable)
+ - Added new website (contributed by John Sichi)
+ - Converted all methods and fields to protected in `HierholzerEulerianCycle` (contributed by simlu)
+ - Optimized specifics hash lookups (contributed by Dimitrios Michail)
+ - Fixed mobile website menu (contributed by Karri Sai Satish Kumar Reddy)
+ - Upgraded Antlr version to 4.7.2 and jheaps to 0.10 (contributed by Dimitrios Michail)
+ - Replaced URL with URI in HelloJGraphT example (contributed by Stephan Schroevers)
+ - Deprecated `FibonacciHeap` (contributed by Timofey Chudakov)
+ - Replaced usage of `Graph.{vertex,edge}Set().contains()` by `Graph.contains{Vertex,Edge}()` (contributed by Ned Twigg)
+ - Updated examples with Guava adapter example (contributed by John Sichi)
+ - Added Warnsdorff rule heuristic and Parberry's algorithm for closed knight's tour problem to demo package (contributed by Kirill Vishnyakov)
+ - Added min weight, max weight and max weight perfect matching algorithms (contributed by Timofey Chudakov)
+ - Fixed bug where DOTImporter throws NullPointerException when trying to parse a vertex without attributes (contributed by Dimitrios Michail)
+ - Added BFS as a shortest path algorithm (contributed by Karri Sai Satish Kumar Reddy)
+ - Added concurrent implementation of the delta-stepping shortest path algorithm (contributed by Semen Chudakov)
+ - Added support for the capacitated minimum spanning tree (CMST) problem (contributed by Christoph Grüne)
+ - Made `GraphMLImporter` ordering deterministic (contributed by Dimitrios Michail)
+ - Added bidirectional A-star (contributed by Semen Chudakov)
+ - Added Yen's k shortest loopless paths algorithm (contributed by Semen Chudakov)
+ - Defer graph vertex iterator initialization in CrossComponentIterator (contributed by John Sichi)
+ - Updated jgraphx version to 3.9.8.1 (contributed by John Sichi)
+ - Added JSON exporter and importer (contributed by Dimitrios Michail)
+ - Enhanced `DirectedAcyclicGraph` to support multiple edges (contributed by Dimitrios Michail based on a suggestion by Sarat Chandra Balla)
+ - Refactored `SerializationTestUtils` and made it generic (contributed by Lavish Kothari)
+ - Added more serialization test coverage (contributed by Lavish Kothari)
+ - Added Goldberg's algorithms for the calculation of maximum density subgraphs (contributed by Andre Immig)
+ - Optimize UnmodifiableUnionSet to lazily read live sizes from underlying sets (contributed by John Sichi)
+ - Added Eppsteins k-shortest paths algorithm (contributed by Semen Chudakov)
+ - Added serialization test for `AsGraphUnion` and made `WeightCombiner` default implementations serializable (contributed by Charul Bhanawat)
+
+- **version 1.3.0** (12-Nov-2018):
+ - Prepared release cycle 1.2.1: removed deprecated code, updated dependencies, etc (contributed by Joris Kinable)
+ - Restored optional tests for `BergeGraphInspector` (contributed by Philipp Kaesgen)
+ - Use POSIX tar format for assembly (contributed by Mark Raynsford)
+ - Moved BrownBacktrackingColoring out of experimental, fixed bugs and wrote tests (contributed by Joris Kinable)
+ - Removed code not dual licensed under EPL-1.0 and LGPL-2.1-or-later: `AsUnweightedGraph` and `AsWeightedGraph` are gone. (supported by Robert Höttger and Oliver Kopp)
+ - Added forest generator based on the Barabasi-Albert model (contributed by Alexandru Văleanu)
+ - Added new implementation of `AsUnweightedGraph` and `AsWeightedGraph` (contributed by Lukas Harzenetter)
+ - Added pull request template (contributed by Oliver Kopp)
+ - Added `GraphSpecificsStrategy` and use the same edge set factory consistently (contributed by Dimitrios Michail)
+ - Added user overview doc (contributed by John Sichi)
+ - Clarified definition of `SimpleGraph` (contributed by Joris Kinable)
+ - Added O(m^1.5) algorithm for counting triangles in undirected graphs (contributed by Alexandru Văleanu)
+ - Calculate actual path weight in `AllDirectedPaths` (contributed by Andrew Gainer-Dewar)
+ - Refactored vertex cover tests (contributed by Alexandru Văleanu)
+ - Added `SimpleGraphMLImporter` for faster parsing (contributed by Dimitrios Michail)
+ - Increased numeric precision in PushRelabelMFImpl (contributed by Alexandru Văleanu)
+ - Added ColorRefinement and ColorRefinementIsomorphismInspector (contributed by Christoph Grüne, Daniel Mock, Oliver Feith and Abdallah Atouani)
+ - Improved efficiency of `BhandariKDisjointShortestPaths` (contributed by Assaf Mizrachi)
+ - Added `UnmodifiableUnionSet` to optimize `AsGraphUnion` (contributed by Dimitrios Michail)
+ - Made `GraphWalk` serializable (contributed by Alexandru Văleanu)
+ - Optimize `JohnsonShortestPaths` space usage (contributed by Dimitrios Michail)
+ - Heuristics for `FloydWarshallShortestPaths` (suggested by shevek, contributed by Dimitrios Michail)
+ - Added new `TreeToPathDecompositionAlgorithm` interface and implementation `HeavyPathDecomposition` (contributed by Alexandru Văleanu)
+ - Removed recursion from `FibonacciHeap` (contributed by Timofey Chudakov)
+ - Added `PruferTreeGenerator` for generating trees based on Prüfer sequences (contributed by Alexandru Văleanu)
+ - Added `VertexToIntegerMapping` utility class (contributed by Alexandru Văleanu)
+ - Handle maxLength=0 case in AllDirectedPaths (reported by Nikolas Havrikov, contributed by Andrew Gainer-Dewar)
+ - Added `SuurballeKDisjointShortestPaths` (contributed by Assaf Mizrachi)
+ - Make AsWeightedGraph propagate weight changes by default when backing graph is weighted (contributed by John Sichi)
+ - Fix assumptions about SAX `characters()` method calls in GraphML importers (contributed by Dimitrios Michail)
+ - Throw exception from no-arg `addVertex` when duplicate vertex generated (contributed by Dimitrios Michail)
+ - Replace `GenericFibonacciHeap` with dependency on jheaps library (contributed by Dimitrios Michail)
+ - Added `DulmageMendelsohnDecomposition` (contributed by Peter Harman)
+ - Package one bundle jar instead of multiple uber jars (contributed by Dimitrios Michail)
+ - Removed touchgraph support and corresponding module jgrapht-touchgraph (contributed by John Sichi)
+ - Added `ClusteringCoefficient` to compute the local and global clustering coefficient of a graph (contributed by Alexandru Văleanu)
+ - Refactored LCA interface, reimplemented Tarjan's algorithm and added HeavyPathLCAFinder, BinaryLiftingLCAFinder, EulerTourRMQLCAFinder (contributed by Alexandru Văleanu)
+ - Added jgrapht-opt module with fastutil graph implementation (contributed by Dimitrios Michail)
+ - Added negative weight cycle reporting in Bellman-Ford (contributed by Dimitrios Michail in response to proposal from Miron Balcerzak)
+ - Added `KolmogorovMinimumWeightPerfectMatching` (contributed by Timofey Chudakov)
+ - Added graph implementation specific for integer vertices and fastutil map to jgrapht-opt module (contributed by Dimitrios Michail)
+ - Added Christofides algorithm for computing 3/2 approximate TSP solutions (contributed by Timofey Chudakov)
+ - Fixed bug in HeldKarpTSP (reported by Timofey Chudako, contributed by Alexandru Văleanu)
+ - Addded `PartitioningAlgorithm` interface and `BipartitePartitioning` implementation for recognizing bipartite graphs (contributed by Alexandru Văleanu)
+ - Fixed bug in `GraphTests.isStronglyConnected`: undirected graphs are now correctly identified as strongly connected whenever the graph is connected (reported by Joris Kinable, contributed by Dimitrios Michail)
+ - Upgraded EPL to v2.0, copyright header cleanup, removed @since tag (contributed by John Sichi)
+ - Use checkstyle to enforce correct file headers (contributed by John Sichi)
+ - Added `ChinesePostman` (contributed by Joris Kinable)
+ - Added `LineGraphConverter` (contributed by Joris Kinable and Nikhil Sharma)
+ - Refactoring for color refinement (contributed by Dimitrios Michail)
+ - Added implementation for minimum cost flow problems through the Successive Shortest Path algorithm with capacity scaling (contributed by Timofey Chudakov)
+ - Updated library dependencies (contributed by Joris Kinable)
+ - Added exporter for the Lemon (LGF) format (contributed by Dimitrios Michail)
+ - Added support for using an edge function in AsWeightedGraph (contributed by Joris Kinable)
+ - Fixed bug in ColorRefinementIsomorphismInspector which required a disjoint graph union (contributed by Christoph Grüne and Dennis Fischer)
+ - Bug fix in the Watts-Strogatz generator which caused a null pointer exception when the graph vertices were any type except integers (contributed by Dimitrios Michail)
+ - Added support for edge weights in CSV export/import (contributed by Dimitrios Michail)
+ - Added support for html attributes and labels in DOTExporter (contributed by PHaroZ)
+ - Unified flow interfaces (contributed by Joris Kinable)
+ - Optimizations for Edmonds maximum cardinality matchings (contributed by Dimitrios Michail)
+
+- **version 1.2.0** (16-May-2018):
+ - Prepared release cycle 1.1.1: removed deprecated code, updated dependencies, etc (contributed by Joris Kinable)
+ - Updated demos (contributed by Dimitrios Michail)
+ - Added assertions to NeighborCache (contributed by Joris Kinable)
+ - Upgraded Antlr version to 4.7 (contributed by Dimitrios Michail)
+ - Rewrote `MaximumWeightBipartiteMatching` with exact arithmetic, introducing a `GenericFibonacciHeap` (contributed by Dimitrios Michail)
+ - Updated jmh to jdk9 compatible version; updated xmlunit to 2.x (contributed by Dimitrios Michail)
+ - Fixed FastLookup specifics to init edge container capacity to 1 (suggested by shevek, contributed by Joris Kinable)
+ - Made `IntrusiveEdgesSpecifics` interface public and optimized add call sequence (suggested by shevek, contributed by Dimitrios Michail)
+ - Fixed deprecation of Class.newInstance for Java 9; cleaned up GraphTests (contributed by Dimitrios Michail)
+ - Fixed PathValidator interface to use GraphPath (contributed by Assaf Mizrachi)
+ - Added Held-Karp dynamic programming algorithm for TSP (contributed by Alexandru Văleanu)
+ - Added fundamental cycle basis implementations (contributed by Dimitrios Michail)
+ - Added `BetweennessCentrality` scoring algorithm (contributed by Assaf Mizrachi)
+ - Automatically publish snapshots after successful Travis CI builds (contributed by Davide Cavestro)
+ - Implemented method findLcas() in NaiveLcaFinder (contributed by Alexandru Văleanu)
+ - Added `MultiObjectiveShortestPathAlgorithm` interface and first implementation `MartinShortestPath` (contributed by Dimitrios Michail)
+ - Added `TwoOptHeuristicTSP` (contributed by Dimitrios Michail)
+ - Fixed bug in `JohnsonSimpleCycles` with custom edge type (spotted by fredshevek, fix contributed by Dimitrios Michail)
+ - Added Automatic-Module Names to the various jgrapht modules to support modularization in JDK 9 (contributed by Mark Raynsford)
+ - Added `GraphTypeBuilder` (contributed by Dimitrios Michail)
+ - Reimplemented BiconnectivityInspector with additional functionality such as computing bridges and articulation points. BiconnectivityInspector now works on multiple graph types (contributed by Joris Kinable)
+ - Revised BlockCutpointGraph and added additional tests (contributed by Joris Kinable)
+ - Removed old JUnit 3 dependencies (contributed by Joris Kinable)
+ - Fixed bug with maxPathLength equal to 1 in AllDirectedPaths (contributed by Andrew Gainer-Dewar)
+ - Allow digits as non-leading character in DOTUtils#isValidID (contributed by Mariusz Smykuła)
+ - Escape quotes in identifiers in `DOTExporter` (contributed by Mariusz Smykuła)
+ - Added `AlphaCentrality` (contributed by Pratik Tibrewal)
+ - Fixed bug in AbstractBaseGraph where degreeOf() method would create vertex instead of throwing an exception (spotted and fixed by Chen Kui)
+ - Added Folkman, Diamond, Tietze, Pappus and Tutte named graphs (contributed by Pratik Tibrewal)
+ - Added automorphism count verification to NamedGraphGeneratorTest (contributed by Pratik Tibrewal)
+ - Removed old JGraph dependency, updated JGraphX to version 3.4.1.3, minor revision of `JGraphXAdapterDemo` (contributed by John Sichi)
+ - Added `ChordalityInspector`, `LexBreadthFirstIterator`, and `MaximumCardinalityIterator` (contributed by Timofey Chudakov)
+ - Removed redundant parameter from `TypeUtil.uncheckedCast` method (contributed by Konstantinos Karatsenidis)
+ - Removed recursion from `NaiveLcaFinder.findLca` method (contributed by Konstantinos Karatsenidis)
+ - Added `AsSynchronizedGraph` in new package `org.jgrapht.graph.concurrent` (contributed by Chen Kui)
+ - Fixed bug with `ClosestFirstIterator` when given multiple start vertices (repro by shevek, fixed by John Sichi)
+ - Added method `GraphMeasurer.getGraphPseudoPeriphery` to compute the Pseudo-Periphery of a graph (contributed by Alexandru Văleanu)
+ - Added `PalmerHamiltonianCycle` which implements Palmer's exact algorithm to find Hamiltonian Cycles in undirected graphs. Added new interface `HamiltonianCycleAlgorithm`. (contributed by Alexandru Văleanu)
+ - Removed lazy instantiation of containers in edge specifics (contributed by Dimitrios Michail)
+ - Added `DinicMFImpl` which implements Dinic's maximum flow algorithm (contributed by Kirill Vishnyakov)
+ - Optimized `PushRelabelMFImpl` implementation which drastically improves max flow computations on certain graphs. (contributed by Alexandru Văleanu)
+ - Added `RandomRegularGraphGenerator` (contributed by Emilio Cruciani)
+ - Reimplemented significantly faster version of Prim's minimum spanning tree algorithm using a FibonacciHeap (suggested by Joris Kinable, contributed by Alexandru Văleanu)
+ - Added new jgrapht-guava module containing adapters for package com.google.common.graph (contributed by Dimitrios Michail)
+ - Demo classes listed on our wiki page are now also included in our demo package (contributed by Vivek Talreja)
+ - Added missing math markup to javadoc in all classes (contributed by Kirill Vishnyakov)
+ - Expose lock as public for `AsSynchronizedGraph`, and add copyless access mode (contributed by John Sichi)
+ - Handle nested structures in `GmlImporter` (suggested by Philippe Marchesseault, contributed by Dimitrios Michail)
+ - Replaced StringBuffer with StringBuilder (contributed by John Sichi)
+ - Added search tree query methods to `BreadthFirstIterator` (contributed by Joris Kinable)
+ - Improved documentation of VF2 subgraph isomorphism algorithm (contributed by John Sichi)
+ - Removed recursion from DAG forward and backwards DFS methods (contributed by Gilles Gosuin)
+ - Implemented performance improvements for `GnmRandomGraphGenerator` and `GnpRandomGraphGenerator` (suggested by @Shevek, contributed by Dimitrios Michail)
+ - Added `WeakChordalityInspector` to test whether a graph is weakly chordal (contributed by Timofey Chudakov)
+ - Fixed typo in `TreeSingleSourcePathsImpl` (contributed by Viktor Volkov)
+ - Deprecated `EdgeFactory` in favor of `Supplier`, and added supplier support for vertices as well (contributed by Dimitrios Michail)
+ - Separate fast and slow tests, via mvn test vs verify (contributed by Dimitrios Michail)
+ - Added `ChordalGraphMinimalVertexSeparatorFinder` for the detection of minimal vertex separators in chordal graphs (contributed by Timofey Chudakov)
+ - Added suites for fast tests, integration tests and performance tests (contributed by John Sichi)
+ - Refactored `ChordalityInspector` and revised several interfaces (vertex cover, independent set, clique, etc) (contributed by Joris Kinable)
+ - Minor improvements to `DOTExporter` (contributed by Dimitrios Michail)
+ - Added graph listener event for edge weight update (contributed by Dimitrios Michail)
+ - Added Planted Partition Graph Generator `PlantedPartitionGraphGenerator` (contributed by Emilio Cruciani)
+ - Added `BergeGraphInspector` which checks whether a graph is perfect (contributed by Philipp Kaesgen)
+ - Added Bhandari K-disjoint shortest paths implementation `BhandariKDisjointShortestPaths` (contributed by Assaf Mizrachi)
+
+- **version 1.1.0** (13-Nov-2017):
+ - Added ID descriptor to maven-assembly-plugin configuration to prevent a 'Assembly is incorrectly configured' error being thrown (contributed by Joris Kinable)
+ - Deleted all previously deprecated methods and general cleanup (contributed by Joris Kinable)
+ - Moved all importers/exporters from org.jgrapht.ext to org.jgrapht.io. This change allows users to use importers/exporters without the dependency on the various visualization libraries. (contributed by Dimitrios Michail)
+ - Added vertex coloring interface `VertexColoringAlgorithm`, as well as several greedy graph coloring algorithms (`LargestDegreeFirstColoring`, `RandomGreedyColoring`, `SaturationDegreeColoring`, `SmallestDegreeLastColoring`). The former `ChromaticNumber` class is now deprecated, as well as some related classes in the experimental package. (contributed by Dimitrios Michail)
+ - Extended the network analysis algorithms by adding closeness centrality computation (contributed by Dimitrios Michail)
+ - Added interface `StrongConnectivityAlgorithm`; Extracted common code of strong connectivity inspectors to abstract base class; added method which computes the graph condensation. (contributed by Dimitrios Michail)
+ - Added interface `TSPAlgorithm`, Added 2-approximation algorithm for metric TSP `TwoApproxMetricTSP`. The old implementation `HamiltonianCycle` is now deprecated due to its reduced efficiency. (contributed by Dimitrios Michail)
+ - Added a new, scalable `DOTImporter` which handles the full DOT specification including XML string identifiers. A dependency on the commons-lang3 package has been added to handle escaping/unescaping of strings efficiently; Updated antlr version to 4.6. (contributed by Dimitrios Michail)
+ - Added Johnson's all-pairs-shortest paths algorithm `JohnsonShortestPaths`; Simplified Bellman-Ford implementation and added support for negative cycle detection; added `AsWeightedUndirectedGraph` and `AsUnweightedUndirectedGraph`; Constructors of `UndirectedGraphUnion` are now public. (contributed by Dimitrios Michail)
+ - Refactored `DirectedAcyclicGraph`, moved it out of the experimental package, and refactored its perfomance tests using jmh; Deleted `GraphSquare` from experimental (inefficient implementation) (contributed by Dimitrios Michail)
+ - Added Watts-Strogatz small-world graph generator, Kleinberg's small-world graph generator, Barabasi-Albert graph generator, Linearized Chord Diagram GraphGenerator, AliasMethodSampler utility class with Vose's implementation; Refactored ScaleFreeGraphGenerator (constructor with random number generator added); Refactored CompleteGraphGenerator to not assume a specific graph type (simple, etc). (contributed by Dimitrios Michail)
+ - Deleted JUnit test suites. (contributed by Joris Kinable)
+ - Added interface `MaximalCliqueEnumerationAlgorithm`; Refactored and added timeout in BronKerbosch clique enumeration; Added pivot variant of Bron-Kerbosch; Added Bron-Kerbosch variant with pivoting and degeneracy ordering; Added Coreness vertex scorer; Added Degeneracy graph iterator; Added performance test for maximal clique enumeration algorithms (contributed by Dimitrios Michail)
+ - Deprecated `DirectedGraph`, `UndirectedGraph`, and `WeightedGraph`, moving their methods up to the base `Graph` interface; added `GraphType` metadata; made usage of DefaultWeightedEdge optional for weighted graphs (contributed by Dimitrios Michail)
+ - Refactored traversal iterators (contributed by Dimitrios Michail)
+ - Backport to support build using Android SDK 24 (contributed by Dimitrios Michail)
+ - Added support for attributes in GmlImporter; extracted common code from importers and exporters into abstract base classes to avoid code duplication. (contributed by Dimitrios Michail)
+ - Fixed issue where HierholzerEulerianCycle would sometimes set the wrong startVertex (reported by Frank Gevaerts, contributed by Dimitrios Michail)
+ - Revised `GraphWalk`; added additional input checks, additional functionality such as reverse and concat, added verification and factory methods. (contributed by Joris Kinable)
+ - Made several algorithm return objects iterable. (contributed by Joris Kinable)
+ - Support latex math notation in Javadoc (contributed by Joris Kinable)
+ - Allow CrossComponentIterator to start from a collection of startVertices (contributed by Patrick Sharp)
+ - New implementation of Edmonds' maximum cardinality matching algorithm for general graphs. Added certifier for maximum cardinality by computing a Edmonds-Gallai decomposition. Reimplemented Hopcroft-Karp's algorithm for bipartite graphs. Added greedy algorithm for maximum cardinality case and enhanced greedy algorithm for the weighted case. Extended UnionFind with additional functionality. (contributed by Joris Kinable)
+ - Optimize map operations in FastLookupSpecifics (suggested by shevek, fix contributed by Joris Kinable)
+ - Added importers and exporters for the graph6 (g6) and sparse6(s6) graph format (contributed by Joris Kinable)
+ - Added graph generator for Generalized Petersen graphs (contributed by Joris Kinable)
+ - Added graph generator for Windmill, Dutch Windmill and Friendship graphs (contributed by Joris Kinable)
+ - Added collection of 31 commonly used named graphs (contributed by Joris Kinable)
+ - Added GraphMeasurer class to compute graph diameter, radius, vertex eccentricity, graph center and graph periphery (contributed by Joris Kinable)
+ - Added GraphMetrics which computes general graph metrics; added method to compute the girth of a graph (contributed by Joris Kinable)
+ - Added GraphTests: isCubic, isOverfull, isForest, isSplit (contributed by Joris Kinable)
+ - Added basic support for graph attributes in DOTExporter (contributed by Dimitrios Michail)
+ - Added a generator which generates the complement graph of a given input graph (contributed by Joris Kinable)
+ - Performance improvement for Johnson's algorithm when a directed graph has no negative edge weights (contributed by Joris Kinable)
+ - Fix `BellmanFordShortestPath` to return null instead of empty path (contributed by Dimitrios Michail)
+ - Added type information in attributes for graph importers/exporters (contributed by Dimitrios Michail, per suggestion from Dimitrij Drus)
+ - Changed `UnionFind` from recursive to iterative (contributed by Piotr Turski)
+ - New `NeighborCache` replaces both `NeighborIndex` and `DirectedNeighborIndex`; this new class supports both directed and undirected graphs (contributed by Szabolcs Besenyei)
+ - Fixed bug in `PushRelabelMFImpl`: passing an object as parameter to `calculateMaxFlow` which is equal but not identical to the corresponding node in the graph would cause a Nullpointer exception.
+
+- **version 1.0.1** (16-Jan-2017):
+ - Deleted all previously deprecated methods (cleanup contributed by Joris Kinable and Dimitrios Michail)
+ - Cleanup of main pom.xml; Added `CONTRIBUTING.md` (contributed by John Sichi)
+ - Added Checkstyle plugin and rules; they are automatically executed by Travis (contributed by Dimitrios Michail)
+ - Unified graph export name providers using a common interface (contributed by Dimitrios Michail)
+ - Fix `GnmRandomGraphGenerator` bug in computation of maximum number of edges (contributed by Dimitrios Michail)
+ - Added new demo class `GraphMLDemo` to demonstrate importing and exporting graphs in the GraphML format (contributed by Dimitrios Michail)
+ - Added project badges (contributed by Daniel Gómez-Sánchez)
+ - Hide autogenerated classes of antlr (contributed by Dimitrios Michail)
+ - DOT-language import/export changes (contributed by Daniel Gómez-Sánchez)
+ - Clean up tests and warnings (contributed by Dimitrios Michail)
+ - Fixed GraphML importer xsd resolution bug (contributed by Dimitrios Michail, spotted by Peter Manning Jr.)
+ - Replaced VertexPair/UnorderedVertexPair with Pair/UnorderedPair (contributed by Dimitrios Michail)
+ - Clean up AbstractBaseGraph/Specifics dependencies (contributed by Dimitrios Michail)
+ - `GraphTests` has been reworked, extended with additional functionality, and moved from experimental to the core package (contributed by Dimitrios Michail and Barak Naveh)
+ - a `IntegerVertexFactory` has been added to the test package to reduce code duplication (contributed by Dimitrios Michail)
+ - 2 new 1/2-approximation algorithms (greedy algorithm and Drake and Hougardy path growing algorithm) have been added; matching algorithms have been moved to dedicated package (contributed by Dimitrios Michail)
+ - Added `HierholzerEulerianCycle`, a Linear time implementation of Hierholzer's algorithm to find a Eulerian Circuit in the graph. This class replaces the old `EulerianCircuit` implementation since it is significantly faster. (contributed by Dimitrios Michail)
+ - Added methods for adding/deletion of specified edge in graph builders (contributed by Skuratovich Sergey)
+ - Fixed a NullPointerException caused by `GraphMLImport` when an attributed was associated with the graph itself (i.e. at the level); this could occur for instance with yED graphml instances. (reported by Tim Schultze, contributed by Dimitrios Michail)
+ - Minor updates and fixes to demo (contributed by Dimitrios Michail)
+ - Removed underscore identifiers and refactored tests in `KuhnMunkresMinimalWeightBipartitePerfectMatchingTest`. (contributed by Szabolcs Besenyei)
+ - All matching algorithms are now unified under a new `MatchingAlgorithm` interface; the old `WeightedMatchingAlgorithm` interface is now deprecated. (contributed by Dimitrios Michail)
+ - Added Borůvka's algorithm for the computation of a minimum spanning tree (contributed by Dimitrios Michail)
+ - Revised spanning tree and spanner interfaces and bundled them under the alg.spanning package (contributed by Dimitrios Michail)
+ - Small improvements in `StopWatch` class (contributed by Dimitrios Michail)
+ - Revised `Subgraph`, `MaskSubgraph` and subclasses to use Java 8 features; incorporated a number of performance improvements. Revised `MaskSubgraph` uses Java 8 predicates instead of the `MaskFunctor` interface. The latter interface is now deprecated. (contributed by Dimitrios Michail)
+ - Added `GusfieldGomoryHuCutTree`, `GusfieldEquivalentFlowTree`, and `PadbergRaoOddMinimumCutset` (contributed by Joris Kinable, following up on a Gomory-Hu proposal from Mads Jensen)
+ - Added support for inconsistent admissible heuristics in A* search (contributed by Joris Kinable)
+ - Added a `DIMACSExporter` which supports exporting graphs in various DIMACS formats (contributed by Dimitrios Michail)
+ - Enforce valid nodes in `FibonacciHeap`; Fixed a bug which could cause an infinite loop in the Fibonacci heap consolidate() method. (contributed by Dimitrios Michail)
+ - Revision of shortest path algorithms. Added interfaces `ShortestPathAlgorithm` and `KShortestPathAlgorithm`, and bundled shortest path algorithms in dedicated package. Adjusted KShortestPaths returns an empty list instead of null if no path exists. (contributed by Dimitrios Michail)
+ - `FlowdWarshall` now has support for multigraphs. Fixed diameter method now returns POSITIVE_INFINITY when a graph is disconnected. (contributed by Dimitrios Michail)
+ - `GraphPath` supports zero edge paths (path consisting of 1 vertex). (contributed by Dimitrios Michail)
+ - `DijkstraShortestPath` as well as several other shortest path classes can now return single-source shortest paths, using the traditional representation of a shortest path tree (contributed by Dimitrios Michail)
+ - Added an implementation of Goldberg and Harrelson's ALT admissible heuristic for A* (contributed by Dimitrios Michail)
+ - Replaced the `ClosestFirstIterator` in `DijkstraShortestPath` by a light-weight version of the iterator which significantly speeds up the shortest path computations. (contributed by Dimitrios Michail)
+ - Added implementation of Larry Page's `PageRank` algorithm. (contributed by Dimitrios Michail)
+ - Added faster transitive closure calculation for DAGs. (contributed by Martin Sturm)
+ - K-shortest paths interface now accepts k as a parameter (contributed by Dimitrios Michail)
+
+- **version 1.0.0** (19-Sept-2016):
+ - Moved to JDK 1.8 (cleanup contributed by Joris Kinable)
+ - Fixes for `MaskSubgraph`, contributed by Andrew Gainer-Dewar
+ - Optimized edge lookups (contributed by Joris Kinable)
+ - Use LinkedHashSet in `CycleDetector` (contributed by Benedikt Waldvogel)
+ - Use unique OSGi bundle symbolic name for uber artifact (contributed by Christoph Zauner)
+ - Replace experimental GraphReader with `DIMACSImporter` (contributed by Joris Kinable)
+ - Implement various graph utility methods (contributed by Christoph Zauner)
+ - Add getFirstHop and getLastHop to `FloydWarshallShortestPaths` (contributed by Joris Kinable)
+ - Allow paths to be expressed in terms of vertices instead of edges; deprecate `GraphPathImpl` in favor of new `GraphWalk` (contributed by Joris Kinable)
+ - Weighted graph support in `GmlExporter` (contributed by Dimitrios Michail)
+ - Add `RandomWalkIterator` (contributed by Assaf Mizrachi)
+ - Add `GreedyMultiplicativeSpanner` (contributed by Dimitrios Michail)
+ - Support undirected graphs in max flow algorithms (contributed by Joris Kinable)
+ - Fix for reading escaped quotes in `DOTImporter` (contributed by Victor Mikhaylov)
+ - Add `BidirectionalDijkstraShortestPath` (contributed by Dimitrios Michail)
+ - Add external path validator for `KShortestPaths` (contributed by Assaf Mizrachi)
+ - Add `GmlImporter` (contributed by Dimitrios Michail)
+ - Fixed bug in HopcroftKarpBipartiteMatching which caused the algorithm to occasionally throw a NullPointerException (contributed by Dimitrios Michail, bug reported by Nils Olberg)
+ - Fixed `AStarShortestPath` to use Object.equals (contributed by Joris Kinable, bug reported by Zgce)
+ - Enhance `DirectedAcyclicGraph` to extend Iterable (contributed by Joris Kinable, suggested by Andrew Pennebaker)
+ - Enhance `MinSourceSinkCut` to make max-flow implementation configurable (contributed by Joris Kinable, suggested by Roman Pearah)
+ - Add new vertex cover algorithms and package (contributed by Joris Kinable and Nils Olberg)
+ - Improved GraphML support (contributed by Dimitrios Michail)
+ - Add common `GraphExporter` and `GraphImporter` interfaces (contributed by Dimitrios Michail)
+ - DOT importer id fix (contributed by Dimitrios Michail)
+ - Add `CSVExporter` and `CSVImporter` (contributed by Dimitrios Michail)
+ - Add `MinimumSTCutAlgorithm` (contributed by Joris Kinable)
+ - Capture trivial paths in `AllDirectedPaths` (contributed by Andrew Gainer-Dewar)
+ - Switch from Jalopy source code formatter to Eclipse, since Jalopy does not support java 8 (contributed by John Sichi)
+ - Fixed a bug in `RandomGraphGenerator`, reported by (@ckapop), which could cause an overflow when calculating the maximum number of edges allowed in a graph (contributed by Dimitrios Michail)
+ - Added generics to code in test package (contributed by Dimitrios Michail)
+ - Fixed a bug in `PushRelabelMFImpl`, reported by Joris Kinable, which caused a NullPointerException whenever the network contained multiple components (contributed by Dimitrios Michail)
+ - Fixed a bug in `MaximumFlowAlgorithmBase`: some vertices ended up with a null prototype vertex (contributed by Dimitrios Michail)
+ - Use equals for compare to fix bug in `EdmondsBlossomShrinking` (contributed by Szabolcs Besenyei)
+ - Reformat all file headers (contributed by Joris Kinable)
+ - Refactor and enhance random graph generators (contributed by Dimitrios Michail)
+ - Fix DirectedAcyclicGraph.removeAllVertices (contributed by Szabolcs Besenyei)
+ - Use Travis to enforce Javadoc correctness (contributed by Joris Kinable)
+ - Corrected all javadoc warnings (contributed by Dimitrios Michail)
+
+- **version 0.9.2** (3-Apr-2016):
+ - Add `HawickJamesSimpleCycles`, contributed by Luiz Kill
+ - Add `DOTImporter`, contributed by Wil Selwood
+ - Optimize `FloydWarshallShortestPaths`, contributed by Mihhail Verhovtsov
+ - Add VF2 isomorphism and subgraph isomorphism detection, contributed by Fabian Späh
+ - Remove old experimental isomorphism implementation
+ - Fix for empty graph input to `KuhnMunkresMinimalWeightBipartitePerfectMatching`, contributed by Szabolcs Besenyei
+ - Fix for `EdmondsBlossomShrinking`, contributed by Alexey Kudinkin
+ - Add `TransitiveReduction`, contributed by Christophe Thiebaud
+ - Add `AStarShortestPath`, contributed by Joris Kinable, Jon Robinson, and Thomas Breitbart
+ - More `FloydWarshallShortestPaths` optimizations, contributed by Joris Kinable
+ - Add `MixedGraphUnion` and `AsWeightedDirectedGraph`; fix UndirectedGraphUnion constructors; contributed by Joris Kinable
+ - Add `GabowStrongConnectivityInspector` and `KosarajuStrongConnectivityInspector`, contributed by Joris Kinable and Sarah Komla-Ebri
+ - Add `PushRelabelMaximumFlow`; boost `EdmondsKarpMaximumFlow`; add `MaximumFlowAlgorithm` interface; add `Pair` and `Extension` utility classes; optional seed parameter to `RandomGraphGenerator`, contributed by Alexey Kudinkin
+ - Add `MaximumWeightBipartiteMatching`, contributed by Graeme Ahokas
+ - Osgify jgrapht-ext, contributed by Christoph Zauner
+ - Add `AllDirectedPaths`, contributed by Andrew Gainer-Dewar
+
+- **version 0.9.1** (5-Apr-2015):
+ - Auto-generation of bundle manifest, contributed by Nicolas Fortin
+ - Travis CI configuration, contributed by Peter Goldstein
+ - TarjanLCA bugfix, contributed by Leo Crawford
+ - Add `SimpleGraphPath`, contributed by Rodrigo Lopez Dato
+ - Add `NaiveLcaFinder`, contributed by Leo Crawford
+ - Make getEdgeWeight throw NPE on null edge, suggested by Joris Kinable
+ - Clarify that shortest path length is weighted, per gjafachini
+ - Add DAG constructor that takes an edge factory, and make TarjanLCA constructor public, contributed by Anders Wallgren
+ - Fixed rounding error in graph generation, contributed by Siarhei
+ - Fixed Javadoc for `DirectedWeightedMultigraph`, noticed by Martin Lowinski
+ - Use annotations to simplify test suites, contributed by Jan Altenbernd
+ - Add missing Override/Deprecated annotations, contributed by Jan Altenbernd
+ - Update maven-compiler-plugin version, contributed by Andrew Chen
+ - Add builder package, contributed by Andrew Chen
+ - Add CliqueMinimalSeparatorDecomposition, contributed by Florian Buenzli, Thomas Tschager, Tomas Hruz, and Philipp Hoppen
+ - Include vertex #toString value in excn message, contributed by Chris Wensel
+ - Open up Specifics to allow for custom backing containers, contributed by Chris Wensel
+ - Make abstract graph constructors protected, contributed by John Sichi
+ - Moved to JDK 1.7
+
+- **version 0.9.0** (06-Dec-2013):
+ - Move to github for source control, and Apache Maven for build, contributed by Andreas Schnaiter, Owen Jacobson, and Isaac Kleinman.
+ - Add source/target vertices to edge events to fix sf.net bug 3486775, spotted by Frank Mori Hess.
+ - Add `EdmondsBlossomShrinking` algorithm, contributed by Alejandro R. Lopez del Huerto.
+ - Fix empty diameter calculation in `FloydWarshallShortestPaths`, contributed by Ernst de Ridder (bug spotted by Jens Lehmann)
+ - Add `HopcroftKarpBipartiteMatching` and `MinSourceSinkCut`, contributed by Joris Kinable
+ - Fix multiple bugs in `StoerWagnerMinimumCut`, contributed by Ernst de Ridder
+ - Fix path weight bug in `FloydWarshallShortestPaths`, contributed by Michal Pasieka
+ - Add `PrimMinimumSpanningTree`, contributed by Alexey Kudinkin
+ - Add `DirectedWeightedPseudograph`, and fix 'DirectedMultigraph' contributed by Adam Gouge
+ - More KSP bugfixes (spotted by Sebastian Mueller, fixed by Guillaume Boulmier)
+ - Add `KuhnMunkresMinimalWeightBipartitePerfectMatching` and associated generators+interfaces (contributed by Alexey Kudinkin)
+ - Add cycle enumeration (contributed by Nikolay Ognyanov, originally from http://code.google.com/p/niographs/ )
+ - Update `removeAllEdges` to match specification (contributed by Graham Hill)
+ - Add `TarjanLowestCommonAncestor`, contributed by Leo Crawford
+ - Add `JGraphXAdapter`, contributed by Sebastian Hubenschmid and JeanYves Tinevez
+ - Add LGPL/EPL dual licensing, coordinated by Oliver Kopp
+ - Refactoring for `DirectedAcyclicGraph`, contributed by Javier Gutierrez
- **version 0.8.3** (20-Jan-2012):
- - fix regression in `DOTExporter` inadvertently introduced by `0.8.2` changes.
- - Add `GridGraphGenerator`, contributed by Assaf Mizrachi.
- - Return coloring from ChromaticNumber, contributed by Harshal Vora.
- - Fix bugs in KSP, contributed by Guillaume Boulmier; note that these bugfixes worsen the running time.
- - Fix an object identity bug in CycleDetector, contributed by Matt Sarjent.
- -Add StoerWagnerMinimumCut, contributed by Robby McKilliam.
- - Fix `MANIFEST.MF`, spotted by Olly.
- - Make `FloydWarshallShortestPaths.getShortestPaths` unidirectional, contributed by Yuriy Nakonechnyy.
+ - fix regression in `DOTExporter` inadvertently introduced by `0.8.2` changes.
+ - Add `GridGraphGenerator`, contributed by Assaf Mizrachi.
+ - Return coloring from ChromaticNumber, contributed by Harshal Vora.
+ - Fix bugs in KSP, contributed by Guillaume Boulmier; note that these bugfixes worsen the running time.
+ - Fix an object identity bug in CycleDetector, contributed by Matt Sarjent.
+ -Add StoerWagnerMinimumCut, contributed by Robby McKilliam.
+ - Fix `MANIFEST.MF`, spotted by Olly.
+ - Make `FloydWarshallShortestPaths.getShortestPaths` unidirectional, contributed by Yuriy Nakonechnyy.
- **version 0.8.2** (27-Nov-2010):
- - Clean up `FibonacciHeapNode` constructor, as suggested by Johan
+ - Clean up `FibonacciHeapNode` constructor, as suggested by Johan
Henriksson.
- - Optimize and enhance `FloydWarshallShortestPaths`, contributed by Soren Davidsen.
- - Optimize `ChromaticNumber`,pointed out by gpaschos@netscape.net.
- - Add unit test for `FloydWarshallShortestPaths` for bug noticed by
+ - Optimize and enhance `FloydWarshallShortestPaths`, contributed by Soren Davidsen.
+ - Optimize `ChromaticNumber`,pointed out by gpaschos@netscape.net.
+ - Add unit test for `FloydWarshallShortestPaths` for bug noticed by
Andrea Pagani.
- - Add vertex factory validation to `RandomGraphGenerator` to prevent a confusing problem encountered by Andrea Pagani.
- - Add `KruskalMinimumSpanningTree` and `UnionFind`, contributed by Tom Conerly.
- - Add attributes to `DOTExporter`, based on suggestion from Chris Lott.
- - Fix inefficient assertion in `TopologicalOrderIterator`, spotted by
+ - Add vertex factory validation to `RandomGraphGenerator` to prevent a confusing problem encountered by Andrea Pagani.
+ - Add `KruskalMinimumSpanningTree` and `UnionFind`, contributed by Tom Conerly.
+ - Add attributes to `DOTExporter`, based on suggestion from Chris Lott.
+ - Fix inefficient assertion in `TopologicalOrderIterator`, spotted by
Peter Lawrey.
- - Fix induced subgraph bug with addition of edge to underlying graph, contributed by Michele Mancioppi.
- - Make `getEdgeWeight` delegate to `DefaultWeightedEdge.getWeight`, spotted by Michael Lindig.
- - Add maven support, contributed by Adrian Marte.
+ - Fix induced subgraph bug with addition of edge to underlying graph, contributed by Michele Mancioppi.
+ - Make `getEdgeWeight` delegate to `DefaultWeightedEdge.getWeight`, spotted by Michael Lindig.
+ - Add maven support, contributed by Adrian Marte.
- **version 0.8.1** (3-Jul-2009):
- - Enhanced `GmlExporter` with customized labels and ID's, contributed by Trevor Harmon.
- - Added new algorithms `HamiltonianCycle`, `ChromaticNumber` and `EulerianCircuit`, plus new generators `HyperCubeGraphGenerator`, `StarGraphGenerator`, and `CompleteBipartiteGraphGenerator`, all contributed by Andrew Newell.
- - Fix bug with vertices which are equals but not identity-same in graphs allowing loops, spotted by Michael Michaud.
- - Fix bug in `EquivalenceIsomorphismInspector`, reported by Tim Engler. - Add `toString` for shortest paths wrapper, spotted by Achim Beutel.
- - Add `FloydWarshallShortestPaths`, contributed by Tom Larkworthy.
- - Enhance `DijskstraShortestPath` to support `GraphPath` interface.
- - Add `GraphUnion` (with directed and undirected variants), contributed by Ilya Razenshteyn.
+ - Enhanced `GmlExporter` with customized labels and ID's, contributed by Trevor Harmon.
+ - Added new algorithms `HamiltonianCycle`, `ChromaticNumber` and `EulerianCircuit`, plus new generators `HyperCubeGraphGenerator`, `StarGraphGenerator`, and `CompleteBipartiteGraphGenerator`, all contributed by Andrew Newell.
+ - Fix bug with vertices which are equals but not identity-same in graphs allowing loops, spotted by Michael Michaud.
+ - Fix bug in `EquivalenceIsomorphismInspector`, reported by Tim Engler. - Add `toString` for shortest paths wrapper, spotted by Achim Beutel.
+ - Add `FloydWarshallShortestPaths`, contributed by Tom Larkworthy.
+ - Enhance `DijskstraShortestPath` to support `GraphPath` interface.
+ - Add `GraphUnion` (with directed and undirected variants), contributed by Ilya Razenshteyn.
- **version 0.8.0** (Sept-2008):
- - Moved to JDK 1.6.
- - Fixed problem with `RandomGraphGenerator` reported by Mario Rossi.
- - Added `CompleteGraphGenerator`, contributed by Tim Shearouse.
- - Fixed `FibonacciHeap` performance problem reported by Jason Lenderman.
- - Made `DotExporter` reject illegal vertex ID's, contributed by Holger Brandl.
- - Fixed bogus assertion for topological sort over empty
+ - Moved to JDK 1.6.
+ - Fixed problem with `RandomGraphGenerator` reported by Mario Rossi.
+ - Added `CompleteGraphGenerator`, contributed by Tim Shearouse.
+ - Fixed `FibonacciHeap` performance problem reported by Jason Lenderman.
+ - Made `DotExporter` reject illegal vertex ID's, contributed by Holger Brandl.
+ - Fixed bogus assertion for topological sort over empty
graph, spotted by Harris Lin.
- - Added scale-free graph generator and `EdmondsKarpMaximumFlow`, contributed by Ilya Razenshteyn.
- - Added `DirectedAcyclicGraph`, contributed by Peter Giles.
- - Added protected `getWeight` accessor to `DefaultWeightedEdge`, likewise `getSource` and `getTarget` on `DefaultEdge`.
- - Optimized iterators to skip calling event firing routines when there are no listeners, and used `ArrayDeque` in a number of places, per suggestion from Ross Judson.
- - Improvements to `StrongConnectivityInspector` and OSGi bundle support contributed by Christian Soltenborn.
+ - Added scale-free graph generator and `EdmondsKarpMaximumFlow`, contributed by Ilya Razenshteyn.
+ - Added `DirectedAcyclicGraph`, contributed by Peter Giles.
+ - Added protected `getWeight` accessor to `DefaultWeightedEdge`, likewise `getSource` and `getTarget` on `DefaultEdge`.
+ - Optimized iterators to skip calling event firing routines when there are no listeners, and used `ArrayDeque` in a number of places, per suggestion from Ross Judson.
+ - Improvements to `StrongConnectivityInspector` and OSGi bundle support contributed by Christian Soltenborn.
- **version 0.7.3** (Jan-2008):
- - Patch to `JGraphModelAdapter.removeVertex` provided by Hookahey.
- - Added `ParanoidGraph`.
- - Removed obsolete `ArrayUtil` (spotted by Boente).
- - Added `GraphPath`, and used it to fix mistake in `0.7.2` (k-shortest-paths was returning a private data structure,
+ - Patch to `JGraphModelAdapter.removeVertex` provided by Hookahey.
+ - Added `ParanoidGraph`.
+ - Removed obsolete `ArrayUtil` (spotted by Boente).
+ - Added `GraphPath`, and used it to fix mistake in `0.7.2` (k-shortest-paths was returning a private data structure,
as discovered by numerous users).
- - Fixed `EdgeReversedGraph.getAllEdges` (spotted by neumanns@users.sf.net).
- - Fixed incorrect assertion in `TopologicalOrderIterator` constructor.
- - Enabled assertions in JUnit tests.
- - Fixed NPE in `BellmanFordShortestPath.getCost`.
- - Fixed a few problems spotted by findbugs.
+ - Fixed `EdgeReversedGraph.getAllEdges` (spotted by neumanns@users.sf.net).
+ - Fixed incorrect assertion in `TopologicalOrderIterator` constructor.
+ - Enabled assertions in JUnit tests.
+ - Fixed NPE in `BellmanFordShortestPath.getCost`.
+ - Fixed a few problems spotted by findbugs.
- **version 0.7.2** (Sept-2007):
- - Added `TransitiveClosure`, contributed by Vinayak Borkar.
- - Added biconnectivity/cutpoint inspection, k-shortest-paths, and masked
+ - Added `TransitiveClosure`, contributed by Vinayak Borkar.
+ - Added biconnectivity/cutpoint inspection, k-shortest-paths, and masked
subgraphs, all contributed by Guillaume Boulmier.
- - Made some Graphs helper methods even more generic, as suggested by JongSoo.
- - Test and fixes for (Directed)NeighborIndex submitted by Andrew Berman.
- - Added `AsUnweighted(Directed)Graph` and `AsWeightedGraph`, contributed by Lucas Scharenbroich.
- - Dropped support for retroweaver.
+ - Made some Graphs helper methods even more generic, as suggested by JongSoo.
+ - Test and fixes for (Directed)NeighborIndex submitted by Andrew Berman.
+ - Added `AsUnweighted(Directed)Graph` and `AsWeightedGraph`, contributed by Lucas Scharenbroich.
+ - Dropped support for retroweaver.
- **version 0.7.1** (March-2007):
- - Fixed some bugs in `CycleDetector` reported by Khanh Vu, and added more testcases for it.
- - Fixed bugs in `DepthFirstIterator` reported by Welson Sun, and added WHITE/GRAY/BLACK states and `vertexFinished` listener event.
- - Exposed `Subgraph.getBase()`, and parameterized `Subgraph` on graph type (per suggestion from Aaron Harnly).
- - Added `EdgeReversedView`.
- - Added `GmlExporter` (contributed by Dimitrios Michail), plus `DOTExporter` and `GraphMLExporter` (both contributed by Trevor Harmon).
- - Enhanced `TopologicalOrderIterator` to take an optional Queue parameter for tie-breaking (per suggestion from JongSoo Park).
- - Fixed some documentation errors reported by Guillaume Boulmier.
+ - Fixed some bugs in `CycleDetector` reported by Khanh Vu, and added more testcases for it.
+ - Fixed bugs in `DepthFirstIterator` reported by Welson Sun, and added WHITE/GRAY/BLACK states and `vertexFinished` listener event.
+ - Exposed `Subgraph.getBase()`, and parameterized `Subgraph` on graph type (per suggestion from Aaron Harnly).
+ - Added `EdgeReversedView`.
+ - Added `GmlExporter` (contributed by Dimitrios Michail), plus `DOTExporter` and `GraphMLExporter` (both contributed by Trevor Harmon).
+ - Enhanced `TopologicalOrderIterator` to take an optional Queue parameter for tie-breaking (per suggestion from JongSoo Park).
+ - Fixed some documentation errors reported by Guillaume Boulmier.
- **version 0.7.0** (July-2006) :
- - Upgraded to JDK 1.5 (generics support added by Christian Hammer with help from Hartmut Benz and John Sichi).
- - Added `(Directed)NeighborIndex` and `MatrixExporter`, contributed by Charles Fry.
- - Added BellmanFord, contributed by Guillaume Boulmier of France Telecom.
- - Removed never-used `LabeledElement`.
- - Renamed package from `org._3pq.jgrapht` to `org.jgrapht`.
- - Made various breaking change to interfaces; edge collections are now Sets, not Lists.
- - Added Touchgraph converter, contributed by Carl Anderson
+ - Upgraded to JDK 1.5 (generics support added by Christian Hammer with help from Hartmut Benz and John Sichi).
+ - Added `(Directed)NeighborIndex` and `MatrixExporter`, contributed by Charles Fry.
+ - Added BellmanFord, contributed by Guillaume Boulmier of France Telecom.
+ - Removed never-used `LabeledElement`.
+ - Renamed package from `org._3pq.jgrapht` to `org.jgrapht`.
+ - Made various breaking change to interfaces; edge collections are now Sets, not Lists.
+ - Added Touchgraph converter, contributed by Carl Anderson
- **version 0.6.0** (July-2005) :
- - Upgraded to JDK 1.4, taking advantage of its new linked hash set/map containers to make edge/vertex set order-deterministic
- - Added support for custom edge lists.
- - Fixed various serialization and Subgraph issues.
- - Added to `JGraphModelAdapter` support for JGraph's "dangling" edges; its constructors have slightly changed and now forbid `null` values.
- - Improved interface to `DijskstraShortestPath`, and added radius support to `ClosestFirstIterator`.
- - Added new `StrongConnectivityInspector` algorithm (contributed by Christian Soltenborn) and `TopologicalOrderIterator` (contributed by Marden Neubert).
- - Deleted deprecated `TraverseUtils`.
- - Upgraded to JGraph `5.6.1.1`.
+ - Upgraded to JDK 1.4, taking advantage of its new linked hash set/map containers to make edge/vertex set order-deterministic
+ - Added support for custom edge lists.
+ - Fixed various serialization and Subgraph issues.
+ - Added to `JGraphModelAdapter` support for JGraph's "dangling" edges; its constructors have slightly changed and now forbid `null` values.
+ - Improved interface to `DijskstraShortestPath`, and added radius support to `ClosestFirstIterator`.
+ - Added new `StrongConnectivityInspector` algorithm (contributed by Christian Soltenborn) and `TopologicalOrderIterator` (contributed by Marden Neubert).
+ - Deleted deprecated `TraverseUtils`.
+ - Upgraded to JGraph `5.6.1.1`.
- **version 0.5.3** (June-2004) :
- - Removed Subgraph verification of element's identity to base graph, upgraded to JGraph 4.0
- - Added the `VisioExporter` which was contributed by Avner Linder
- - minor bug fixes and improvements.
+ - Removed Subgraph verification of element's identity to base graph, upgraded to JGraph 4.0
+ - Added the `VisioExporter` which was contributed by Avner Linder
+ - minor bug fixes and improvements.
- **version 0.5.2** (March-2004) :
- - Serialization improvements, fixes to subgraphs and listenable graphs
- - added support for JGraph > JGraphT change propagation for JGraph adapter (contributed by Erik Postma)
- - upgraded to JGraph 3.1, various bug fixes and improvements.
+ - Serialization improvements, fixes to subgraphs and listenable graphs
+ - added support for JGraph > JGraphT change propagation for JGraph adapter (contributed by Erik Postma)
+ - upgraded to JGraph 3.1, various bug fixes and improvements.
- **version 0.5.1** (November-2003) :
- - Semantics of `Graph.clone()` has changed, please check the documentation if you're using it.
- - Added Dijkstra's shortest path, vertex cover approximations, new graph generation framework
- - upgraded to JGraph 3.0
- - various bug fixes and API improvements.
+ - Semantics of `Graph.clone()` has changed, please check the documentation if you're using it.
+ - Added Dijkstra's shortest path, vertex cover approximations, new graph generation framework
+ - upgraded to JGraph 3.0
+ - various bug fixes and API improvements.
- **version 0.5.0** (14-Aug-2003) :
- - a new connectivity inspector added
- - edge API refactored to be simpler
- - improved ant build
- - improved event model
- - all known bugs were fixed, documentation clarifications, other small improvements.
- - API of 0.5.0 is not 100% backward compatible with 0.4.1 but upgrade is simple and straightforward.
+ - a new connectivity inspector added
+ - edge API refactored to be simpler
+ - improved ant build
+ - improved event model
+ - all known bugs were fixed, documentation clarifications, other small improvements.
+ - API of 0.5.0 is not 100% backward compatible with 0.4.1 but upgrade is simple and straightforward.
- **version 0.4.1** (05-Aug-2003) :
- - A new adapter to JGraph that provides graph visualizations, new depth-first and breadth-first iteration algorithms
- - various bug fixes and refactoring
- - moved unit-tests to a separate folder hierarchy and added more unit-tests.
+ - A new adapter to JGraph that provides graph visualizations, new depth-first and breadth-first iteration algorithms
+ - various bug fixes and refactoring
+ - moved unit-tests to a separate folder hierarchy and added more unit-tests.
-- **version 0.4.0** (July-2003) : Initial public release.
\ No newline at end of file
+- **version 0.4.0** (July-2003) : Initial public release.
diff --git a/README.md b/README.md
index f71d7c99921..fae5fd38a74 100644
--- a/README.md
+++ b/README.md
@@ -1,86 +1,187 @@
-# JGraphtT
+[](https://github.com/jgrapht/jgrapht/actions/workflows/master-workflow.yaml)
+[](http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22jgrapht%22)
+[](https://central.sonatype.com/repository/maven-snapshots/org/jgrapht/jgrapht/maven-metadata.xml)
+[](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html)
+[](https://www.eclipse.org/legal/epl-2.0)
+[](https://www.java.com/)
-Released: January, 2012
+# JGraphT
-Written by [Barak Naveh](mailto:barak_naveh@users.sourceforge.net) and Contributors
+
-(C) Copyright 2003-2012, by Barak Naveh and Contributors. All rights
+Released: May 2, 2023
+
+Written by [Barak Naveh](mailto:barak_naveh@users.sourceforge.net) and Contributors
+
+(C) Copyright 2003-2023, by Barak Naveh and Contributors. All rights
reserved.
-Please address all contributions, suggestions, and inquiries to the current project administrator [John Sichi](mailto:perfecthash@users.sf.net)
+Please address all contributions, suggestions, and inquiries to the [user mailing list](https://lists.sourceforge.net/lists/listinfo/jgrapht-users)
+
+## Introduction
+
+JGraphT is a free Java class library that provides mathematical graph-theory objects and algorithms. It runs on Java 2 Platform (requires JDK 11 or later starting with JGraphT 1.5.0).
+
+JGraphT may be used under the terms of either the
+
+ * GNU Lesser General Public License (LGPL) 2.1
+
-## Introduction ##
+or the
-JGraphT is a free Java class library that provides mathematical graph-theory objects and algorithms. It runs on Java 2 Platform (requires JDK 1.6 or later).
+ * Eclipse Public License (EPL)
+
-JGraphT is licensed under the terms of the GNU Lesser General Public License (LGPL). A copy of the [license](license-LGPL.txt) is included in the download.
+As a recipient of JGraphT, you may choose which license to receive the code under.
+
+For detailed information on the dual license approach, see .
+
+A copy of the [EPL license](license-EPL.txt) and the [LPGL license](license-LGPL.txt) is included in the download.
Please note that JGraphT is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Please refer to the license for details.
-## Contents ##
+ SPDX-License-Identifier: LGPL-2.1-or-later OR EPL-2.0
+
+## Release Contents
+
+The files below make up the table of contents for a release distribution archive (produced by `mvn package`):
- `README.md` this file
- `CONTRIBUTORS.md` list of contributors
- `HISTORY.md` changelog
-- `licence-LGPL.txt` GNU Lesser General Public License
+- `license-EPL.txt` Eclipse Public License 2.0
+- `license-LGPL.txt` GNU Lesser General Public License 2.1
- `javadoc/` Javadoc documentation
-- `lib/` JGraphT libraries:
-- `jgrapht-core-x.y.z.jar` core library
-- `jgrapht-demo-x.y.z.jar` demo classes
-- `jgrapht-ext-x.y.z.jar` extensions
-- `jgrapht-x.y.z-combined.jar` all libraries rolled into one
-- `jgraph-a.b.c.jar` JGraph dependency library
+- `lib/` JGraphT libraries and dependencies:
+ - `jgrapht-core-x.y.z.jar` core library
+ - `jgrapht-demo-x.y.z.jar` demo classes
+ - `jgrapht-opt-x.y.z.jar` optimized graph implementations
+ - `jgrapht-ext-x.y.z.jar` extensions
+ - `jgrapht-io-x.y.z.jar` Importers/Exporters for various graph formats
+ - `jgrapht-guava-x.y.z.jar` Adapter classes for the Guava library
+ - `jgrapht-unimi-dsi-x.y.z.jar` Webgraph adapter and succinct graph implementations
+ - `jgraphx-a.b.c.jar` JGraphX dependency library
+ - `jheaps-x.y.jar` JHeaps library
+ - `antlr4-runtime-x.y.jar` ANTLR parser runtime
+ - `commons-lang3-x.y.z.jar` Apache Commons Lang library
+ - `commons-text-x.y.jar` Apache Commons Text library
+ - `fastutil-x.y.z.jar` Fastutil library
+ - `guava-x.y-jre.jar` Guava library
+ - `jsap-x.y.jar` Jsap library
+ - `logback-classic-x.y.z.jar` Logger
+ - `logback-core-x.y.z.jar` Logger
+ - `slf4j-api-x.y.z.jar` Logger api
+ - `sux4j-x.y.z.jar` Sux4j library
+ - `webgraph-x.y.z.jar` Webgraph library
+ - `webgraph-big-z.y.z.jar` Webgraph big library
+ - `apfloat-x.x.x.jar` Apfloat library
+
- `source/` complete source tree used to build this release
-- `pom.xml` Maven project file
## Getting Started ##
+The JGraphT [wiki](https://github.com/jgrapht/jgrapht/wiki) provides various helpful pages for new users, including a [How to use JGraphT in your projects](https://github.com/jgrapht/jgrapht/wiki/Users:-How-to-use-JGraphT-as-a-dependency-in-your-projects) page.
The package `org.jgrapht.demo` includes small demo applications to help you get started. If you spawn your own demo app and think others can use it, please send it to us and we will add it to that package.
-## Upgrading Versions ##
+To run the graph visualization demo from the downloaded release, try executing this command in the lib directory:
+
+ java -jar jgrapht-demo-x.y.z.jar
+
+More information can be found on the [user pages](https://github.com/jgrapht/jgrapht/wiki#user-pages) of our wiki. Finally, all classes come with corresponding test classes. These test classes contain many examples.
+
+To help us understand how you use JGraphT, and which features are important to you, [tell](https://github.com/jgrapht/jgrapht/wiki/Users:-Projects-Using-JGraphT) us how you are using JGraphT, and [cite](https://github.com/jgrapht/jgrapht/wiki/Users:-How-to-cite-JGraphT) the usage of JGraphT in your book, paper, website, or technical report.
+
+## Using via Maven
+
+Starting from 0.9.0, every JGraphT release is published to the Maven Central Repository. You can add a dependency from your project as follows:
+
+```xml
+org.jgrapht
+jgrapht-core
+1.5.2
+```
+
+We have also started auto-publishing SNAPSHOT builds for every successful commit to master. To use the bleeding edge:
+
+```xml
+org.jgrapht
+jgrapht-core
+1.5.3-SNAPSHOT
+```
+
+and make sure the snapshot repository is enabled:
+
+```xml
+
+
+ Central Portal Snapshots
+ central-portal-snapshots
+ https://central.sonatype.com/repository/maven-snapshots
+
+ false
+
+
+ true
+
+
+
+```
+
+## Upgrading Versions
To help upgrading, JGraphT maintains a one-version-backwards compatibility. While this compatibility is not a hard promise, it is generally respected. (This policy was not followed for the jump from `0.6.0` to `0.7.0` due to the pervasive changes required for generics.) You can upgrade via:
-- **The safe way** : compile your app with the JGraphT version that immediately follows your existing version and follow the deprecation notes, if they exist, and modify your application accordingly. Then move to the next version, and on, until you're current.
-- **The fast way** : go to the latest JGraphT right away - if it works, you're done.
+- **The safe way**: compile your app with the JGraphT version that immediately follows your existing version and follow the deprecation notes, if they exist, and modify your application accordingly. Then move to the next version, and on, until you're current.
+- **The fast way**: go to the latest JGraphT right away - if it works, you're done.
Reading the [change history](HISTORY.md) is always recommended.
-## Documentation ##
+## Documentation
-A local copy of the Javadoc HTML files is included in this distribution. The latest version of these files is also available [on-line](http://www.jgrapht.org/javadoc).
+A local copy of the Javadoc HTML files is included in the distribution. The latest version of these files is also available [online](http://www.jgrapht.org/javadoc).
-## Dependencies ##
+## Dependencies
-- JGraphT requires JDK 1.6 or later to build.
-- [JUnit](http://www.junit.org) is a unit testing framework. You need JUnit only if you want to run the unit tests. JUnit is licensed under the terms of the IBM Common Public License. The JUnit tests included with JGraphT have been created using JUnit `3.8.1`.
-- [XMLUnit](http://xmlunit.sourceforge.net) extends JUnit with XML capabilities. You need XMLUnit only if you want to run the unit tests. XMLUnit is licensed under the terms of the BSD
- License.
-- [JGraph](http://sourceforge.net/projects/jgraph) is a graph visualization and editing component. You need JGraph only if you want to create graph visualizations using the JGraphT-to-JGraph adapter. JGraph is licensed under the terms of the GNU Lesser General Public License (LGPL).
-- [Touchgraph](http://sourceforge.net/projects/touchgraph) is a graph visualization and layout component. You need Touchgraph only if you want to create graph visualizations using the JGraphT-to-Touchgraph converter. Touchgraph is licensed under the terms of an Apache-style License.
+- JGraphT requires JDK 11 or later to build starting with version 1.5.0.
+- [JHeaps](https://www.jheaps.org/) is a library with priority queues. JHeaps is licensed under the terms of the Apache License, Version 2.0.
+- [JUnit](https://www.junit.org) is a unit testing framework. You need JUnit only if you want to run the unit tests. JUnit is licensed under the terms of the Eclipse Public License - v 2.0. The JUnit tests included with JGraphT have been created using JUnit 5.
+- [XMLUnit](https://www.xmlunit.org/) extends JUnit with XML capabilities. You need XMLUnit only if you want to run the unit tests. XMLUnit is licensed under the terms of the BSD License.
+- [JGraphX](https://github.com/jgraph/jgraphx) is a graph visualizations and editing component (the successor to the older JGraph library). You need JGraphX only if you want to use the JGraphXAdapter to visualize the JGraphT graph interactively via JGraphX. JGraphX is licensed under the terms of the BSD license.
+- [ANTLR](https://www.antlr.org) is a parser generator. It is used for reading text files containing graph representations, and is only required by the jgrapht-io module. ANTLR v4 is licensed under the terms of the [BSD license](https://www.antlr.org/license.html).
+- [Guava](https://github.com/google/guava) is Google's core libraries for Java. You need Guava only if you are already using Guava's graph data-structures and wish to use our adapter classes in order to execute JGraphT's algorithms. Only required by the [jgrapht-guava](jgrapht-guava) module.
+- [Apache Commons Proper](https://commons.apache.org/components.html) is an Apache project containing reusable Java components. The packages [commons-text](https://commons.apache.org/proper/commons-text/) and [commons-lang3.](https://commons.apache.org/proper/commons-lang/) which provide additional utilities for String manipulation are only required by the jgrapht-io module. The package [commons-math](https://commons.apache.org/proper/commons-text/) is only required by the jgrapht-unimi-dsi module.
+- [fastutil](http://fastutil.di.unimi.it/) provides a collection of type-specific maps, sets, lists and queues with a small memory footprint and fast access and insertion. Fastutil is only required by the jgrapht-opt module.
+- [webgraph](https://webgraph.di.unimi.it/) provides a framework for graph compression enabling management of very large graphs. Webgraph is only required by the jgrapht-unimi-dsi module.
+- [sux4j](https://sux.di.unimi.it/) provides implementations of basic succinct data structures. Sux4j is only required by the jgrapht-unimi-dsi module.
+- [jsap](https://www.martiansoftware.com/jsap/) provides a simple argument parser. Jsap is only required by the jgrapht-unimi-dsi module.
+- [apfloat](https://www.apfloat.org/apfloat_java/) provides support for high performance arbitrary precision arithmetic. Apfloat is licensed under the terms of the MIT license.
-## Online Resources ##
+## Online Resources
-The JGraphT website is at [http://www.jgrapht.org](http://www.jgrapht.org). You can use this site to:
+The JGraphT website is at . You can use this site to:
- **Obtain the latest version**: latest version and all previous versions of JGraphT are available online.
- **Report bugs**: if you have any comments, suggestions or bugs you want to report.
- **Get support**: if you have questions or need help with JGraphT.
-There is also a [wiki](http://wiki.jgrapht.org) set up for everyone in the JGraphT community to share information about the project.
+There is also a [wiki](https://github.com/jgrapht/jgrapht/wiki) set up for everyone in the JGraphT community to share information about the project. For support, refer to our [support page](https://github.com/jgrapht/jgrapht/wiki/Users:-Getting-Support)
-Source code is hosted on [github](https://github.com/lingeringsocket/jgrapht). You can send contributions as pull requests there.
+Source code is hosted on [github](https://github.com/jgrapht/jgrapht). You can send contributions as pull requests there.
-## Your Improvements ##
+## Your Improvements
-If you add improvements to JGraphT please send them to us as pull requests on github. We will add them to the next release so that everyone can enjoy them. You might also benefit from it: others may fix bugs in your source files or may continue to enhance them.
+If you add improvements to JGraphT please send them to us as [pull requests on github](https://github.com/jgrapht/jgrapht/wiki/Dev-guide:-How-to-make-your-first-(code)-contribution). We will add them to the next release so that everyone can enjoy them. You might also benefit from it: others may fix bugs in your source files or may continue to enhance them.
-## Thanks ##
+## Thanks
With regards from
[Barak Naveh](mailto:barak_naveh@users.sourceforge.net), JGraphT Project Creator
-[John Sichi](mailto:perfecthash@users.sourceforge.net), JGraphT Project Administrator
\ No newline at end of file
+[John Sichi](mailto:perfecthash@users.sourceforge.net), JGraphT Project Administrator
+
+[Joris Kinable](https://github.com/jkinable), JGraphtT Project Reviewer/Committer and Release Manager
+
+[Dimitrios Michail](https://github.com/d-michail), JGraphT Project Reviewer/Committer
diff --git a/docs/CNAME b/docs/CNAME
new file mode 100644
index 00000000000..71606dd9119
--- /dev/null
+++ b/docs/CNAME
@@ -0,0 +1 @@
+jgrapht.org
diff --git a/docs/Gemfile b/docs/Gemfile
new file mode 100644
index 00000000000..f8dd7464ecd
--- /dev/null
+++ b/docs/Gemfile
@@ -0,0 +1,3 @@
+source 'https://rubygems.org'
+gem 'github-pages', group: :jekyll_plugins
+gem 'jekyll-redirect-from', group: :jekyll_plugins
diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock
new file mode 100644
index 00000000000..4ddbc15a6c7
--- /dev/null
+++ b/docs/Gemfile.lock
@@ -0,0 +1,261 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ activesupport (7.0.4.2)
+ concurrent-ruby (~> 1.0, >= 1.0.2)
+ i18n (>= 1.6, < 2)
+ minitest (>= 5.1)
+ tzinfo (~> 2.0)
+ addressable (2.8.1)
+ public_suffix (>= 2.0.2, < 6.0)
+ coffee-script (2.4.1)
+ coffee-script-source
+ execjs
+ coffee-script-source (1.11.1)
+ colorator (1.1.0)
+ commonmarker (0.23.8)
+ concurrent-ruby (1.2.2)
+ dnsruby (1.61.9)
+ simpleidn (~> 0.1)
+ em-websocket (0.5.3)
+ eventmachine (>= 0.12.9)
+ http_parser.rb (~> 0)
+ ethon (0.16.0)
+ ffi (>= 1.15.0)
+ eventmachine (1.2.7)
+ execjs (2.8.1)
+ faraday (2.7.4)
+ faraday-net_http (>= 2.0, < 3.1)
+ ruby2_keywords (>= 0.0.4)
+ faraday-net_http (3.0.2)
+ ffi (1.15.5)
+ forwardable-extended (2.6.0)
+ gemoji (3.0.1)
+ github-pages (228)
+ github-pages-health-check (= 1.17.9)
+ jekyll (= 3.9.3)
+ jekyll-avatar (= 0.7.0)
+ jekyll-coffeescript (= 1.1.1)
+ jekyll-commonmark-ghpages (= 0.4.0)
+ jekyll-default-layout (= 0.1.4)
+ jekyll-feed (= 0.15.1)
+ jekyll-gist (= 1.5.0)
+ jekyll-github-metadata (= 2.13.0)
+ jekyll-include-cache (= 0.2.1)
+ jekyll-mentions (= 1.6.0)
+ jekyll-optional-front-matter (= 0.3.2)
+ jekyll-paginate (= 1.1.0)
+ jekyll-readme-index (= 0.3.0)
+ jekyll-redirect-from (= 0.16.0)
+ jekyll-relative-links (= 0.6.1)
+ jekyll-remote-theme (= 0.4.3)
+ jekyll-sass-converter (= 1.5.2)
+ jekyll-seo-tag (= 2.8.0)
+ jekyll-sitemap (= 1.4.0)
+ jekyll-swiss (= 1.0.0)
+ jekyll-theme-architect (= 0.2.0)
+ jekyll-theme-cayman (= 0.2.0)
+ jekyll-theme-dinky (= 0.2.0)
+ jekyll-theme-hacker (= 0.2.0)
+ jekyll-theme-leap-day (= 0.2.0)
+ jekyll-theme-merlot (= 0.2.0)
+ jekyll-theme-midnight (= 0.2.0)
+ jekyll-theme-minimal (= 0.2.0)
+ jekyll-theme-modernist (= 0.2.0)
+ jekyll-theme-primer (= 0.6.0)
+ jekyll-theme-slate (= 0.2.0)
+ jekyll-theme-tactile (= 0.2.0)
+ jekyll-theme-time-machine (= 0.2.0)
+ jekyll-titles-from-headings (= 0.5.3)
+ jemoji (= 0.12.0)
+ kramdown (= 2.3.2)
+ kramdown-parser-gfm (= 1.1.0)
+ liquid (= 4.0.4)
+ mercenary (~> 0.3)
+ minima (= 2.5.1)
+ nokogiri (>= 1.13.6, < 2.0)
+ rouge (= 3.26.0)
+ terminal-table (~> 1.4)
+ github-pages-health-check (1.17.9)
+ addressable (~> 2.3)
+ dnsruby (~> 1.60)
+ octokit (~> 4.0)
+ public_suffix (>= 3.0, < 5.0)
+ typhoeus (~> 1.3)
+ html-pipeline (2.14.3)
+ activesupport (>= 2)
+ nokogiri (>= 1.4)
+ http_parser.rb (0.8.0)
+ i18n (1.12.0)
+ concurrent-ruby (~> 1.0)
+ jekyll (3.9.3)
+ addressable (~> 2.4)
+ colorator (~> 1.0)
+ em-websocket (~> 0.5)
+ i18n (>= 0.7, < 2)
+ jekyll-sass-converter (~> 1.0)
+ jekyll-watch (~> 2.0)
+ kramdown (>= 1.17, < 3)
+ liquid (~> 4.0)
+ mercenary (~> 0.3.3)
+ pathutil (~> 0.9)
+ rouge (>= 1.7, < 4)
+ safe_yaml (~> 1.0)
+ jekyll-avatar (0.7.0)
+ jekyll (>= 3.0, < 5.0)
+ jekyll-coffeescript (1.1.1)
+ coffee-script (~> 2.2)
+ coffee-script-source (~> 1.11.1)
+ jekyll-commonmark (1.4.0)
+ commonmarker (~> 0.22)
+ jekyll-commonmark-ghpages (0.4.0)
+ commonmarker (~> 0.23.7)
+ jekyll (~> 3.9.0)
+ jekyll-commonmark (~> 1.4.0)
+ rouge (>= 2.0, < 5.0)
+ jekyll-default-layout (0.1.4)
+ jekyll (~> 3.0)
+ jekyll-feed (0.15.1)
+ jekyll (>= 3.7, < 5.0)
+ jekyll-gist (1.5.0)
+ octokit (~> 4.2)
+ jekyll-github-metadata (2.13.0)
+ jekyll (>= 3.4, < 5.0)
+ octokit (~> 4.0, != 4.4.0)
+ jekyll-include-cache (0.2.1)
+ jekyll (>= 3.7, < 5.0)
+ jekyll-mentions (1.6.0)
+ html-pipeline (~> 2.3)
+ jekyll (>= 3.7, < 5.0)
+ jekyll-optional-front-matter (0.3.2)
+ jekyll (>= 3.0, < 5.0)
+ jekyll-paginate (1.1.0)
+ jekyll-readme-index (0.3.0)
+ jekyll (>= 3.0, < 5.0)
+ jekyll-redirect-from (0.16.0)
+ jekyll (>= 3.3, < 5.0)
+ jekyll-relative-links (0.6.1)
+ jekyll (>= 3.3, < 5.0)
+ jekyll-remote-theme (0.4.3)
+ addressable (~> 2.0)
+ jekyll (>= 3.5, < 5.0)
+ jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0)
+ rubyzip (>= 1.3.0, < 3.0)
+ jekyll-sass-converter (1.5.2)
+ sass (~> 3.4)
+ jekyll-seo-tag (2.8.0)
+ jekyll (>= 3.8, < 5.0)
+ jekyll-sitemap (1.4.0)
+ jekyll (>= 3.7, < 5.0)
+ jekyll-swiss (1.0.0)
+ jekyll-theme-architect (0.2.0)
+ jekyll (> 3.5, < 5.0)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-cayman (0.2.0)
+ jekyll (> 3.5, < 5.0)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-dinky (0.2.0)
+ jekyll (> 3.5, < 5.0)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-hacker (0.2.0)
+ jekyll (> 3.5, < 5.0)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-leap-day (0.2.0)
+ jekyll (> 3.5, < 5.0)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-merlot (0.2.0)
+ jekyll (> 3.5, < 5.0)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-midnight (0.2.0)
+ jekyll (> 3.5, < 5.0)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-minimal (0.2.0)
+ jekyll (> 3.5, < 5.0)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-modernist (0.2.0)
+ jekyll (> 3.5, < 5.0)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-primer (0.6.0)
+ jekyll (> 3.5, < 5.0)
+ jekyll-github-metadata (~> 2.9)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-slate (0.2.0)
+ jekyll (> 3.5, < 5.0)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-tactile (0.2.0)
+ jekyll (> 3.5, < 5.0)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-theme-time-machine (0.2.0)
+ jekyll (> 3.5, < 5.0)
+ jekyll-seo-tag (~> 2.0)
+ jekyll-titles-from-headings (0.5.3)
+ jekyll (>= 3.3, < 5.0)
+ jekyll-watch (2.2.1)
+ listen (~> 3.0)
+ jemoji (0.12.0)
+ gemoji (~> 3.0)
+ html-pipeline (~> 2.2)
+ jekyll (>= 3.0, < 5.0)
+ kramdown (2.3.2)
+ rexml
+ kramdown-parser-gfm (1.1.0)
+ kramdown (~> 2.0)
+ liquid (4.0.4)
+ listen (3.8.0)
+ rb-fsevent (~> 0.10, >= 0.10.3)
+ rb-inotify (~> 0.9, >= 0.9.10)
+ mercenary (0.3.6)
+ mini_portile2 (2.8.1)
+ minima (2.5.1)
+ jekyll (>= 3.5, < 5.0)
+ jekyll-feed (~> 0.9)
+ jekyll-seo-tag (~> 2.1)
+ minitest (5.18.0)
+ nokogiri (1.14.2)
+ mini_portile2 (~> 2.8.0)
+ racc (~> 1.4)
+ octokit (4.25.1)
+ faraday (>= 1, < 3)
+ sawyer (~> 0.9)
+ pathutil (0.16.2)
+ forwardable-extended (~> 2.6)
+ public_suffix (4.0.7)
+ racc (1.6.2)
+ rb-fsevent (0.11.2)
+ rb-inotify (0.10.1)
+ ffi (~> 1.0)
+ rexml (3.2.5)
+ rouge (3.26.0)
+ ruby2_keywords (0.0.5)
+ rubyzip (2.3.2)
+ safe_yaml (1.0.5)
+ sass (3.7.4)
+ sass-listen (~> 4.0.0)
+ sass-listen (4.0.0)
+ rb-fsevent (~> 0.9, >= 0.9.4)
+ rb-inotify (~> 0.9, >= 0.9.7)
+ sawyer (0.9.2)
+ addressable (>= 2.3.5)
+ faraday (>= 0.17.3, < 3)
+ simpleidn (0.2.1)
+ unf (~> 0.1.4)
+ terminal-table (1.8.0)
+ unicode-display_width (~> 1.1, >= 1.1.1)
+ typhoeus (1.4.0)
+ ethon (>= 0.9.0)
+ tzinfo (2.0.6)
+ concurrent-ruby (~> 1.0)
+ unf (0.1.4)
+ unf_ext
+ unf_ext (0.0.8.2)
+ unicode-display_width (1.8.0)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ github-pages
+ jekyll-redirect-from
+
+BUNDLED WITH
+ 2.3.9
diff --git a/docs/LGPL.html b/docs/LGPL.html
new file mode 100644
index 00000000000..1794e5ab0e3
--- /dev/null
+++ b/docs/LGPL.html
@@ -0,0 +1,441 @@
+
+
+
+
+
+
+ LGPL
+
+
+
+
+
GNU Lesser General Public License
+Version 2.1, February 1999
+
+
+
+
Copyright (C) 1991, 1999 Free Software
+ Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
[This is the
+ first released version of the Lesser GPL. It also counts as the successor
+ of the GNU Library Public License, version 2, hence the version number 2.1.]
+
+
Preamble
+
+
The licenses for most software are designed to take away your freedom to
+ share and change it. By contrast, the GNU General Public Licenses are
+ intended to guarantee your freedom to share and change free software--to
+ make sure the software is free for all its users.
+
This license, the Lesser General Public License, applies to some
+ specially designated software packages--typically libraries--of the Free
+ Software Foundation and other authors who decide to use it. You can use it
+ too, but we suggest you first think carefully about whether this license or
+ the ordinary General Public License is the better strategy to use in any
+ particular case, based on the explanations below.
+
When we speak of free software, we are referring to freedom of use, not
+ price. Our General Public Licenses are designed to make sure that you have
+ the freedom to distribute copies of free software (and charge for this
+ service if you wish); that you receive source code or can get it if you want
+ it; that you can change the software and use pieces of it in new free
+ programs; and that you are informed that you can do these things.
+
To protect your rights, we need to make restrictions that forbid
+ distributors to deny you these rights or to ask you to surrender these
+ rights. These restrictions translate to certain responsibilities for you if
+ you distribute copies of the library or if you modify it.
+
For example, if you distribute copies of the library, whether gratis or
+ for a fee, you must give the recipients all the rights that we gave you. You
+ must make sure that they, too, receive or can get the source code. If you
+ link other code with the library, you must provide complete object files to
+ the recipients, so that they can relink them with the library after making
+ changes to the library and recompiling it. And you must show them these
+ terms so they know their rights.
+
We protect your rights with a two-step method: (1) we copyright the
+ library, and (2) we offer you this license, which gives you legal permission
+ to copy, distribute and/or modify the library.
+
To protect each distributor, we want to make it very clear that there is
+ no warranty for the free library. Also, if the library is modified by
+ someone else and passed on, the recipients should know that what they have
+ is not the original version, so that the original author's reputation will
+ not be affected by problems that might be introduced by others.
+
Finally, software patents pose a constant threat to the existence of any
+ free program. We wish to make sure that a company cannot effectively
+ restrict the users of a free program by obtaining a restrictive license from
+ a patent holder. Therefore, we insist that any patent license obtained for a
+ version of the library must be consistent with the full freedom of use
+ specified in this license.
+
Most GNU software, including some libraries, is covered by the ordinary
+ GNU General Public License. This license, the GNU Lesser General Public
+ License, applies to certain designated libraries, and is quite different
+ from the ordinary General Public License. We use this license for certain
+ libraries in order to permit linking those libraries into non-free programs.
+
When a program is linked with a library, whether statically or using a
+ shared library, the combination of the two is legally speaking a combined
+ work, a derivative of the original library. The ordinary General Public
+ License therefore permits such linking only if the entire combination fits
+ its criteria of freedom. The Lesser General Public License permits more lax
+ criteria for linking other code with the library.
+
We call this license the "Lesser" General Public License because it does
+ Less to protect the user's freedom than the ordinary General Public License.
+ It also provides other free software developers Less of an advantage over
+ competing non-free programs. These disadvantages are the reason we use the
+ ordinary General Public License for many libraries. However, the Lesser
+ license provides advantages in certain special circumstances.
+
For example, on rare occasions, there may be a special need to encourage
+ the widest possible use of a certain library, so that it becomes a de-facto
+ standard. To achieve this, non-free programs must be allowed to use the
+ library. A more frequent case is that a free library does the same job as
+ widely used non-free libraries. In this case, there is little to gain by
+ limiting the free library to free software only, so we use the Lesser
+ General Public License.
+
In other cases, permission to use a particular library in non-free
+ programs enables a greater number of people to use a large body of free
+ software. For example, permission to use the GNU C Library in non-free
+ programs enables many more people to use the whole GNU operating system, as
+ well as its variant, the GNU/Linux operating system.
+
Although the Lesser General Public License is Less protective of the
+ users' freedom, it does ensure that the user of a program that is linked
+ with the Library has the freedom and the wherewithal to run that program
+ using a modified version of the Library.
+
The precise terms and conditions for copying, distribution and
+ modification follow. Pay close attention to the difference between a "work
+ based on the library" and a "work that uses the library". The former
+ contains code derived from the library, whereas the latter must be combined
+ with the library in order to run.
+
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+
+
+ 0. This License Agreement applies to any software library or other program
+ which contains a notice placed by the copyright holder or other authorized
+ party saying it may be distributed under the terms of this Lesser General
+ Public License (also called "this License"). Each licensee is addressed as
+ "you".
+
A "library" means a collection of software functions and/or data prepared
+ so as to be conveniently linked with application programs (which use some of
+ those functions and data) to form executables.
+
The "Library", below, refers to any such software library or work which
+ has been distributed under these terms. A "work based on the Library" means
+ either the Library or any derivative work under copyright law: that is to
+ say, a work containing the Library or a portion of it, either verbatim or
+ with modifications and/or translated straightforwardly into another
+ language. (Hereinafter, translation is included without limitation in the
+ term "modification".)
+
"Source code" for a work means the preferred form of the work for making
+ modifications to it. For a library, complete source code means all the
+ source code for all modules it contains, plus any associated interface
+ definition files, plus the scripts used to control compilation and
+ installation of the library.
+
Activities other than copying, distribution and modification are not
+ covered by this License; they are outside its scope. The act of running a
+ program using the Library is not restricted, and output from such a program
+ is covered only if its contents constitute a work based on the Library
+ (independent of the use of the Library in a tool for writing it). Whether
+ that is true depends on what the Library does and what the program that uses
+ the Library does.
+
1. You may copy and distribute verbatim copies of the Library's complete
+ source code as you receive it, in any medium, provided that you
+ conspicuously and appropriately publish on each copy an appropriate
+ copyright notice and disclaimer of warranty; keep intact all the notices
+ that refer to this License and to the absence of any warranty; and
+ distribute a copy of this License along with the Library.
+
You may charge a fee for the physical act of transferring a copy, and you
+ may at your option offer warranty protection in exchange for a fee.
+
2. You may modify your copy or copies of the Library or any portion of
+ it, thus forming a work based on the Library, and copy and distribute such
+ modifications or work under the terms of Section 1 above, provided that you
+ also meet all of these conditions:
+
* a) The modified work must itself be a software library.
+
* b) You must cause the files modified to carry prominent notices stating
+ that you changed the files and the date of any change.
+
* c) You must cause the whole of the work to be licensed at no charge to
+ all third parties under the terms of this License.
+
* d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses the
+ facility, other than as an argument passed when the facility is invoked,
+ then you must make a good faith effort to ensure that, in the event an
+ application does not supply such function or table, the facility still
+ operates, and performs whatever part of its purpose remains meaningful.
+
(For example, a function in a library to compute square roots has a
+ purpose that is entirely well-defined independent of the application.
+ Therefore, Subsection 2d requires that any application-supplied function or
+ table used by this function must be optional: if the application does not
+ supply it, the square root function must still compute square roots.)
+
These requirements apply to the modified work as a whole. If identifiable
+ sections of that work are not derived from the Library, and can be
+ reasonably considered independent and separate works in themselves, then
+ this License, and its terms, do not apply to those sections when you
+ distribute them as separate works. But when you distribute the same sections
+ as part of a whole which is a work based on the Library, the distribution of
+ the whole must be on the terms of this License, whose permissions for other
+ licensees extend to the entire whole, and thus to each and every part
+ regardless of who wrote it.
+
Thus, it is not the intent of this section to claim rights or contest
+ your rights to work written entirely by you; rather, the intent is to
+ exercise the right to control the distribution of derivative or collective
+ works based on the Library.
+
In addition, mere aggregation of another work not based on the Library
+ with the Library (or with a work based on the Library) on a volume of a
+ storage or distribution medium does not bring the other work under the scope
+ of this License.
+
3. You may opt to apply the terms of the ordinary GNU General Public
+ License instead of this License to a given copy of the Library. To do this,
+ you must alter all the notices that refer to this License, so that they
+ refer to the ordinary GNU General Public License, version 2, instead of to
+ this License. (If a newer version than version 2 of the ordinary GNU General
+ Public License has appeared, then you can specify that version instead if
+ you wish.) Do not make any other change in these notices.
+
Once this change is made in a given copy, it is irreversible for that
+ copy, so the ordinary GNU General Public License applies to all subsequent
+ copies and derivative works made from that copy.
+
This option is useful when you wish to copy part of the code of the
+ Library into a program that is not a library.
+
4. You may copy and distribute the Library (or a portion or derivative of
+ it, under Section 2) in object code or executable form under the terms of
+ Sections 1 and 2 above provided that you accompany it with the complete
+ corresponding machine-readable source code, which must be distributed under
+ the terms of Sections 1 and 2 above on a medium customarily used for
+ software interchange.
+
If distribution of object code is made by offering access to copy from a
+ designated place, then offering equivalent access to copy the source code
+ from the same place satisfies the requirement to distribute the source code,
+ even though third parties are not compelled to copy the source along with
+ the object code.
+
5. A program that contains no derivative of any portion of the Library,
+ but is designed to work with the Library by being compiled or linked with
+ it, is called a "work that uses the Library". Such a work, in isolation, is
+ not a derivative work of the Library, and therefore falls outside the scope
+ of this License.
+
However, linking a "work that uses the Library" with the Library creates
+ an executable that is a derivative of the Library (because it contains
+ portions of the Library), rather than a "work that uses the library". The
+ executable is therefore covered by this License. Section 6 states terms for
+ distribution of such executables.
+
When a "work that uses the Library" uses material from a header file that
+ is part of the Library, the object code for the work may be a derivative
+ work of the Library even though the source code is not. Whether this is true
+ is especially significant if the work can be linked without the Library, or
+ if the work is itself a library. The threshold for this to be true is not
+ precisely defined by law.
+
If such an object file uses only numerical parameters, data structure
+ layouts and accessors, and small macros and small inline functions (ten
+ lines or less in length), then the use of the object file is unrestricted,
+ regardless of whether it is legally a derivative work. (Executables
+ containing this object code plus portions of the Library will still fall
+ under Section 6.)
+
Otherwise, if the work is a derivative of the Library, you may distribute
+ the object code for the work under the terms of Section 6. Any executables
+ containing that work also fall under Section 6, whether or not they are
+ linked directly with the Library itself.
+
6. As an exception to the Sections above, you may also combine or link a
+ "work that uses the Library" with the Library to produce a work containing
+ portions of the Library, and distribute that work under terms of your
+ choice, provided that the terms permit modification of the work for the
+ customer's own use and reverse engineering for debugging such modifications.
+
You must give prominent notice with each copy of the work that the
+ Library is used in it and that the Library and its use are covered by this
+ License. You must supply a copy of this License. If the work during
+ execution displays copyright notices, you must include the copyright notice
+ for the Library among them, as well as a reference directing the user to the
+ copy of this License. Also, you must do one of these things:
+
* a) Accompany the work with the complete corresponding machine-readable
+ source code for the Library including whatever changes were used in the work
+ (which must be distributed under Sections 1 and 2 above); and, if the work
+ is an executable linked with the Library, with the complete machine-readable
+ "work that uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified executable
+ containing the modified Library. (It is understood that the user who changes
+ the contents of definitions files in the Library will not necessarily be
+ able to recompile the application to use the modified definitions.)
+
* b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a copy of the
+ library already present on the user's computer system, rather than copying
+ library functions into the executable, and (2) will operate properly with a
+ modified version of the library, if the user installs one, as long as the
+ modified version is interface-compatible with the version that the work was
+ made with.
+
* c) Accompany the work with a written offer, valid for at least three
+ years, to give the same user the materials specified in Subsection 6a,
+ above, for a charge no more than the cost of performing this distribution.
+
* d) If distribution of the work is made by offering access to copy from
+ a designated place, offer equivalent access to copy the above specified
+ materials from the same place.
+
* e) Verify that the user has already received a copy of these materials
+ or that you have already sent this user a copy.
+
For an executable, the required form of the "work that uses the Library"
+ must include any data and utility programs needed for reproducing the
+ executable from it. However, as a special exception, the materials to be
+ distributed need not include anything that is normally distributed (in
+ either source or binary form) with the major components (compiler, kernel,
+ and so on) of the operating system on which the executable runs, unless that
+ component itself accompanies the executable.
+
It may happen that this requirement contradicts the license restrictions
+ of other proprietary libraries that do not normally accompany the operating
+ system. Such a contradiction means you cannot use both them and the Library
+ together in an executable that you distribute.
+
7. You may place library facilities that are a work based on the Library
+ side-by-side in a single library together with other library facilities not
+ covered by this License, and distribute such a combined library, provided
+ that the separate distribution of the work based on the Library and of the
+ other library facilities is otherwise permitted, and provided that you do
+ these two things:
+
* a) Accompany the combined library with a copy of the same work based on
+ the Library, uncombined with any other library facilities. This must be
+ distributed under the terms of the Sections above.
+
* b) Give prominent notice with the combined library of the fact that
+ part of it is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
8. You may not copy, modify, sublicense, link with, or distribute the
+ Library except as expressly provided under this License. Any attempt
+ otherwise to copy, modify, sublicense, link with, or distribute the Library
+ is void, and will automatically terminate your rights under this License.
+ However, parties who have received copies, or rights, from you under this
+ License will not have their licenses terminated so long as such parties
+ remain in full compliance.
+
9. You are not required to accept this License, since you have not signed
+ it. However, nothing else grants you permission to modify or distribute the
+ Library or its derivative works. These actions are prohibited by law if you
+ do not accept this License. Therefore, by modifying or distributing the
+ Library (or any work based on the Library), you indicate your acceptance of
+ this License to do so, and all its terms and conditions for copying,
+ distributing or modifying the Library or works based on it.
+
10. Each time you redistribute the Library (or any work based on the
+ Library), the recipient automatically receives a license from the original
+ licensor to copy, distribute, link with or modify the Library subject to
+ these terms and conditions. You may not impose any further restrictions on
+ the recipients' exercise of the rights granted herein. You are not
+ responsible for enforcing compliance by third parties with this License.
+
11. If, as a consequence of a court judgment or allegation of patent
+ infringement or for any other reason (not limited to patent issues),
+ conditions are imposed on you (whether by court order, agreement or
+ otherwise) that contradict the conditions of this License, they do not
+ excuse you from the conditions of this License. If you cannot distribute so
+ as to satisfy simultaneously your obligations under this License and any
+ other pertinent obligations, then as a consequence you may not distribute
+ the Library at all. For example, if a patent license would not permit
+ royalty-free redistribution of the Library by all those who receive copies
+ directly or indirectly through you, then the only way you could satisfy both
+ it and this License would be to refrain entirely from distribution of the
+ Library.
+
If any portion of this section is held invalid or unenforceable under any
+ particular circumstance, the balance of the section is intended to apply,
+ and the section as a whole is intended to apply in other circumstances.
+
It is not the purpose of this section to induce you to infringe any
+ patents or other property right claims or to contest validity of any such
+ claims; this section has the sole purpose of protecting the integrity of the
+ free software distribution system which is implemented by public license
+ practices. Many people have made generous contributions to the wide range of
+ software distributed through that system in reliance on consistent
+ application of that system; it is up to the author/donor to decide if he or
+ she is willing to distribute software through any other system and a
+ licensee cannot impose that choice.
+
This section is intended to make thoroughly clear what is believed to be
+ a consequence of the rest of this License.
+
12. If the distribution and/or use of the Library is restricted in
+ certain countries either by patents or by copyrighted interfaces, the
+ original copyright holder who places the Library under this License may add
+ an explicit geographical distribution limitation excluding those countries,
+ so that distribution is permitted only in or among countries not thus
+ excluded. In such case, this License incorporates the limitation as if
+ written in the body of this License.
+
13. The Free Software Foundation may publish revised and/or new versions
+ of the Lesser General Public License from time to time. Such new versions
+ will be similar in spirit to the present version, but may differ in detail
+ to address new problems or concerns.
+
Each version is given a distinguishing version number. If the Library
+ specifies a version number of this License which applies to it and "any
+ later version", you have the option of following the terms and conditions
+ either of that version or of any later version published by the Free
+ Software Foundation. If the Library does not specify a license version
+ number, you may choose any version ever published by the Free Software
+ Foundation.
+
14. If you wish to incorporate parts of the Library into other free
+ programs whose distribution conditions are incompatible with these, write to
+ the author to ask for permission. For software which is copyrighted by the
+ Free Software Foundation, write to the Free Software Foundation; we
+ sometimes make exceptions for this. Our decision will be guided by the two
+ goals of preserving the free status of all derivatives of our free software
+ and of promoting the sharing and reuse of software generally.
+
+
NO WARRANTY
+
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
+ THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+ PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+ OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO
+ THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY
+ PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
+ CORRECTION.
+
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+ REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+ INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+ OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO
+ LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR
+ THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER
+ SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGES.
+
END OF TERMS AND CONDITIONS
+
+
How to Apply These Terms to Your New Libraries
+
If you develop a new library, and you want it to be of the greatest possible
+ use to the public, we recommend making it free software that everyone can
+ redistribute and change. You can do so by permitting redistribution under
+ these terms (or, alternatively, under the terms of the ordinary General
+ Public License).
+
To apply these terms, attach the following notices to the library. It is
+ safest to attach them to the start of each source file to most effectively
+ convey the exclusion of warranty; and each file should have at least the
+ "copyright" line and a pointer to where the full notice is found.
+
< one line to give the library's name and a brief idea of what it does. >
+ Copyright (C) < year > < name of author >
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by the
+ Free Software Foundation; either version 2.1 of the License, or (at your
+ option) any later version.
+
This library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
You should have received a copy of the GNU Lesser General Public License
+ along with this library; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
Also add information on how to contact you by electronic and paper mail.
+
You should also get your employer (if you work as a programmer) or your
+ school, if any, to sign a "copyright disclaimer" for the library, if
+ necessary. Here is a sample; alter the names:
+
Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob'
+ (a library for tweaking knobs) written by James Random Hacker.
+
< signature of Ty Coon >, 1 April 1990
+ Ty Coon, President of Vice
+
+
+ {% include analytics.html %}
+
+
diff --git a/docs/_posts/2000-01-01-intro.md b/docs/_posts/2000-01-01-intro.md
new file mode 100755
index 00000000000..d64b7aa649c
--- /dev/null
+++ b/docs/_posts/2000-01-01-intro.md
@@ -0,0 +1,49 @@
+---
+title: "Home"
+bg: white
+color: black
+style: center
+---
+
+
+
+### a Java library of graph theory data structures and algorithms
+{: .text-blue}
+
+#### now with [Python bindings](https://pypi.org/project/jgrapht) too!
+{: .text-blue}
+
+
+
+### *flexible*
+
+##### **any object** can be used for vertex and edge types, with full **type safety** via generics
+##### edges can be **directed** or **undirected**, **weighted** or **unweighted**
+##### **simple graphs**, **multigraphs**, and **pseudographs**
+##### **unmodifiable** graphs allow modules to provide "read-only" access to internal graphs
+##### **listenable** graphs allow external listeners to track modification events
+##### live **subgraph** views on other graphs
+##### **compositions** and **converter views** for combining and adapting graphs
+##### **customizable** incidence and adjacency representations
+
+
+
+### *powerful*
+##### specialized **iterators** for graph traversal (**DFS**, **BFS**, etc)
+##### **algorithms** for path finding, clique detection, isomorphism detection, coloring, common ancestors, tours, connectivity, matching, cycle detection, partitions, cuts, flows, centrality, spanning, **and the list goes on**
+##### **exporters** and **importers** for popular external representations such as GraphViz
+##### **live adapters** to other graph libraries such as **JGraphX visualization** and **Guava Graphs**
+##### **generators** and **transforms**
+
+
+
+### *efficient*
+##### designed for performance, with **near-native** speed in many cases
+##### adapters for memory-optimized **fastutil** representation
+##### **sparse** representations for immutable graphs
+
+
+
+ Fork me on GitHub
+
+
diff --git a/docs/_posts/2000-01-02-jumpstart.md b/docs/_posts/2000-01-02-jumpstart.md
new file mode 100755
index 00000000000..91dd6ed132e
--- /dev/null
+++ b/docs/_posts/2000-01-02-jumpstart.md
@@ -0,0 +1,32 @@
+---
+title: "Jumpstart"
+bg: green
+color: black
+fa-icon: bolt
+---
+
+## Maven
+
+JGraphT releases are published to the **Maven Central Repository**, so you can
+easily add us as a dependency to your project:
+
+
+
+(There are also [instructions](https://github.com/jgrapht/jgrapht#using-via-maven) for how to use the latest **SNAPSHOT** build instead.)
+
+
+
+## Development Environment
+
+First, find out how to set up [your favorite IDE (or the command line)](https://github.com/jgrapht/jgrapht/wiki/Users:-How-to-use-JGraphT-as-a-dependency-in-your-projects) to work with JGraphT.
+
+
+
+## Hello JGraphT
+
+Next, try compiling and running the [hello world](guide/HelloJGraphT) example.
+
+Once you get that working, dig into the [user guide](guide/UserOverview) to learn more about JGraphT!
diff --git a/docs/_posts/2000-01-03-docs.md b/docs/_posts/2000-01-03-docs.md
new file mode 100755
index 00000000000..4f0c24862cd
--- /dev/null
+++ b/docs/_posts/2000-01-03-docs.md
@@ -0,0 +1,15 @@
+---
+title: "Docs"
+bg: blue
+color: black
+fa-icon: book
+---
+
+## [README](https://github.com/jgrapht/jgrapht/blob/master/README.md)
+## [User Guide](guide/UserOverview)
+## [Wiki](https://github.com/jgrapht/jgrapht/wiki)
+## [Javadoc for latest release](javadoc)
+## [Javadoc for latest SNAPSHOT build](javadoc-SNAPSHOT)
+## Javadoc for older releases, e.g. [javadoc-1.0.0](javadoc-1.0.0)
+## [Documentation for python bindings](https://python-jgrapht.readthedocs.io)
+## [Research Paper in ACM TOMS](https://dl.acm.org/doi/10.1145/3381449)
diff --git a/docs/_posts/2000-01-04-download.md b/docs/_posts/2000-01-04-download.md
new file mode 100755
index 00000000000..832e666ffec
--- /dev/null
+++ b/docs/_posts/2000-01-04-download.md
@@ -0,0 +1,30 @@
+---
+title: "Download"
+bg: turquoise
+color: white
+fa-icon: cloud-download
+style: center
+---
+
+# Latest Release
+
+For development without Maven, or for [running demos from the command
+line](https://github.com/jgrapht/jgrapht/wiki/Users:-Running-JGraphT-demos), you can download a full archive of the release:
+
+
+
+Regardless of which archive format you download, you'll have the same [release contents](https://github.com/jgrapht/jgrapht#release-contents) after unpacking.
+
+
+
+# Historical Releases
+
+[Older releases](http://sourceforge.net/project/showfiles.php?group_id=86459&package_id=89784) are also available. They have less functionality, but may be useful with obsolete JDK's or JRE's.
+
diff --git a/docs/_posts/2000-01-05-community.md b/docs/_posts/2000-01-05-community.md
new file mode 100644
index 00000000000..2518f65102a
--- /dev/null
+++ b/docs/_posts/2000-01-05-community.md
@@ -0,0 +1,20 @@
+---
+title: "Community"
+bg: purple
+color: white
+fa-icon: users
+---
+
+## Get answers on [StackOverflow](https://stackoverflow.com/questions/tagged/jgrapht)
+
+## Browse [known issues](https://github.com/jgrapht/jgrapht/issues) or report [a new issue](https://github.com/jgrapht/jgrapht/wiki/Users:-Getting-Support)
+
+## Join [the user mailing list](https://sourceforge.net/projects/jgrapht/lists/jgrapht-users)
+
+## Check out [open pull requests](https://github.com/jgrapht/jgrapht/pulls)
+
+## Learn how to [contribute your first improvement](https://github.com/jgrapht/jgrapht/wiki/Dev-guide:-Become-a-Contributor)
+
+## Tell us your success story: [how are you are using JGraphT?](https://github.com/jgrapht/jgrapht/wiki/Users:-Projects-Using-JGraphT)
+
+## Cite JGraphT [in your research](https://github.com/jgrapht/jgrapht/wiki/Users:-How-to-cite-JGraphT)
diff --git a/docs/_posts/2000-01-06-news.md b/docs/_posts/2000-01-06-news.md
new file mode 100644
index 00000000000..df9cb04942a
--- /dev/null
+++ b/docs/_posts/2000-01-06-news.md
@@ -0,0 +1,20 @@
+---
+title: "News"
+bg: orange
+color: white
+fa-icon: exclamation
+style: center
+---
+## **2-May-2023:** Release 1.5.2 is now available!
+
+## **29-Jun-2020:** First Release of Python Bindings!
+### Read the [announcement](https://medium.com/@dimitrios.michail/announcing-the-python-bindings-of-jgrapht-918d0cf386de) here.
+
+## **14-Jun-2020:** Release 1.5.0 is now available!
+### Read the [release announcement](https://sourceforge.net/p/jgrapht/news/2020/06/jgrapht-version-150-released/) for more info.
+
+## **21-May-2020:** JGraphT Research Paper Published!
+### [Our paper](https://dl.acm.org/doi/10.1145/3381449), published in the ACM Transactions on Mathematical Software, provides an in-depth look at the design of JGraphT, and also includes performance comparisons against other libraries.
+
+## **21-Feb-2020:** Release 1.4.0 is now available!
+### Read the [release announcement](https://sourceforge.net/p/jgrapht/news/2020/02/jgrapht-version-140-released/) for more info.
diff --git a/docs/_posts/2000-01-07-ack.md b/docs/_posts/2000-01-07-ack.md
new file mode 100644
index 00000000000..cfd81624c4f
--- /dev/null
+++ b/docs/_posts/2000-01-07-ack.md
@@ -0,0 +1,37 @@
+---
+title: "Thanks"
+bg: lavender
+fa-icon: heart
+color: black
+style: center
+---
+
+The JGraphT team is grateful to all of our [contributors](https://github.com/jgrapht/jgrapht/blob/master/CONTRIBUTORS.md) over the years for making the project what it is today!
+
+
+
+
+
+JGraphT is dual-licensed under [LGPL 2.1](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html) and [EPL 2.0](https://www.eclipse.org/legal/epl-2.0/). As a recipient of JGraphT, you may choose which license to receive the code under. Licensing information for libraries on which the project depends is available in the [README](https://github.com/jgrapht/jgrapht#dependencies).
+
+Project development takes place on [github](https://github.com/jgrapht/jgrapht), but we still make use of [sourceforge](https://sourceforge.net/projects/jgrapht) for some resources as well.
+
+This website is built using
+[Jekyll](https://github.com/jekyll/jekyll), with help from the
+[SinglePaged theme](https://github.com/t413/SinglePaged) and the [Primer theme](https://github.com/pages-themes/primer).
+
+
+
+
+If you enjoy using JGraphT, show us by clicking the **Like** button for
+our [Facebook page](https://www.facebook.com/jgrapht)!
+
+
+
+
diff --git a/docs/combo.css b/docs/combo.css
new file mode 100644
index 00000000000..c64e1a6b694
--- /dev/null
+++ b/docs/combo.css
@@ -0,0 +1,5 @@
+---
+---
+{% include css/base.css %}
+{% include css/skeleton.css %}
+{% include css/main.css %}
diff --git a/docs/guide-templates/GuavaAdapter.md b/docs/guide-templates/GuavaAdapter.md
new file mode 100644
index 00000000000..66d9a6e8d75
--- /dev/null
+++ b/docs/guide-templates/GuavaAdapter.md
@@ -0,0 +1,29 @@
+---
+title: Guava Graph Adapter
+---
+
+# {{ page.title }}
+
+If you are using [Guava's common.graph data structure](https://github.com/google/guava/wiki/GraphsExplained), and would like to take advantage of an algorithm implemented by JGraphT, it's quite straightforward to do this via the adapters supplied by JGraphT.
+
+For example, suppose you've created a Guava graph as follows:
+
+```java
+:[source code](http://code.jgrapht.org/raw/master/jgrapht-guava/src/test/java/org/jgrapht/graph/guava/MutableGraphAdapterTest.java?example=createGuavaGraph)
+```
+
+The graph does not have any information associated with the edges, so we can use JGraphT's [MutableGraphAdapter](https://jgrapht.org/javadoc/org.jgrapht.guava/org/jgrapht/graph/guava/MutableGraphAdapter.html) to view it in JGraphT:
+
+```java
+:[source code](http://code.jgrapht.org/raw/master/jgrapht-guava/src/test/java/org/jgrapht/graph/guava/MutableGraphAdapterTest.java?example=adaptGuavaGraph)
+```
+
+Now suppose we want to find a [minimum vertex cover](https://brilliant.org/wiki/vertex-cover) for this graph. JGraphT supplies [several algorithms](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/alg/vertexcover/package-summary.html) for this purpose:
+
+```java
+:[source code](http://code.jgrapht.org/raw/master/jgrapht-guava/src/test/java/org/jgrapht/graph/guava/MutableGraphAdapterTest.java?example=findVertexCover)
+```
+
+Since the result is just a set of strings, it can be used to directly reference the JGraphT view as well as the underlying Guava graph.
+
+For more information on the available adapters, please see the [org.jgrapht.graph.guava javadoc](https://jgrapht.org/javadoc/org.jgrapht.guava/org/jgrapht/graph/guava/package-summary.html).
diff --git a/docs/guide-templates/HelloJGraphT.md b/docs/guide-templates/HelloJGraphT.md
new file mode 100644
index 00000000000..0f7f3a4d6df
--- /dev/null
+++ b/docs/guide-templates/HelloJGraphT.md
@@ -0,0 +1,9 @@
+---
+title: Hello JGraphT Complete Example
+---
+
+# {{ page.title }}
+
+```java
+:[source code](http://code.jgrapht.org/raw/master/jgrapht-demo/src/main/java/org/jgrapht/demo/HelloJGraphT.java)
+```
diff --git a/docs/guide-templates/LabeledEdges.md b/docs/guide-templates/LabeledEdges.md
new file mode 100644
index 00000000000..0b68f6e7e88
--- /dev/null
+++ b/docs/guide-templates/LabeledEdges.md
@@ -0,0 +1,47 @@
+---
+title: Labeled Edges
+---
+
+# {{ page.title }}
+
+
+A common requirement for JGraphT applications is the need to associate a label
+with each edge. This can be accomplished efficiently via a custom edge class:
+
+```java
+:[source code](http://code.jgrapht.org/raw/master/jgrapht-demo/src/main/java/org/jgrapht/demo/LabeledEdges.java?example=edgeclass)
+```
+
+JGraphT's default graph and edge implementations take care of
+maintaining the connectivity information between vertices, so the
+custom edge subclass only needs to store the label. Since the custom
+edge class does not override `equals`/`hashCode`, each edge object is
+distinct from every other edge object (regardless of whether they
+share the same label). Consequently, labels do not have to be
+unique within the same graph.
+
+As defined above, `RelationshipEdge` could be used in either a
+directed or undirected graph. In the example below, we apply it to a
+a backstabby form of non-symmetric friendship via a directed graph:
+
+```java
+:[source code](http://code.jgrapht.org/raw/master/jgrapht-demo/src/main/java/org/jgrapht/demo/LabeledEdges.java?example=create)
+```
+
+Since the `RelationshipEdge` class does not have a default constructor, edges
+must be explicitly instantiated and added via [addEdge(V,V,E)](http://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/Graph.html#addEdge-V-V-E-) rather than implicitly instantiated via
+[addEdge(V,V)](http://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/Graph.html#addEdge-V-V-).
+
+Once the graph has been populated, label information can be accessed during traversal:
+
+```java
+:[source code](http://code.jgrapht.org/raw/master/jgrapht-demo/src/main/java/org/jgrapht/demo/LabeledEdges.java?example=print)
+```
+
+Given two vertices, an application can check the label on the edge between them by using [getEdge(V,V)](http://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/Graph.html#getEdge-V-V-):
+
+```java
+:[source code](http://code.jgrapht.org/raw/master/jgrapht-demo/src/main/java/org/jgrapht/demo/LabeledEdges.java?example=isEnemyOf)
+```
+
+You can find the complete source code for this example at [LabeledEdge.java](https://github.com/jgrapht/jgrapht/blob/master/jgrapht-demo/src/main/java/org/jgrapht/demo/LabeledEdges.java)
diff --git a/docs/guide-templates/Sux4JImplementations.md b/docs/guide-templates/Sux4JImplementations.md
new file mode 100644
index 00000000000..18fe1ab7155
--- /dev/null
+++ b/docs/guide-templates/Sux4JImplementations.md
@@ -0,0 +1,54 @@
+---
+title: Sux4J-Based Implementations
+---
+
+# {{ page.title }}
+
+[Sux4J](https://sux4j.di.unimi.it/) is a library containing
+implementations of [succinct data structures](https://en.wikipedia.org/wiki/Succinct_data_structure)
+in Java. Such structures can be used to store graphs in a very compact form. For example,
+the memory footprint of the [English Wikipedia graph in 2013](http://law.di.unimi.it/webdata/enwiki-2013/)
+would be a few gigabytes in a trivial object-based representation, it is 1.6GB in JGraphT's
+[sparse representation](https://jgrapht.org/javadoc/org.jgrapht.opt/org/jgrapht/opt/graph/sparse/SparseIntDirectedGraph.html),
+but it is just 500MB in a succinct representation. The denser the graph, the more
+marked these differences will be.
+
+The implementations in the package
+[org.jgrapht.sux4j](https://jgrapht.org/javadoc/org.jgrapht.unimi.dsi/org/jgrapht/sux4j/package-summary.html)
+make it possible to use succinct representation of graphs in JGraphT.
+The implementations are serializable, and you can download ready-made
+graphs in this form from the [LAW web site](http://law.di.unimi.it/datasets.php).
+
+The typical use case for these adapters is:
+
+- You need a compact format.
+- You have less than 231 vertices and less than 231 edges.
+- You have metadata associated with the vertices and with the edges.
+- Optionally, you need fast [adjacency tests](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/Graph.html#containsEdge%28V,V%29).
+
+Such metadata can be easily stored in an array or list indexed by the vertices or
+the edges. If you have metadata on the vertices only, or if your number
+of vertices or edges does not satisfy the limitations above, a [WebGraph
+adapter](https://jgrapht.org/javadoc/org.jgrapht.unimi.dsi/org/jgrapht/webgraph/package-summary.html)
+might be more appropriate. A separate [guide](WebGraphAdapters) is available for
+WebGraph adapters.
+
+The two main implementations are [`SuccinctDirectedGraph`](https://jgrapht.org/javadoc/org.jgrapht.unimi.dsi/org/jgrapht/sux4j/SuccinctDirectedGraph.html)
+and [`SuccinctUndirectedGraph`](https://jgrapht.org/javadoc/org.jgrapht.unimi.dsi/org/jgrapht/sux4j/SuccinctUndirectedGraph.html).
+They both use pairs to represent edges, but you can easily [map edges](https://jgrapht.org/javadoc/org.jgrapht.unimi.dsi/org/jgrapht/sux4j/SuccinctDirectedGraph.html#getEdgeFromIndex%28long%29)
+in a contiguous segment of integers starting from zero; the mapping is reasonably fast.
+
+Note that one of the benefits of the succinct representation used by these classes is that
+[adjacency tests](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/Graph.html#containsEdge%28V,V%29) are very fast.
+
+If you need, however, an implementation whose vertex and edge type is
+`Integer` (for example, for usage with [Python
+bindings](https://pypi.org/project/jgrapht/)), there are classes
+[`SuccinctIntDirectedGraph`](https://jgrapht.org/javadoc/org.jgrapht.unimi.dsi/org/jgrapht/sux4j/SuccinctIntDirectedGraph.html)
+and
+[`SuccinctIntUndirectedGraph`](https://jgrapht.org/javadoc/org.jgrapht.unimi.dsi/org/jgrapht/sux4j/SuccinctIntUndirectedGraph.html).
+These classes, however, are fairly slow due to the necessity of
+continuously remapping edges from pairs to indices. We suggest that you use them
+only in the directed case and for outgoing arcs. However, in some cases
+they might provide the only representation of this type that is small
+enough to be loaded in main memory.
diff --git a/docs/guide-templates/UserOverview.md b/docs/guide-templates/UserOverview.md
new file mode 100644
index 00000000000..dc7454dff5b
--- /dev/null
+++ b/docs/guide-templates/UserOverview.md
@@ -0,0 +1,471 @@
+---
+title: Overview for Application Developers
+---
+
+# {{ page.title }}
+{:.no_toc}
+
+This overview will help get you started with using the JGraphT library in
+your own applications. We'll cover the following topics:
+
+1. Table of contents
+{:toc}
+
+## Development Setup
+
+First, [set up your development environment](https://github.com/jgrapht/jgrapht/wiki/Users:-How-to-use-JGraphT-as-a-dependency-in-your-projects) with JGraphT as a dependency.
+
+## Hello JGraphT
+
+In JGraphT, a graph is defined as a set of vertices connected by a set
+of edges. Many possible variations on this fundamental definition are
+supported, as we'll explain further on; but for now, let's take a look
+at a simple example of creating a directed graph:
+
+```java
+:[source code](http://code.jgrapht.org/raw/master/jgrapht-demo/src/main/java/org/jgrapht/demo/HelloJGraphT.java?example=uriCreate)
+```
+
+Notice how the vertex objects are instances of the
+[java.net.URI](https://docs.oracle.com/javase/8/docs/api/java/net/URI.html)
+class. JGraphT does not supply a vertex class itself; instead, you're
+free to choose your own based on whatever works best for your
+application, subject to certain restrictions mentioned below.
+
+You are also free to choose your own edge class. If you don't need to
+associate any application-specific information with your edges, you
+can just use the library-supplied
+[DefaultEdge](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/graph/DefaultEdge.html)
+as in this example. The graph constructor takes the edge class as a
+parameter so that it can create new edge objects implicitly whenever
+`addEdge` is called to connect two vertices.
+
+## Choosing Vertex and Edge Types
+
+There are a number of restrictions to be aware of when choosing custom
+vertex and edge types, mostly regarding override of the
+`equals`/`hashCode` methods; be sure to read through
+[this overview](VertexAndEdgeTypes).
+
+## Graph Accessors
+
+Once a graph has been created, an application can access its vertices
+and edges directly via live set views:
+
+```java
+:[source code](http://code.jgrapht.org/raw/master/jgrapht-demo/src/main/java/org/jgrapht/demo/HelloJGraphT.java?example=findVertex)
+```
+
+Here we iterate over all vertices of the graph via the [vertexSet](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/Graph.html#vertexSet--) method, filtering for only those
+whose URL has `www.jgrapht.org` for its hostname; in our example, we can
+expect to find exactly one match, which we obtain via `findAny().get()`.
+
+Given a reference to a vertex or edge, we can find connections via
+`Graph` methods such as `getEdgeSource`, `getEdgeTarget`, `edgesOf`,
+`incomingEdgesOf`, and `outgoingEdgesOf`. Given a pair of vertices,
+we can find the edge(s) connecting them via `getEdge` and
+`getAllEdges`. Here, collection-returning methods should not to be
+assumed to be live views (although they may be for some graph
+implementations). In some cases, the returned collections may be
+unmodifiable, while in others they may consist of transient results.
+In no case should an application expect modifications to the returned
+collection to result in modifications to the underyling graph.
+
+The [Graphs](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/Graphs.html)
+utility class has additional convenience methods such as
+[successorListOf](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/Graphs.html#successorListOf-org.jgrapht.Graph-V-)
+and
+[getOppositeVertex](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/Graphs.html#getOppositeVertex-org.jgrapht.Graph-E-V-)
+for easing common access patterns.
+
+Note that the default graph implementations guarantee predictable
+ordering for the collections that they maintain; so, for example, if
+you add vertices in the order `[B, A, C]`, you can expect to see them in
+that order when iterating over the vertex set. However, this is not a
+requirement of the `Graph` interface, so other graph implementations
+are not guaranteed to honor it.
+
+## Graph Structures
+
+Besides choosing your vertex and edge classes, JGraphT also allows you
+to choose a graph structure. One way to do so is by instantiating a
+concrete class which implements the
+[Graph](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/Graph.html) interface,
+as with `DefaultDirectedGraph` in the example above. When doing so,
+you can make your selection from the table below (or from your own
+subclasses of any of these).
+
+| Class Name | Edges | Self-loops | Multiple edges | Weighted |
+|:----------------------------:|:--------:|:----------:|:--------------:|:--------:|
+|SimpleGraph |undirected|no | no |no |
+|Multigraph |undirected|no | yes |no |
+|Pseudograph |undirected|yes | yes |no |
+|DefaultUndirectedGraph |undirected|yes | no |no |
+|SimpleWeightedGraph |undirected|no | no |yes |
+|WeightedMultigraph |undirected|no | yes |yes |
+|WeightedPseudograph |undirected|yes | yes |yes |
+|DefaultUndirectedWeightedGraph|undirected|yes | no |yes |
+|SimpleDirectedGraph |directed |no | no |no |
+|DirectedMultigraph |directed |no | yes |no |
+|DirectedPseudograph |directed |yes | yes |no |
+|DefaultDirectedGraph |directed |yes | no |no |
+|SimpleDirectedWeightedGraph |directed |no | no |yes |
+|DirectedWeightedMultigraph |directed |no | yes |yes |
+|DirectedWeightedPseudograph |directed |yes | yes |yes |
+|DefaultDirectedWeightedGraph |directed |yes | no |yes |
+
+The structural properties are as follows:
+
+* undirected edges: an edge simply connects a vertex pair, without imposing a direction
+* directed edges: an edge has a source and a target
+* self-loops: whether to allow edges which connect a vertex to itself
+* multiple edges: whether to allow more than one edge between the same vertex pair (note that in a directed graph, two edges between the same vertex pair but with opposite direction do not count as multiple edges)
+* weighted: whether a double weight is associated with each edge (for these graph types, you'll usually want to use [DefaultWeightedEdge](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/graph/DefaultWeightedEdge.html) as your edge class); unweighted graphs are treated as if they have a uniform edge weight of 1.0, which allows them to be used in algorithms such as finding a shortest path
+
+The [GraphType](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/GraphType.html)
+interface allows you to access this metadata for an existing graph
+instance (using the
+[getType](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/Graph.html#getType--)
+accessor).
+
+You can also use [GraphTypeBuilder](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/graph/builder/GraphTypeBuilder.html) to instantiate a new graph without directly constructing a concrete class:
+
+```java
+:[source code](http://code.jgrapht.org/raw/master/jgrapht-demo/src/main/java/org/jgrapht/demo/GraphBuilderDemo.java?example=buildType)
+```
+
+`GraphTypeBuilder` uses the property values you supply in order to
+automatically choose the correct concrete class for you. This is
+generally a cleaner pattern to follow, but it's not applicable if you
+end up needing to subclass one of the provided graph classes.
+
+## Graph Modification
+
+Earlier, we saw how to add vertices and edges to a new graph by
+calling the
+[addVertex](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/Graph.html#addVertex-V-)
+and
+[addEdge](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/Graph.html#addEdge-V-V-)
+methods on the `Graph` interface. Likewise, there are corresponding
+methods for removing graph components. All of these methods are
+modeled on the `java.util` collections framework, so:
+
+* adding a duplicate object to a set (e.g. when adding a vertex) is not an error, but the duplicate is discarded
+* adding a duplicate object to a non-unique collection (e.g. when adding an edge to a multigraph) inserts the new instance
+* attempting to remove an object which was not part of the graph is not an error
+* but _attempting to access attributes of an object which is not part of the graph_ is strictly forbidden, and results in an `IllegalArgumentException` (e.g. when you ask for the edges of a vertex, but the vertex is not currently part of the graph)
+
+The strictness enforcement mentioned above is the default in order to
+help catch application errors. There are two convenience helpers
+available to assist with this when adding components to a graph; both
+of them take care of automatically adding vertices whenever edges are
+added:
+
+* The [Graphs](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/Graphs.html) utility class provides methods such as [addEdgeWithVertices](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/Graphs.html#addEdgeWithVertices-org.jgrapht.Graph-V-V-)
+* The [GraphBuilder](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/graph/builder/AbstractGraphBuilder.html) framework also allows you to use [method chaining](https://en.wikipedia.org/wiki/Method_chaining) when populating data in a new graph.
+
+Here's an example using `GraphBuilder` to construct a
+[kite graph](http://mathworld.wolfram.com/KiteGraph.html):
+
+```java
+:[source code](http://code.jgrapht.org/raw/master/jgrapht-demo/src/main/java/org/jgrapht/demo/GraphBuilderDemo.java?example=buildEdges)
+```
+
+The integer vertex objects are added to the graph implicitly as the
+referencing edges are added. Note that building the graph proceeds in
+two phases; first `buildEmptySimpleGraph` builds an empty graph
+instance for the specified graph type, then `GraphBuilder` takes over
+for populating the vertices and edges.
+
+### Vertex and Edge Suppliers
+
+JGraphT optionally allows you to provide a graph with vertex and edge
+suppliers. When these are available, the graph will automatically
+construct a new object instance whenever one is not explicitly
+supplied by the corresponding `add` method.
+
+### Modification Listeners
+
+JGrapht provides a framework for reacting to graph modifications via
+the
+[ListenableGraph](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/ListenableGraph.html)
+interface. By default, graph instances are not listenable for
+efficiency; here's how to use the framework:
+
+* wrap your graph instance via [DefaultListenableGraph](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/graph/DefaultListenableGraph.html)
+* perform all modifications on the wrapper (not the underlying graph instance)
+* register one or more [GraphListener](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/event/GraphListener.html) to react to modification events
+
+This can be a convenient way to keep other data structures or
+visualizations in sync with graph changes. For example, suppose your
+graph represents a CAD model being visualized; then every time the
+graph is edited, all affected views can be automatically refreshed
+from listener events.
+
+### Concurrency
+
+The default graph implementations are not safe for concurrent reads
+and writes from different threads. If an application attempts to
+modify a graph in one thread while another thread is reading or
+writing the same graph, undefined behavior will result. However,
+concurrent reads against the same graph from different threads are
+safe. (Note that the Graph interface itself makes no such guarantee,
+so for non-default implementations, different rules may apply.)
+
+If you need support for concurrent reads and writes, consider using
+the
+[AsSynchronizedGraph wrapper](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/graph/concurrent/AsSynchronizedGraph.html).
+
+## Graph Generation
+
+Besides constructing vertices and edges individually, applications can
+also generate graph instances according to predefined patterns. This
+is often useful for generating test cases or default topologies.
+JGraphT provides a number of different generators for this purpose in
+the
+[org.jgrapht.generate](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/generate/package-summary.html)
+package. Here's an example of generating a [complete graph](http://mathworld.wolfram.com/CompleteGraph.html):
+
+```java
+:[source code](http://code.jgrapht.org/raw/master/jgrapht-demo/src/main/java/org/jgrapht/demo/CompleteGraphDemo.java?example=class)
+```
+
+The `SIZE` parameter controls the number of vertices added to the
+graph (which in turn dictates the number of edges added).
+
+## Graph Traversal
+
+Once you've created a graph, you can traverse it using an ordering
+such as depth-first, breadth-first, or topological. JGraphT provides
+for this via package
+[org.jgrapht.traverse](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/traverse/package-summary.html).
+The common interface is
+[GraphIterator](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/traverse/GraphIterator.html),
+which specializes the generic Java `Iterator` interface with JGraphT
+specifics. A graph iterator produces vertices in the requested order;
+as the iteration proceeds, additional information (such as when a
+particular edge is traversed) can be obtained by registering a
+[TraversalListener](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/event/TraversalListener.html).
+(The specific meaning of traversal events varies with the iterator
+type.)
+
+Here's an example using depth-first ordering on our HelloJGraphT example:
+
+```java
+:[source code](http://code.jgrapht.org/raw/master/jgrapht-demo/src/main/java/org/jgrapht/demo/HelloJGraphT.java?example=traverse)
+```
+
+with expected output
+
+```
+http://www.jgrapht.org
+http://www.wikipedia.org
+http://www.google.com
+```
+
+In this example, no extra information is required during the
+traversal, so it is treated as a standard Java `Iterator`.
+
+## Graph Algorithms
+
+Beyond basic traversals, you'll often want to run more complex algorithms on
+a graph. JGraphT provides quite a few of these, so they are subcategorized
+under the
+[org.jgrapht.alg parent package](https://jgrapht.org/javadoc/org.jgrapht.core/module-summary.html).
+For example, various shortest path algorithms are implemented in
+[org.jgrapht.alg.shortestpath](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/alg/shortestpath/package-summary.html).
+
+In cases where there are alternative algorithms available for the same
+problem, the commonality is abstracted via an interface in
+[org.jgrapht.alg.interfaces](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/alg/interfaces/package-summary.html).
+This makes it easier to write application code which selects an
+optimal algorithm implementation for a given graph instance.
+
+Here's an example of running [strongly connected components](http://mathworld.wolfram.com/StronglyConnectedComponent.html) and shortest path algorithms on a directed graph:
+
+```java
+:[source code](http://code.jgrapht.org/raw/master/jgrapht-demo/src/main/java/org/jgrapht/demo/DirectedGraphDemo.java?example=main)
+```
+
+with expected output
+
+```
+Strongly connected components:
+([i], [])
+([h], [])
+([e, f, g], [(e,f), (f,g), (g,e)])
+([a, b, c, d], [(a,b), (b,d), (d,c), (c,a)])
+
+Shortest path from i to c:
+[(i : h), (h : e), (e : d), (d : c)]
+
+Shortest path from c to i:
+null
+```
+
+## Graph Serialization and Export/Import
+
+The default graph implementations provided by JGraphT are
+[serializable](https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html)
+as long as you choose vertex and edge types which are themselves
+serializable.
+
+Serialization is a convenient way to store a graph instance as binary
+data, but the format is not human-readable, and we don't make any
+guarantee of serialization compatibility across JGraphT versions. (In
+other words, if you serialize a graph with version X, and then attempt
+to deserialize it with version X+1, an exception may be thrown.)
+
+To address this, JGraphT provides module
+[org.jgrapht.io](https://jgrapht.org/javadoc/org.jgrapht.io/module-summary.html)
+for exporting and importing graphs in a variety of standard formats.
+These can also be used for data interchange with other applications.
+
+Continuing our HelloJGraphT example, here's how to export a graph in [GraphViz .dot](https://www.graphviz.org/) format:
+
+```java
+:[source code](http://code.jgrapht.org/raw/master/jgrapht-demo/src/main/java/org/jgrapht/demo/HelloJGraphT.java?example=render)
+```
+
+with expected output
+
+```
+strict digraph G {
+ www_google_com [ label="http://www.google.com" ];
+ www_wikipedia_org [ label="http://www.wikipedia.org" ];
+ www_jgrapht_org [ label="http://www.jgrapht.org" ];
+ www_jgrapht_org -> www_wikipedia_org;
+ www_google_com -> www_jgrapht_org;
+ www_google_com -> www_wikipedia_org;
+ www_wikipedia_org -> www_google_com;
+}
+```
+
+which GraphViz renders as:
+
+
+
+If you just want a quick dump of the structure of a small graph, you
+can also use the `toString` method; here's another example from the HelloJGraphT demo:
+
+```java
+:[source code](http://code.jgrapht.org/raw/master/jgrapht-demo/src/main/java/org/jgrapht/demo/HelloJGraphT.java?example=toString)
+```
+
+which produces
+
+```
+([v1, v2, v3, v4], [{v1,v2}, {v2,v3}, {v3,v4}, {v4,v1}])
+
+```
+
+First comes the vertex set, followed by the edge set. Directed edges
+are rendered with round brackets, whereas undirected edges are
+rendered with curly brackets. Custom edge attributes are not
+rendered. If you want a nicer rendering, you can override
+[toStringFromSets](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/graph/AbstractGraph.html#toStringFromSets-java.util.Collection-java.util.Collection-boolean-)
+in your graph implementation, but you're probably better off using one
+of the exporters instead.
+
+## Graph Cloning
+
+The `Graph` interface does not expose a public `clone` method, because
+we do not require all implementations to be cloneable. However, all
+subclasses of
+[AbstractBaseGraph](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/graph/AbstractBaseGraph.html)
+are cloneable. The clone semantics are shallow in that the same vertex
+and edge objects are shared between the original graph and the clone;
+however, the vertex and edge sets and all associated connectivity
+structures are copied, not shared, so that the two graphs are otherwise
+independent.
+
+## Graph Comparisons
+
+The default JGraphT implementations of the `Graph` interface override `equals`/`hashCode`, so it's possible to use them to compare two graph instances. However, it's important to note that the definition of equality used may not be the one you are expecting. Here are the rules used:
+
+* the two graph instances must be of identical concrete class (e.g. `DefaultDirectedGraph`)
+* the vertex sets of the two graph instances must be equal (using the definition from [java.util.Set](https://docs.oracle.com/javase/7/docs/api/java/util/Set.html#equals(java.lang.Object)), and taking into account the `equals` implementation of the vertex type you've chosen)
+* the edges sets of the two graph instances must be equal (again using the `java.util.Set` definition, and taking into account the `equals` implementation of the edge type you've chosen)
+* for a given edge, the source/target/weight must be equal in both graph instances (for undirected graphs, the source/target distinction is ignored)
+
+In general, an exact copy of a graph object via `Graphs.addGraph` or
+`clone` will be equal to the original according to this definition
+(assuming the same concrete class is chosen for the copy). However,
+for copy via serialization followed by deserialization, this won't
+hold unless both the vertex and edge classes override `equals`/`hashCode`.
+
+If you were expecting a structural comparison instead, then you might
+want to investigate the
+[isomorphism](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/alg/isomorphism/package-summary.html)
+package. In the unrestricted case, isomorphism detection can take
+exponential time, but it can be speeded up significantly if you're
+able to guide it with a labeling. For example, suppose you have two
+graphs with anonymous edges, but the vertex set is the same, and you
+want to decide whether the graphs are effectively equal. In that case, you can run an
+isomorphism inspector with a comparator specified for the vertices.
+Then JGraphT can tell you whether the two graphs are structurally
+equivalent (and if so, provide a mapping between the edge objects).
+
+## Graph Wrappers
+
+Besides core graph data structures, JGraphT also provides a number of useful wrappers which allow you to define live _transformed_ views into other graphs:
+
+* [AsGraphUnion](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/graph/AsGraphUnion.html): a union of two underlying graphs
+* [AsSubgraph](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/graph/AsSubgraph.html): a subgraph (possibly induced) of an underlying graph
+* [AsUndirectedGraph](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/graph/AsUndirectedGraph.html): an undirected view of an underlying directed graph (with edge directions ignored)
+* [AsUnmodifiableGraph](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/graph/AsUnmodifiableGraph.html): an unmodifiable view of an underlying graph
+* [AsUnweightedGraph](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/graph/AsUnweightedGraph.html): an unweighted view of a underlying weighted graph (ignoring all edge weights and treating them as 1.0 instead)
+* [AsWeightedGraph](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/graph/AsWeightedGraph.html): a weighted view of an underlying unweighted graph (with edge-specific weights imposed via a map)
+* [EdgeReversedGraph](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/graph/EdgeReversedGraph.html): an edge-reversed view of a directed graph
+
+Wrappers add some access cost, so if you don't need a live view, and you will be accessing the transformed results heavily, then you can copy the view to a snapshot using [Graphs.addGraph](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/Graphs.html#addGraph-org.jgrapht.Graph-org.jgrapht.Graph-).
+
+## Graph Adapters
+
+### Guava Graph Adapter
+
+If you are already using
+[com.google.common.graph](https://google.github.io/guava/releases/snapshot/api/docs/com/google/common/graph/package-summary.html)
+for representing graphs, it's easy to interoperate with JGraphT by
+using our
+[adapter package](https://jgrapht.org/javadoc/org.jgrapht.guava/org/jgrapht/graph/guava/package-summary.html).
+Simply instantiate the correct adapter on top of your Guava graph, and
+you'll have an implementation of JGraphT's `Graph` interface which
+stays in sync with the Guava graph automatically, at no extra memory
+cost. Now you can [run JGraphT algorithms](GuavaAdapter) on top of your Guava graph,
+or run our importers or exporters against it.
+
+### Adapters for Very Large Graphs
+
+If you are trying to run algorithms over very large graphs, the
+default JGraphT representations may eat up too much of your main
+memory. Instead, you can use the adapters provided for
+[WebGraph](WebGraphAdapters) or
+[succinct graphs](Sux4JImplementations) (via Sux4J).
+
+### JGraphX Adapter
+
+JGraphT also provides an adapter that lets you use a JGraphT graph
+instance as the data model for a
+[JGraphX](https://jgraph.github.io/mxgraph/docs/manual_javavis.html)
+visualization. All you need to do is wrap your JGraphT graph with
+[org.jgrapht.ext.JGraphXAdapter](https://jgrapht.org/javadoc/org.jgrapht.ext/org/jgrapht/ext/JGraphXAdapter.html) as in the following example:
+
+```java
+:[source code](http://code.jgrapht.org/raw/master/jgrapht-demo/src/main/java/org/jgrapht/demo/JGraphXAdapterDemo.java?example=full)
+```
+
+## Running Demos
+
+If you want to run the demo programs excerpted throughout this
+overview, see
+[these instructions](https://github.com/jgrapht/jgrapht/wiki/Users:-Running-JGraphT-demos).
+You can also find the full source code in
+[github](https://github.com/jgrapht/jgrapht/tree/master/jgrapht-demo/src/main/java/org/jgrapht/demo).
+
+## Browsing Unit Tests
+
+Another good way to learn how to use the various classes provided by
+JGraphT is to study their usage in unit tests. Here's the source code
+of
+[tests for the core classes](https://github.com/jgrapht/jgrapht/tree/master/jgrapht-core/src/test/java/org/jgrapht).
diff --git a/docs/guide-templates/VertexAndEdgeTypes.md b/docs/guide-templates/VertexAndEdgeTypes.md
new file mode 100644
index 00000000000..79337d43607
--- /dev/null
+++ b/docs/guide-templates/VertexAndEdgeTypes.md
@@ -0,0 +1,304 @@
+---
+title: Vertex and Edge Types
+---
+
+# {{ page.title }}
+{:.no_toc}
+
+When constructing a JGraphT graph, it's important to select the vertex
+and edge types carefully in order to ensure correct behavior while
+satisfying application requirements. This page walks through a number
+of variations based on common application use cases:
+
+1. Table of contents
+{:toc}
+
+## equals and hashCode
+
+Vertex and edge objects are used as keys inside of the default graph
+implementation, so when choosing their types, you must follow these
+rules:
+
+* You must follow the contract defined in `java.lang.Object` for both [equals](https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object)) and [hashCode](https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode()).
+* In particular, if you override either `equals` or `hashCode`, you must override them both
+* Your implementation for `hashCode` must produce a value which does not change over the lifetime of the object
+
+[This article](https://www.ibm.com/developerworks/java/library/j-jtp05273/index.html) explains some of the nuances.
+
+Additional guidelines are provided in the scenario-specific sections below.
+
+## Anonymous Vertices
+
+Applications interested only in graph structure (e.g. graph theory
+research) may want to save memory by keeping vertices as minimalist as
+possible. In this case, just use
+[java.lang.Object](https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html)
+as the vertex type. In this case, the vertex `hashCode` may serve as
+a "nearly" unique identifier during debugging.
+
+## Vertices as Key Values
+
+More common is for each vertex to represent a key value, as in the
+[HelloJGraphT](UserOverview#hello-jgrapht) example (where each vertex
+corresponds to a website identified by a URL). For this use case, a
+`String`, `Integer`, or similar class is a good choice for vertex
+type. In this case, it's important to note that the value must be
+unique within the graph. In other words, for a vertex of type
+`String`, the `String` value is an _identifier_, not a mere _label_.
+
+## Vertices with Attributes
+
+More sophisticated applications may need to associate non-key
+attributes (possibly multiple) with each vertex. The obvious way to
+do this is with a class that stores the attributes, but there are a
+few different cases to consider.
+
+### No keys
+
+If all attributes on the vertex are non-key, then the approach is
+straightforward. For example, suppose you are modeling molecular
+structures, where the vertices are atoms and the edges are the bonds
+between them. Then you might define a class
+
+```java
+class AtomVertex
+{
+ Element element; // using enum of the periodic table
+ int formalCharge; // for bookkeeping purposes
+ ... other atomic properties ...
+}
+```
+
+In this case, you should **not** override `equals` and `hashCode`,
+since there may be many distinct atoms with the exact same properties.
+
+### All keys
+
+Conversely, if all attributes are components of a key, then the
+approach is also simple. Suppose your application is a software
+package manager, and each vertex in your graph corresponds to a
+package, with edges representing package dependencies. Then you might
+define a class like
+
+```java
+class SoftwarePackageVertex
+{
+ final String orgName;
+ final String packageName;
+ final String packageVersion;
+
+ ... constructor etc ...
+
+ public String toString()
+ {
+ return orgName + "-" + packageName + "-" + packageVersion;
+ }
+
+ public int hashCode()
+ {
+ return toString().hashCode();
+ }
+
+ public boolean equals(Object o)
+ {
+ return (o instanceof SoftwarePackageVertex) && (toString().equals(o.toString()));
+ }
+}
+```
+
+Here, you almost certainly **do** want to override `equals` and
+`hashCode`, since there should not be more than one vertex object
+representing the same package version. And you'll be able to access
+an existing vertex in a graph just by constructing it, without having
+to iterate over all vertices in the graph to find it.
+
+Note that the fields are declared final; this is important since
+vertices and edges are used as hash keys, meaning their hash codes
+must never change after construction.
+
+### Key subset
+
+Now we come to the problematic case. Continuing the previous example,
+suppose you want to add a `releaseDate` field to
+`SoftwarePackageVertex` in order to track when the package version was
+released. This new field is not part of the key; it's just data. But
+what do we do about `equals`/`hashCode`?
+
+* It's not a good idea to incorporate `releaseDate` into them for a number of reasons. For example, if we want to reference the vertex for a package by its identifier, but we don't know its release date, how do we find the vertex? And what if the release date changes for an unreleased package? How do we avoid two distinct vertex objects representing the same package version?
+* However, if we don't incorporate `releaseDate` into `equals`/`hashCode`, then we could end up with inconsistencies due to two vertex objects with different `releaseDate` values being treated as equivalent.
+
+So if you try to implement this case, beware that you're likely to run into unforeseen pitfalls.
+
+## Vertices as Pointers
+
+A more flexible way to handle the situation above is to make the
+vertex refer to an external object rather than containing data itself.
+For the example above, the vertex type could be
+`SoftwarePackageVertex` as originally defined, without the release
+date. Then additional information such as the release date would be
+stored via a separate `SoftwarePackageVersion` class, with a map keyed
+on `SoftwarePackageVertex` for lookups. This keeps the graph
+representation clear, but adds some lookup cost.
+
+An optimization is to implement the vertex as a direct reference:
+
+```java
+class SoftwarePackageVertex
+{
+ final SoftwarePackageVersion version;
+
+ public String toString()
+ {
+ return version.keyString();
+ }
+
+ public int hashCode()
+ {
+ return toString().hashCode();
+ }
+
+ public boolean equals(Object o)
+ {
+ return (o instanceof SoftwarePackageVertex) && (toString().equals(o.toString()));
+ }
+}
+
+class SoftwarePackageVersion
+{
+ final String orgName;
+ final String packageName;
+ final String packageVersion;
+ Date releaseDate;
+
+ public String keyString()
+ {
+ return orgName + "-" + packageName + "-" + packageVersion;
+ }
+}
+```
+
+This way, we can construct a vertex from a package version at any
+time, and given a vertex, we can directly access package version
+information without any map lookup required. The application is still
+responsible for avoiding inconsistencies due to the existence of
+multiple SoftwarePackageVersion objects with the same key, but now
+that responsibility is separate from the graph representation.
+
+## Anonymous Edges
+
+Now let's move on to edge types. The most common case is that there
+is no information associated with an edge other than its connectivity.
+Generally, you can use the `DefaultEdge` class provided by JGraphT for
+this and not think about it any further. However, there is one point
+you should be aware of:
+
+* JGraphT optimizes `DefaultEdge`-based graphs by using an intrusive technique in which the connectivity information is stored inside the edge object itself (rather than inside the graph).
+
+As a result, if you need to add the same edge object to two different
+graphs, then those graphs must have the same vertex connections for
+that edge, otherwise undefined behavior will result. If this (rare)
+case applies to your application, then instead of using `DefaultEdge`,
+just use `java.lang.Object` as your edge type. Note that this adds a
+map lookup penalty to connectivity accessor methods.
+
+It's common in JGraphT for edge objects to be reused across graphs;
+for example, an algorithm may return a subgraph of the input graph as
+its result, and the subgraph will reuse subsets of the input graph's
+vertex and edge sets. In these cases, the connectivity equivalence is
+valid (or if it's not, the algorithm avoids reuse).
+
+## Weighted Edges
+
+Another common case is for each edge to bear a double-valued weight as
+its only attribute (e.g. a physical network with latency measured for
+each link). For this case, JGraphT supplies the `DefaultWeightedEdge`
+class, which extends the optimization mentioned in the previous
+section by storing the weight directly on the edge object.
+
+The same caveats apply, with the additional restriction that if a
+`DefaultWeightedEdge` is reused in another graph, it will have the
+same weight in both graphs. Again, if this presents a problem, then
+use `java.lang.Object` as your edge class instead.
+
+## Edges as Key Values
+
+Sometimes, applications may be able to associate a unique key value
+with each edge. For example, consider a graph representing money
+transfers between bank accounts, where the vertices represent the
+accounts and the edges represent the transfers. In this case, the
+application could use a `String` containing the transfer transaction
+ID as the edge type.
+
+* _NOTE:_ Although correct, this implementation may not be optimal, since it loses the connectivity optimization described for `DefaultEdge` above.
+
+However, it would definitely be **incorrect** to use the transaction
+amount as the edge type, since this is not unique across the entire
+graph. (A weighted edge could instead be used for this purpose.)
+
+## Edges with Attributes
+
+For edges with multiple attributes or non-key attributes, the same
+considerations as those
+[given previously for vertices](#vertices-with-attributes) apply. In
+addition, when defining a class which will be used as an edge type,
+applications will typically want to subclass either `DefaultEdge` or
+`DefaultWeightedEdge` (subject to the caveats already mentioned).
+Those base classes do not override `equals`/`hashCode`, but
+applications are free to do so in subclasses as appropriate.
+
+Note that when overriding `equals`/`hashCode` for an edge class, it is
+incorrect to incorporate the edge source/target into the operations;
+the edge identity is always independent of its connectivity.
+
+For an example of how to apply a `String` attribute as a non-key label
+on each edge, see [the LabeledEdges demo](LabeledEdges.md). JGraphT
+does not provide a labeled edge class since there are many different
+ways to implement this pattern.
+
+## Vertices and Edges as External Objects
+
+In some cases, an application may want to use existing complex objects
+as vertex and/or edge types directly. For example, consider an
+application in which the graph is used in a manager thread to optimize
+concurrent dataflow, with each vertex representing a worker thread and
+each edge representing a dataflow producer/consumer queue. In this
+case, it would be OK to use
+[java.lang.Thread](https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html)
+for the vertex type and
+[LinkedBlockingDeque](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/LinkedBlockingDeque.html)
+for the edge type (since these classes do no override
+`equals`/`hashCode`).
+
+However, if the queue implementation were such that it allowed two
+queue instances to be compared for value-equality via `equals`, then this
+would **not** be a good choice for edge type. In this case, it would
+be necessary to wrap the queue in a custom edge class which references
+it,
+[similar to what was described for vertices above](#vertices-as-pointers).
+
+## Labeled Edges in a Multigraph
+
+This is one case for which JGraphT does not currently support a 100%
+efficient implementation. Suppose we want to represent a
+[finite state machine](https://en.wikipedia.org/wiki/Finite-state_machine)
+using a pseudograph (allowing both self-loops and multiple edges
+between vertices). Vertices will represent states, and edges
+will represent transitions. For the vertex type, we might choose
+`String`, but for the edge type, we can't use `String` since
+transition names are not unique across the entire graph; they are only
+unique within the subset of edges between a given pair of vertices.
+
+Instead, we can use a labeled edge class as
+[described above](#edges-with-attributes). However, suppose we want
+to find an existing edge given a pair of vertices and a transition
+name. This requires invoking
+[getAllEdges](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/Graph.html#getAllEdges-V-V-)
+for the vertex pair and then searching through the result, filtering
+by transition name. If many transitions are defined, this may become
+slow.
+
+It would be nice if there were a faster solution for this problem,
+especially since the graph's edge set already provides an index into
+all edges in the graph. There are kludgy ways to accomplish a
+constant time lookup, but we don't recommend them, so we won't go into
+them here.
diff --git a/docs/guide-templates/WebGraphAdapters.md b/docs/guide-templates/WebGraphAdapters.md
new file mode 100644
index 00000000000..8ea5fe639c3
--- /dev/null
+++ b/docs/guide-templates/WebGraphAdapters.md
@@ -0,0 +1,57 @@
+---
+title: WebGraph Adapters
+---
+
+# {{ page.title }}
+
+[WebGraph](https://webgraph.di.unimi.it/) is a framework for storing and
+accessing graphs (and in particular web graphs) in a compressed form,
+making it possible to load and access very large graphs with a moderate
+amount of memory. You can download ready-made graphs in this form from the
+[LAW web site](http://law.di.unimi.it/datasets.php), or compress your own
+graphs using the instructions provided in the [package overview](https://webgraph.di.unimi.it/docs/).
+
+For example, the memory footprint of a [snapshot of web sites from Indochina in 2004](http://law.di.unimi.it/webdata/indochina-2004/)
+with 200 million edges would be a few gigabytes in a trivial representation, it is 260MB in JGraphT's
+[sparse representation](https://jgrapht.org/javadoc/org.jgrapht.opt/org/jgrapht/opt/graph/sparse/SparseIntDirectedGraph.html),
+but it is just 59MB in WebGraph.
+
+The adapters in the package
+[org.jgrapht.webgraph](https://jgrapht.org/javadoc/org.jgrapht.unimi.dsi/org/jgrapht/webgraph/package-summary.html)
+make it possible to use graphs in WebGraph format in JGraphT.
+
+The typical use case for these adapters is:
+
+- You need a compact format (vertices will be just contiguous integers starting from zero).
+- The type of graph you are storing is compressible.
+- You have metadata associated with the vertices, but not with the arcs.
+
+Such metadata can be easily stored in an array indexed by the vertices,
+or possibly by a [`fastutil` big array](https://fastutil.di.unimi.it/docs/it/unimi/dsi/fastutil/BigArrays.html)
+if you have more than 231 vertices (lists and [big lists](https://fastutil.di.unimi.it/docs/it/unimi/dsi/fastutil/BigList.html) are another option).
+
+If you need to associate metadata with the arcs, and manage the graph in a
+compact format, a succinct representation from the package
+[org.jgrapht.sux4j](https://jgrapht.org/javadoc/org.jgrapht.unimi.dsi/org/jgrapht/sux4j/package-summary.html)
+might be more appropriate, as those representation associate with
+each edge an integer in a contiguous range starting from zero.
+A separate [guide](Sux4JImplementations) is available for
+succinct graph adapters.
+
+WebGraph has two versions: the standard version manages graph with
+at most 231 vertices, whereas the big version manages graphs with
+at most 263 vertices. For each version, there is a directed
+adapter and an undirected adapter. The Javadoc documentation of
+[`ImmutableDirectedGraphAdapter`](https://jgrapht.org/javadoc/org.jgrapht.unimi.dsi/org/jgrapht/webgraph/ImmutableDirectedGraphAdapter.html)
+and [`ImmutableUndirectedGraphAdapter`](https://jgrapht.org/javadoc/org.jgrapht.unimi.dsi/org/jgrapht/webgraph/ImmutableUndirectedGraphAdapter.html)
+contain examples of how to load graphs in webgraph and use them
+to build an adapter. The big adapters work in the same way.
+
+Note that WebGraph has two main representations:
+[`BVGraph`](https://webgraph.di.unimi.it/docs/it/unimi/dsi/webgraph/BVGraph.html)
+uses compression techniques that work well with web graphs;
+[`EFGraph`](https://webgraph.di.unimi.it/docs/it/unimi/dsi/webgraph/EFGraph.html)
+uses [succinct techniques](https://en.wikipedia.org/wiki/Succinct_data_structure),
+which might be more useful with less repetitive graphs such as social graphs. In particular, `EFGraph` implements a
+[fast adjacency test](https://jgrapht.org/javadoc/org.jgrapht.core/org/jgrapht/Graph.html#containsEdge%28V,V%29).
+You should choose the representation that better suits your data and access primitives.
diff --git a/docs/guide/.gitignore b/docs/guide/.gitignore
new file mode 100644
index 00000000000..4052ed8dbe4
--- /dev/null
+++ b/docs/guide/.gitignore
@@ -0,0 +1,5 @@
+# Markdown files get expanded from ../guide-templates, so ignore
+# generated output here. Do NOT try to git add .md files here;
+# put them in ../guide-templates instead.
+
+*.md
diff --git a/docs/guide/hello.png b/docs/guide/hello.png
new file mode 100644
index 00000000000..4c0e131fc4e
Binary files /dev/null and b/docs/guide/hello.png differ
diff --git a/docs/img/apple-touch-icon.png b/docs/img/apple-touch-icon.png
new file mode 100644
index 00000000000..14a8519aed0
Binary files /dev/null and b/docs/img/apple-touch-icon.png differ
diff --git a/docs/img/bgnoise.png b/docs/img/bgnoise.png
new file mode 100644
index 00000000000..2912433c798
Binary files /dev/null and b/docs/img/bgnoise.png differ
diff --git a/docs/img/favicon.ico b/docs/img/favicon.ico
new file mode 100644
index 00000000000..bfc2884f0e0
Binary files /dev/null and b/docs/img/favicon.ico differ
diff --git a/docs/img/logo.png b/docs/img/logo.png
new file mode 100644
index 00000000000..d8535e2b9e5
Binary files /dev/null and b/docs/img/logo.png differ
diff --git a/docs/index.html b/docs/index.html
new file mode 100644
index 00000000000..5e9a16b7cef
--- /dev/null
+++ b/docs/index.html
@@ -0,0 +1,71 @@
+---
+---
+
+
+
+
+
+ {{ site.title }}
+
+
+
+
+
+ {% if site.favicon %}{% endif %}
+ {% if site.touch_icon %}{% endif %}
+
+
+
+
+
+
+
+
+
+
+
+
+ {% for page in site.posts reversed %}
+ {% capture id %}{{ page.id | remove:'/' | downcase }}{% endcapture %}
+
The following applet shows how a JGraphT graph can be visualized using
+JGraph. Try to play and drag
+around the vertices and edges to get the feel of it.
+
+
+
Note: Java 1.3 or above must be installed for
+this applet to work correctly.
+
+
+
+
+
+
+
+
+
+
a JGraphT graph visualized using JGraph.
+
+
+
+
+
How it Works
+
+
It's very simple: the JGraphT library comes with an
+adapter that makes JGraphT graphs compatible with JGraph. To visualize a JGraphT
+graph you just need to initialize JGraph via that adapter.
+
+
Example code:
+
+
+
// create a JGraphT graph
+ ListenableGraph g = new ListenableDirectedGraph( DefaultEdge.class );
+
+ // create a visualization using JGraph, via the adapter
+ JGraph jgraph = new JGraph( new JGraphModelAdapter( g ) );
+
+
+
+
+
Is that all?! Yes, that's all. Any modification now made to the graph g will
+automatically be reflected by the JGraph component.
+
+
+
+
+
+
+
+
+
+
+
+
Source Code of the Applet
+
+
+
+
The full source code of this demo is listed below and is also included in the
+JGraphT distribution (download now).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
package org.jgrapht.demo;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Rectangle;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.swing.JApplet;
+import javax.swing.JFrame;
+
+import org.jgraph.JGraph;
+import org.jgraph.graph.DefaultGraphCell;
+import org.jgraph.graph.GraphConstants;
+
+import org.jgrapht.ListenableGraph;
+import org.jgrapht.ext.JGraphModelAdapter;
+import org.jgrapht.graph.ListenableDirectedGraph;
+import org.jgrapht.graph.DefaultEdge;
+
+/**
+ * A demo applet that shows how to use JGraph to visualize JGraphT graphs.
+ *
+ * @author Barak Naveh
+ *
+ * @since Aug 3, 2003
+ */
+publicclass JGraphAdapterDemo extends JApplet {
+ privatestaticfinal Color DEFAULT_BG_COLOR = Color.decode( "#FAFBFF" );
+ privatestaticfinal Dimension DEFAULT_SIZE = new Dimension( 530, 320 );
+
+ //
+private JGraphModelAdapter m_jgAdapter;
+
+ /**
+ * @see java.applet.Applet#init().
+ */
+ publicvoid init( ) {
+ // create a JGraphT graph
+ ListenableGraph g = new ListenableDirectedGraph( DefaultEdge.class );
+
+ // create a visualization using JGraph, via an adapter
+ m_jgAdapter = new JGraphModelAdapter( g );
+
+ JGraph jgraph = new JGraph( m_jgAdapter );
+
+ adjustDisplaySettings( jgraph );
+ getContentPane( ).add( jgraph );
+ resize( DEFAULT_SIZE );
+
+ // add some sample data (graph manipulated via JGraphT)
+ g.addVertex( "v1" );
+ g.addVertex( "v2" );
+ g.addVertex( "v3" );
+ g.addVertex( "v4" );
+
+ g.addEdge( "v1", "v2" );
+ g.addEdge( "v2", "v3" );
+ g.addEdge( "v3", "v1" );
+ g.addEdge( "v4", "v3" );
+
+ // position vertices nicely within JGraph component
+ positionVertexAt( "v1", 130, 40 );
+ positionVertexAt( "v2", 60, 200 );
+ positionVertexAt( "v3", 310, 230 );
+ positionVertexAt( "v4", 380, 70 );
+
+ // that's all there is to it!...
+ }
+
+
+ privatevoid adjustDisplaySettings( JGraph jg ) {
+ jg.setPreferredSize( DEFAULT_SIZE );
+
+ Color c = DEFAULT_BG_COLOR;
+ String colorStr = null;
+
+ try {
+ colorStr = getParameter( "bgcolor" );
+ }
+ catch( Exception e ) {}
+
+ if( colorStr != null ) {
+ c = Color.decode( colorStr );
+ }
+
+ jg.setBackground( c );
+ }
+
+
+ privatevoid positionVertexAt( Object vertex, int x, int y ) {
+ DefaultGraphCell cell = m_jgAdapter.getVertexCell( vertex );
+ Map attr = cell.getAttributes( );
+ Rectangle b = GraphConstants.getBounds( attr );
+
+ GraphConstants.setBounds( attr, new Rectangle( x, y, b.width, b.height ) );
+
+ Map cellAttr = new HashMap( );
+ cellAttr.put( cell, attr );
+ m_jgAdapter.edit( cellAttr, null, null, null, null );
+ }
+}
+
+
+
+
+
+
diff --git a/etc/ReleaseProcess.md b/etc/ReleaseProcess.md
new file mode 100644
index 00000000000..5b581db6033
--- /dev/null
+++ b/etc/ReleaseProcess.md
@@ -0,0 +1,29 @@
+# JGraphT Release Process
+
+1. Let other developers on [jgrapht-dev](https://groups.google.com/forum/#!forum/jgrapht-dev) know that you're starting on the release and ask them to hold off on merging changes until the release is complete.
+1. Review the README.md, HISTORY.md, CONTRIBUTORS.md, and update:
+ * Version
+ * Dependencies
+ * Release notes
+ * Contributors
+ * Copyright year
+1. Review/update github issues to make sure they reflect the current state. If there were important bug/feature changes, it is worth mentioning them in the README.md release notes.
+1. Run `mvn clean; mvn javadoc:aggregate` to build the javadoc and make sure it is generated without errors/warnings. Fix where necessary. Make sure Eclipse build is warning-free.
+1. Run all the JUnit tests via `mvn test`. Fix where necessary.
+1. Reformat all code [using Eclipse](codeFormatter.sh).
+1. Commit all work and push to github, merge with master branch. Locally, switch back to the master branch and perform a `git pull upstream master` to ensure that the local and upstream master are synced after merging the code formatting changes.
+1. Run `mvn -Dmaven.artifact.threads=1 -DskipTests clean deploy` to push the latest snapshot to Sonatype.
+1. Run `mvn package -DskipTests; mvn release:prepare; mvn release:perform` to create the Maven artifacts and push them to Maven Central
+1. Publish the release [using the Sonatype UI](http://central.sonatype.org/pages/releasing-the-deployment.html). Make sure to login to the old https://oss.sonatype.org/, and NOT https://s01.oss.sonatype.org/ or you will get a `Incorrect username, password or no permission to use the Nexus User Interface.` error!
+1. Before continuing, restart from a fresh clone to make sure your workspace is clean, and checkout the release branch there by performing a `git checkout jgrapht-x.y.z`. Otherwise, if you have old files lying around that are hidden by `.gitignore`, they may get accidentally included in the release archive.
+1. Run `mvn javadoc:aggregate; mvn -DskipTests install` from the new release branch to produce the release archive distribution
+1. Upload the release archive distribution to sourceforge using the File Release System.
+1. Add the javadocs for the new release to the [javadoc repository](https://github.com/jgrapht/jgrapht-javadoc). To do this, push a commit which replaces the contents of the existing javadoc directory, and also [adds an identical copy](https://github.com/jgrapht/jgrapht/wiki/Website-Deployment#javadoc) under a new javadoc-x.y.z directory.
+1. Update [the website](../docs) with links to the new downloads, version numbers. Make sure you are on the `master` branch, NOT on the `gh-pages` branch! (To be specific, you'll need to update the [Jumpstart](../docs/_posts/2000-01-02-jumpstart.md), [Download](../docs/_posts/2000-01-04-download.md), and [News](../docs/_posts/2000-01-06-news.md) sections.) which can be found under `./docs/_posts/`. Be sure to push this commit **after** the javadoc update from the previous step; this will trigger an automatic rebuild of the website (the javadoc gets loaded automatically).
+1. Announce the new version in the mailing lists: jgrapht-users@lists.sourceforge.net, jgrapht-announce@lists.sourceforge.net
+1. Update and commit the version number in HISTORY.md to reflect the beginning of development for the next version. Finally, remove all existing deprecated methods.
+1. Check and, if necessary, update dependencies: `mvn versions:display-dependency-updates`. Recompile to check whether any of the version updates introduced errors, e.g. because some methods have been deprecated: `mvn -Dmaven.compiler.showWarnings=true -Dmaven.compiler.showDeprecation=true clean compile`. Then use `mvn package` to rebuild an archive distribution. Unpack an archive (either .zip or .tar.gz) under `jgrapht-dist/target`, and then inspect the contents of the unpacked `jgrapht-x.y.z-SNAPSHOT/lib` directory. Make sure that no unexpected transitive dependencies have crept in by comparing the jars with those from the release archive distribution (which you can download and unpack). If everything is OK, then submit the dependency updates as a pull request and wait for a reviewer to merge them. We perform dependency updates at the start of a new development cycle to give plenty of time for any incompatibilities to be noticed, but it's also OK to do this step in the middle of a long development cycle (or at any time as needed for specific dependencies, e.g. to take advantage of a new feature, or to close a security hole).
+
+## Notes
+* The release artifacts are signed with private keys. In order to sign this release, you'll need to make sure you've already [created and published your own key](http://blog.sonatype.com/2010/01/how-to-generate-pgp-signatures-with-maven).
+* To rebuild the full release package after it has been pushed to github, you can run `git checkout jgrapht-x.y.z` (the tag you published for the release), and then run `mvn clean; mvn javadoc:aggregate; mvn package`
diff --git a/etc/build.properties.template b/etc/build.properties.template
deleted file mode 100644
index 6d37a9a31ba..00000000000
--- a/etc/build.properties.template
+++ /dev/null
@@ -1,53 +0,0 @@
-# ==========================================
-# JGraphT : a free Java graph-theory library
-# ==========================================
-#
-# Project Info: http://jgrapht.sourceforge.net/
-# Project Creator: Barak Naveh (http://sourceforge.net/users/barak_naveh)
-#
-# (C) Copyright 2003-2006, by Barak Naveh and Contributors.
-#
-# This library is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
-# License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this library; if not, write to the Free Software Foundation, Inc.,
-# 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
-#
-# ~~~~~~~~~
-# etc/build.properties
-# ~~~~~~~~~
-#
-# Original Author: John V. Sichi
-# Contributor(s): -
-#
-# $Id$
-#
-# Changes
-# ~~~~~~~
-# 31-July-2005 : Initial revision (JVS);
-# 01-July-2006 : Update for version 0.7 (JVS);
-# ~~~~~~~
-#
-# etc/build.properties is used to customize the JGraphT build.
-# To use it, uncomment the settings below for the attributes you want
-# to customize, then change the values to your site-specifics.
-# The ant buildfile will override its own defaults with any
-# uncommented values it sees here.
-
-# NOTE: If you are building JGraphT directly from Subversion rather than from
-# a distribution, create etc/build.properties by making a copy of
-# etc/build.properties.template. (The template file should only be
-# changed by developers who are enhancing the build process
-# with customizability.)
-
-# ~~~~~~~~~~~~~~~~~
-# End build.properties
-# ~~~~~~~~~~~~~~~~~
diff --git a/etc/checkstyle_suppressions.xml b/etc/checkstyle_suppressions.xml
new file mode 100644
index 00000000000..a57ab41f5c5
--- /dev/null
+++ b/etc/checkstyle_suppressions.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/etc/codeFormatter.sh b/etc/codeFormatter.sh
new file mode 100755
index 00000000000..5222940eac1
--- /dev/null
+++ b/etc/codeFormatter.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+#Applies code formatting rules defined by the eclipse formatter on all java classes recursively.
+#Details about the formatter: http://help.eclipse.org/neon/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Ftasks%2Ftasks-231.htm
+#Details about the formatter config file: http://help.eclipse.org/neon/topic/org.eclipse.jdt.doc.user/tasks/tasks-232.htm?cp=1_3_10_1
+
+# This works well with Eclipse Neon; later Eclipse versions don't work. Note that Eclipse Neon only works with java 8; newer java version cause problems, hence the explicit java_path definition below.
+
+#Path to eclipse. Needs eclipse Neon or newer.
+eclipse_path=/opt/eclipse/eclipse
+#Path to Java
+java_path=/usr/lib/jvm/java-8-openjdk-amd64/bin/java
+#format configuration
+config_file=./etc/org.eclipse.jdt.core.prefs
+#get the root dir (1st ancestor of the location where this script is stored)
+SRC_DIR=`dirname "$BASH_SOURCE"`/..
+
+set -e
+
+function format(){
+ find ./jgrapht-core/ -name *.java | parallel --no-notice --eta $eclipse_path -nosplash -vm $java_path -application org.eclipse.jdt.core.JavaCodeFormatter -quiet -config $config_file
+
+ find ./jgrapht-demo/ -name *.java | parallel --no-notice --eta $eclipse_path -nosplash -vm $java_path -application org.eclipse.jdt.core.JavaCodeFormatter -quiet -config $config_file
+
+ find ./jgrapht-dist/ -name *.java | parallel --no-notice --eta $eclipse_path -nosplash -vm $java_path -application org.eclipse.jdt.core.JavaCodeFormatter -quiet -config $config_file
+
+ find ./jgrapht-ext/ -name *.java | parallel --no-notice --eta $eclipse_path -nosplash -vm $java_path -application org.eclipse.jdt.core.JavaCodeFormatter -quiet -config $config_file
+
+ find ./jgrapht-guava/ -name *.java | parallel --no-notice --eta $eclipse_path -nosplash -vm $java_path -application org.eclipse.jdt.core.JavaCodeFormatter -quiet -config $config_file
+
+ find ./jgrapht-io/ -name *.java | parallel --no-notice --eta $eclipse_path -nosplash -vm $java_path -application org.eclipse.jdt.core.JavaCodeFormatter -quiet -config $config_file
+}
+
+#switch to the root directory. This allows us to invoke this script from any directory. Then format.
+pushd $SRC_DIR
+format
+popd
diff --git a/etc/downloadJavadoc.sh b/etc/downloadJavadoc.sh
new file mode 100755
index 00000000000..6f45d5a40fe
--- /dev/null
+++ b/etc/downloadJavadoc.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+
+# Downloads released Javadoc to local directory
+
+set -e
+
+: ${GITHUB_WORKSPACE?"variable value required"}
+
+pushd ${GITHUB_WORKSPACE}
+
+rm -rf docs/javadoc*
+git clone https://github.com/jgrapht/jgrapht-javadoc.git
+mv jgrapht-javadoc/javadoc* docs
+rm -rf jgrapht-javadoc
+
+emit() {
+ module=$1
+ stripped=${2#"./"}
+ file=${GITHUB_WORKSPACE}/docs/javadoc/$stripped
+ mkdir -p $(dirname "$file")
+ echo "---" > $file
+ echo "redirect_to: " https://jgrapht.org/javadoc/$module/$stripped >> $file
+ echo "---" >> $file
+}
+
+export -f emit
+
+# Creates redirects from pre-module javadoc structure to post-module
+pushd docs/javadoc
+for dir in `ls -1 -d org.jgrapht.*`
+do
+ module=${dir%"/"}
+ pushd ${module}
+ find . -name '*.html' -print | xargs -I {} bash -c "emit ${module} {}"
+ popd
+done
+popd
+
+popd
diff --git a/etc/eclipse-formatter-settings.xml b/etc/eclipse-formatter-settings.xml
index 99685090b3e..2a820857327 100644
--- a/etc/eclipse-formatter-settings.xml
+++ b/etc/eclipse-formatter-settings.xml
@@ -1,246 +1,365 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/etc/expandMarkdown.sh b/etc/expandMarkdown.sh
new file mode 100755
index 00000000000..d635264b3c2
--- /dev/null
+++ b/etc/expandMarkdown.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+# Expands transclusions in markdown templates
+#
+# Usage:
+#
+# export GITHUB_WORKSPACE=/path/to/jgrapht-clone
+# expandMarkdown.sh [ github-user-id/repository-name/branch-name ]
+#
+# If the argument is omitted, then jgrapht/jgrapht/master is implicit.
+
+set -e
+
+: ${GITHUB_WORKSPACE?"variable value required"}
+
+shopt -s failglob
+
+USER_BRANCH=${1:-jgrapht/jgrapht/master}
+
+pushd ${GITHUB_WORKSPACE}/docs/guide-templates
+
+for file in *.md; do
+ outfile="${GITHUB_WORKSPACE}/docs/guide/${file}"
+ rm -f ${outfile}
+ echo "Expanding ${file} to ${outfile}"
+ sed -e "s#raw/master#raw/user/${USER_BRANCH}#g" < ${file} | \
+ hercule --stdin -o ${outfile}
+done
+
+popd
diff --git a/etc/graph-links.html b/etc/graph-links.html
deleted file mode 100644
index 62117b5e720..00000000000
--- a/etc/graph-links.html
+++ /dev/null
@@ -1,244 +0,0 @@
-
-
-
-
-
-
-
-
- Graph Links
-
-
-
-
-
-
Graph Links
-
-
-
-
-
In this page contains a list of links of graph-related sites. The links are
-not sorted in any particular order or significance.
-http://www.bluemarsh.com/java/graph/ - GraphMaker is a Java
-application for graphically illustrating graph algorithms, such as breadth-first
-searches and minimum-spanning trees.
http://wilma.sourceforge.net/ - a
-Java library which allows other programs to create animated 3d graph
-visualisations.
-
http://jung.sourceforge.net/ - a
-library that provides a common and extendible language for the modeling,
-analysis, and visualization of data that can be represented as a graph or
-network.
-
-
-
-
-
\ No newline at end of file
diff --git a/etc/header-boilerplate.txt b/etc/header-boilerplate.txt
new file mode 100644
index 00000000000..489c85507cb
--- /dev/null
+++ b/etc/header-boilerplate.txt
@@ -0,0 +1,17 @@
+/*
+ * (C) Copyright BEGINYEAR-ENDYEAR, by AUTHORNAME and Contributors
+ *
+ * JGraphT : a free Java graph-theory library
+ *
+ * See the CONTRIBUTORS.md file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0, or the
+ * GNU Lesser General Public License v2.1 or later
+ * which is available at
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1-standalone.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR LGPL-2.1-or-later
+ */
diff --git a/etc/jgrapht_checks.xml b/etc/jgrapht_checks.xml
new file mode 100644
index 00000000000..e9de4b41512
--- /dev/null
+++ b/etc/jgrapht_checks.xml
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/etc/licenses/antlr-license.txt b/etc/licenses/antlr-license.txt
new file mode 100644
index 00000000000..2042d1bda6c
--- /dev/null
+++ b/etc/licenses/antlr-license.txt
@@ -0,0 +1,52 @@
+[The "BSD 3-clause license"]
+Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the copyright holder nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+=====
+
+MIT License for codepointat.js from https://git.io/codepointat
+MIT License for fromcodepoint.js from https://git.io/vDW1m
+
+Copyright Mathias Bynens
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/etc/licenses/apache-license-2.0.txt b/etc/licenses/apache-license-2.0.txt
new file mode 100644
index 00000000000..d6456956733
--- /dev/null
+++ b/etc/licenses/apache-license-2.0.txt
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/etc/licenses/jgraphx-license.txt b/etc/licenses/jgraphx-license.txt
new file mode 100644
index 00000000000..7fdadcf7a9b
--- /dev/null
+++ b/etc/licenses/jgraphx-license.txt
@@ -0,0 +1,24 @@
+Copyright (c) 2001-2014, JGraph Ltd
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the JGraph nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL JGRAPH BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/etc/licenses/mit-license.txt b/etc/licenses/mit-license.txt
new file mode 100644
index 00000000000..14e2e075df0
--- /dev/null
+++ b/etc/licenses/mit-license.txt
@@ -0,0 +1,19 @@
+Copyright (c)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/etc/logo/jgrapht-logo-black.ai b/etc/logo/jgrapht-logo-black.ai
new file mode 100644
index 00000000000..8058baae034
--- /dev/null
+++ b/etc/logo/jgrapht-logo-black.ai
@@ -0,0 +1,290 @@
+%PDF-1.5
+4 0 obj
+<<
+/Type /Page
+/Parent 2 0 R
+/Contents 5 0 R
+/PieceInfo <<
+ /Illustrator 6 0 R>>
+/MediaBox [-0.0000 -0.0000 479.9999 479.9999]
+/TrimBox [0.0000 0.0000 479.9999 479.9999]
+/CropBox [-0.0000 -0.0000 479.9999 479.9999]
+/Resources <<
+/ProcSet [/PDF]
+>>
+>>
+endobj
+6 0 obj
+<<
+ /Private 7 0 R>>
+endobj
+7 0 obj
+<<
+ /AIPrivateData1 8 0 R /CreatorVersion 11
+ /ContainerVersion 9
+ /RoundtripVersion 11
+ /NumBlock 1 >>
+endobj
+8 0 obj
+<<
+/Filter [/ASCIIHexDecode /FlateDecode ]
+/Length 16523
+>>
+stream
+78daed5cd96e5cd7957d17a07fb8fd6020e986abcf3ce84da24cb401263162079d7e3218ba22b353
+24058a72ec7c7dd65afbdca1c8a287f45bc3766c5fadba67da67cf7bdf7cf26f5f7cf9e9eb6feefe
+b2ff34eedccb179f7c7276bfbf7cb8bb7f2570fafc70f8f8e1e19ec8f49baf7ef7dbc9fb9dd35fd3
+67dfbfbfbb7fd87f33fdf5feee663abbbbdf1fdefef1f57f638aafae1f0efb57fffbceef2eaf9729
+afef6edf5e3eec5f4dbfbbbb9d7e7ff7dde4c314dcab185f253ef8f6026fbeb9fb78fbcdf5edbb37
+77dfbf72939b52d33f9ce4edddd5c79bfdedc317f77757fb0f1fceee0e77f71f5e4d673f5cde4ebf
+bb7c875f2ea7ffd91f0e777f9fde1c2eaffeb61df3e5c7f7ef0fd7fb6ffeb8ff70f7f11ec35f4def
+31cd87fdc3a4637e7dd87fb73f84af5f7f9e27bf0b9316fc8f47ef3cfcf0feeeddfde5fb6f7f18ef
+b9c99f7a4f3bfbfc065bc27b05eff9d3f36d48fbe30b5f7df816870a58af9dfaf9c3b7972419e668
+da14e778fd79b47dfce903f6012af179e05fed6fde1f7013a471486edafc33de5849bdffee7afff7
+57b8aedbbd7ecb5fbfbe7ff8f2fa1f98725ccd34f0df7fbcb9b8fc61cf2b71033abf3eeccfefee6f
+2e1fb87981f5ebafbefd78f397dbcbebc32b3040d33f3ad59bfdbb6b32c825664e394dffb5ff7e7a
+f3c3c3fe037ef4c9175f9debe1ad3fd75fee67ff85e1eefff0d7afc37f1dfeebf05f87ff3afcffc7
+70bc96433a4bf9fcedf99973bff4df18feaf0d7c32bcc29e39effcf95b97e62762fab3e756ed0968
+d273717e9c71f921ea396a92a2e73c4f38e3a5ae3887afabc675ad472f6b72d7b6fbc3bf3b87f3a5
+ac3fd6e3adbb05dd4c97ed57fb650ce7ba9b01e9782fe76ff3f99383644e21d28db3daaa6e4c9436
+83dfaebbd0d3f9fc9e0ddf1026bfd6735b5ed52ac7d3af77a1cdaf3f2ec36dfb75730f679b617e3e
+d0bcfa7a517ad96f2e738be7ed84e9e8ecde4875a6d7fad8f0860fbc91f58d7e1fb7330f1f9771fc
+f2385659b69b8eefc5b86e398dff6c9cff99eb73dc53c0dfb6cc6b176cf5eda98bbd622fdb4be76f
+c39b137cd18df29a4fa70abf74aa2de597ad6938077d7672aab7f3533837897bc46558e5d144a19e
+1a3cd8e688f6fef404eef590f130b89258d4eadaf84ccf3e53605d63e6f08d44bcb1dfe7e17143a0
+3a56389a72bd2c239a4d8ee1e17c2b0463f36f8e373f0697a3e39c6d2e6e214dde0c09c70759570d
+7627af67d2bdfe79ab3d2267de9cfde7acf678290e8fdb41dbb957b23dc296c5169e7fb2def946d7
+3ccb0d5cfd5f5ad7161d94dfae1b17b5fc63ebdaa2367c05d3f17a2777b5d9c166f3cfef60d16e6d
+1d6eff35d2e5c7f0cfddc7d8fcf3371efd230b1837cf6d3dfb9b1fa1fdeb23b6de2c62eae2f43aab
+55af26dd8fa4efd1d9db23998f3f7da8596416a3ec171beedd7a98f4e6a9d6f78f54e5f9e6f5d7ab
+c5f1e989f15adeb1e1671b23957e7ce5e3374ce2e835f48dd7908e6d2a7e4dab6edf1ae9d9fdf31b
+7d3bbc260c8ac7f67419d8c75b79b67163821303fc338e539a3dab85ea256c657c3944de2ae975f0
+e25d6060d9fa4bdb410b57948d07d637366e234b69e3c9b5adf5591c95bc79231ebb46f9b13f53c3
+133b9f374e697aea94d6477ea3a679de291e8afa5ff5a97fd6f0fe5644fae4b3db6f98611a8f6777
+374c727d58b24f5fdcdf1deedef18f9fdf5e1d3e7eb39fd3853f275bf813439e4b1efec4b0e77289
+3f31ecd9d4e24f8c7b94690491569a88445fee1f3ebe7ff9e20919fef3faf6fae1faf270fd8ffdf4
+0ed3edbfdf5fcdafd9a43ff6c6a3ed7efddde5fd87674e72929a3f36f7230afe826d3cf3aec832e8
+a034a708a3dce7cb17931f7f3379fda99fa29f4299429c2efef2f2c56ff4d2e47f3b5ddcbe7cf1f1
+e50b3ffdf98f2f5fb8e90ff8d7ce79df26fcc7c5aeff3837fdf9523ff031d5beebbd97e9e6e58be5
+7979b8d88063c0c532f409b01df6d7972ffefdc94e6c54ae25e33fad94aa9df89276d02871f2d9ef
+7ac08f3704cbaef54030ec8a7e2d0d436b039277d0680148ddb590c0beb9ed920f793ae3c0bacbb9
+e1d7dc77c9e5aad760cef8e07621b73471f2e8391048277d38b0965d6a0e4c5d311b76c763f85a77
+d1c52430b612f4e0a18af590b50d3cf4d26c205eb16d8016cd55feda7721b63ec16862da1885b498
+8b909e9bd743ceb81f0c0caeec6acb5cd1ef720895db10e83a4110ae76163680e49085049e9d480f
+1db3958ed9ec503836c84e6a000c88ff26221e7f899ebd262f24c46c14ae0e1be3fe5bdb85e2bbd1
+b6e181d46818dbbc13dd7cae58bde59deb85b485ea89dc4f8b3b5793513b753766e3b5bbae4bc164
+5d44a03d0082d5833342613b9821a75df520dd1898bcb611704c5e04e7f77acde1b590b487ec4931
+f04f6c108d33db6a05a71953b508b6697de77b769adfc788079cb1b786ad66f0438dd928d67625d4
+2e26692d75a33f38db3b324cc6b56650db7bb025f913484c2c73f888ad2637dea9369b2f381d589a
+b3e5824b09be92e5926e048435c48b632bced8639d07269778bf79e71d4ea7f99b107248e740b72b
+55cc5940fc9a6c20c012663039db3f76eb6bd4915bcdcdc08079a0467c876c4687255c845c34227e
+574b2453050a2a16ed583d075b82a07306160abca6f2a015911e2174448ac75df89e282f831a3034
+09b2cc5f7165b6370fbbd0a3810e54d649715baade81452174c1277063737a07e42c33896af536b0
+c782070fa6856701042c1173176de1db70870d67ec75bab2813dba2e02e60411e3fc31b270c8cda4
+5875bf2dd4a407f086b383f75d0c14190c84b71d253be082acf9bd0b490fa94bacb0870e79bc1a4c
+55024f9470225528c17b7920c971f39c3cfaac5be814fc33bb38302d499df17e1eda00f755a8c77a
+a102046f77e8a2928850425dd38393feecd22785dbe05d94d66da04f589df785c3443dd027b33b6d
+5423e081e8676982a6aae47fc85aa5f6bb30158721942c103953c1566a9214c466095b1edc5ba2de
+4905b7cc6d80cf21e904c9e41001eaba027526e9ce9d4a9befc4c2c9e164445f6d60a4b669a64b43
+e76bd86d86aed6662a3552e555862a24ba62fa072626820f2074b8df62fcef0b05361a182b044a0f
+a51b92a2942488107b1002c3336683cae505f15790364aad8546fa0309f893d466713c115e8e9025
+0d4c2082eba68da1f8b3b69160593a8d51a5d0919e782d9ba5485468983665508f032b6d5f72361b
+ef8e9a0a92de21ff780d6b8566880f104c1fa166830646087e33fa47e8c6a0dbf1d475b8f4485b16
+8b99800841e3543553a2613d1336612b822cc51769b39423a64d0982964c5b22ce2002b5e392d740
+10d50642c967ed1f64c176ccb6028c140a3ea49ced01ca23492167d9170e34a58d835767961a9360
+4df30d5aee83ec459a1cf25259ff7de2549c9df234cc539178c664ccd3c900370682dc06e60a9b45
+61af4dc4844ef3c398a64602920f9d5970726c0dbc8e46d7055c7131c04cd52afb450a0ba13f0324
+ca546920b7d7a8578b5f66abcd0c6be1ad5d0c41cee41918b550c0c302219b9d9702596b857e0594
+0064d94d66b8a51fc07866fbf013b4bf96000899304186421d26ef314d8657f7a79fefd96173496e
+16d45385ef43b242ab24d92ca82084e47ec25160d5dc0ca4a9939bc940364a22c783506373ab0942
+3275aa5b47bd0e96c7410844fa07d498107b9310d803b06b1408b930b60308fd1c3434076a13df29
+5d4eb337da271fe0dfb46cebc510ec5e01f648cbcd8d359e2be06e1ae5bf53e9f32e03ae3c495f03
+49435f844aa10ae6d2e11cda0640c85317880d835d0298be552f970ef62c0881720e42607dc736e0
+5eb43a3c3fa8ab8948e9b10b0151b2901ca2299a5a920da4e7d7e4a2c1576b296a1bb48bb4be64d6
+262f8426cdc961a5ee26d1e15942ad54e9ebdc864b47bb05ef75e87a3a5820322c5f5811f2957c48
+1bd7c74db620964cc61302343988994a1aa34ca5776f5e99d7ad8a5ac3c4832e2083f43c5981efc3
+e0e217af81c90d5d112029299a3a2a5cefc24028902457ad770a2310f8e4597a03842b83f65c119a
+bf97346e52ceff081c1c2414f683029507225d4a1326cf9003b38958cc3491e6403a290722a99b1f
+0efd5fc7405f8f6f9b609b59a07893f444f6e4122422949981deae9a60a01b4c0381bd5521453105
+d475add4d2b8db0e3fc8b43a043c0f732c1f86e6c6fb601717649b8004535fd0fcbdd8a13263906c
+3a0d5738b43a7c92429f040c1532af835a9df728539ec82999572684274da6e86043e13a365d6809
+decc31dce13a23763bd5fc100d4c3267343d9212aed8148c2c08b6dd5adc0e8410702a9903cedf46
+20c06dac7b1072bcd531f0ca2c5749d104a228186414d3fba0a1c20720608768e109ec87915a14ce
+9a1fe3cc34241299e7951fcef00ad46e8993405b66053bbcb8c2b8a9c37366cc72650e004221271f
+3b262a7c32464de67527f906b0ec26bb180823d66685e4cd1d65d4d6aa0905ed5d74f23f1df996af
+c1f816b9b2455130f44a7571049b65b81321ae3e76129b41531644cbe6752b06878a856e34cf1cda
+dd2e8eea998112411c15c7f4dc2d331b8e9e8f33245016b8ab0c7f5a3a046f45ed2bd2e6489fd220
+90d7393273004d067c624d9e18e6c8ae68ee627a9333c15969d96260470e800d8558670130b07962
+40d3d330fe3ecda3e09a0283b677343ab63ed49961c6f6302f85d62f04062f52900bc2703e9b8d32
+10362ad05f0565644ba09ce0f5d2898edc1373d72b00da615bd1b9ed4b9e162b6da61150c7624917
+bf6260a7c8e3063ae0382eeed0a5206b0c2eb763c4d8e651a52ab4a98ce2a542c1aab0204518fc09
+e87ac6240a7b1836e34e66e36fe4b670bec9bf8bba2408b59f04142f5bdce8ac3f7119ce4eb811e6
+8950f59654cdac16dae31b039d022080662623f32ed40a407a6798021221c24903c98ba168cc0170
+15089f8508e0775f25764c1524b3acf05f8a3c039fa9e728136c5894af408e1b46ba7a455170d0ea
+30f9f0bbe1647b097aa77c080433c975a02b97334d0ad5eaf0e342651412a584fcb1da26d88bd9e9
+16ed5a9ed2e4977b6de089c21b852a8565f665786d0de1153078d00e8117f80f9e0c01d01bdc49e9
+8a95ac05cd1ca3f95fbd0e3901c6c2839cb4caeb06e01908913a9d5ccb517d180204c22932b82ecc
+338436fb299dd90c825073b83c3aa8d24516a3752199ee6b60ea09bfd96c102766ff02747b966bc6
+d770ed40dad0de9cbc71209476eb661d980063901112b572d72e9a02a72a2ce15ac9bf9e712281ca
+3c00cd2345844077e6f2d02430901056319c17563b3b6395340b0472032f09c8267534bdcc82f1c0
+08ac64e3b927879f8955666028750624a60402819c1d4715de4b18f21b02d83d3083cafc5253e08e
+0d556617a0bfc8685a8b4253cce5926b41871a9138423c8c02e13dafbc72d7b82b5c7d4aa1d9bcd1
+d66ad40b4c6a617d585ec7972038dc50a4c5c034d869602a0780c35c1ac5bc9337ba22560e3a2bdc
+1966258979fa5334f989692f307ea351a77fd860a7a05d208aa6d0956d25ef449a446e92195e9a22
+2a4a28e6096b554a4b88cc9ef938689d53301d8cb7bdd450618688f2e470f8ce2c2bcd40a46135bf
+5e1885825828962285b5698549a948a9b4b0890e74a8bc26bc096b56e464c3b0735b81120da504ae
+0f4c27135134328b4262168aa00bf65aa14746049e8a21f0ba9d21319a6be603b38c3435a02895f7
+85814e5934863799de8a27519409631c496dc9145de46c30bcbe8df0ddcbf764822dd391f47aad97
+60b93ad764e141046656984283ba3647c9cb4d68caa255b97e58283359ce81212573160233739c7c
+56f98ab53ced9bec3f9d5306695419dc3cb60015c7c91d937c4199f230af08523b81a02207d2d1a6
+a962b426520371622dbe13871dc6b683d409c8584a1ab122d41cd3d5016e786054c963e6e6068351
+4d12b13c3a6f9cea4adbc0a26424322b44cd5e835e523b3c3646af9634649847a957c1e1cc564c88
+6ba08ae0bad6518530ca6481660a99d7a453498d05f7bb0a69302aa6e7c8b2c3c302b366290ca74c
+12e943378a1a03f4e4c698f0f3a64360e7cda7f354bdb4d4749c158dd98d177b8dc72402f36003c1
+d56d0ed42c050bf9cdae0fe54d3f89fa853aa4d2903101ccac7c603a44f7eb94cbe966629a1fa620
+9251391b3d44128dce6995e129a47fd2c0c2ca4ca033119bd95f1d93bc410f278e84a58846cbd6e9
+1230e111983043e01220f04d861e7e0fd406e6a7af44153b07913d8cd994f9a61b00ed01245b6681
+ef20c604c7767a8e9029b9c64c9f0b84ca859c8b8d61edd314997d28e2281a154d45191c9942ecdf
+05e6376032834a2ee0015fa88f6969795f44923c47386d9926710e9465dce84ed41193392a01728b
+8e4969650ad9e9444a192aeac6a24100f615663fd76901a6829b9c6110d8699e022b3f3df115ce4e
+f80fe6827021477b4af7861af4c63428f3bfd4e09191406305910b0090374653e568bd19c730389e
+d551625a07b1a61fe68260f59208f8483c00f9d3b140440466d7098921997081f683559860aef61a
+1485a94aaa593aa894cd522def4ea5dd99572008f72d5b66a438335cae319724fd5f8a097e1a413c
+c14842d26723952f4ed0e3d85373273cb513fff9dbcb17d44dad5381661a5ff3835790b124eb8fcc
+e98147fb117820c86c76d9802c9ac07481228999493e2c080e200150196506a1da0acb22a39a534b
+cacf8091e6190af7b00511ff42817288ccb05b0fc20d3bfab80b7275eabc17cf804cedc239844317
+857796e7481c96de2a1da019842f87dba22d4ff0d11337b320910115f6cca5173014ab741cb6a06f
+96005be79f89b06e6346385b6250cc52fe0c72b6447526cb3a8f8d7246c62d0432f48230b4a4608a
+2c0b58cd173c6c413a10226962e98d2a15e60a11331d2c667aeb06e16c2c6b32465ac08b23902ea0
+b36a144ed173dd803a45a135f52b085b0fd92be663997bbf228398a2c90242a9c1c4d96c0b48dbdf
+a27806e7cc725c1007075da5dcc905b9b2db872d492b78b053c0b6b5cdd8c2d487374f028ece11c2
+b826d9ed2f203d50b8f436db0c26a5ef6820e9de531341a0ba944851fab9ae884ecad02bf815bcd8
+8233675e9ce2e1c33320183e322f5be8956f183e7a19e0cdb4912e4567e66366f815d930fc0a6e18
+7e0567865fe79f9976ddc696e19baa518f94c30a761638e431c041370bbd805cd731c74f176a06a3
+943e55100cad02ca0d32a440a79841aa2f761d1cb620b51c33c9ebfcb3265cb731233c054be14e03
+375a94093d6ab6558b32804bb5aff3afc8bc0dd16406e1c744df074dfc9c8b3b05ce1774d8828be2
+6a4ce7ba0d03d06bc96a219891ab537c7278062453416655ac106f1708d4cd16dcf02a02452641fa
+f1b4195bf25bae8e0cbd99c65cd96f41b6ecb7801b8681e7ced682fc0cb8bde2055cae38fbe1e52f
+579ce84ec5e32b5e8fb6b19e2bb85d37a411539d0467725d9ca2e17320080e1bcbc8dc9449ac5952
+bc01f1504cfd465569ea73e07657ec3b0a8fe9b680dbe170e833abc6cf80634b17a7f6f91cf857cb
+f047a784c17aa81564c1858583c316a48661bf04ebbf39e40d27b04ade8f8cec95954b4aeac707df
+80ecbc6a7ecebac35fe82ba875e9edb5bc826c168287da2caf1bd465b4209ca13bab08cce0e6c84f
+cffb1ca81a3433bafdf8c637e07a112c6f15359fcc2077ce2aad22f91964074596ed43885895b25c
+9148efd1cfcd1806cec7391c81f3a997f917ca2cdb98117598c0170a12d80d551111c1f5d8802a43
+6765ab61c5523d42061b5c5961dac0d9e0aa92ce4028d56740487aaa739f0c4b94cace9d02e90cb3
+4a79d882e037684a6795112597167e439415d46eb4e53755a67a3d72e1987b4530b3b1862c3ee22d
+bfe1e705d99e770171412d9af25cc1c23447b5d4b6cd3fb3caba8d19b93ac551bf3c17ccaa63660c
+85189171b7b7decccaa00ce637b0b2d7ada1d2d119a1e68b7d2095e6373239d32ccda74e4c285c80
+8e9948eb2e91bf8369d81314540e0d144122aed5a5e3c3fb80818e05b1914e67cd8d5e5554775bb4
+b611b5ed4495a2b90dc6746c1125e24715420d867023158357c90a5b0299ac2082db60412f0e7bce
+8e8394eb5c3783e7689e42aa23e34790dd3aa035dc796624882468262255157d2088ecbbdc9394ea
+5285cb4cd1cb1349aa39b39d24d03bc30d07e6aa832a264d48e873e34fb16e35d19619c88bd15bc4
+5656d2adb194e3e19843ebe1eed8f1c06405d55bf6709ff94e76ddcfd470cc9ef1523cd3d3a66b03
+ef17215aeda6f35af6bc38a63bac0d504463559f6c50d51bcbf9d9d644b3062d10b407c7c201f9a7
+f8d18683fdabd82ea6f24c8e25061630989c5fe13391c232566475318c5e98c0d03e935b22f821d5
+b9985fd8d610216d9e3504665dba77861415a803bda4d6c63bc1cfdd21916b71b614295808400b54
+8a6e24ab7cead9fd24fe21cfe73e0f546a94ee5253c703e777645ac73ca1f248117b107332ef1d8c
+f108321832308f021076abf200334e506a731da7f108f48ebb3aa722136b0c07590488a3f5a006a6
+1a94be1ebc4d900d56ca8f51c76b2a76fa107164422220b665d5da2c14410d9eb04b954c38f29fcc
+86b1684cb03b669b1921b1d10932ca46863c72689494ca3697c1a20a55bd0d7465241e23bb057108
+760256cbdfb2d8c2824267eaef6ae4e8549a660c9dd5dde2d8894c8359d9026939bacad090b15709
+23714ace647d8103a10aa33a3820a3c5aa1abd5a3f0da4bcdb1e461a434ca57c55656b46b32a3774
+401192d51ca3c919dbb1a9b696a5352376250f137dd851e3a397c438bb4596e2bbca794e26911d36
+f4115807cc4a6ab16f62f8e3ecd453131fc1a6263865998225d28204534525e5dfe8178f83535305
+3680d340c5b90b83d5cc60be7f645dda7aebe8a1b0a7a0b9d120cf9c95e203f6cfca04b1a59197c2
+0a5fafa3ff4589b55eecea97b64726272bfddc3110dac6146656ab42196d4c54aa5030de1af0998d
+2052ba35d55a1b53a06ec4fd46eb3ea389e35766028b679a9acdd16c9c2192addd1ed4638f069196
+06e3b165b23a537a3ea98912ba85ac4ba42a550ea4b76aaab28418e78671dfa2c594c90f2791a5bb
+2eb9a6d08d1639e73a1166f8a9f49ab2385dda20f6d1f2c58c294d34251daf77731f6402d8b8a4ce
+f79e594325c29e116ff4674b6f89c582d1aaee6cf628f46426a0b07ed1e91d340bbb338306ad1858
+8a4cd266997d546a27c97a2db2406a5d2799fd8051c58e319012aafdb33ee2aa9fbf7b08d19909c8
+2ad308c9a69093ec0bdb4e3b0825a31fdaf215857a7ca2fadb9c759ee20d73219afaed9e381567a7
+3c8d1134503cd97944823b904a1e080439d1f52398a86689342762b23d6e1853cf162d9237f661c1
+d9315a9875656d1a7f326109f4b6b2381c072ad6586ad61f1621a9c12750a0aaa5dfdde84a23a81e
+0755bfdd8836d843c41802f487db3d947cb3ee9b60d794a5164cde3b2761bb4d64ef89f326b361dc
+0ef44967de8560682311fd8426bfdcb36364eb55846657162b308c37e0287b7e8c412514c9e68cc6
+6b6a758ba8a9b48f81cefad4791af6a1b2909f295244928240c60951594ba931331d853fa9899fc9
+2f169a00566f475199d16c1113a9d16a83600e6b2ff079249d93534d8975dc6a0dfaac655120b437
+7e6010ac90d5473d4aee3b430ed9432039b9f9ab1ba834679e5d2c2354605fb2f3020b3b6bad9f89
+2e033c3ba7f3aadddf052112bbf10d893ea4910358c835405a574689150ef53371866ede5f184548
+26ad921f659f3e1afb182198116673bf3a5769d91aa9c1e6d9de1835f1739d94a4b6a1bdc6a5e0f6
+59f73095cfbe8b486d44eaad08f96be87b35128ddbac457ccdb63f653c1784f558e5593890beaa53
+e9c3db40a864a3067d13dac6c82c9b543e8d3053b7540355feb2b30f24c697153d3bd34c31fbf165
+88638938ca6b73d661d6d9333d9295a5960dfd3d638bbcdc66325dd8d9dddaaca72d8bda44447ffd
+1fceb5a3816af3610928aaa89bade7a827a538bd35f4db405f1edd386b4d62153658d73e77692739
+712a1226f3ec28ee41e6942d4254879d4d1fdd90c8ca394d8a2565308363355b06aa531575dd14dc
+197b4d5fac11a92cf91289918d24b4dece3e25a2e66e2a70f153101f960fdb2a3f152053c14d09a6
+e06bb72bae6ccad21771ecc8964967ebcc30b0851f92f142635522c0d3cb4e1ba470ff94df79e008
+6e3b6f4a2baabb7445d86ba2efca968154b7a3963bcf4fa67529db7711da8321f3569b363f065e99
+2deaa91bc5d4cca6337655346984d9410b24ab06c3cba2a61f1fbf2579a632e3dd942ec0a85e3973
+c9ad49b426b204dfd78764ba38de515334662d099235663f1bd59a1a3dc918a3ac8d8029c8c807b5
+cfd10d61fd767cbc97f49d92be30f461fe1430f1431dbaa29d7d39eac5646d9c5e6d54a680da46d4
+e00733e3e3194a13a4cd9a7cb22793405b76b6b0c90157e18a25e52a3f9785b7dc6c20dda56c9e7b
+73ac67a8c982968a9fa378a53f8af560715770c5dcac4602a55560b0a85d7681bd271c9bd86129db
+4195cbf91164563331623cecbf96f1f11540d575092606972ab12ae9a30a5cb76e0bcb5bf1e02324
+a2a6aaaabe1409b59542590f13f554d352c999da9276aa8c88cd2a55ecf5284c3084a1a271e981cd
+a79915731221b21b5b05e442bfbe5b0b49e3195579ce5636886a72f5025dd76b4c27a8358d9fbb28
+b3cfef70b235abb96cdda634c14e5fcdd1a1cec18e098f39a9ada33b1d7cb88d6a04cbe3534635a5
+717efacea58e0a536051df402c11951deb6ad363d62f8facb7f9065bfa273a806ca8c5c53576421b
+a2b6317e5aa952e263a7e2ec94a731673cb1f99487abcbecd1c878661fcc107bd50cd82bcaef23a2
+8c6f33a43a662c8458c7934c830ecb8a08a56c7cb7a96f32d5a6c86f448325698adc8696d8214261
+4965381229f9d982e34aed3505d91796c7cc592e076df7f826968dc75dae22b338d9bec16b71e8a2
+4abf98d29dd88b74a4cfe933f662dacfb3e1ebe2144d56cf0effbb7833be0dffecf61b7df4fde9a7
+fc70fc8bcb77fbafee2faf0ffc54fcdd87cbeff6d3e5ededddc3e5c3fe3d7e9adeddef3f3cdcddef
+277e314f84839601cf7ca4feb0bfbfb9bec5143ff9e9fbf36f3efe9efef937c7c7fccfbfb0fd3f05
+38f5d6279f7cf687f3972f5ebef827956842b4>
+endstream
+endobj
+5 0 obj
+<<
+/Filter [/ASCII85Decode /FlateDecode ]
+/Length 34
+>>
+stream
+GhOt'1B7FZ"#S^CKb'rAF*Y:rk'%+Q~>
+endstream
+endobj
+2 0 obj
+<<
+/Type /Pages
+/Kids [4 0 R]
+/Count 1
+>>
+endobj
+1 0 obj
+<<
+/Type /Catalog
+/Pages 2 0 R
+/OCProperties<< /D<< /Order[]/ON[]/OFF[]/RBGroups[]>>/OCGs[]>>
+>>
+endobj
+3 0 obj
+<<
+/CreationDate
+/ModDate
+/Producer
+/Creator
+/Title
+>>
+endobj
+xref
+0 9
+0000000000 65535 f
+0000017284 00000 n
+0000017220 00000 n
+0000017403 00000 n
+0000000010 00000 n
+0000017090 00000 n
+0000000291 00000 n
+0000000331 00000 n
+0000000467 00000 n
+trailer
+<<
+/Size 9
+/Root 1 0 R
+/Info 3 0 R
+/ID [<2919245bd05467827549e8412ab96fab><2919245bd05467827549e8412ab96fab>]
+>>
+startxref
+17861
+%%EOF
\ No newline at end of file
diff --git a/etc/logo/jgrapht-logo-black.eps b/etc/logo/jgrapht-logo-black.eps
new file mode 100644
index 00000000000..76062f9bf2c
Binary files /dev/null and b/etc/logo/jgrapht-logo-black.eps differ
diff --git a/etc/logo/jgrapht-logo-black.jpg b/etc/logo/jgrapht-logo-black.jpg
new file mode 100644
index 00000000000..9929a76bfb7
Binary files /dev/null and b/etc/logo/jgrapht-logo-black.jpg differ
diff --git a/etc/logo/jgrapht-logo-black.pdf b/etc/logo/jgrapht-logo-black.pdf
new file mode 100644
index 00000000000..9649234409d
Binary files /dev/null and b/etc/logo/jgrapht-logo-black.pdf differ
diff --git a/etc/logo/jgrapht-logo-black.png b/etc/logo/jgrapht-logo-black.png
new file mode 100644
index 00000000000..0dbff4cd824
Binary files /dev/null and b/etc/logo/jgrapht-logo-black.png differ
diff --git a/etc/logo/jgrapht-logo-black.psd b/etc/logo/jgrapht-logo-black.psd
new file mode 100644
index 00000000000..971b9eafa6c
Binary files /dev/null and b/etc/logo/jgrapht-logo-black.psd differ
diff --git a/etc/logo/jgrapht-logo-blue.ai b/etc/logo/jgrapht-logo-blue.ai
new file mode 100644
index 00000000000..e0b8721f3ed
--- /dev/null
+++ b/etc/logo/jgrapht-logo-blue.ai
@@ -0,0 +1,289 @@
+%PDF-1.5
+4 0 obj
+<<
+/Type /Page
+/Parent 2 0 R
+/Contents 5 0 R
+/PieceInfo <<
+ /Illustrator 6 0 R>>
+/MediaBox [-0.0000 -0.0000 479.9999 479.9999]
+/TrimBox [0.0000 0.0000 479.9999 479.9999]
+/CropBox [-0.0000 -0.0000 479.9999 479.9999]
+/Resources <<
+/ProcSet [/PDF]
+>>
+>>
+endobj
+6 0 obj
+<<
+ /Private 7 0 R>>
+endobj
+7 0 obj
+<<
+ /AIPrivateData1 8 0 R /CreatorVersion 11
+ /ContainerVersion 9
+ /RoundtripVersion 11
+ /NumBlock 1 >>
+endobj
+8 0 obj
+<<
+/Filter [/ASCIIHexDecode /FlateDecode ]
+/Length 16451
+>>
+stream
+78daed5cd96e5cd7957d17a07fb8fd6020e986abcf3ce84da24cb401263162079d7e3218ba22b353
+24058a72ec7c7dafb5f6b94391454f8f0d2bb07db5ea9e699f3def7df3c9bf7df1e5a7afbfb9fbdb
+fed3b8732f5f7cf2c9d9fdfef2e1eefe95c0e9f3c3e1e387877b22d3efbefac3ef27ef774e7fa6cf
+be7f7f77ffb0ff66fafbfdddcd747677bf3fbcfdf3ebffc6145f5d3f1cf6affef75dd85d5e2f535e
+dfddbebd7cd8bf9afe70773bfdf1eebbc98729b857b1bc72190fbebdc09b6fee3ede7e737dfbeecd
+ddf7afdce4a6d4f40f27797b77f5f1667ffbf0c5fdddd5fec387b3bbc3ddfd8757d3d90f97b7d31f
+2edfe197cbe97ff687c3dd3fa73787cbab7f6cc77cf9f1fdfbc3f5fe9b3fef3fdc7dbcc7f057d37b
+4cf361ff30e9985f1ff6dfed0fe1ebd79fe7c9efc2a405ffe3d13b0f3fbcbf7b777ff9fedb1fc67b
+6ef2a7ded3ce3ebfc196f05ec17bfef47c1bd2fef8c2571fbec5a102d66ba77efef0ed254986399a
+36c5395e7f1e6d1f7ff9807d804a7c1ef857fb9bf707dc04691c929b36ff8c375652efbfbbdefff3
+15aeeb76afdff2d7afef1fbebcfe17a61c57330dfc8f1f6f2e2e7fd8f34adc80ceaf0ffbf3bbfb9b
+cb076e5e60fdfaab6f3fdefcedf6f2faf00a0cd0f48f4ef566ffee9a0c728999534ed37fedbf9fde
+fcf0b0ff801f9debe1ad3fd71ff70bff68f8affff3dbf0df86ff36fcb7e1bf0dffff311cafe590ce
+523e7f7b7ee6dc2ffd3786ffba814f86d78add78e7cfdfba343f11d3df3db76a4f40939e8bf3e38c
+cb0f51cf5193143de779c2192f75c5397c5d35ae6b3d7a5993bbb6dd1ffedd399c2f65fdb51e6fdd
+2de866ba6cbfda2f6338d7dd0c48c77b397f9bcf9f1c24730a916e9cd5567563a2b419fc76dd859e
+cee7f76cf88630f9b59edbf2aa56399e7ebd0b6d7efd71196edbaf9b7b38db0cf3f381e6d5d78bd2
+cb7e73995b3c6f274c4767f746aa33bdd6c786377ce08dac6ff4fbb89d79f8b88ce397c7b1cab2dd
+747c2fc675cb69fc67e3fccf5c9feb47cbbc9e57df9e7a598b2fdb4be76fc39b137cd117caafa7fa
+65536d29df37ec68b4fdece4546fe7a7706e12f788cbb0caa389423d35786cfe88f6fef404eef52c
+e33357f217adae8dcff4ecc797c535660edf48c49be5de372bf423013d9a72bd2c239a4d8ee1e17c
+2b0463f36f8e373f0697a3e39c6d2eee918a881b3a94ed6fe3487627af67d2bdfe79ab3d2267de9c
+fde7acf678290e8fdb41dbb957b23dc296c5169e7fb2def946d73ccb0d5cfd57ad6b8baeca6a5937
+1e11f0592e2c1b79df2aa0ed7a2777b5d9c166f3cfef6019de56d4fe6ba4cb8fe19fbb8f2365f5dc
+3e8e2c60dc3cb7f5ec6f7e84f6af8fc8b85964a88b93ebac56bd6ed0bea5c7f6eced91ccc79f3ed4
+2c328b51f68b0df71b9aa7374fa7f28f54e5f9e6f5d7abc5f1e989f15adeb1e1671b23957e7ce5e3
+3716892b5b359d8e6d2a7e4dab6edf1ae9d9fdf31b620d458141f1988d8e75df7c719b3b3d31c03f
+e338a599e717aa97b095f1e51079aba4d7c18b7781815b99afc7373cb8a26c3cb0beb1711b594a1b
+4fae3d629d8d3358ea31d7a58ddbb5713f6a7862e7f3c6294d4f9dd2fac86fd434cf3bc54351ff5a
+9ffa670def6f45a44f3ebbfd8619a6f1787677c324d78725fbf4c5fddde1ee1dfffaf9edd5e1e337
+fb395df873b2853f31e4b9e4e14f0c7b2e97f813c39e4d2dfec4b84799461069a58948f4e5fee1e3
+fb972f9e90e13faf6faf1fae2f0fd7ffda4fef30ddfefbfdd5fc9a4dfa636f3cdaeed7df5dde7f78
+e62427a9f963733fa2e02fd8c633ef8a2c830e4a738a30ca7dbe7c31f9f13f26af3ff553f4532853
+88d3c5df5ebef89d5e9afcefa78bdb972ffcf4d73fbf7ce1a63fe15f4aa94f6e976bc9f84f2ba54e
+7fbd5c7e48b5ef7aef65ba79f962795e1e2e36e01870b199f311b01df6f7972ffefde3e99d9cf8cf
+3ff066493b289538f9ec773d60b33704cbaef54030ec8a7e2d0d47a90d48de41a9052075d7420207
+e7b64b3ee4e98c03eb2ee7865f73df2597ab5e73c1f1c1ed426e69e2e4d1732090ee7dd3c05a76a9
+39f075c56ca0160fe36bdd451793c0d84ad0838736d643d636f0d04bb38178c5b6018a3457f96bdf
+85d8fa04bb89696314d2622e427a6e5e0f39c7ce81c1955d6d992bfa5d0ea1721b025d27888bac9d
+450e20396421816727d243c76ca563363b148e0d3a931a000342c08988c71fd1b3d7e48584988dc2
+d56163dc7f6bbb507c37da363c901a0d639b77a29bcf15abb7bc73bd90b6d03e91fb6971e76a326a
+a7eec66c6443d7752998ac8b08340940b07a7046286c0733e4b4ab1ea41b0393d736028ec98be0fc
+5eaf39bc1692f6903d2906fe890dd271665bade07c63aa16c136adef7ccf4ef3fb18f18033f6d6b0
+d50c7ea8311bc5daae84dac524ada56ef4077f7b4786c9b8d60c6a7b0fb6247f028989950e1fb1d5
+e4c63bd566f305a7034b73b65c7029c157b25cd28d80b08678716cc5197bacf3c0e412ef37efbcc3
+e9347f13420ee91ce876a58a390b885f930d0458c20c2667fbc76e7d8d3a72abb91918300f3489ef
+10c6e8b0848b908b46c4ef6a8964aa40c581453b56cfc19620e89c818562afa93c6845a447081d91
+e27117be27cacba0066c4d822cf3575c99edcdc334f468a003957552dc16991c77572174c1277063
+737a07e42c33896af536b0c782070fa6857301042c1173176de1de70870d67ec75bab2813dba2e02
+e60411e3fc31b276c8cda45875bf2dd4a407f086b383f75d0c14190cac2e44c90eb8206b7eef42d2
+43ea122beca1431eaf065395c013259c48454af05e1e4872dc3c278f3eeb163a05ffcc2e0e4c4b52
+67bc9f8736c07d15eab15ea800c1db1dbaa824229450d7f4e0a43fbbf449e1367817a5751be81356
+e77de130510f74cbec4e1bd5087820fa599aa0a92af91fb256a9fd2e4cc56108250b44ce54b0959a
+2405b159c29607f796a87752c12d731be073483a4132394480baae409d49ba73a7d2e63bb17072f8
+19d1571b18a96d9ae9d2d0f91a769ba1abb5994a8d547995a10a89ae98fe818989e003081deeb718
+fffb42818d06c60a81d243e986a428250922c41e84c0f08cd9a0727941fc15a48d526ba191fe4002
+fe26b5591c4f8497236449031388e0ba696328feac6d2458964e63542974a4275ecb662912151aa6
+4d19d4e3c04adb979ccdc6bba3a682a477c83f5ec35aa119e20304d347a8d9a0811182df8cfe11ba
+31e8763c751d2e3dd296c562262042d03855cd946858cf844dd88a204bf145da2ce588695382a025
+d39608358840edb8e4351044b58150f259fb0759b01db3ad002385820f29677b80f24852c859f685
+034d69e3e0d599a5c62458d37c8396fb207b912687bc5496809f381567a73c0df357249e3119f374
+32c08d8120b781b9c26651d86b1331a1d3fc30a6a99180e44367169c1c5b03afa3d17501575c0c30
+53b5ca7e91c242e8cf008932551ac8ed35ead5e297d96a33c35a786b174390337906462d14f0b040
+c866e7a540d65aa15f012500597693196ee907309ed93efc04edaf250042264c90a15087c97b4c93
+e1dbfde597fa77d86292b3052555e10191b8d02d49960b8a08b1b99f7020d836370369eae469b291
+8d92e0f138d4dbdc7082a84c9d4ad751bb83f1711c02915e02f52684dfe40456014c1b05423a8cf9
+00424b070dcd813ac577ca98d3ec8d56ca0778392ddb7a3104bb5d803dd27e73638de70ab8a1462d
+d0a9fa79a301179fa4b581a4a13542a5680573ec700e6d0320a4aa0bc486c13401acdfaa976307ab
+168440450721b0c1631b70325a1dfe1f94d644a4f4d885802859480ed1d44d2dc906d2ff6b72d4e0
+b1b514b50d5a47da60b26c932f42c3e6e4b6528393e8f02fa15caab4766ec3b1a3f5820f3b343edd
+2c1019f62fac08b94b9ea48debe3265b106326e309019a1cc44c258d51a6d8bb37dfcceb5645ad61
+e841179041da9eacc0f76176f18bd7c0e486c6089097144d2915ae776120d44892c3d63b4512083c
+f32ced01c295417bae08fddf4b1a37a91060840f0e720a2b42b1ca039146a521937fc881d9042d66
+1a4a73239d540491d4cd1b8715a863a0afc7b74db0cd2c50bcc97b227b720912112acd406f574d30
+d019a699c0deaa90a2c8024abb56ea6adc6d873764ba1d629e8751962743a3e37db08b0bb2504082
+2931e8ff5eec5099914836cd862b1cba1d9e49a16702860a99d741ddce7b94414fe494cc2b13c293
+265377b0a470209b2eb4046f46194e719d11bb9d6ade88062619351a204909576c0a491604db6e2d
+6e07420838958c02e76f231ce036d63d0839deea187865f6aba468025114123296e97dd050410410
+b043b4200556c4482d0a67cd8f7166201289ccf3ca1b6790056ab7c449a02db3421e5e5c61f4d4e1
+3f3372b9323700019193a71d13d53e19a326f3bd933c04d877935d0c84296bb342f2e69432766bd5
+8482562f3a79a18e7ccbd760828b1cdaa258187aa5ba3842ce329c8a10574f3b89cda0290b6266f3
+bd158943c542379a7f0eed6e1747f5cc7089208e8a637aee96290e47ffc71912280bdc5586572d1d
+82b7a2f61599e3903ea54120af7364e6009a0c78c69a3c31d8915dd1dcc5f4266782cbd2b245c28e
+1c004b0ab1ce026066f3c4b0a6a7e102f8348f82830a0cdaded1e8d8fa50678619dbc3bc145abf10
+18c248412e0883fa6c36ca40d8a840af1594912d817282ef4b573a724f4c62af0068876d45e7b62f
+795aacb49946401d8b255dfc8a819d228f1be886e3b8b8439782ac31b8dc8e11639b4795aa00a732
+96970a05abc2821461f02aa0eb199928f861f08c3b998dbf91db82fa262f2fea9220d47e1250bc6c
+71a3cbfec465383be146983f42d55b5235b35a688f6f0c740a83009a998cccbe502b00e99dc10a48
+8438270d242f86a23113c055207c162880df7d95d8316190ccb2c27f29f20c7ca69ea34cb07351be
+02396e18e9ea154bc14dabc3e4c3fb86abed25e89df22110cc24d7810e5dce342954abc39b0b95b1
+489412f2c76a9b602f66a75bb46b794a935febbb81330aef150a15f6d997e1bb35845ac0e04d3b04
+61e042f833044075f028652c563218f4738ce685f53aa40518eb1072d52a2f1d806750441a75f22e
+47f5610e1014a7c840bb30e710daecad7466360842d9e10ae9ac4a2359bcd68564bab2816928fc66
+b341a898090cd0f0590e1a5fc3e50369438773f2c68150ddad9b8d60328c014748d4cd5dbb680aa2
+aab084cb25177bc68c042a73023492141402dd99e343c3c0a04258c5705e5bed6c9455022d10c80d
+1c25209becd1003323c60323c892a5e79e1c7e2656998da1ec1990981e080472761c55782f614871
+0860fac06c2a734d4d413c36549969801623bb692d8a4e31c74b0e06dd6a44e508f7300a84f7bcf2
+ca5de3ae70f5298566f3465bab513b30c185f5617f1d5f82f87043917603d360a781691d000e7369
+147350dee88ab839e8ac706a98a124e6e955d1f027a6c0c0fe8da69d5e6283b5828e81409a5a57e6
+95bc136918b949667b6990a82ea19e27ac552933213293e6e3a0754ec13431def6524685d9224a95
+c3e13b33ae340691e6d5bc7b61140a62a158ba1436a71526a82265d34228bad1a1f29af0266c5a91
+ab0df3ce6d05ca355413b83e30b54c4431c92c0a891929822ed86b857e1911f82b86c0f77686c468
+0e9a0fcc38d2e080a254e117063a65d418e464fa2c9e4451568c31257526d37591b3c1fcfa364279
+2f0f94c9b64c77d2ebb55e82e5ed5c939d07119865613a0d4adbdc252f67a129a356e50062a1ccc4
+39078694cc6508ccd271f259f12be2f2b472f202e8a23254a3cae0e6b105283a4eee98f00bca9a87
+794590da0904153990ee360d166336911a88136bf19d38ac31b61da44e40c652d28818a1e698ba0e
+70c603634b1e333737188c6a9288e5d479e35457da061625239159216af61af492bae3b131fab6a4
+21833d4abd8a0f67b662427403550407b68e8a8451260b3483c81c275d4b6a2c38e155488369313d
+47961d7e1698354b61386595481f3a53d418a02737c6e49f371d026b6f9e9da7eaa5bda6fbac98cc
+6ebcd86b3c261198071b08ae6e73b866e958c86f767d286f7a4bd42fd42195e68cc96066e8035323
+ba5fa7bc4e3713d3fc3005918ccad9e82792687451ab0c4f21fd9306165669025d8ad8cc0aeb98e4
+0dfa3971242f45345ab64ec780c98fc0e419c29700816f32f7f07ea036303f3d26aad83994ec61cc
+a62c389d01680f20d9f20b7c07912638b6d37f844cc941662a5d20542ee45c6c0c9b9fa6c81c4411
+47d1a8682acae0c81a62ff2e30cb019319547e010ff8427d4c4bcbfb2292e43fc275cb348973b82c
+e346a7a28ec8cc5109905b744c4a2bd3c94e2752fa50b137160d02b0af307bbb4e0b302ddce41283
+c04ef31458f9e989af7076c27f3047840b39da533a39d4a037a641990ba6068f8c071a6b8a5c0080
+7c329a2a47ebcd688621f2ac8e12933b8838fd301704ab9744c053e201c89f8ec5222230bb4e480c
+c9840bb41facc26473b5d7a0284c5552cdd24da56c966a39782aedceec02413871d9f223c599e172
+8d1925e9ff524cf0d308e5094612929e1ba97c71821ec7fe9afbd9fe1a7553eb54a099c6d7bce115
+6444c95a24f37be0d17e041e0832b35d36200b28305da0486296920f0b8203480054529941a8b6c2
+12c9a8ecd492f23360a47986c23d6c4144c150a01c2233ecd68370c38e9eee825c9d3aefc53320d3
+bc700ee1d045e19da53a128765b84a076806e1cbe1b668cb133cf5c4cd2c486458853d73e9050cc5
+aa1e872de89ba5c1d6f96722acdb9811ce96181ab3b23f839c2d519dc9b2ce63a39c91710b810cbd
+200c30299822cb0256f3050f5b900e84489a5886a34a85b942dc4c078b59dfba41381b4b9c8c9416
+f0e208a40be8ac328553f45c37a04e51684dfd0ac2d643f68af958e6deafc820a668b280506a3071
+36db02d2f6b7289ec139b31c1744c3415729777241aeecf6614bd20a1eec14b06d6d33b63001e2cd
+9380a3738430ae4976fb0b480f142ebdcd368349493c1a48baf7d44410a82e25529484ae2ba293b2
+3e1efc0a5e6cc199332f4ef1f0e119100c1f999d2df4ca370c1fbd0cf066da4897a233ff3133fc8a
+6c187e05370cbf8233c3aff3cf4cbb6e63cbf04d95a947ca61053b8b1df218e0a09b855e40aeeb98
+e9a70b3583514a9f2a08865601e5061952a053cc20d5173b100e5b905a8ef9e475fe5913aedb9811
+9e826571a7811b2dcab41e35dbaa4519c0a5dad7f95764de86683283f063a2ef83267ecec89d02e7
+0b3a6cc14571352675dd8601e8b564b513ccc8d5293e393c0392a920b32a5988b70b04ea660b6e78
+1581225321fd78da8c2df92d574786de4c66aeecb7205bf65bc00dc3c073679b417e06dc5ef1022e
+579cfdf0f2972b4e74a7e2f115af47db58cf15dcae1bd288a94e8233b92e4ed1f0391004878d6564
+6eca24d62c29de807828a67ea36a35f53970bb2bf62085c7745bc0ed7038f49915e467c0b1a58b53
+fb7c0efcbbe5f9a353c2603dd40ab2ecc2f2c1610b52c3b07782b5e01cf286135831ef4746f6ca8a
+2625f5e3836f407661353fe7dee12ff415d4baf4f65a5e41360ec1436d96dd0dea385a10ced09dd5
+05667073e4a7e77d0e543d9a79dd7e7ce31b70bd0816b98a1a5166903b67c55691fc0cb29b22cbf6
+2144ac4a5cae48a4f7e8e7c60c03e7e31c8ec0f9d4cbfc0b65966dcc88ba4de00b0509ec86aa8888
+e07a6c4095a4b372d6b062a91e21830daeac486de06c705555672094ea3320243dd5b96786854a65
+e74e81748659ab3c6c41f01b34a5b3fa88924b0bbf21ca0a6a3ddaf29bea53bd1eb970ccc02298d9
+58439620f196dff0f3826ccfbb80b8a0164d79ae60619aa35a82dbe69f5965ddc68c5c9de2a85f9b
+11660532339242a4c8e8db5bb766656806231c58e5ebd662e9e89250ffc53e904a231c99a26996ec
+536f26d42e40c77ca4f59bc8ebc134ec120a2a8d060a2211d7ead203e27dc040c7e2d848adb3fe46
+df2aaadf2d5a23891a79a2cad2dc06233b368d12f1a322a1964338938ac4ab24864d824c5910c19d
+b0b817875567f741ca75aea1c17f347f21d591f723c8fe1d501c4e3df3124412f41391aaea3e10c4
+f75d4e4a4a75a9c865a6ebe58f24d59fd96012e8a3e19e0333d641d5932624f4b915a858ff9a68cb
+3ce4c5e83662732be9d658d6f170cfa1fb7077ec7e60ca824a2e7b38d17c27bbee676a38e6d07829
+9e496ad3b881f78b40ad76d37c2d7b5e1c931ed61828a2b1c24f36a8ea96e5fc6c74a271832e08da
+8363f980fc53fc68ccc1fe5578175379a6c812c30b984dceaf209a4861492bb2d21846774c60809f
+c92d11fc90ea5cd82f6c71889039cf4a02732fdd3b438a8ad581be526be39de0e74e91c8b5385b8a
+142f84a1058a453792554af5ec8712ff90e7739f072a414aa7a9a9fb81f33b32ad63b650d9a4883d
+883999fd0ec6780419121998473108bb5591807927a8b6b9a6d37804fac85dbd5491e93506852c05
+c4d1865003130e4a620fde26c8962b65c9a8e935157b7f883832211110db726b6d168aa0964f58a7
+4a261c5950e6c4584026d81d73ce8c93d8fa04196553431e99344a4a65cbcb605105acde06ba32d2
+8f91fd8338047b03ab657159726159a13301783532752a533392ceea7471ec4da6d9ac6c8ab44c5d
+6580c808ac84913e2567b2cac081508851dd1c90d162b58d5eadb70652de6d0f239921a652d6aab2
+4da359c51b3aa008c96a94d1e48cf0d8665bcbd2a611bb5288899eeca8f7d15762b4dd22cbf25da5
+3d27c3c86e1b7a0aac0966a5b6d84331bc72f6eea9ad8f60535b9c724dc1d2694182a9d292b270f4
+8ec7c1a9a9025bc269a6e2dc91c1ca66b00820b2466ddd76f453d85fd0dc689967e64a51023b6a65
+88d8e4c84b619dafd7d10ba3f45a2f76f54b2324539495deee18086d630a33ab6da18c96262a5528
+186f2df9cc491029ddda6cada5295037e27ea3f5a3d1d0f1d33381c53359cd766936d110c9d6800f
+eab15f83484b83f1d844599d293d9fd45609dd42d62552953007d25b355559428c730bb96fd122cb
+e487abc8025e975c53e846d39c739d08f3fc547a4db99c2e6d10fb68ff62de94869a928ed7bb3911
+32016c62522f7ccfaca41261ff8837fab3c9b7c462216955bf36fb157a32135058c5e8f4119a05df
+99a183560c2c482669b3cc9e2ab59664bd165926b50e94cc0ec1a892c7184809d5fe592571d5cf5f
+4284e8cc0464156b846453c849f6858da81d8492d10f6df9ae42fd3e51bd6ece7a51f186b9104dbd
+774f9c8ab3539ec6081d289eec4222c11d48250f04829ce800124c54b3449a1331d92a378ca967bb
+16c91bfbb0e0ec212dccbdb2428dbf99b004fa5c591c8e03156b3535eb0f8b90d4ec132850d592f0
+6e74a81154bf836ae06ec41cec27622401fac3f91e4abe59274eb06bca520b26ef9d93b0f526b20f
+c57993d9306e07faa433fb4230b4918e7e42935febdf31caf52a48b34f8bd518c61e709a3d3fd2a0
+2a8a647646e635b5ba45d46cdac74067fdeb3c13fb5359d4cf142c224901216386a80ca694991990
+c29fd4dccf44188b4e00abb703a9e468168949d5687542b088b51af83c12d0c9a9bec49a6eb5c67d
+d6b52816da1b3f3c0856d4eaa33625579ee187ac22909cdcfc350e149b33ff2e961136b05fd97981
+851db7d6e144c701fe9dd379f519800b42247ce3db127d602337b0907780b4aeec12ab1dea70e20c
+dd7cc0300a924c60253f4a407db4fa315a3053cca67ff5b2d2be355283edb4bd3182e2673c294979
+43878d4bc175b306628a9f3d18913a89d45b1172d9d0fa6a2d1ab7598bb89b8d80ca7e2e086bb3ca
+b970203d56a73288b78150cc460d7a28b490911937297e9a62a671a90caabc66671f4e8c2f2e7a76
+a69f62f6e38b11c7727194efe6ace7acb3977a242e4b2d1bfa7b461879b9cd641ab1b3dfb559975b
+16b58988fefaffa26b4703d5f8c372505481375b17524f4a777a6bf4b781be3cba71d69dc42a6cbc
+ae7deede4e72e554304ce6df51e8838c2a9b86a8143b1b40ba219155741a164bd06006c7cab6cc54
+a742eaba293835f69abe64235259fe2512239b4a68c39d7d6244fddd54ece227223e2c1fbc557e42
+40a682b3124ccdd76e575cd9a6a52fe5d8a32dc3ce369a61660b3f30e385c6aaa480a7af9d3648e1
+fe29bff3c011e876de945654bfe98ab0ef44df9b2d03a974475d779e9f4ceb52b6ef25b40743e6ad
+366d7e0cbc328bd453378aa9bd4d67ecaa6ed214b3a71648563d8697457d3f3e8a4bf24f65ccbba9
+5e8051dd73e6985bdb684d6409beaf0fcc7471bca3a698ccda13246bcc8436aa35b57e923146891b
+615390a90f6aa8a333c25aeef8a82fe9fb257d79e8c3fc8960e2073c74483b7b74d49dc93a397ddb
+a8ac01b58da8c10f69c647359426489b35fc644f2681b6ec6c6a931bae2216cbcb55de2e8b70b9d9
+403a4dd9fcf7e658db50c305ed153f53f14a8514ebc7e2aee090b9598d044aabc060b1bbec02fb50
+3836b1e752b6832a97f323d4ac6662c478d87f2de3a32c80aaf1124c0c31556e550248d5b86e9d17
+96c3e2c14760444d55558929126a2b8bb23626eaa9bea5f233b525ed5419719b55add8f751986608
+4345e3d203db5133abe72442647fb68ac985de7db77692c633aa0a9dad8410d5f6ea05baaed79854
+509b1a3f8351969fdfe7646b5c73d9fa4f69829dbea6a35b9d831d137e73528b47773af8701ed514
+96c7278e6a50e3fcf4a04b1dd5a6c002bf8158222a53d6d5b2c70c601e1970f30db6f44f7403d962
+8b8b6bec8d36442d64fce45265c5c74ec5d9294f63ce7e62f3290f879739a491fdcc3e9821f6aa1f
+b07b945f4c4419df664875cc5b08b1ee2799061d96d5114ad9f89e53df6aaa6591df8e064bd514b9
+0d2db15b84c292ca702452f2b305c795da6b0ab52f2ca799b35c0edaeef1ad2c5b91bb1c46e672b2
+7d9bd7e2d04595de31a53bb12fe9489fd373ecc5b49f67f3d7c5299aacfeddc59bf1cdf867b7dfe8
+63f04f3fe507e55f5cbedb7f757f797de027e4ef3e5c7eb79f2e6f6fef1e2e1ff6eff1d3f4ee7eff
+e1e1ee7e3ff14b7a221cb40c78e6e3f587fdfdcdf52da6f8c94fe29f7ff3f177f6cfbf393ef27ffe
+85edff59c0a9b73ef9e4b33f9dbf7cf1f2c5ff017c5544da>
+endstream
+endobj
+5 0 obj
+<<
+/Filter [/ASCII85Decode /FlateDecode ]
+/Length 34
+>>
+stream
+GhOt'1B7FZ"#S^CKb'rAF*Y:rk'%+Q~>
+endstream
+endobj
+2 0 obj
+<<
+/Type /Pages
+/Kids [4 0 R]
+/Count 1
+>>
+endobj
+1 0 obj
+<<
+/Type /Catalog
+/Pages 2 0 R
+/OCProperties<< /D<< /Order[]/ON[]/OFF[]/RBGroups[]>>/OCGs[]>>
+>>
+endobj
+3 0 obj
+<<
+/CreationDate
+/ModDate
+/Producer
+/Creator
+/Title
+>>
+endobj
+xref
+0 9
+0000000000 65535 f
+0000017212 00000 n
+0000017148 00000 n
+0000017331 00000 n
+0000000010 00000 n
+0000017018 00000 n
+0000000291 00000 n
+0000000331 00000 n
+0000000467 00000 n
+trailer
+<<
+/Size 9
+/Root 1 0 R
+/Info 3 0 R
+/ID [<35fb597d36428342dc114047b9758f5f><35fb597d36428342dc114047b9758f5f>]
+>>
+startxref
+17789
+%%EOF
\ No newline at end of file
diff --git a/etc/logo/jgrapht-logo-blue.eps b/etc/logo/jgrapht-logo-blue.eps
new file mode 100644
index 00000000000..312244c4b3c
Binary files /dev/null and b/etc/logo/jgrapht-logo-blue.eps differ
diff --git a/etc/logo/jgrapht-logo-blue.jpg b/etc/logo/jgrapht-logo-blue.jpg
new file mode 100644
index 00000000000..301ebffb70f
Binary files /dev/null and b/etc/logo/jgrapht-logo-blue.jpg differ
diff --git a/etc/logo/jgrapht-logo-blue.pdf b/etc/logo/jgrapht-logo-blue.pdf
new file mode 100644
index 00000000000..99387231b72
Binary files /dev/null and b/etc/logo/jgrapht-logo-blue.pdf differ
diff --git a/etc/logo/jgrapht-logo-blue.png b/etc/logo/jgrapht-logo-blue.png
new file mode 100644
index 00000000000..390a04ab351
Binary files /dev/null and b/etc/logo/jgrapht-logo-blue.png differ
diff --git a/etc/logo/jgrapht-logo-blue.psd b/etc/logo/jgrapht-logo-blue.psd
new file mode 100644
index 00000000000..2241de5b450
Binary files /dev/null and b/etc/logo/jgrapht-logo-blue.psd differ
diff --git a/etc/logo/jgrapht-logo-transparent-cropped-javadocheader.png b/etc/logo/jgrapht-logo-transparent-cropped-javadocheader.png
new file mode 100644
index 00000000000..78e8b96b5df
Binary files /dev/null and b/etc/logo/jgrapht-logo-transparent-cropped-javadocheader.png differ
diff --git a/etc/logo/jgrapht-logo-transparent-cropped.png b/etc/logo/jgrapht-logo-transparent-cropped.png
new file mode 100644
index 00000000000..d8535e2b9e5
Binary files /dev/null and b/etc/logo/jgrapht-logo-transparent-cropped.png differ
diff --git a/etc/logo/jgrapht-logo-transparent.ai b/etc/logo/jgrapht-logo-transparent.ai
new file mode 100644
index 00000000000..9923083c864
--- /dev/null
+++ b/etc/logo/jgrapht-logo-transparent.ai
@@ -0,0 +1,289 @@
+%PDF-1.5
+4 0 obj
+<<
+/Type /Page
+/Parent 2 0 R
+/Contents 5 0 R
+/PieceInfo <<
+ /Illustrator 6 0 R>>
+/MediaBox [-0.0000 -0.0000 479.9999 479.9999]
+/TrimBox [0.0000 0.0000 479.9999 479.9999]
+/CropBox [-0.0000 -0.0000 479.9999 479.9999]
+/Resources <<
+/ProcSet [/PDF]
+>>
+>>
+endobj
+6 0 obj
+<<
+ /Private 7 0 R>>
+endobj
+7 0 obj
+<<
+ /AIPrivateData1 8 0 R /CreatorVersion 11
+ /ContainerVersion 9
+ /RoundtripVersion 11
+ /NumBlock 1 >>
+endobj
+8 0 obj
+<<
+/Filter [/ASCIIHexDecode /FlateDecode ]
+/Length 16445
+>>
+stream
+78daed5cdb6e1dc7957d17a07fe879309064e03375bfe84da24c8c012631620793793218ea44e6cc
+2129909463e7ebb3d6dad597c38b2d67de065662a7b54e5575d5ae7ddfbbf3d9bf7df5f5e7afdfdd
+fc75ff79dcb9972f3efbece4767f7e7f73fb4ae0f4e5e1f0f1eefe96c8f49b6f7effdbc9fb9dd39f
+e98b1f3edcdcdeefdf4d7fbbbdb99a4e6e6ef787b77f7afd5f58e29bcbfbc3fed5ffbcdf9d5f2e2b
+5ede5cbf3dbfdfbf9a7e7f733dfde1e6fbc98729b85731bc72050fbebdc0c837371fafdf5d5ebf7f
+73f3c32b37b92935fdc345dede5c7cbcda5fdf7f757b73b1bfbb3bb939dcdcdebd9a4e7e3cbf9e7e
+7ffe1ebf9c4fffbd3f1c6efe3ebd399c5ffcef76ced71f3f7c385ceedffd697f77f3f116d35f4d1f
+b0ccddfe7ed229bf3decbfdf1fc2b7afbfcc93df85492ffcf70763ee7ffc70f3fef6fcc3773f8e71
+6ef24f8dd3cebebcc29630ae609c7f7abd0d657ffac51777dfe15001ef6b4ffd7cf7dd394986359a
+36c5355e7f196d1f7fbec33e40253e0ffc9bfdd587036e82340ec94d9b7fc68895d4fbef2ff77f7f
+85ebbadeebb7fcedebdbfbaf2fff8125c7d54c03ffc3c7abb3f31ff7bc1237a0d3cbc3fef4e6f6ea
+fc9e9b1758bffde6bb8f577fbd3ebf3cbc020334fda353bdd9bfbf24839c63e594d3f49ffb1fa637
+3fdeefeff0a34fbef8ea5c0f6ffda9feb84ffe83e9eefff0e7d7e9bf4eff75faafd37f9dfeff633a
+86e5904e523e7d7b7ae2c22ffd37a6ff6b131f4dafd5c1e971fef4ad4bf31331fddd03194f40939e
+8ba3b771f443d473d42245cf795e70c64b5d714e5fdf1ad7773d18acc55ddbee0fffee9cce41597f
+adc75b770bba592edbaff6cb98cef76e26a4e3bd9cbecda78f0e92b9844837ce6a6f0d63a1b499fc
+76dd859e4ee771367d4398fc5acf6d19aab71c2fbfde8536bffeb84cb7edd7cd3d9c6ca6f9f940f3
+dbd78bd260ef368b6cf0bc5d301d9ddd1ba94e34ac8f0d6ff8c01b59dfe8f7713bf3f47119c783c7
+b1cab2dd747c2fc675cb69fc17e3fccf5c9fe39ef8c75ef35a12f7e0d4c586d8601b74fa36bc7982
+2fba515eebe954ee972eb5a5fcb2354de7a42f9e5ceaedfc144e4de21e7019def260a1509f9a3cd8
+e688f6fee905dceb21e36e7025b1a8b76be3333dfb4c81f51d33876f24e28dfd3e4f8f1b02d5f186
+a325d7cb32a2d9e2981e4eb7423036ffe678f36372393acec9e6e216d2e4cd14777c90f5adc1eee4
+f54cbad79ff6b607e4cc9bb37fcadb1ebe8ad3e376d276ed956c0fb0e5650bcf3f7adfe946d73ccb
+0d7cfbbff45e7be9a0fcf6bd7151cb3ff55e7ba94d5fc174fcbe2777b5d9c166f3cfef60d16e6d9d
+6eff6ba4cb0fe14fddc7d8fcf3371efd030b1837cf6d3dfb9b9fa0fdeb23b6debcc4d4c5d3ef59ad
+7a35e97e207d0fcede1ec87cfcf943cd22b31865bfd870bf394c7af358ebfb07aaf27433fcf56a71
+7c7a64bc963136fd6463a4d24fbff97884491cbd86bef11ad2b14dc5af69d5ed5b233d5ca395e263
+81a249f1d89e2e13fb1895671b37167862827fc6714ab367b550bd6cfd89f51079aba4d7c98b7781
+8965eb2f6d272d5c51361e58dfd8b88d2ca58d27d7b6d6677154f266443c768df2437fa68647763e
+6f9cd2f4d829ad0ffc462df3bc533c14f5bfea537fd2f4fe5644faec8beb77cc308dc7939b2b26b9
+ee96ecd357b737879bf7fceb97d717878feff673baf053b2853f33e5b9e4e1cf4c7b2e97f833d39e
+4d2dfeccbc0799461069a58948f4f5fefee387972f1e91e13f2eaf2fef2fcf0f97ffd84fefb1dcfe
+87fdc53ccc16fda9110fb6fbedf7e7b777cf9ce4496afed4da0f28f80bb6f1cc589165d041694e11
+46b9cf972f263ffec3e4f5e77e8a7e0a650a713afbebcb17bfd1a0c9ff763abb7ef9e2e3cb17bfc3
+3f7efacb9f5ebe70d31ff12f25d627b7cbb564fc4f2ba54e7f01bbfa927690e538f9ec773de0c72b
+8265d77a20187645bf9686a9b501c93b78480148ddb590c038b9ed920f793ae1c4bacbb9e1d7dc77
+c9e5aa61905a3eb85dc82d4d5c3c7a4e04d2bd6f9a58cb2e350776aa580dbb9bce08d65d7431098c
+ad043d7828413d646d030fbd349b8821b68dda77cd55feda7721b63ec15c61d91885b4988b909e9b
+d743ceb173627065575be61bfd2e8750b90d81ae1304e16a676d01480e5948e0d989f4d0b15ae958
+cd0e856383eca406c080c86b22e2f147f4ec3579212166a37075d818f7dfda2e14df8db60d0fa446
+c3dce69de8e673c5db5bdeb95e485b087de47e5adcb99a8cdaa9bbb11aafdd755d0a16eb22025d05
+20787b7046286c072be4b4ab1ea41b1393d736028ec98be0fa5ec31c8685a43d644f8a817f620353
+9ed8562b38cd98aa45b04deb3bdfb3d3fa3e463ce08cbd356c35831f6acc46b1b62ba17631496ba9
+1bfd3bf8c4916132ae3583dade832dc99f40626281c1476c35b931a6da6abee0746069ae960b2e25
+f84a964bba1110d6102f8ead38638f759e985ce2fde69d77389dd66f42c8219d13ddae54316701f1
+6bb289004b9841ec47fbc76e7d8d3a72abb91918b00e04d877c8667478858b908b46c4ef6a8964aa
+4041c54b3bde9e83bd82a0730696de8b86550f5a11e9114247a478dc85ef89f232a801159f20cbfc
+1557667bf3d0c83d1ae840659d14b74526c7dd55085df009dcd89cc6809c652651adde26f658f0e0
+c1b4b0e940c0123177d1165e0577d870c65ea70b9bd8a3eb22604e1031ae1f234b76dc4c8a55f7db
+424d7a006f383b78dfc54091c144780251b2032ec85a1fae4dd243ea122beca1431e2f065395c013
+259c48b541f05e1e4872dc3c178f3eeb163a05ffc42e0e4c4b52678ccf431be0be0af5582f5480e0
+ed0e5d5412114aa86b7a70d29f5dfaa4701bbc8bd2ba4df4096fe77de130510fa09cb33b6d5423e0
+81e8676982a6aae47fc85aa5f63b33158729942c103953c1566a9214c466095b1edc5ba2c6a4825b
+e636c0e790748264728800755d813a9374e74ea5cd31b1707198f7e8ab4d8cd436cd7469e81c86dd
+66e86a6da65223555e65a842a22ba67f606222f8004287fb2dc6ffbe5060a381b142a0f450ba2129
+4a498208b10721303c6335a85c5e107f0569a3d45a68a43f9080bf496d16c7136170842c69620211
+5c376d0cc59fb58d04cbd2698c2a858ef4c4b06c962251a161d994413d4eacb47dc9d96abc3b6a2a
+487a87fc6318de159a213e40307d849a0d9a1821f8cde81fa11b836ec753d7e1d2236d592c660222
+048d4bd54c8986f54cd884bd116429be489ba51cb16c4a10b464da921e3e10a81d97bc2682a83611
+4a3e6bff200bb663b61560a450f021e56c0f501e490a39cbbe70a2296d1cbc3ab3d45804ef34dfa0
+e53ec85ea4c9212f9595d7474ec5c9539e06b6f1b7219e3119f37432c0958120b781b9c26651d86b
+1331a1d3fc30a6a99180e44367169c1c5b03afa3d17501579c0d3053b5ca7e91c242e8cf00893255
+9ac8ed35ead5e297d56a33c35a786b674390337906462d14f0b040c866e7a540d65aa15f01250059
+7693196ee907309ed93efc04edaf5700844c982043a10e93f7902646abdffdf9d33d3b6c2ec9cd82
+7aaaf07d48566895249b05158460d84f380aac9a9b813475723319c86649e478106a6c6e354148a6
+4e75abd60ab03c0e4220d23fa0c684d89b84c01e805da340c885b11d40e8e7a0a939509bf84ee972
+5abdd13ef900ffa6657b5f0cc1ee15608fb4dcdc58e3b902eea651fe3b953eef32e0ca93f4359034
+f445a814aa602e1dcea16d00843c7581d830d82580e95bf572e960cf821028e72004d6776c03ee45
+abc3f383ba9a88941ebb1010250bc9219aa2a925d9447a7e4d2e1a7cb596a2b641bb48eb4b666df2
+4268d29c1c56ea6e121d9e25d44a95bece6db874b45bf05e87aea7830522c3f28515215fc987b479
+7ddc640b62c9643c21408b8398a9a431cb547af7e69579ddaaa8354c3ce8023248cf9315381e0617
+bf784d4c6ee88a004949d1d451e1fbce0c84024972d57aa73002814f9ea53740b83268cf3742f3f7
+92c64dcaf91f81838384c27e50a0f240a44b69c2e419726236118b9926d21c4827e5402475f3c3a1
+ffeb98e8ebf16d136c330b146f929ec89e7c0589086566a0b7ab2618e806d340606f5548514c0175
+cd1486eeb6c30f32ad0e01cfc31ccb87a1b9f13ed8c505d92620c1d417347f2f76a8cc18249b4ec3
+150ead0e9fa4d027014385cceba056e73dca9427724ae69509e14993293ad850b88e4d175a823773
+0c77b8ce88dd4e353f441393cc194d8fa4846f6c0a461604db6e2d6e274208b894cc01d76f2310e0
+36d63d0839deea98786196aba4680251140c328ae97dd050e10310b043b4f004f6c3482d0a67ad8f
+79661a1289ccf3ca0f6778056ab7c445a02db3821d5e5c61dcd4e1393366b9300700a190938f1d13
+153e19a326f3ba937c035876935d4c84116bb342f2e68e326a6bd58482f62e3af99f8e7ccb6130be
+45ae6c51140cbd525d1cc16619ee4488ab8f9dc466d09405d1b279dd8ac1a162a11bcd338776b78b
+a37a66a0441047c5313d77cb9c82a3e7e30c099405ee2ac39f960ec1a8a87d45da1ce9531a04f23a
+67664ea0c9804facc513c31cd915ad5d4c6f7225382b2d5b0cecc801b0a110eb2c0006364f0c687a
+1ac6dfa779165c5360d0f68e46c7de0f756698b13dcc4ba1f50b81c18b14e482309ccf66a30c848d
+0af4574119d912282778bd74a223f7c444fa0a8076d856746e3bc8d362a5cd3202ea7859d2c5af18
+d829f2b8810e388e8b3b7429c81a83cbed1831b67956a90a6d2aa378a950b02a2c4811067f02ba9e
+3189c21e86cdb893d9f81bb92d9c6ff2efa22e0942ed2701c5cb16373aeb8f5c869327dc08f344a8
+7a4baa66560bedf195814e01104033939179176a0520bd334c018910e1a481e4c55034e600f81608
+9f8508e0775f25764c1524b3acf05f8a3c039fa9e728136c1594af408e1b46ba7a455170d0ea30f9
+f0bbe1647b097aa77c080433c975a02b97334d0ad5eaf0e342651412a584fcb1da26d88bd9e916ed
+5a1ed3e4977b6de089c21b852a8565f665786d0de1153078d00e8117f80f9e0c01d01bdc49e98a95
+ac05cd1ca3f95fbd0e3901c694bf9cb4caeb06e01908913a9d5ccb597d180204c22932b82ecc3384
+36fb299dd90c825073b83c3aa8d24516a3752199ee6b60ea09bfd96a102766ff02747b966bc661b8
+76206d686f2ede38114abb75b30e4c8031c808895ab96b174d8153159670ade45fcf389140651e80
+e6912242a03b73796812184808ab98ce0bab9d3da94a9a0502b981970464933a9a5e66c178600456
+b2f1dc93c3cfc42a3330943a0312530281009b170014de4b18f21b02d83d3083cafc5253e08e0d55
+6617a0bfc8687a1785a698cb25d7820e35227184789805c27b5e79e5ae7157b8fa9442b375a3bdab
+512f30a985f7c3f23a0e82e07043911603cb60a781a91c000e6b6916f34edee88a5839e8ac706798
+9524e6e94fd1e427a6bdc0f88d469dfe61839d827681289a4257b695bc136912b9496678698aa828
+a19827bcab525a4264f6ccc741eb9c82e9608cf65243851922ca93c3e13bb3ac34039186d5fc7a61
+140a62a1588a14d6a61526a522a5d2c2263ad0a1f29a3012d6acc8c98661e7b602251a4a095c1f98
+4e26a268641685c42c1441176c58a14746049e8a21f0ba9d21319a6be603b38c3435a02895f79981
+4e5934863799de8a27519409631c496dc9145de46a30bcbe8df0ddcbf764822dd391f41ad64bb05c
+9d6bb2f02002332b4ca1415d9ba3e4e5263465d1aa5c3fbc283359ce89212573160233735c7c56f9
+8ab53ced9bec3f9d5306695419dc3cb60015c7c51d937c4199f230bf11a4760241454ea4a34d53c5
+684da406e2c45a1c13871dc6b683d409c8584a1ab122d41cd3d5016e786054c963e6e60683514d12
+b13c3a6f9cea4adbc04bc9486456889a0d835e52233a3646af9634649847a957c1e1c4de9810d740
+15c175ada30a6194c902cd1432af49a7921a0bee7715d260544ccf916587870566cd52184e9924d2
+876e143506e8c98d31e1e74d87c0ce9b4fe7a97a69a9e9382b1ab31b2f368cc72402f36013c1d56d
+0ed42c050bf9cdae0fe54d3f89fa853aa4d2903101ccac7c603a44f7eb94cbe966629a1fa6209251
+b91a3d44128dce6995e129a47fd2c4c2ca4ca033119bd95f1d93bc410f278e84a58846cbd6e91230
+e111983043e01220f04d861e7e0fd406d6a7af44153b07913d8cd594f9a61b00ed01245b66816310
+6382633b3d47c8945c63a6cf0542e542cec5c6b0f6698acc3e1471148d8a96a20c8e4c21f6ef02f3
+1b3099412517f0802fd4c7b4b4bc2f22499e239cb64c933807ca326e7427ea88c91c9500b945c7a4
+b43285ec7422a50c1575e3a54100f615663fd7e9054c053739c320b0d33a05567e7ae42b9c3ce13f
+980bc21739da53ba37d4a057a64199ffa5068f8c04b02e5c5f2740de184d95a3f5661cc3e0785647
+89691dc49a7e980b82d54b22e023f100e44fc7021111985d27248664c205da0f566182b9da30280a
+539554b37450299ba55ade9d4abb33af4010ee5bb6cc487166b85c632e49fabf1413fc3482788291
+84a4cf462a9f3d418f634fcd1d796aac51f2c6e0a30cbf8d9e1ab552eb549d9966d73ce0156414c9
+ca23b379e0ce7e041e08328f5d3620cb25305aa045624e920f0b82ad8bf55540994128b5c282c8a8
+e3d492f23360a46186aa3d6c4144be509d9c2203ecd68370c38edeed825c3c75deb367402675e116
+c2958bc23b0b73240e8b6e95aecf0cc28bc33dd18a2778e7899b5990c8500a7be6ab173014ab711c
+b6a06f96fa5ad79f89b06e6346b85a6238ccf2f90c72b54445269b3acf8d7243c62d04b2f28230a8
+a4488a2c0b58cd0b3c6c41ba0e226962d18dca14860ab1325d2be678eb06e16a2c68323a5ac0b323
+90ce9fb33a144ed173dd803a45a11df52b082b0fa92be65d9963bf228398a2c902429dc1b8d96a0b
+48abdfa27806e7cc72591001075da51cc905b9b0db8715492b78b053c0aab5cddcc2a487371f022e
+ce11c28826d9ed2f207d4f38f3b6da0c2625ee681ae9d8530741a0bad44751e2b9ae884ecaa02bf8
+153cdb8233679e3dc5c3876740307c6446b6d01fdf307cf432bd9b65239d89ce9cc7ccf02bb261f8
+15dc30fc0ace0cbfae3f33edba8d2dc337d5a11e288715ec2c6dc857806b6eb67901f95ec7ec3e9d
+a7198c52f7544130b10a2537c890029d6206a9bed86f70d882d472cc21afebcf9a70ddc68cf0142c
+823b4ddc6851a6f2a8d9562dcad02dd5beaebf22f3364493198407137d1f34f17316ee2970bea0c3
+165c14576322d76d1880fe4a56f3c08c5c3cc52787674032156456650af17681405d6dc10daf2244
+64faa31f2f9bb125bfe5eac8a09b09cc95fd1664cb7e0bb86118f8ec6c2ac8cf80db2b5ec0e58ab3
+1ffefd72c5898e543cbee2f5681bebb982dbf78634a2a927c1995c674fd1f0391004878d654c6eca
+24d62c29de807828a67ea3ea33f53970bb2b761c8587745bc0ed74b8f299f5e267c0b1a5b3a7f6f9
+1cf837cbed47a754c17aa81564a9852583c316a48661a7042bbf39e40d27b03ede8f8cec85154a4a
+eac707df80ecb96a7eceb7c35fe82ba8f7d2cf6b7905d92604dfb4594637a8bf6841b84277560b98
+c1cd911f9ff73950d567e672fbf18d6fc0f52258d82a6a3b9941ee9cf559c5f033c8de892cdb87e0
+b02a59b92291eea39fdb300c9c8f733802e7532feb2f9459b63123ea2d812f1424b01baa221682eb
+b1015580ceca53c38aa57a840c36b8b092b481b3c1550d9d2150aacf8090f454e70e19162795977b
+0aa433ccfae4610b82dfa0299dd54494565af80df15550a3d196df5493eaf5c88563d61561ccc61a
+b2ec88517ec3cf0bb23def02e2825a34e5b98285098e6a496d5b7f6695751b3372f11447fdf22c30
+eb8d99d113a24346dcdeba322bc33198dfc09a5eb7564a4767849a2ff681549adfc8b44cb3049f7a
+30a170013ae620adaf44fe0e96613750502134500489b856975e0fef03263a96c246229dd5367a55
+517d6dd11a46d4b0135584e63618cdb13994881ff507b516c28d54f45d252b6c06649a82086e83a5
+bc38ec397b0d52ae73c50c9ea3790aa98e5c1f41f6e980d670e7998b2092a0998854d5f28120a6ef
+724f52aa4bfd2d33392f4f24a9dacc469240ef0c371c98a50eaa953421a1cf2d3fc5fad4445be61e
+cf4657110344d2adb188e3e19843ebe1eed8ebc03405d55bf6709f3926bbee676a38e6cd78299e89
+69d3b581f78b10ad76d3792d7b5e1c131dd60028a2b19e4f36a8ea8ae5fa6c68a259831608da8363
+c980fc53fc68c0c1fe5566175379a6c512030b184caeafc0994861012bb2ae1846174c60509fc92d
+11fc90ea5cc62f6c68889036cfea01f32ddd3b438a4ad3815e526b634cf0735f48e4bbb85a8a142c
+04a0052a4537925538f5ec7b12ff90e7739f272a294a77a9a9d781eb3b32ad63865019a4883d8839
+99f10ec67804190c199847e907bb556180b92628b5b982d378047ac75d3d5391293586834cffc7d1
+745003930c4a5c0fde26c8d62a65c6a8e3b5147b7c883832211110dbf2696d168aa0d64ed8a54a26
+1c994fe6c1582e26d81df3cc8c909880808cb285218fec1925a5b2c165b0a842556f135d1929c7c8
+3e411c823d80d532b72cb3b094d099f4bb18d93915a5194367f5b538f620d36056363f5a76ae3234
+64ec55c2489992335959e044a8c2a8de0dc868b17a46afd6490329efb68791c61053295355d994d1
+acbe0d1d508464b5c56871c6766ca7ad6569ca885d69c3441f7654f7e82531ce6e9145f8ae429e93
+49646f0d7d045600b3d259ec9818fe387bf4d4be47b0a9fd4df9a56029b420c15439499937fac5e3
+e0d45481addf345071eebf601d3398ef1f5991b6ae3a7a28ec26686eb4c6335ba5f8809db332416c
+66e4a5b0b6d7ebe87c514aad17bbfaa5e19169c94a3f774c84b6318599d5a450460313952a148cb7
+d67b662388946eedb4d6c014a81b71bfd1face68e23c599460f14c50b32d9a2d3344b235da837aec
+ce20d2d2603c364b56674acf27b54f42b79075895425c981f4564d559610e3dc2aee5bb49832f9e1
+24b268d725d714bad11ce75c27c2dc3e955e5316a74b1bc43e9abd982ba589a6a4637837f7412680
+2d4bea79ef99d55322ec16f1467f36f396582c18adeacb6677424f66020a2b179dde41b3b03b3368
+d01b038b9049da2cb3834a8d2459c3224ba3d66f92d9091855e6181329a1da3f2b23aefaf98b8710
+9d9980ac028d906c0a39c9beb0e1b4835032faa12ddf4fa8bb27aab3cd59cf2946980bd1d469f7c8
+a93879cad3184103c5933d4724b803a9e4814090135d3f82896a96487322261be38631f56cce2279
+631f169cbda285f95656a5f1371396406f2b8bc371a0622da566fd6111925a7b0205aa5ae2dd8d7e
+3482ea6e50dddb8d6883dd438c21407fb8dd43c937ebbb09764d596ac1e4bd731136da44769d386f
+321bc6ed409f74e65d08863652d08f68f2cb3d3b46b65ee567f663b1f6c278038eb2e76718544291
+6cce68bca656b788da49fb98e8ac439da761072a4bf8992245242908649c1095b5941a33d351f893
+daf799fc62890960f576141518cd1631911aad2a08e6b0c6029f47d23939559358c1add69acf2a16
+05427be3a705c14a587d54a2e4be33e4903d0492939bbfb7814a73e6d9c532420576243b2fb0b0a7
+d63a99e832c0b3733aaf1afd5d1022b11b5f8fe8131a3980855c03a475659458db50271357e8e6fd
+85517e64d22af951f0e9a3a58f11821961b6f5ab679596ad911a6c9bed8d51133fd449496a1bda6b
+5c0a6e9f150f53f9ecb888d446a4de8a90bf86be570bd1b8cd5ac4d76cf853c673415889559e8513
+e9ab3a153dbc4d844a366ad037a16d8cccb249e5d30833754b3550e52f3bfb34627c53d1b333cd14
+b31fdf84381687a3bc3667bd659dddd22359596ad9d0df33b6c8cb6d26d3859d7dadcdbad9b2a84d
+44f4d7ffc75b3b9aa8061f167fa2cab9d9ba8d7a528ad35b2bbf4df4e5c18db3ca2456616b75ed73
+7f769213a7f26032cf8ee21e644ed91c4475d8d9eed10d89ac99d3a45852062b38d6b165a03a5551
+d74dc19db161fa568d4865b197488c6c21a1f576f61111357753698b1f81f8b07cd256f99100990a
+6e4a30055fbb5d71653b96be85632fb64c3a9b6686812dfc848c171aab12019e5e76da2085fba7fc
+ce134770db79537aa3fa4a57845d26faa26c9948753baab8f3fa645a97b27d11a13d18326fb569f3
+63e285d9a29eba514c6d6c3a63572d934698bdb340b26a30bc2c6afaf1d95b92672a33de4de9028c
+ea923397dcda436b224b70bc3e21d3c5f18e9aa2316b4690ac31fbd9a8d6d4e249c618056d044c41
+463ea8718e6e082bb7e3b3bda42f94f46da10ff34780899fe8d015edecc8511726abe2f46aa33205
+d436a2063f95199fcd509a206dd6de933d9904dab2b3794d0eb80a572c2657f9b92cbce56613e92e
+65f3dc9b633d43ed15b454fc10c52bfd51acfb8abb822be666351228ad028345edb20bec3ae1dcc4
+de4ad90eaa5cae8f20b39a8911e361ffb58ccfae00aaa24b3031b8547155491f55e0baf55958de8a
+071f2111355555f5a548a8ad14ca7a98a8a79a968acdd496b45365446c56a96297476182210c158d
+4b0f6c3bcdac959308917dd82a1d17faf5dd9a471acfa89a73b6b241547bab17e8ba86319da0a634
+7ee8a2cc3ebfc0c9d6a6e6b2f599d2043b7d2f47873a073b263ce6a4868eee74f0e136aa052c8f8f
+18d58ec6f5e93b973a2a4c81e57c03f18aa8ec5857831eb37e7964bdcd37d8d23fd101642b2d2eae
+b107da10358cf1a34a95121f3a15274f791a73c6139b4f79b8bacc1e8d8c67f6c10cb157cd805da2
+fc3222caf83643aa63c64288f53ac934e8b0ac8850cac6179bfa1a530d8afc3a345892a6c86d6889
+bd21149654862391929f2d38aed48629c83eb33c66ce723968bbc7d7b06c39ee721599c5c9f6f55d
+8b431755fac594eec42ea4237d4e9fb117d37e9ead5e674fd164f5ecf0dfb337e37bec2faedfe943
+ebcf3fe7c7da5f9dbfdf7f737b7e79e0e7d9efefcebfdf4fe7d7d737f7e7f7fb0ff8697a7fbbbfbb
+bfb9dd4ffc4a9d08272d139ef930fc7e7f7b75798d257ef673f3e7473efc86fdf991e303fae7076c
+3fc47f6ad4679f7df1c7d3972f5ebef827b4322ac2>
+endstream
+endobj
+5 0 obj
+<<
+/Filter [/ASCII85Decode /FlateDecode ]
+/Length 34
+>>
+stream
+GhOt'1B7FZ"#S^CKb'rAF*Y:rk'%+Q~>
+endstream
+endobj
+2 0 obj
+<<
+/Type /Pages
+/Kids [4 0 R]
+/Count 1
+>>
+endobj
+1 0 obj
+<<
+/Type /Catalog
+/Pages 2 0 R
+/OCProperties<< /D<< /Order[]/ON[]/OFF[]/RBGroups[]>>/OCGs[]>>
+>>
+endobj
+3 0 obj
+<<
+/CreationDate
+/ModDate
+/Producer
+/Creator
+/Title
+>>
+endobj
+xref
+0 9
+0000000000 65535 f
+0000017206 00000 n
+0000017142 00000 n
+0000017325 00000 n
+0000000010 00000 n
+0000017012 00000 n
+0000000291 00000 n
+0000000331 00000 n
+0000000467 00000 n
+trailer
+<<
+/Size 9
+/Root 1 0 R
+/Info 3 0 R
+/ID [<5587793bbad24a52ab1ae826d4d40cba><5587793bbad24a52ab1ae826d4d40cba>]
+>>
+startxref
+17783
+%%EOF
\ No newline at end of file
diff --git a/etc/logo/jgrapht-logo-transparent.eps b/etc/logo/jgrapht-logo-transparent.eps
new file mode 100644
index 00000000000..c42b45e502b
Binary files /dev/null and b/etc/logo/jgrapht-logo-transparent.eps differ
diff --git a/etc/logo/jgrapht-logo-transparent.jpg b/etc/logo/jgrapht-logo-transparent.jpg
new file mode 100644
index 00000000000..f1092b85cb2
Binary files /dev/null and b/etc/logo/jgrapht-logo-transparent.jpg differ
diff --git a/etc/logo/jgrapht-logo-transparent.pdf b/etc/logo/jgrapht-logo-transparent.pdf
new file mode 100644
index 00000000000..b2c08c55a92
Binary files /dev/null and b/etc/logo/jgrapht-logo-transparent.pdf differ
diff --git a/etc/logo/jgrapht-logo-transparent.png b/etc/logo/jgrapht-logo-transparent.png
new file mode 100644
index 00000000000..69262aa6801
Binary files /dev/null and b/etc/logo/jgrapht-logo-transparent.png differ
diff --git a/etc/logo/jgrapht-logo-transparent.psd b/etc/logo/jgrapht-logo-transparent.psd
new file mode 100644
index 00000000000..f83f8039a21
Binary files /dev/null and b/etc/logo/jgrapht-logo-transparent.psd differ
diff --git a/etc/org.eclipse.jdt.core.prefs b/etc/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000000..d42c55426f9
--- /dev/null
+++ b/etc/org.eclipse.jdt.core.prefs
@@ -0,0 +1,362 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns=false
+org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns=false
+org.eclipse.jdt.core.formatter.align_with_spaces=false
+org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=32
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=48
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=32
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=32
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=32
+org.eclipse.jdt.core.formatter.alignment_for_assignment=16
+org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_loops=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain=0
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=49
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=16
+org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_module_statements=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
+org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=32
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=32
+org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=32
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=32
+org.eclipse.jdt.core.formatter.alignment_for_shift_operator=0
+org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=17
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=17
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=17
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=17
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=17
+org.eclipse.jdt.core.formatter.alignment_for_type_arguments=16
+org.eclipse.jdt.core.formatter.alignment_for_type_parameters=16
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=32
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch=0
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=next_line_on_wrap
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=next_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=next_line
+org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped=false
+org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=false
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.indent_tag_description=false
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags=do not insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
+org.eclipse.jdt.core.formatter.comment.line_length=100
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=1
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=1
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_not_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case=insert
+org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_code_block_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_method_body_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.lineSplit=100
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=space
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.text_block_indentation=0
+org.eclipse.jdt.core.formatter.use_on_off_tags=true
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false
+org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_before_relational_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_shift_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
+org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter
diff --git a/etc/prepareDocs.sh b/etc/prepareDocs.sh
new file mode 100755
index 00000000000..b2a5be4980c
--- /dev/null
+++ b/etc/prepareDocs.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+# Prepare docs directory for deployment to gh-pages branch after build on master
+
+set -e
+
+: ${GITHUB_WORKSPACE?"variable value required"}
+
+${GITHUB_WORKSPACE}/etc/expandMarkdown.sh
+rm -f ${GITHUB_WORKSPACE}/docs/guide/.gitignore
+${GITHUB_WORKSPACE}/etc/downloadJavadoc.sh
+mv ${GITHUB_WORKSPACE}/target/reports/apidocs ${GITHUB_WORKSPACE}/docs/javadoc-SNAPSHOT
diff --git a/etc/release-process.html b/etc/release-process.html
deleted file mode 100644
index 37aa14c8732..00000000000
--- a/etc/release-process.html
+++ /dev/null
@@ -1,227 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- JGraphT Release Process
-
-
-
-
-
JGraphT Release Process
-
-
-
-
Update the new version number and SVN tag in the build.xml file.
-
-
Review the README.md, HISTORY.md, CONTRIBUTORS.md, and META-INF/MANIFEST.MF files and update:
-
-
Version
-
Dependencies
-
Release notes
-
Contributors
-
-
-
Review/update the bug/feature trackers to make sure they reflect the
-current state. If there were important bug/feature changes, it is worth
-mentioning them in the README.md release notes.
-
-
Bring dependent libraries (e.g. JGraph) up to date and update
-lib/lib-readme.txt accordingly.
-
-
Run ant to build the javadoc and make sure it is generated without
-errors/warnings. Fix where necessary. Make sure Eclipse build is
-warning-free.
-
-
We used to run Checkstyle globally to make a "code quality review";
-we may bring this back, and/or add PMD/FindBugs, and Emma for
-code coverage.
-
-
Run all the JUnit tests. Fix where necessary.
-
-
Run jalopy to reformat the code.
-
-
Commit all work to SVN.
-
-
Add a SVN tag using the convention: ver_x_y_z (e.g., the tag ver_0_7_1
-denotes Version 0.7.1). The command for this is something like
-svn copy https://jgrapht.svn.sourceforge.net/svnroot/jgrapht/trunk
- https://jgrapht.svn.sourceforge.net/svnroot/jgrapht/tags/ver_0_7_1
- -m "Tag for the 0.7.1 release of JGraphT"
-
-
-At this stage, the release is complete in SVN and only a distribution
-is needed to be built. The distribution is built from SVN to ensure
-that whatever gets released is reproducible later.
-
-
The ant build.xml has a hack that allows specifying a SVN tag.
-You just need to invoke:
-
-
- ant -Dsvntag=ver_0_7_1 release
-
-
-It will checkout from SVN the tagged version 0.7.1, and build a
-distribution for it.
-
-
Upload the release to SF and add it using the File Release System.
-
-
Update the website with the latest javadocs.
-
-
Update the website with links to the new downloads, version numbers,
-etc. This involves uploading web/index.html (at least).
-
-
Announce the new version in the wiki and mailing lists; also click
-the File Release System notification button.
-
-
Update and commit the version number in build.xml again to reflect
-the beginning of development for the next version.
-
-
-
-
-
-
-
-
-
-
Copyright 2005, by Barak Naveh
- and Contributors. All rights reserved.
- *
- * @author Barak Naveh
- * @since Jul 14, 2003
- */
-public interface DirectedGraph
- extends Graph
-{
- //~ Methods ----------------------------------------------------------------
-
- /**
- * Returns the "in degree" of the specified vertex. An in degree of a vertex
- * in a directed graph is the number of inward directed edges from that
- * vertex. See
- * http://mathworld.wolfram.com/Indegree.html.
- *
- * @param vertex vertex whose degree is to be calculated.
- *
- * @return the degree of the specified vertex.
- */
- public int inDegreeOf(V vertex);
-
- /**
- * Returns a set of all edges incoming into the specified vertex.
- *
- * @param vertex the vertex for which the list of incoming edges to be
- * returned.
- *
- * @return a set of all edges incoming into the specified vertex.
- */
- public Set incomingEdgesOf(V vertex);
-
- /**
- * Returns the "out degree" of the specified vertex. An out degree of a
- * vertex in a directed graph is the number of outward directed edges from
- * that vertex. See
- * http://mathworld.wolfram.com/Outdegree.html.
- *
- * @param vertex vertex whose degree is to be calculated.
- *
- * @return the degree of the specified vertex.
- */
- public int outDegreeOf(V vertex);
-
- /**
- * Returns a set of all edges outgoing from the specified vertex.
- *
- * @param vertex the vertex for which the list of outgoing edges to be
- * returned.
- *
- * @return a set of all edges outgoing from the specified vertex.
- */
- public Set outgoingEdgesOf(V vertex);
-}
-
-// End DirectedGraph.java
diff --git a/jgrapht-core/src/main/java/org/jgrapht/EdgeFactory.java b/jgrapht-core/src/main/java/org/jgrapht/EdgeFactory.java
deleted file mode 100644
index c9b82afc4c1..00000000000
--- a/jgrapht-core/src/main/java/org/jgrapht/EdgeFactory.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/* ==========================================
- * JGraphT : a free Java graph-theory library
- * ==========================================
- *
- * Project Info: http://jgrapht.sourceforge.net/
- * Project Creator: Barak Naveh (http://sourceforge.net/users/barak_naveh)
- *
- * (C) Copyright 2003-2008, by Barak Naveh and Contributors.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- */
-/* ----------------
- * EdgeFactory.java
- * ----------------
- * (C) Copyright 2003-2008, by Barak Naveh and Contributors.
- *
- * Original Author: Barak Naveh
- * Contributor(s): Christian Hammer
- *
- * $Id$
- *
- * Changes
- * -------
- * 24-Jul-2003 : Initial revision (BN);
- * 11-Mar-2004 : Made generic (CH);
- *
- */
-package org.jgrapht;
-
-/**
- * An edge factory used by graphs for creating new edges.
- *
- * @author Barak Naveh
- * @since Jul 14, 2003
- */
-public interface EdgeFactory
-{
- //~ Methods ----------------------------------------------------------------
-
- /**
- * Creates a new edge whose endpoints are the specified source and target
- * vertices.
- *
- * @param sourceVertex the source vertex.
- * @param targetVertex the target vertex.
- *
- * @return a new edge whose endpoints are the specified source and target
- * vertices.
- */
- public E createEdge(V sourceVertex, V targetVertex);
-}
-
-// End EdgeFactory.java
diff --git a/jgrapht-core/src/main/java/org/jgrapht/Graph.java b/jgrapht-core/src/main/java/org/jgrapht/Graph.java
index 18ab404a2f2..a2da7925a6d 100644
--- a/jgrapht-core/src/main/java/org/jgrapht/Graph.java
+++ b/jgrapht-core/src/main/java/org/jgrapht/Graph.java
@@ -1,435 +1,631 @@
-/* ==========================================
- * JGraphT : a free Java graph-theory library
- * ==========================================
- *
- * Project Info: http://jgrapht.sourceforge.net/
- * Project Creator: Barak Naveh (http://sourceforge.net/users/barak_naveh)
- *
- * (C) Copyright 2003-2008, by Barak Naveh and Contributors.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- * License for more details.
+/*
+ * (C) Copyright 2003-2023, by Barak Naveh and Contributors.
*
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- */
-/* ----------
- * Graph.java
- * ----------
- * (C) Copyright 2003-2008, by Barak Naveh and Contributors.
- *
- * Original Author: Barak Naveh
- * Contributor(s): John V. Sichi
- * Christian Hammer
+ * JGraphT : a free Java graph-theory library
*
- * $Id$
+ * See the CONTRIBUTORS.md file distributed with this work for additional
+ * information regarding copyright ownership.
*
- * Changes
- * -------
- * 24-Jul-2003 : Initial revision (BN);
- * 06-Nov-2003 : Change edge sharing semantics (JVS);
- * 11-Mar-2004 : Made generic (CH);
- * 07-May-2006 : Changed from List to Set (JVS);
- * 28-May-2006 : Moved connectivity info from edge to graph (JVS);
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0, or the
+ * GNU Lesser General Public License v2.1 or later
+ * which is available at
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1-standalone.html.
*
+ * SPDX-License-Identifier: EPL-2.0 OR LGPL-2.1-or-later
*/
package org.jgrapht;
-import java.util.*;
+import java.util.Collection;
+import java.util.Set;
+import java.util.function.Supplier;
+import org.jgrapht.graph.DefaultGraphIterables;
/**
- * The root interface in the graph hierarchy. A mathematical graph-theory graph
- * object G(V,E) contains a set V of vertices and a set
- * E of edges. Each edge e=(v1,v2) in E connects vertex v1 to vertex v2.
- * for more information about graphs and their related definitions see
+ * The root interface in the graph hierarchy. A mathematical graph-theory graph object
+ * {@code G(V,E)} contains a set {@code V} of vertices and a set {@code E} of edges.
+ * Each edge e=(v1,v2) in E connects vertex v1 to vertex v2. for more information
+ * about graphs and their related definitions see
* http://mathworld.wolfram.com/Graph.html.
*
- *
This library generally follows the terminology found at:
- * http://mathworld.wolfram.com/topics/GraphTheory.html. Implementation of
- * this interface can provide simple-graphs, multigraphs, pseudographs etc. The
- * package org.jgrapht.graph provides a gallery of abstract and
- * concrete graph implementations.
+ *
+ * This library generally follows the terminology found at:
+ *
+ * http://mathworld.wolfram.com/topics/GraphTheory.html. Implementation of this interface can
+ * provide simple-graphs, multigraphs, pseudographs etc. The package {@code org.jgrapht.graph}
+ * provides a gallery of abstract and concrete graph implementations.
+ *
+ *
+ *
+ * This library works best when vertices represent arbitrary objects and edges represent the
+ * relationships between them. Vertex and edge instances may be shared by more than one graph.
+ *
*
- *
This library works best when vertices represent arbitrary objects and
- * edges represent the relationships between them. Vertex and edge instances may
- * be shared by more than one graph.
+ *
+ * Through generics, a graph can be typed to specific classes for vertices {@code V} and edges
+ * {@code E}. Such a graph can contain vertices of type {@code V} and all
+ * sub-types and Edges of type {@code E} and all sub-types.
+ *
*
- *
Through generics, a graph can be typed to specific classes for vertices
- * V and edges E<T>. Such a graph can contain
- * vertices of type V and all sub-types and Edges of type
- * E and all sub-types.
+ *
+ * For guidelines on vertex and edge classes, see
+ * this wiki page.
*
- *
For guidelines on vertex and edge classes, see this wiki
- * page.
+ * @param the graph vertex type
+ * @param the graph edge type
*
* @author Barak Naveh
- * @since Jul 14, 2003
*/
public interface Graph
{
- //~ Methods ----------------------------------------------------------------
-
/**
- * Returns a set of all edges connecting source vertex to target vertex if
- * such vertices exist in this graph. If any of the vertices does not exist
- * or is null, returns null. If both vertices
- * exist but no edges found, returns an empty set.
+ * Returns a set of all edges connecting source vertex to target vertex if such vertices exist
+ * in this graph. If any of the vertices does not exist or is {@code null}, returns
+ * {@code null}. If both vertices exist but no edges found, returns an empty set.
*
- *
In undirected graphs, some of the returned edges may have their source
- * and target vertices in the opposite order. In simple graphs the returned
- * set is either singleton set or empty set.
+ *
+ * In undirected graphs, some of the returned edges may have their source and target vertices in
+ * the opposite order. In simple graphs the returned set is either singleton set or empty set.
+ *
*
* @param sourceVertex source vertex of the edge.
* @param targetVertex target vertex of the edge.
*
* @return a set of all edges connecting source vertex to target vertex.
*/
- public Set getAllEdges(V sourceVertex, V targetVertex);
+ Set getAllEdges(V sourceVertex, V targetVertex);
/**
- * Returns an edge connecting source vertex to target vertex if such
- * vertices and such edge exist in this graph. Otherwise returns
- * null. If any of the specified vertices is null
- * returns null
+ * Returns an edge connecting source vertex to target vertex if such vertices and such edge
+ * exist in this graph. Otherwise returns {@code null}.
+ * If any of the specified vertices is {@code null} returns {@code null}
*
- *
In undirected graphs, the returned edge may have its source and target
- * vertices in the opposite order.
+ *
+ * In undirected graphs, the returned edge may have its source and target vertices in the
+ * opposite order.
+ *
*
* @param sourceVertex source vertex of the edge.
* @param targetVertex target vertex of the edge.
*
* @return an edge connecting source vertex to target vertex.
*/
- public E getEdge(V sourceVertex, V targetVertex);
+ E getEdge(V sourceVertex, V targetVertex);
/**
- * Returns the edge factory using which this graph creates new edges. The
- * edge factory is defined when the graph is constructed and must not be
- * modified.
- *
- * @return the edge factory using which this graph creates new edges.
+ * Return the vertex supplier that the graph uses whenever it needs to create new vertices.
+ *
+ *
+ * A graph uses the vertex supplier to create new vertex objects whenever a user calls method
+ * {@link Graph#addVertex()}. Users can also create the vertex in user code and then use method
+ * {@link Graph#addVertex(Object)} to add the vertex.
+ *
+ *
+ * In contrast with the {@link Supplier} interface, the vertex supplier has the additional
+ * requirement that a new and distinct result is returned every time it is invoked. More
+ * specifically for a new vertex to be added in a graph {@code v} must not be equal
+ * to any other vertex in the graph. More formally, the graph must not contain any vertex
+ * {@code v2} such that {@code v2.equals(v)}.
+ *
+ *
+ * Care must also be taken when interchanging calls to methods {@link Graph#addVertex(Object)}
+ * and {@link Graph#addVertex()}. In such a case the user must make sure never to add vertices
+ * in the graph using method {@link Graph#addVertex(Object)}, which are going to be returned in
+ * the future by the supplied vertex supplier. Such a sequence will result into an
+ * {@link IllegalArgumentException} when calling method {@link Graph#addVertex()}.
+ *
+ * @return the vertex supplier or {@code null} if the graph has no such supplier
+ *
+ * @throws UnsupportedOperationException if this graph disallows access to the vertex supplier
*/
- public EdgeFactory getEdgeFactory();
+ Supplier getVertexSupplier();
/**
- * Creates a new edge in this graph, going from the source vertex to the
- * target vertex, and returns the created edge. Some graphs do not allow
- * edge-multiplicity. In such cases, if the graph already contains an edge
- * from the specified source to the specified target, than this method does
- * not change the graph and returns null.
- *
- *
The source and target vertices must already be contained in this
- * graph. If they are not found in graph IllegalArgumentException is
- * thrown.
- *
- *
This method creates the new edge e using this graph's
- * EdgeFactory. For the new edge to be added e
- * must not be equal to any other edge the graph (even if the graph
- * allows edge-multiplicity). More formally, the graph must not contain any
- * edge e2 such that e2.equals(e). If such
- * e2 is found then the newly created edge e is
- * abandoned, the method leaves this graph unchanged returns
- * null.
+ * Return the edge supplier that the graph uses whenever it needs to create new edges.
+ *
+ *
+ * A graph uses the edge supplier to create new edge objects whenever a user calls method
+ * {@link Graph#addEdge(Object, Object)}. Users can also create the edge in user code and then
+ * use method {@link Graph#addEdge(Object, Object, Object)} to add the edge.
+ *
+ *
+ * In contrast with the {@link Supplier} interface, the edge supplier has the additional
+ * requirement that a new and distinct result is returned every time it is invoked. More
+ * specifically for a new edge to be added in a graph {@code e} must not be equal to
+ * any other edge in the graph (even if the graph allows edge-multiplicity). More formally, the
+ * graph must not contain any edge {@code e2} such that {@code e2.equals(e)}.
+ *
+ * @return the edge supplier {@code null} if the graph has no such supplier
+ *
+ * @throws UnsupportedOperationException if this graph disallows access to the edge supplier
+ */
+ Supplier getEdgeSupplier();
+
+ /**
+ * Creates a new edge in this graph, going from the source vertex to the target vertex, and
+ * returns the created edge. Some graphs do not allow edge-multiplicity. In such cases, if the
+ * graph already contains an edge from the specified source to the specified target, then this
+ * method does not change the graph and returns {@code null}.
+ *
+ *
+ * The source and target vertices must already be contained in this graph. If they are not found
+ * in graph {@link IllegalArgumentException} is thrown.
+ *
+ *
+ * This method creates the new edge {@code e} using this graph's edge supplier (see
+ * {@link #getEdgeSupplier()}). For the new edge to be added {@code e} must not be
+ * equal to any other edge the graph (even if the graph allows edge-multiplicity). More
+ * formally, the graph must not contain any edge {@code e2} such that
+ * {@code e2.equals(e)}. If such {@code e2} is found then the newly created edge
+ * {@code e} is abandoned, the method leaves this graph unchanged and returns {@code null}.
+ *
+ *
+ * If the underlying graph implementation's {@link #getEdgeSupplier()} returns
+ * {@code null}, then this method cannot create edges and throws an
+ * {@link UnsupportedOperationException}.
*
* @param sourceVertex source vertex of the edge.
* @param targetVertex target vertex of the edge.
*
- * @return The newly created edge if added to the graph, otherwise
- * null.
+ * @return The newly created edge if added to the graph, otherwise {@code null}.
*
- * @throws IllegalArgumentException if source or target vertices are not
- * found in the graph.
- * @throws NullPointerException if any of the specified vertices is
- * null.
+ * @throws IllegalArgumentException if source or target vertices are not found in the graph
+ * or if there is a property of this graph that prevents the
+ * addition of the edge
+ * @throws NullPointerException if any of the specified vertices is {@code null}.
+ * @throws UnsupportedOperationException if the graph was not initialized with an edge supplier
+ * or if this graph disallows modification
*
- * @see #getEdgeFactory()
+ * @see #getEdgeSupplier()
*/
- public E addEdge(V sourceVertex, V targetVertex);
+ E addEdge(V sourceVertex, V targetVertex);
/**
- * Adds the specified edge to this graph, going from the source vertex to
- * the target vertex. More formally, adds the specified edge,
- * e, to this graph if this graph contains no edge e2
- * such that e2.equals(e). If this graph already contains such
- * an edge, the call leaves this graph unchanged and returns false.
- * Some graphs do not allow edge-multiplicity. In such cases, if the graph
- * already contains an edge from the specified source to the specified
- * target, than this method does not change the graph and returns
- * false. If the edge was added to the graph, returns
- * true.
- *
- *
The source and target vertices must already be contained in this
- * graph. If they are not found in graph IllegalArgumentException is
- * thrown.
+ * Adds the specified edge to this graph, going from the source vertex to the target vertex.
+ * More formally, adds the specified edge, {@code e}, to this graph if this graph contains
+ * no edge {@code e2} such that {@code e2.equals(e)}. If this graph already contains such
+ * an edge, the call leaves this graph unchanged and returns {@code false}. Some graphs
+ * do not allow edge-multiplicity. In such cases, if the graph already contains an edge
+ * from the specified source to the specified target, then this method does not change the
+ * graph and returns {@code false}. If the edge was added to the graph, returns {@code true}.
*
* @param sourceVertex source vertex of the edge.
* @param targetVertex target vertex of the edge.
* @param e edge to be added to this graph.
*
- * @return true if this graph did not already contain the specified
- * edge.
+ * @return {@code true} if this graph did not already contain the specified edge.
*
- * @throws IllegalArgumentException if source or target vertices are not
- * found in the graph.
- * @throws ClassCastException if the specified edge is not assignment
- * compatible with the class of edges produced by the edge factory of this
- * graph.
- * @throws NullPointerException if any of the specified vertices is
- * null.
+ * @throws IllegalArgumentException if source or target vertices are not found in the graph
+ * or if there is a property of this graph that prevents the
+ * addition of the edge
+ * @throws ClassCastException if the specified edge is not assignment compatible with the class
+ * of edges produced by the edge factory of this graph.
+ * @throws NullPointerException if any of the arguments is {@code null}
+ * @throws UnsupportedOperationException if this graph disallows modification
*
* @see #addEdge(Object, Object)
- * @see #getEdgeFactory()
+ * @see #getEdgeSupplier()
*/
- public boolean addEdge(V sourceVertex, V targetVertex, E e);
+ boolean addEdge(V sourceVertex, V targetVertex, E e);
/**
- * Adds the specified vertex to this graph if not already present. More
- * formally, adds the specified vertex, v, to this graph if
- * this graph contains no vertex u such that
- * u.equals(v). If this graph already contains such vertex, the call
- * leaves this graph unchanged and returns false. In combination
- * with the restriction on constructors, this ensures that graphs never
- * contain duplicate vertices.
+ * Creates a new vertex in this graph and returns it.
+ *
+ *
+ * This method creates the new vertex {@code v} using this graph's vertex supplier (see
+ * {@link #getVertexSupplier()}). For the new vertex to be added {@code v} must not
+ * be equal to any other vertex in the graph. More formally, the graph must not contain any
+ * vertex {@code v2} such that {@code v2.equals(v)}. If such {@code v2} is found then
+ * the newly created vertex {@code v} is abandoned, the method leaves this graph unchanged
+ * and throws an {@link IllegalArgumentException}.
+ *
+ *
+ * If the underlying graph implementation's {@link #getVertexSupplier()} returns
+ * {@code null}, then this method cannot create vertices and throws an
+ * {@link UnsupportedOperationException}.
+ *
+ *
+ * Care must also be taken when interchanging calls to methods {@link Graph#addVertex(Object)}
+ * and {@link Graph#addVertex()}. In such a case the user must make sure never to add vertices
+ * in the graph using method {@link Graph#addVertex(Object)}, which are going to be returned in
+ * the future by the supplied vertex supplier. Such a sequence will result into an
+ * {@link IllegalArgumentException} when calling method {@link Graph#addVertex()}.
+ *
+ * @return The newly created vertex if added to the graph.
+ *
+ * @throws IllegalArgumentException if the graph supplier returns a vertex which is already in
+ * the graph
+ * @throws UnsupportedOperationException if this graph was not initialized with a vertex supplier
+ * or if this graph disallows modification
+ *
+ * @see #getVertexSupplier()
+ */
+ V addVertex();
+
+ /**
+ * Adds the specified vertex to this graph if not already present. More formally, adds the
+ * specified vertex, {@code v}, to this graph if this graph contains no vertex
+ * {@code u} such that {@code u.equals(v)}.
+ * If this graph already contains such vertex, the call leaves this graph
+ * unchanged and returns {@code false}. In combination with the restriction on
+ * constructors, this ensures that graphs never contain duplicate vertices.
*
* @param v vertex to be added to this graph.
*
- * @return true if this graph did not already contain the specified
- * vertex.
+ * @return {@code true} if this graph did not already contain the specified vertex.
*
- * @throws NullPointerException if the specified vertex is
- * null.
+ * @throws IllegalArgumentException if there is a property that disallows adding the specified vertex
+ * @throws NullPointerException if the specified vertex is {@code null}.
+ * @throws UnsupportedOperationException if this graph disallows modification
*/
- public boolean addVertex(V v);
+ boolean addVertex(V v);
/**
- * Returns true if and only if this graph contains an edge going
- * from the source vertex to the target vertex. In undirected graphs the
- * same result is obtained when source and target are inverted. If any of
- * the specified vertices does not exist in the graph, or if is
- * null, returns false.
+ * Returns {@code true} if and only if this graph contains an edge going from the source
+ * vertex to the target vertex. In undirected graphs the same result is obtained when source and
+ * target are inverted. If any of the specified vertices does not exist in the graph, or if is
+ * {@code null}, returns {@code false}.
*
* @param sourceVertex source vertex of the edge.
* @param targetVertex target vertex of the edge.
*
- * @return true if this graph contains the specified edge.
+ * @return {@code true} if this graph contains the specified edge.
*/
- public boolean containsEdge(V sourceVertex, V targetVertex);
+ boolean containsEdge(V sourceVertex, V targetVertex);
/**
- * Returns true if this graph contains the specified edge. More
- * formally, returns true if and only if this graph contains an
- * edge e2 such that e.equals(e2). If the
- * specified edge is null returns false.
+ * Returns {@code true} if this graph contains the specified edge. More formally, returns
+ * {@code true} if and only if this graph contains an edge {@code e2} such that
+ * {@code e.equals(e2)}. If the specified edge is {@code null} returns
+ * {@code false}.
*
* @param e edge whose presence in this graph is to be tested.
*
- * @return true if this graph contains the specified edge.
+ * @return {@code true} if this graph contains the specified edge.
*/
- public boolean containsEdge(E e);
+ boolean containsEdge(E e);
/**
- * Returns true if this graph contains the specified vertex. More
- * formally, returns true if and only if this graph contains a
- * vertex u such that u.equals(v). If the
- * specified vertex is null returns false.
+ * Returns {@code true} if this graph contains the specified vertex. More formally, returns
+ * {@code true} if and only if this graph contains a vertex {@code u} such that
+ * {@code u.equals(v)}. If the specified vertex is {@code null} returns
+ * {@code false}.
*
* @param v vertex whose presence in this graph is to be tested.
*
- * @return true if this graph contains the specified vertex.
+ * @return {@code true} if this graph contains the specified vertex.
*/
- public boolean containsVertex(V v);
+ boolean containsVertex(V v);
/**
- * Returns a set of the edges contained in this graph. The set is backed by
- * the graph, so changes to the graph are reflected in the set. If the graph
- * is modified while an iteration over the set is in progress, the results
- * of the iteration are undefined.
+ * Returns a set of the edges contained in this graph. The set is backed by the graph, so
+ * changes to the graph are reflected in the set. If the graph is modified while an iteration
+ * over the set is in progress, the results of the iteration are undefined.
*
- *
The graph implementation may maintain a particular set ordering (e.g.
- * via {@link java.util.LinkedHashSet}) for deterministic iteration, but
- * this is not required. It is the responsibility of callers who rely on
- * this behavior to only use graph implementations which support it.
+ *
+ * The graph implementation may maintain a particular set ordering (e.g. via
+ * {@link java.util.LinkedHashSet}) for deterministic iteration, but this is not required. It is
+ * the responsibility of callers who rely on this behavior to only use graph implementations
+ * which support it.
+ *
*
* @return a set of the edges contained in this graph.
*/
- public Set edgeSet();
+ Set edgeSet();
/**
- * Returns a set of all edges touching the specified vertex. If no edges are
- * touching the specified vertex returns an empty set.
+ * Returns the degree of the specified vertex.
+ *
+ *
+ * A degree of a vertex in an undirected graph is the number of edges touching that vertex.
+ * Edges with same source and target vertices (self-loops) are counted twice.
+ *
+ *
+ * In directed graphs this method returns the sum of the "in degree" and the "out degree".
+ *
+ * @param vertex vertex whose degree is to be calculated.
+ * @return the degree of the specified vertex.
*
- * @param vertex the vertex for which a set of touching edges is to be
- * returned.
+ * @throws IllegalArgumentException if vertex is not found in the graph.
+ * @throws NullPointerException if vertex is {@code null}.
+ * @throws ArithmeticException if the result overflows an int
+ */
+ int degreeOf(V vertex);
+
+ /**
+ * Returns a set of all edges touching the specified vertex. If no edges are touching the
+ * specified vertex returns an empty set.
*
+ * @param vertex the vertex for which a set of touching edges is to be returned.
* @return a set of all edges touching the specified vertex.
*
* @throws IllegalArgumentException if vertex is not found in the graph.
- * @throws NullPointerException if vertex is null.
+ * @throws NullPointerException if vertex is {@code null}.
+ */
+ Set edgesOf(V vertex);
+
+ /**
+ * Returns the "in degree" of the specified vertex.
+ *
+ *
+ * In the case of undirected graphs this method returns the number of edges touching the vertex.
+ * Edges with same source and target vertices (self-loops) are counted twice.
+ *
+ * @param vertex vertex whose degree is to be calculated.
+ * @return the degree of the specified vertex.
+ *
+ * @throws IllegalArgumentException if vertex is not found in the graph.
+ * @throws NullPointerException if vertex is {@code null}.
+ * @throws ArithmeticException if the result overflows an int
+ */
+ int inDegreeOf(V vertex);
+
+ /**
+ * Returns a set of all edges incoming into the specified vertex.
+ *
+ *
+ * In the case of undirected graphs this method returns all edges touching the vertex, thus,
+ * some of the returned edges may have their source and target vertices in the opposite order.
+ *
+ * @param vertex the vertex for which the list of incoming edges to be returned.
+ * @return a set of all edges incoming into the specified vertex.
+ *
+ * @throws IllegalArgumentException if vertex is not found in the graph.
+ * @throws NullPointerException if vertex is {@code null}.
*/
- public Set edgesOf(V vertex);
+ Set incomingEdgesOf(V vertex);
/**
- * Removes all the edges in this graph that are also contained in the
- * specified edge collection. After this call returns, this graph will
- * contain no edges in common with the specified edges. This method will
- * invoke the {@link #removeEdge(Object)} method.
+ * Returns the "out degree" of the specified vertex.
+ *
+ *
+ * In the case of undirected graphs this method returns the number of edges touching the vertex.
+ * Edges with same source and target vertices (self-loops) are counted twice.
+ *
+ * @param vertex vertex whose degree is to be calculated.
+ * @return the degree of the specified vertex.
+ *
+ * @throws IllegalArgumentException if vertex is not found in the graph.
+ * @throws NullPointerException if vertex is {@code null}.
+ * @throws ArithmeticException if the result overflows an int
+ */
+ int outDegreeOf(V vertex);
+
+ /**
+ * Returns a set of all edges outgoing from the specified vertex.
+ *
+ *
+ * In the case of undirected graphs this method returns all edges touching the vertex, thus,
+ * some of the returned edges may have their source and target vertices in the opposite order.
+ *
+ * @param vertex the vertex for which the list of outgoing edges to be returned.
+ * @return a set of all edges outgoing from the specified vertex.
+ *
+ * @throws IllegalArgumentException if vertex is not found in the graph.
+ * @throws NullPointerException if vertex is {@code null}.
+ */
+ Set outgoingEdgesOf(V vertex);
+
+ /**
+ * Removes all the edges in this graph that are also contained in the specified edge collection.
+ * After this call returns, this graph will contain no edges in common with the specified edges.
+ * This method will invoke the {@link #removeEdge(Object)} method.
*
* @param edges edges to be removed from this graph.
*
- * @return true if this graph changed as a result of the call
+ * @return {@code true} if this graph changed as a result of the call
*
- * @throws NullPointerException if the specified edge collection is
- * null.
+ * @throws NullPointerException if the specified edge collection is {@code null}
+ * @throws UnsupportedOperationException if this graph disallows modification
*
* @see #removeEdge(Object)
* @see #containsEdge(Object)
*/
- public boolean removeAllEdges(Collection extends E> edges);
+ boolean removeAllEdges(Collection extends E> edges);
/**
- * Removes all the edges going from the specified source vertex to the
- * specified target vertex, and returns a set of all removed edges. Returns
- * null if any of the specified vertices does not exist in the
- * graph. If both vertices exist but no edge is found, returns an empty set.
- * This method will either invoke the {@link #removeEdge(Object)} method, or
- * the {@link #removeEdge(Object, Object)} method.
+ * Removes all the edges going from the specified source vertex to the specified target vertex,
+ * and returns a set of all removed edges. Returns {@code null} if any of the specified
+ * vertices does not exist in the graph. If both vertices exist but no edge is found, returns an
+ * empty set. This method will either invoke the {@link #removeEdge(Object)} method, or the
+ * {@link #removeEdge(Object, Object)} method.
*
* @param sourceVertex source vertex of the edge.
* @param targetVertex target vertex of the edge.
*
- * @return the removed edges, or null if no either vertex not
- * part of graph
+ * @return the removed edges, or {@code null} if either vertex is not part of graph
+ *
+ * @throws UnsupportedOperationException if this graph disallows modification
*/
- public Set removeAllEdges(V sourceVertex, V targetVertex);
+ Set removeAllEdges(V sourceVertex, V targetVertex);
/**
- * Removes all the vertices in this graph that are also contained in the
- * specified vertex collection. After this call returns, this graph will
- * contain no vertices in common with the specified vertices. This method
- * will invoke the {@link #removeVertex(Object)} method.
+ * Removes all the vertices in this graph that are also contained in the specified vertex
+ * collection. After this call returns, this graph will contain no vertices in common with the
+ * specified vertices. This method will invoke the {@link #removeVertex(Object)} method.
*
* @param vertices vertices to be removed from this graph.
*
- * @return true if this graph changed as a result of the call
+ * @return {@code true} if this graph changed as a result of the call
*
- * @throws NullPointerException if the specified vertex collection is
- * null.
+ * @throws NullPointerException if the specified vertex collection is {@code null}.
+ * @throws UnsupportedOperationException if this graph disallows modification
*
* @see #removeVertex(Object)
* @see #containsVertex(Object)
*/
- public boolean removeAllVertices(Collection extends V> vertices);
+ boolean removeAllVertices(Collection extends V> vertices);
/**
- * Removes an edge going from source vertex to target vertex, if such
- * vertices and such edge exist in this graph. Returns the edge if removed
- * or null otherwise.
+ * Removes an edge going from source vertex to target vertex, if such vertices and such edge
+ * exist in this graph. Returns the edge if removed or {@code null} otherwise.
*
* @param sourceVertex source vertex of the edge.
* @param targetVertex target vertex of the edge.
*
- * @return The removed edge, or null if no edge removed.
+ * @return The removed edge, or {@code null} if no edge removed.
+ *
+ * @throws UnsupportedOperationException if this graph disallows modification
*/
- public E removeEdge(V sourceVertex, V targetVertex);
+ E removeEdge(V sourceVertex, V targetVertex);
/**
- * Removes the specified edge from the graph. Removes the specified edge
- * from this graph if it is present. More formally, removes an edge
- * e2 such that e2.equals(e), if the graph contains such
- * edge. Returns true if the graph contained the specified edge.
- * (The graph will not contain the specified edge once the call returns).
+ * Removes the specified edge from the graph. Removes the specified edge from this graph if it
+ * is present. More formally, removes an edge {@code e2} such that {@code e2.equals(e)},
+ * if the graph contains such edge. Returns {@code true} if the graph contained
+ * the specified edge. (The graph will not contain the specified edge once the call returns).
*
- *
If the specified edge is null returns
- * false.
+ *
+ * If the specified edge is {@code null} returns {@code false}.
+ *
*
* @param e edge to be removed from this graph, if present.
*
- * @return true if and only if the graph contained the
- * specified edge.
+ * @return {@code true} if and only if the graph contained the specified edge.
+ *
+ * @throws UnsupportedOperationException if this graph disallows modification
*/
- public boolean removeEdge(E e);
+ boolean removeEdge(E e);
/**
- * Removes the specified vertex from this graph including all its touching
- * edges if present. More formally, if the graph contains a vertex
- * u such that u.equals(v), the call removes all edges
- * that touch u and then removes u itself. If no
- * such u is found, the call leaves the graph unchanged.
- * Returns true if the graph contained the specified vertex. (The
- * graph will not contain the specified vertex once the call returns).
+ * Removes the specified vertex from this graph including all its touching edges if present.
+ * More formally, if the graph contains a vertex {@code u} such that {@code u.equals(v)},
+ * the call removes all edges that touch {@code u} and then removes {@code u} itself.
+ * If no such {@code u} is found, the call leaves the graph unchanged.
+ * Returns {@code true} if the graph contained the specified vertex.
+ * (The graph will not contain the specified vertex once the call returns).
*
- *
If the specified vertex is null returns
- * false.
+ *
+ * If the specified vertex is {@code null} returns {@code false}.
+ *
*
* @param v vertex to be removed from this graph, if present.
*
- * @return true if the graph contained the specified vertex;
- * false otherwise.
+ * @return {@code true} if the graph contained the specified vertex; {@code false}
+ * otherwise.
+ *
+ * @throws UnsupportedOperationException if this graph disallows modification
*/
- public boolean removeVertex(V v);
+ boolean removeVertex(V v);
/**
- * Returns a set of the vertices contained in this graph. The set is backed
- * by the graph, so changes to the graph are reflected in the set. If the
- * graph is modified while an iteration over the set is in progress, the
- * results of the iteration are undefined.
+ * Returns a set of the vertices contained in this graph. The set is backed by the graph, so
+ * changes to the graph are reflected in the set. If the graph is modified while an iteration
+ * over the set is in progress, the results of the iteration are undefined.
*
- *
The graph implementation may maintain a particular set ordering (e.g.
- * via {@link java.util.LinkedHashSet}) for deterministic iteration, but
- * this is not required. It is the responsibility of callers who rely on
- * this behavior to only use graph implementations which support it.
+ *
+ * The graph implementation may maintain a particular set ordering (e.g. via
+ * {@link java.util.LinkedHashSet}) for deterministic iteration, but this is not required. It is
+ * the responsibility of callers who rely on this behavior to only use graph implementations
+ * which support it.
+ *
*
* @return a set view of the vertices contained in this graph.
*/
- public Set vertexSet();
+ Set vertexSet();
/**
- * Returns the source vertex of an edge. For an undirected graph, source and
- * target are distinguishable designations (but without any mathematical
- * meaning).
+ * Returns the source vertex of an edge. For an undirected graph, source and target are
+ * distinguishable designations (but without any mathematical meaning).
*
* @param e edge of interest
*
* @return source vertex
*/
- public V getEdgeSource(E e);
+ V getEdgeSource(E e);
/**
- * Returns the target vertex of an edge. For an undirected graph, source and
- * target are distinguishable designations (but without any mathematical
- * meaning).
+ * Returns the target vertex of an edge. For an undirected graph, source and target are
+ * distinguishable designations (but without any mathematical meaning).
*
* @param e edge of interest
*
* @return target vertex
*/
- public V getEdgeTarget(E e);
+ V getEdgeTarget(E e);
+
+ /**
+ * Get the graph type. The graph type can be used to query for additional metadata such as
+ * whether the graph supports directed or undirected edges, self-loops, multiple (parallel)
+ * edges, weights, etc.
+ *
+ * @return the graph type
+ */
+ GraphType getType();
/**
- * Returns the weight assigned to a given edge. Unweighted graphs return 1.0
- * (as defined by {@link WeightedGraph#DEFAULT_EDGE_WEIGHT}), allowing
- * weighted-graph algorithms to apply to them where meaningful.
+ * The default weight for an edge.
+ */
+ double DEFAULT_EDGE_WEIGHT = 1.0;
+
+ /**
+ * Returns the weight assigned to a given edge. Unweighted graphs return 1.0 (as defined by
+ * {@link #DEFAULT_EDGE_WEIGHT}), allowing weighted-graph algorithms to apply to them when
+ * meaningful.
*
* @param e edge of interest
- *
* @return edge weight
- *
- * @see WeightedGraph
+ *
+ * @throws IllegalArgumentException if the specified edge is not in this graph
+ * @throws NullPointerException if argument is {@code null}
*/
- public double getEdgeWeight(E e);
-}
+ double getEdgeWeight(E e);
+
+ /**
+ * Assigns a weight to an edge.
+ *
+ * @param e edge on which to set weight
+ * @param weight new weight for edge
+ *
+ * @throws NullPointerException if {@code e} is {@code null}
+ * @throws UnsupportedOperationException if the graph does not support weights
+ * or if there is a property of this graph that
+ * disallows modification of the weight
+ */
+ void setEdgeWeight(E e, double weight);
+
+ /**
+ * Assigns a weight to an edge between {@code sourceVertex} and {@code targetVertex}.
+ *
+ * When there exist multiple edges between {@code sourceVertex} and
+ * {@code targetVertex}, consider using {@link #setEdgeWeight(Object, double)} instead.
+ *
+ * @param sourceVertex source vertex of the edge
+ * @param targetVertex target vertex of the edge
+ * @param weight new weight for edge
+ *
+ * @throws NullPointerException if either one of {@code sourceVertex} or
+ * {@code targetVertex} is {@code null}, or
+ * if there is no edge between the two vertices
+ * @throws UnsupportedOperationException if the graph does not support weights
+ */
+ default void setEdgeWeight(V sourceVertex, V targetVertex, double weight)
+ {
+ this.setEdgeWeight(this.getEdge(sourceVertex, targetVertex), weight);
+ }
-// End Graph.java
+ /**
+ * Access the graph using the {@link GraphIterables} interface. This allows accessing graphs
+ * without the restrictions imposed by 32-bit arithmetic. Moreover, graph implementations are
+ * free to implement this interface without explicitly materializing intermediate results.
+ *
+ * @return the graph iterables
+ */
+ default GraphIterables iterables()
+ {
+ return new DefaultGraphIterables(this);
+ }
+
+}
diff --git a/jgrapht-core/src/main/java/org/jgrapht/GraphHelper.java b/jgrapht-core/src/main/java/org/jgrapht/GraphHelper.java
deleted file mode 100644
index e45510a5f1e..00000000000
--- a/jgrapht-core/src/main/java/org/jgrapht/GraphHelper.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/* ==========================================
- * JGraphT : a free Java graph-theory library
- * ==========================================
- *
- * Project Info: http://jgrapht.sourceforge.net/
- * Project Creator: Barak Naveh (http://sourceforge.net/users/barak_naveh)
- *
- * (C) Copyright 2003-2008, by Barak Naveh and Contributors.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- */
-/* ----------------
- * GraphHelper.java
- * ----------------
- * (C) Copyright 2003-2008, by Barak Naveh and Contributors.
- *
- * Original Author: Barak Naveh
- * Contributor(s): Christian Hammer
- * Mikael Hansen
- *
- * $Id$
- *
- * Changes
- * -------
- * 10-Jul-2003 : Initial revision (BN);
- * 06-Nov-2003 : Change edge sharing semantics (JVS);
- * 11-Mar-2004 : Made generic (CH);
- * 07-May-2006 : Changed from List to Set (JVS);
- * 28-May-2006 : Moved connectivity info from edge to graph (JVS);
- *
- */
-package org.jgrapht;
-
-/**
- * A collection of utilities to assist the working with graphs.
- *
- * @author Barak Naveh
- * @since Jul 31, 2003
- * @deprecated Use {@link Graphs} instead.
- */
-@Deprecated public abstract class GraphHelper
- extends Graphs
-{
-}
-
-// End GraphHelper.java
diff --git a/jgrapht-core/src/main/java/org/jgrapht/GraphIterables.java b/jgrapht-core/src/main/java/org/jgrapht/GraphIterables.java
new file mode 100644
index 00000000000..d012fedb429
--- /dev/null
+++ b/jgrapht-core/src/main/java/org/jgrapht/GraphIterables.java
@@ -0,0 +1,250 @@
+/*
+ * (C) Copyright 2020-2023, by Dimitrios Michail and Contributors.
+ *
+ * JGraphT : a free Java graph-theory library
+ *
+ * See the CONTRIBUTORS.md file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0, or the
+ * GNU Lesser General Public License v2.1 or later
+ * which is available at
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1-standalone.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR LGPL-2.1-or-later
+ */
+package org.jgrapht;
+
+import org.jgrapht.util.LiveIterableWrapper;
+
+/**
+ * Presents a graph as a collection of views suitable for graphs which contain a very large number
+ * of vertices or edges. Graph algorithms written these methods can work with graphs without the
+ * restrictions imposed by 32-bit arithmetic.
+ *
+ *
+ * Whether the returned iterators support removal of elements is left to the graph implementation.
+ * It is the responsibility of callers who rely on this behavior to only use graph implementations
+ * which support it.
+ *
+ *
+ * @param the graph vertex type
+ * @param the graph edge type
+ *
+ * @author Dimitrios Michail
+ */
+public interface GraphIterables
+{
+ /**
+ * Get the underlying graph.
+ *
+ * @return the underlying graph
+ */
+ Graph getGraph();
+
+ /**
+ * Returns an iterable over the edges of the graph.
+ *
+ *
+ * Whether the ordering is deterministic, depends on the actual graph implementation. It is the
+ * responsibility of callers who rely on this behavior to only use graph implementations which
+ * support it.
+ *
+ * @return an iterable over the edges of the graph.
+ */
+ default Iterable edges()
+ {
+ return new LiveIterableWrapper<>(() -> getGraph().edgeSet());
+ }
+
+ /**
+ * Return the number of edges in the graph.
+ *
+ * @return the number of edges.
+ */
+ default long edgeCount()
+ {
+ return getGraph().edgeSet().size();
+ }
+
+ /**
+ * Returns an iterable view over the vertices contained in this graph. The returned iterator is
+ * a live view of the vertices. If the graph is modified while an iteration is in progress, the
+ * results of the iteration are undefined.
+ *
+ *
+ * The graph implementation may maintain a particular ordering for deterministic iteration, but
+ * this is not required. It is the responsibility of callers who rely on this behavior to only
+ * use graph implementations which support it.
+ *
+ *
+ * @return an iterable view of the vertices contained in this graph
+ */
+ default Iterable vertices()
+ {
+ return new LiveIterableWrapper<>(() -> getGraph().vertexSet());
+ }
+
+ /**
+ * Return the number of vertices in the graph.
+ *
+ * @return the number of vertices
+ */
+ default long vertexCount()
+ {
+ return getGraph().vertexSet().size();
+ }
+
+ /**
+ * Returns an iterable view over all edges touching the specified vertex. The returned iterators
+ * are live views. If the graph is modified while an iteration is in progress, the results of
+ * the iteration are undefined. If no edges are touching the specified vertex, the returned
+ * iterators are already exhausted.
+ *
+ * @param vertex input vertex
+ * @return an iterable view of the vertices contained in this graph
+ * @throws IllegalArgumentException if vertex is not found in the graph.
+ * @throws NullPointerException if vertex is {@code null}.
+ */
+ default Iterable edgesOf(V vertex)
+ {
+ return new LiveIterableWrapper<>(() -> getGraph().edgesOf(vertex));
+ }
+
+ /**
+ * Returns the degree of the specified vertex.
+ *
+ *
+ * A degree of a vertex in an undirected graph is the number of edges touching that vertex.
+ * Edges with same source and target vertices (self-loops) are counted twice.
+ *
+ *
+ * In directed graphs this method returns the sum of the "in degree" and the "out degree".
+ *
+ * @param vertex vertex whose degree is to be calculated.
+ * @return the degree of the specified vertex.
+ *
+ * @throws IllegalArgumentException if vertex is not found in the graph.
+ * @throws NullPointerException if vertex is {@code null}.
+ */
+ default long degreeOf(V vertex)
+ {
+ return getGraph().degreeOf(vertex);
+ }
+
+ /**
+ * Returns an iterable view over all edges incoming into the specified vertex. The returned
+ * iterators are live views. If the graph is modified while an iteration is in progress, the
+ * results of the iteration are undefined.
+ *
+ *
+ * In the case of undirected graphs the returned iterators return all edges touching the vertex,
+ * thus, some of the returned edges may have their source and target vertices in the opposite
+ * order.
+ *
+ * @param vertex input vertex
+ * @return an iterable view of all edges incoming into the specified vertex
+ * @throws IllegalArgumentException if vertex is not found in the graph.
+ * @throws NullPointerException if vertex is {@code null}.
+ */
+ default Iterable incomingEdgesOf(V vertex)
+ {
+ return new LiveIterableWrapper<>(() -> getGraph().incomingEdgesOf(vertex));
+ }
+
+ /**
+ * Returns the "in degree" of the specified vertex.
+ *
+ *
+ * In the case of undirected graphs this method returns the number of edges touching the vertex.
+ * Edges with same source and target vertices (self-loops) are counted twice.
+ *
+ * @param vertex vertex whose degree is to be calculated.
+ * @return the degree of the specified vertex.
+ *
+ * @throws IllegalArgumentException if vertex is not found in the graph.
+ * @throws NullPointerException if vertex is {@code null}.
+ */
+ default long inDegreeOf(V vertex)
+ {
+ return getGraph().inDegreeOf(vertex);
+ }
+
+ /**
+ * Returns an iterable view over all edges outgoing into the specified vertex. The returned
+ * iterators are live views. If the graph is modified while an iteration is in progress, the
+ * results of the iteration are undefined.
+ *
+ *
+ * In the case of undirected graphs the returned iterators return all edges touching the vertex,
+ * thus, some of the returned edges may have their source and target vertices in the opposite
+ * order.
+ *
+ * @param vertex input vertex
+ * @return an iterable view of all edges outgoing from the specified vertex
+ * @throws IllegalArgumentException if vertex is not found in the graph.
+ * @throws NullPointerException if vertex is {@code null}.
+ */
+ default Iterable outgoingEdgesOf(V vertex)
+ {
+ return new LiveIterableWrapper<>(() -> getGraph().outgoingEdgesOf(vertex));
+ }
+
+ /**
+ * Returns the "out degree" of the specified vertex.
+ *
+ *
+ * In the case of undirected graphs this method returns the number of edges touching the vertex.
+ * Edges with same source and target vertices (self-loops) are counted twice.
+ *
+ * @param vertex vertex whose degree is to be calculated.
+ * @return the degree of the specified vertex.
+ *
+ * @throws IllegalArgumentException if vertex is not found in the graph.
+ * @throws NullPointerException if vertex is {@code null}.
+ */
+ default long outDegreeOf(V vertex)
+ {
+ return getGraph().outDegreeOf(vertex);
+ }
+
+ /**
+ * Returns an iterable view over all edges connecting source vertex to target vertex if such
+ * vertices exist in this graph. The returned iterators are live views. If the graph is modified
+ * while an iteration is in progress, the results of the iteration are undefined.
+ *
+ * If any of the vertices does not exist or is {@code null}, returns {@code null}. If
+ * both vertices exist but no edges found, returns an iterable which returns exhausted
+ * iterators.
+ *
+ *
+ * In undirected graphs, some of the returned edges may have their source and target vertices in
+ * the opposite order. In simple graphs the returned set is either singleton set or empty set.
+ *
+ *
+ * @param sourceVertex source vertex of the edge.
+ * @param targetVertex target vertex of the edge.
+ *
+ * @return an iterable view of all edges connecting source to target vertex.
+ *
+ * @throws IllegalArgumentException if vertex is not found in the graph.
+ * @throws NullPointerException if vertex is {@code null}.
+ */
+ default Iterable allEdges(V sourceVertex, V targetVertex)
+ {
+ return new LiveIterableWrapper<>(() -> getGraph().getAllEdges(sourceVertex, targetVertex));
+ }
+
+}
diff --git a/jgrapht-core/src/main/java/org/jgrapht/GraphMapping.java b/jgrapht-core/src/main/java/org/jgrapht/GraphMapping.java
index 1f70b58e015..e9045f343cc 100644
--- a/jgrapht-core/src/main/java/org/jgrapht/GraphMapping.java
+++ b/jgrapht-core/src/main/java/org/jgrapht/GraphMapping.java
@@ -1,75 +1,54 @@
-/* ==========================================
- * JGraphT : a free Java graph-theory library
- * ==========================================
- *
- * Project Info: http://jgrapht.sourceforge.net/
- * Project Creator: Barak Naveh (http://sourceforge.net/users/barak_naveh)
+/*
+ * (C) Copyright 2005-2023, by Assaf Lehr and Contributors.
*
- * (C) Copyright 2003-2008, by Barak Naveh and Contributors.
+ * JGraphT : a free Java graph-theory library
*
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
+ * See the CONTRIBUTORS.md file distributed with this work for additional
+ * information regarding copyright ownership.
*
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- * License for more details.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0, or the
+ * GNU Lesser General Public License v2.1 or later
+ * which is available at
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1-standalone.html.
*
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- */
-/* -----------------
- * GraphMapping.java
- * -----------------
- * (C) Copyright 2005-2008, by Assaf Lehr and Contributors.
- *
- * Original Author: Assaf Lehr
- * Contributor(s): John V. Sichi
- *
- * Changes
- * -------
+ * SPDX-License-Identifier: EPL-2.0 OR LGPL-2.1-or-later
*/
package org.jgrapht;
/**
- * GraphMapping represents a bidirectional mapping between two graphs (called
- * graph1 and graph2), which allows the caller to obtain the matching vertex or
- * edge in either direction, from graph1 to graph2, or from graph2 to graph1. It
- * does not have to always be a complete bidirectional mapping (it could return
- * null for some lookups).
+ * GraphMapping represents a bidirectional mapping between two graphs (called graph1 and graph2),
+ * which allows the caller to obtain the matching vertex or edge in either direction, from graph1 to
+ * graph2, or from graph2 to graph1. It does not have to always be a complete bidirectional mapping
+ * (it could return null for some lookups).
+ *
+ * @param the graph vertex type
+ * @param the graph edge type
*
* @author Assaf Lehr
- * @since Jul 30, 2005
*/
public interface GraphMapping
{
- //~ Methods ----------------------------------------------------------------
-
/**
- * Gets the mapped value where the key is vertex
+ * Gets the mapped value where the key is {@code vertex}
*
* @param vertex vertex in one of the graphs
- * @param forward if true, uses mapping from graph1 to graph2; if false, use
- * mapping from graph2 to graph1
+ * @param forward if true, uses mapping from graph1 to graph2; if false, use mapping from graph2
+ * to graph1
*
* @return corresponding vertex in other graph, or null if none
*/
- public V getVertexCorrespondence(V vertex, boolean forward);
+ V getVertexCorrespondence(V vertex, boolean forward);
/**
- * Gets the mapped value where the key is edge
+ * Gets the mapped value where the key is {@code edge}
*
* @param edge edge in one of the graphs
- * @param forward if true, uses mapping from graph1 to graph2; if false, use
- * mapping from graph2 to graph1
+ * @param forward if true, uses mapping from graph1 to graph2; if false, use mapping from graph2
+ * to graph1
*
* @return corresponding edge in other graph, or null if none
*/
- public E getEdgeCorrespondence(E edge, boolean forward);
+ E getEdgeCorrespondence(E edge, boolean forward);
}
-
-// End GraphMapping.java
diff --git a/jgrapht-core/src/main/java/org/jgrapht/GraphMetrics.java b/jgrapht-core/src/main/java/org/jgrapht/GraphMetrics.java
new file mode 100644
index 00000000000..c128a57000d
--- /dev/null
+++ b/jgrapht-core/src/main/java/org/jgrapht/GraphMetrics.java
@@ -0,0 +1,362 @@
+/*
+ * (C) Copyright 2017-2023, by Joris Kinable and Contributors.
+ *
+ * JGraphT : a free Java graph-theory library
+ *
+ * See the CONTRIBUTORS.md file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0, or the
+ * GNU Lesser General Public License v2.1 or later
+ * which is available at
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1-standalone.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR LGPL-2.1-or-later
+ */
+package org.jgrapht;
+
+import org.jgrapht.alg.shortestpath.*;
+import org.jgrapht.alg.util.*;
+import org.jgrapht.util.*;
+
+import java.util.*;
+import java.util.stream.*;
+
+/**
+ * Collection of methods which provide numerical graph information.
+ *
+ * @author Joris Kinable
+ * @author Alexandru Valeanu
+ */
+public abstract class GraphMetrics
+{
+
+ /**
+ * Compute the diameter of the
+ * graph. The diameter of a graph is defined as $\max_{v\in V}\epsilon(v)$, where $\epsilon(v)$
+ * is the eccentricity of vertex $v$. In other words, this method computes the 'longest shortest
+ * path'. Two special cases exist. If the graph has no vertices, the diameter is 0. If the graph
+ * is disconnected, the diameter is {@link Double#POSITIVE_INFINITY}.
+ *
+ * For more fine-grained control over this method, or if you need additional distance metrics
+ * such as the graph radius, consider using {@link org.jgrapht.alg.shortestpath.GraphMeasurer}
+ * instead.
+ *
+ * @param graph input graph
+ * @param graph vertex type
+ * @param graph edge type
+ * @return the diameter of the graph.
+ */
+ public static double getDiameter(Graph graph)
+ {
+ return new GraphMeasurer<>(graph).getDiameter();
+ }
+
+ /**
+ * Compute the radius of the graph.
+ * The radius of a graph is defined as $\min_{v\in V}\epsilon(v)$, where $\epsilon(v)$ is the
+ * eccentricity of vertex $v$. Two special cases exist. If the graph has no vertices, the radius
+ * is 0. If the graph is disconnected, the diameter is {@link Double#POSITIVE_INFINITY}.
+ *
+ * For more fine-grained control over this method, or if you need additional distance metrics
+ * such as the graph diameter, consider using {@link org.jgrapht.alg.shortestpath.GraphMeasurer}
+ * instead.
+ *
+ * @param graph input graph
+ * @param graph vertex type
+ * @param graph edge type
+ * @return the diameter of the graph.
+ */
+ public static double getRadius(Graph graph)
+ {
+ return new GraphMeasurer<>(graph).getRadius();
+ }
+
+ /**
+ * Compute the girth of the graph. The
+ * girth of a graph is the length (number of edges) of the smallest cycle in the graph. Acyclic
+ * graphs are considered to have infinite girth. For directed graphs, the length of the shortest
+ * directed cycle is returned (see Bang-Jensen, J., Gutin, G., Digraphs: Theory, Algorithms and
+ * Applications, Springer Monographs in Mathematics, ch 1, ch 8.4.). Simple undirected graphs
+ * have a girth of at least 3 (triangle cycle). Directed graphs and Multigraphs have a girth of
+ * at least 2 (parallel edges/arcs), and in Pseudo graphs have a girth of at least 1
+ * (self-loop).
+ *
+ * This implementation is loosely based on these notes.
+ * In essence, this method invokes a Breadth-First search from every vertex in the graph. A
+ * single Breadth-First search takes $O(n+m)$ time, where $n$ is the number of vertices in the
+ * graph, and $m$ the number of edges. Consequently, the runtime complexity of this method is
+ * $O(n(n+m))=O(mn)$.
+ *
+ * An algorithm with the same worst case runtime complexity, but a potentially better average
+ * runtime complexity of $O(n^2)$ is described in: Itai, A. Rodeh, M. Finding a minimum circuit
+ * in a graph. SIAM J. Comput. Vol 7, No 4, 1987.
+ *
+ * @param graph input graph
+ * @param graph vertex type
+ * @param graph edge type
+ * @return girth of the graph, or {@link Integer#MAX_VALUE} if the graph is acyclic.
+ */
+ public static int getGirth(Graph graph)
+ {
+ final int nil = -1;
+ final boolean isAllowingMultipleEdges = graph.getType().isAllowingMultipleEdges();
+
+ // Ordered sequence of vertices
+ List vertices = new ArrayList<>(graph.vertexSet());
+ // Index map of vertices in ordered sequence
+ Map indexMap = new HashMap<>();
+ for (int i = 0; i < vertices.size(); i++)
+ indexMap.put(vertices.get(i), i);
+
+ // Objective
+ int girth = Integer.MAX_VALUE;
+ // Array storing the depth of each vertex in the search tree
+ int[] depth = new int[vertices.size()];
+ // Queue for BFS
+ Queue queue = new ArrayDeque<>();
+
+ // Check whether the graph has self-loops
+ if (graph.getType().isAllowingSelfLoops())
+ for (V v : vertices)
+ if (graph.containsEdge(v, v))
+ return 1;
+
+ NeighborCache neighborIndex = new NeighborCache<>(graph);
+
+ if (graph.getType().isUndirected()) {
+
+ // Array which keeps track of the search tree structure to prevent revisiting parent
+ // nodes
+ int[] parent = new int[vertices.size()];
+
+ // Start a BFS search tree from each vertex. The search stops when a triangle (smallest
+ // possible cycle) is found.
+ // The last two vertices can be ignored.
+ for (int i = 0; i < vertices.size() - 2 && girth > 3; i++) {
+
+ // Reset data structures
+ Arrays.fill(depth, nil);
+ Arrays.fill(parent, nil);
+ queue.clear();
+
+ depth[i] = 0;
+ queue.add(vertices.get(i));
+ int depthU;
+
+ do {
+ V u = queue.poll();
+ int indexU = indexMap.get(u);
+ depthU = depth[indexU];
+
+ // Visit all neighbors of vertex u
+ for (V v : neighborIndex.neighborsOf(u)) {
+ int indexV = indexMap.get(v);
+
+ if (parent[indexU] == indexV) { // Skip the parent of vertex u, unless there
+ // are multiple edges between u and v
+ if (!isAllowingMultipleEdges || graph.getAllEdges(u, v).size() == 1)
+ continue;
+ }
+
+ int depthV = depth[indexV];
+ if (depthV == nil) { // New neighbor discovered
+ queue.add(v);
+ depth[indexV] = depthU + 1;
+ parent[indexV] = indexU;
+ } else { // Rediscover neighbor: found cycle.
+ girth = Math.min(girth, depthU + depthV + 1);
+ }
+ }
+ } while (!queue.isEmpty() && 2 * (depthU + 1) - 1 < girth);
+ }
+ } else { // Directed case
+ for (int i = 0; i < vertices.size() - 1 && girth > 2; i++) {
+
+ // Reset data structures
+ Arrays.fill(depth, nil);
+ queue.clear();
+
+ depth[i] = 0;
+ queue.add(vertices.get(i));
+ int depthU;
+
+ do {
+ V u = queue.poll();
+ int indexU = indexMap.get(u);
+ depthU = depth[indexU];
+
+ // Visit all neighbors of vertex u
+ for (V v : neighborIndex.successorsOf(u)) {
+ int indexV = indexMap.get(v);
+
+ int depthV = depth[indexV];
+ if (depthV == nil) { // New neighbor discovered
+ queue.add(v);
+ depth[indexV] = depthU + 1;
+ } else if (depthV == 0) { // Rediscover root: found cycle.
+ girth = Math.min(girth, depthU + depthV + 1);
+ }
+ }
+ } while (!queue.isEmpty() && depthU + 1 < girth);
+ }
+ }
+
+ assert graph.getType().isUndirected() && graph.getType().isSimple() && girth >= 3
+ || graph.getType().isAllowingSelfLoops() && girth >= 1 || girth >= 2
+ && (graph.getType().isDirected() || graph.getType().isAllowingMultipleEdges());
+ return girth;
+ }
+
+ /**
+ * An $O(|V|^3)$ (assuming vertexSubset provides constant time indexing) naive implementation
+ * for counting non-trivial triangles in an undirected graph induced by the subset of vertices.
+ *
+ * @param graph the input graph
+ * @param vertexSubset the vertex subset
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return the number of triangles in the graph induced by vertexSubset
+ */
+ static long naiveCountTriangles(Graph graph, List vertexSubset)
+ {
+ long total = 0;
+
+ if (graph.getType().isAllowingMultipleEdges()) {
+ for (int i = 0; i < vertexSubset.size(); i++) {
+ for (int j = i + 1; j < vertexSubset.size(); j++) {
+ for (int k = j + 1; k < vertexSubset.size(); k++) {
+ V u = vertexSubset.get(i);
+ V v = vertexSubset.get(j);
+ V w = vertexSubset.get(k);
+
+ int uvEdgeCount = graph.getAllEdges(u, v).size();
+ if (uvEdgeCount == 0) {
+ continue;
+ }
+ int vwEdgeCount = graph.getAllEdges(v, w).size();
+ if (vwEdgeCount == 0) {
+ continue;
+ }
+ int wuEdgeCount = graph.getAllEdges(w, u).size();
+ if (wuEdgeCount == 0) {
+ continue;
+ }
+ total += uvEdgeCount * vwEdgeCount * wuEdgeCount;
+ }
+ }
+ }
+ } else {
+ for (int i = 0; i < vertexSubset.size(); i++) {
+ for (int j = i + 1; j < vertexSubset.size(); j++) {
+ for (int k = j + 1; k < vertexSubset.size(); k++) {
+ V u = vertexSubset.get(i);
+ V v = vertexSubset.get(j);
+ V w = vertexSubset.get(k);
+
+ if (graph.containsEdge(u, v) && graph.containsEdge(v, w)
+ && graph.containsEdge(w, u))
+ {
+ total++;
+ }
+ }
+ }
+ }
+ }
+
+ return total;
+ }
+
+ /**
+ * An $O(|E|^{3/2})$ algorithm for counting the number of non-trivial triangles in an undirected
+ * graph. A non-trivial triangle is formed by three distinct vertices all connected to each
+ * other.
+ *
+ *
+ * For more details of this algorithm see Ullman, Jeffrey: "Mining of Massive Datasets",
+ * Cambridge University Press, Chapter 10
+ *
+ * @param graph the input graph
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return the number of triangles in the graph
+ * @throws NullPointerException if {@code graph} is {@code null}
+ * @throws IllegalArgumentException if {@code graph} is not undirected
+ */
+ public static long getNumberOfTriangles(Graph graph)
+ {
+ GraphTests.requireUndirected(graph);
+
+ final int sqrtV = (int) Math.sqrt(graph.vertexSet().size());
+
+ List vertexList = new ArrayList<>(graph.vertexSet());
+
+ /*
+ * The book suggest the following comparator: "Compare vertices based on their degree. If
+ * equal compare them of their actual value, since they are all integers".
+ */
+
+ // Fix vertex order for unique comparison of vertices
+ Map vertexOrder =
+ CollectionUtil.newHashMapWithExpectedSize(graph.vertexSet().size());
+ int k = 0;
+ for (V v : graph.vertexSet()) {
+ vertexOrder.put(v, k++);
+ }
+
+ Comparator comparator = Comparator
+ .comparingInt(graph::degreeOf).thenComparingInt(System::identityHashCode)
+ .thenComparingInt(vertexOrder::get);
+
+ vertexList.sort(comparator);
+
+ // vertex v is a heavy-hitter iff degree(v) >= sqrtV
+ List heavyHitterVertices =
+ vertexList.stream().filter(x -> graph.degreeOf(x) >= sqrtV).collect(
+ Collectors.toCollection(ArrayList::new));
+
+ // count the number of triangles formed from only heavy-hitter vertices
+ long numberTriangles = naiveCountTriangles(graph, heavyHitterVertices);
+
+ for (E edge : graph.edgeSet()) {
+ V v1 = graph.getEdgeSource(edge);
+ V v2 = graph.getEdgeTarget(edge);
+
+ if (v1 == v2) {
+ continue;
+ }
+
+ if (graph.degreeOf(v1) < sqrtV || graph.degreeOf(v2) < sqrtV) {
+ // ensure that v1 <= v2 (swap them otherwise)
+ if (comparator.compare(v1, v2) > 0) {
+ V tmp = v1;
+ v1 = v2;
+ v2 = tmp;
+ }
+
+ for (E e : graph.edgesOf(v1)) {
+ V u = Graphs.getOppositeVertex(graph, e, v1);
+
+ // check if the triangle is non-trivial: u, v1, v2 are distinct vertices
+ if (u == v1 || u == v2) {
+ continue;
+ }
+
+ /*
+ * Check if v2 <= u and if (u, v2) is a valid edge. If both of them are true,
+ * then we have a new triangle (v1, v2, u) and all three vertices in the
+ * triangle are ordered (v1 <= v2 <= u) so we count it only once.
+ */
+ if (comparator.compare(v2, u) <= 0 && graph.containsEdge(u, v2)) {
+ numberTriangles++;
+ }
+ }
+ }
+ }
+
+ return numberTriangles;
+ }
+}
diff --git a/jgrapht-core/src/main/java/org/jgrapht/GraphPath.java b/jgrapht-core/src/main/java/org/jgrapht/GraphPath.java
index c08e679a93d..e333ffb4385 100644
--- a/jgrapht-core/src/main/java/org/jgrapht/GraphPath.java
+++ b/jgrapht-core/src/main/java/org/jgrapht/GraphPath.java
@@ -1,105 +1,133 @@
-/* ==========================================
- * JGraphT : a free Java graph-theory library
- * ==========================================
- *
- * Project Info: http://jgrapht.sourceforge.net/
- * Project Creator: Barak Naveh (http://sourceforge.net/users/barak_naveh)
- *
- * (C) Copyright 2003-2008, by Barak Naveh and Contributors.
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
- * License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- */
-/* ----------
- * Graph.java
- * ----------
- * (C) Copyright 2008-2008, by John V. Sichi and Contributors.
+/*
+ * (C) Copyright 2008-2023, by John V Sichi and Contributors.
*
- * Original Author: John V. Sichi
- * Contributor(s): -
+ * JGraphT : a free Java graph-theory library
*
- * $Id$
+ * See the CONTRIBUTORS.md file distributed with this work for additional
+ * information regarding copyright ownership.
*
- * Changes
- * -------
- * 1-Jan-2008 : Initial revision (JVS);
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0, or the
+ * GNU Lesser General Public License v2.1 or later
+ * which is available at
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1-standalone.html.
*
+ * SPDX-License-Identifier: EPL-2.0 OR LGPL-2.1-or-later
*/
package org.jgrapht;
import java.util.*;
-
/**
- * A GraphPath represents a
- * path in a {@link Graph}. Note that a path is defined primarily in terms
- * of edges (rather than vertices) so that multiple edges between the same pair
- * of vertices can be discriminated.
+ * A GraphPath represents a path in a
+ * {@link Graph}. Unlike some definitions, the path is not required to be a
+ * Simple Path.
+ *
+ * @param the graph vertex type
+ * @param the graph edge type
*
* @author John Sichi
- * @since Jan 1, 2008
*/
public interface GraphPath
{
- //~ Methods ----------------------------------------------------------------
-
/**
- * Returns the graph over which this path is defined. The path may also be
- * valid with respect to other graphs.
+ * Returns the graph over which this path is defined. The path may also be valid with respect to
+ * other graphs.
*
* @return the containing graph
*/
- public Graph getGraph();
+ Graph getGraph();
/**
* Returns the start vertex in the path.
*
* @return the start vertex
*/
- public V getStartVertex();
+ V getStartVertex();
/**
* Returns the end vertex in the path.
*
* @return the end vertex
*/
- public V getEndVertex();
+ V getEndVertex();
/**
- * Returns the edges making up the path. The first edge in this path is
- * incident to the start vertex. The last edge is incident to the end
- * vertex. The vertices along the path can be obtained by traversing from
- * the start vertex, finding its opposite across the first edge, and then
- * doing the same successively across subsequent edges; {@link
- * Graphs#getPathVertexList} provides a convenience method for this.
+ * Returns the edges making up the path. The first edge in this path is incident to the start
+ * vertex. The last edge is incident to the end vertex. The vertices along the path can be
+ * obtained by traversing from the start vertex, finding its opposite across the first edge, and
+ * then doing the same successively across subsequent edges; see {@link #getVertexList()}.
*
- *
Whether or not the returned edge list is modifiable depends on the
- * path implementation.
+ *
+ * Whether or not the returned edge list is modifiable depends on the path implementation.
*
* @return list of edges traversed by the path
*/
- public List getEdgeList();
+ default List getEdgeList()
+ {
+ List vertexList = this.getVertexList();
+ if (vertexList.size() < 2)
+ return Collections.emptyList();
+
+ Graph g = this.getGraph();
+ List edgeList = new ArrayList<>();
+ Iterator vertexIterator = vertexList.iterator();
+ V u = vertexIterator.next();
+ while (vertexIterator.hasNext()) {
+ V v = vertexIterator.next();
+ edgeList.add(g.getEdge(u, v));
+ u = v;
+ }
+ return edgeList;
+ }
/**
- * Returns the weight assigned to the path. Typically, this will be the sum
- * of the weights of the edge list entries (as defined by the containing
- * graph), but some path implementations may use other definitions.
+ * Returns the path as a sequence of vertices.
+ *
+ * @return path, denoted by a list of vertices
+ */
+ default List getVertexList()
+ {
+ List edgeList = this.getEdgeList();
+
+ if (edgeList.isEmpty()) {
+ V startVertex = getStartVertex();
+ if (startVertex != null && startVertex.equals(getEndVertex())) {
+ return Collections.singletonList(startVertex);
+ } else {
+ return Collections.emptyList();
+ }
+ }
+
+ Graph g = this.getGraph();
+ List list = new ArrayList<>();
+ V v = this.getStartVertex();
+ list.add(v);
+ for (E e : edgeList) {
+ v = Graphs.getOppositeVertex(g, e, v);
+ list.add(v);
+ }
+ return list;
+ }
+
+ /**
+ * Returns the weight assigned to the path. Typically, this will be the sum of the weights of
+ * the edge list entries (as defined by the containing graph), but some path implementations may
+ * use other definitions.
*
* @return the weight of the path
*/
- public double getWeight();
-}
+ double getWeight();
-// End GraphPath.java
+ /**
+ * Returns the length of the path, measured in the number of edges.
+ *
+ * @return the length of the path, measured in the number of edges
+ */
+ default int getLength()
+ {
+ return getEdgeList().size();
+ }
+
+}
diff --git a/jgrapht-core/src/main/java/org/jgrapht/GraphTests.java b/jgrapht-core/src/main/java/org/jgrapht/GraphTests.java
new file mode 100644
index 00000000000..929cba86c95
--- /dev/null
+++ b/jgrapht-core/src/main/java/org/jgrapht/GraphTests.java
@@ -0,0 +1,868 @@
+/*
+ * (C) Copyright 2003-2023, by Barak Naveh, Dimitrios Michail and Contributors.
+ *
+ * JGraphT : a free Java graph-theory library
+ *
+ * See the CONTRIBUTORS.md file distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0, or the
+ * GNU Lesser General Public License v2.1 or later
+ * which is available at
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1-standalone.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR LGPL-2.1-or-later
+ */
+package org.jgrapht;
+
+import org.jgrapht.alg.connectivity.*;
+import org.jgrapht.alg.cycle.*;
+import org.jgrapht.alg.interfaces.*;
+import org.jgrapht.alg.partition.*;
+import org.jgrapht.alg.planar.*;
+
+import java.util.*;
+import java.util.stream.*;
+
+/**
+ * A collection of utilities to test for various graph properties.
+ *
+ * @author Barak Naveh
+ * @author Dimitrios Michail
+ * @author Joris Kinable
+ * @author Alexandru Valeanu
+ */
+public abstract class GraphTests
+{
+ private static final String GRAPH_CANNOT_BE_NULL = "Graph cannot be null";
+ private static final String GRAPH_MUST_BE_DIRECTED_OR_UNDIRECTED =
+ "Graph must be directed or undirected";
+ private static final String GRAPH_MUST_BE_UNDIRECTED = "Graph must be undirected";
+ private static final String GRAPH_MUST_BE_DIRECTED = "Graph must be directed";
+ private static final String GRAPH_MUST_BE_WEIGHTED = "Graph must be weighted";
+
+ /**
+ * Test whether a graph is empty. An empty graph on n nodes consists of n isolated vertices with
+ * no edges.
+ *
+ * @param graph the input graph
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return true if the graph is empty, false otherwise
+ *
+ * @throws NullPointerException if graph is {@code null}
+ */
+ public static boolean isEmpty(Graph graph)
+ {
+ Objects.requireNonNull(graph, GRAPH_CANNOT_BE_NULL);
+ return graph.edgeSet().isEmpty();
+ }
+
+ /**
+ * Check if a graph is simple. A graph is simple if it has no self-loops and multiple (parallel)
+ * edges.
+ *
+ * @param graph a graph
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return true if a graph is simple, false otherwise
+ *
+ * @throws NullPointerException if graph is {@code null}
+ */
+ public static boolean isSimple(Graph graph)
+ {
+ Objects.requireNonNull(graph, GRAPH_CANNOT_BE_NULL);
+
+ GraphType type = graph.getType();
+ if (type.isSimple()) {
+ return true;
+ }
+
+ // no luck, we have to check
+ for (V v : graph.vertexSet()) {
+ Set neighbors = new HashSet<>();
+ for (E e : graph.outgoingEdgesOf(v)) {
+ V u = Graphs.getOppositeVertex(graph, e, v);
+ if (u.equals(v) || !neighbors.add(u)) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Check if a graph has self-loops. A self-loop is an edge with the same source and target
+ * vertices.
+ *
+ * @param graph a graph
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return true if a graph has self-loops, false otherwise
+ *
+ * @throws NullPointerException if graph is {@code null}
+ */
+ public static boolean hasSelfLoops(Graph graph)
+ {
+ Objects.requireNonNull(graph, GRAPH_CANNOT_BE_NULL);
+
+ if (!graph.getType().isAllowingSelfLoops()) {
+ return false;
+ }
+
+ // no luck, we have to check
+ for (E e : graph.edgeSet()) {
+ if (graph.getEdgeSource(e).equals(graph.getEdgeTarget(e))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Check if a graph has multiple edges (parallel edges), that is, whether the graph contains two
+ * or more edges connecting the same pair of vertices.
+ *
+ * @param graph a graph
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return true if a graph has multiple edges, false otherwise
+ *
+ * @throws NullPointerException if graph is {@code null}
+ */
+ public static boolean hasMultipleEdges(Graph graph)
+ {
+ Objects.requireNonNull(graph, GRAPH_CANNOT_BE_NULL);
+
+ if (!graph.getType().isAllowingMultipleEdges()) {
+ return false;
+ }
+
+ // no luck, we have to check
+ for (V v : graph.vertexSet()) {
+ Set neighbors = new HashSet<>();
+ for (E e : graph.outgoingEdgesOf(v)) {
+ V u = Graphs.getOppositeVertex(graph, e, v);
+ if (!neighbors.add(u)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Test whether a graph is complete. A complete undirected graph is a simple graph in which
+ * every pair of distinct vertices is connected by a unique edge. A complete directed graph is a
+ * directed graph in which every pair of distinct vertices is connected by a pair of unique
+ * edges (one in each direction).
+ *
+ * @param graph the input graph
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return true if the graph is complete, false otherwise
+ *
+ * @throws NullPointerException if graph is {@code null}
+ */
+ public static boolean isComplete(Graph graph)
+ {
+ Objects.requireNonNull(graph, GRAPH_CANNOT_BE_NULL);
+ int n = graph.vertexSet().size();
+ int allEdges;
+ if (graph.getType().isDirected()) {
+ allEdges = Math.multiplyExact(n, n - 1);
+ } else if (graph.getType().isUndirected()) {
+ if (n % 2 == 0) {
+ allEdges = Math.multiplyExact(n / 2, n - 1);
+ } else {
+ allEdges = Math.multiplyExact(n, (n - 1) / 2);
+ }
+ } else {
+ throw new IllegalArgumentException(GRAPH_MUST_BE_DIRECTED_OR_UNDIRECTED);
+ }
+ return graph.edgeSet().size() == allEdges && isSimple(graph);
+ }
+
+ /**
+ * Test if the inspected graph is connected. A graph is connected when, while ignoring edge
+ * directionality, there exists a path between every pair of vertices. In a connected graph,
+ * there are no unreachable vertices. When the inspected graph is a directed graph, this
+ * method returns true if and only if the inspected graph is weakly connected. An empty
+ * graph is not considered connected.
+ *
+ *
+ * This method does not performing any caching, instead recomputes everything from scratch. In
+ * case more control is required use {@link ConnectivityInspector} directly.
+ *
+ * @param graph the input graph
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return true if the graph is connected, false otherwise
+ *
+ * @throws NullPointerException if graph is {@code null}
+ *
+ * @see ConnectivityInspector
+ */
+ public static boolean isConnected(Graph graph)
+ {
+ Objects.requireNonNull(graph, GRAPH_CANNOT_BE_NULL);
+ return new ConnectivityInspector<>(graph).isConnected();
+ }
+
+ /**
+ * Tests if the inspected graph is biconnected. A biconnected graph is a connected graph on two
+ * or more vertices having no cutpoints.
+ *
+ *
+ * This method does not performing any caching, instead recomputes everything from scratch. In
+ * case more control is required use
+ * {@link org.jgrapht.alg.connectivity.BiconnectivityInspector} directly.
+ *
+ * @param graph the input graph
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return true if the graph is biconnected, false otherwise
+ *
+ * @throws NullPointerException if graph is {@code null}
+ *
+ * @see org.jgrapht.alg.connectivity.BiconnectivityInspector
+ */
+ public static boolean isBiconnected(Graph graph)
+ {
+ Objects.requireNonNull(graph, GRAPH_CANNOT_BE_NULL);
+ return new BiconnectivityInspector<>(graph).isBiconnected();
+ }
+
+ /**
+ * Test whether a directed graph is weakly connected.
+ *
+ *
+ * This method does not performing any caching, instead recomputes everything from scratch. In
+ * case more control is required use {@link ConnectivityInspector} directly.
+ *
+ * @param graph the input graph
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return true if the graph is weakly connected, false otherwise
+ *
+ * @throws NullPointerException if graph is {@code null}
+ *
+ * @see ConnectivityInspector
+ */
+ public static boolean isWeaklyConnected(Graph graph)
+ {
+ return isConnected(graph);
+ }
+
+ /**
+ * Test whether a graph is strongly connected.
+ *
+ *
+ * This method does not performing any caching, instead recomputes everything from scratch. In
+ * case more control is required use {@link KosarajuStrongConnectivityInspector} directly.
+ *
+ *
+ * In case of undirected graphs this method delegated to {@link #isConnected(Graph)}.
+ *
+ * @param graph the input graph
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return true if the graph is strongly connected, false otherwise
+ *
+ * @throws NullPointerException if graph is {@code null}
+ *
+ * @see KosarajuStrongConnectivityInspector
+ */
+ public static boolean isStronglyConnected(Graph graph)
+ {
+ Objects.requireNonNull(graph, GRAPH_CANNOT_BE_NULL);
+ if (graph.getType().isUndirected()) {
+ return isConnected(graph);
+ } else {
+ return new KosarajuStrongConnectivityInspector<>(graph).isStronglyConnected();
+ }
+ }
+
+ /**
+ * Test whether an undirected graph is a tree.
+ *
+ * @param graph the input graph
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return true if the graph is tree, false otherwise
+ */
+ public static boolean isTree(Graph graph)
+ {
+ if (!graph.getType().isUndirected()) {
+ throw new IllegalArgumentException(GRAPH_MUST_BE_UNDIRECTED);
+ }
+
+ return (graph.edgeSet().size() == (graph.vertexSet().size() - 1)) && isConnected(graph);
+ }
+
+ /**
+ * Test whether an undirected graph is a forest. A forest is a set of disjoint trees. By
+ * definition, any acyclic graph is a forest. This includes the empty graph and the class of
+ * tree graphs.
+ *
+ * @param graph the input graph
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return true if the graph is forest, false otherwise
+ */
+ public static boolean isForest(Graph graph)
+ {
+ if (!graph.getType().isUndirected()) {
+ throw new IllegalArgumentException(GRAPH_MUST_BE_UNDIRECTED);
+ }
+ if (graph.vertexSet().isEmpty()) // null graph is not a forest
+ return false;
+
+ int nrConnectedComponents = new ConnectivityInspector<>(graph).connectedSets().size();
+ return graph.edgeSet().size() + nrConnectedComponents == graph.vertexSet().size();
+ }
+
+ /**
+ * Test whether a graph is overfull.
+ * A graph is overfull if $|E|>\Delta(G)\lfloor |V|/2 \rfloor$, where $\Delta(G)$ is the
+ * maximum degree of the graph.
+ *
+ * @param graph the input graph
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return true if the graph is overfull, false otherwise
+ */
+ public static boolean isOverfull(Graph graph)
+ {
+ int maxDegree = graph.vertexSet().stream().mapToInt(graph::degreeOf).max().getAsInt();
+ return graph.edgeSet().size() > maxDegree * Math.floor(graph.vertexSet().size() / 2.0);
+ }
+
+ /**
+ * Test whether an undirected graph is a
+ * split graph. A split graph is a graph
+ * in which the vertices can be partitioned into a clique and an independent set. Split graphs
+ * are a special class of chordal graphs. Given the degree sequence $d_1 \geq,\dots,\geq d_n$ of
+ * $G$, a graph is a split graph if and only if : \[\sum_{i=1}^m d_i = m (m - 1) + \sum_{i=m +
+ * 1}^nd_i\], where $m = \max_i \{d_i\geq i-1\}$. If the graph is a split graph, then the $m$
+ * vertices with the largest degrees form a maximum clique in $G$, and the remaining vertices
+ * constitute an independent set. See Brandstadt, A., Le, V., Spinrad, J. Graph Classes: A
+ * Survey. Philadelphia, PA: SIAM, 1999. for details.
+ *
+ * @param graph the input graph
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return true if the graph is a split graph, false otherwise
+ */
+ public static boolean isSplit(Graph graph)
+ {
+ requireUndirected(graph);
+ if (!isSimple(graph) || graph.vertexSet().isEmpty())
+ return false;
+
+ List degrees = new ArrayList<>(graph.vertexSet().size());
+ degrees
+ .addAll(graph.vertexSet().stream().map(graph::degreeOf).collect(Collectors.toList()));
+ Collections.sort(degrees, Collections.reverseOrder()); // sort degrees descending order
+ // Find m = \max_i \{d_i\geq i-1\}
+ int m = 1;
+ for (; m < degrees.size() && degrees.get(m) >= m; m++) {
+ }
+ m--;
+
+ int left = 0;
+ for (int i = 0; i <= m; i++)
+ left += degrees.get(i);
+ int right = m * (m + 1);
+ for (int i = m + 1; i < degrees.size(); i++)
+ right += degrees.get(i);
+ return left == right;
+ }
+
+ /**
+ * Test whether a graph is bipartite.
+ *
+ * @param graph the input graph
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return true if the graph is bipartite, false otherwise
+ * @see BipartitePartitioning#isBipartite()
+ */
+ public static boolean isBipartite(Graph graph)
+ {
+ return new BipartitePartitioning<>(graph).isBipartite();
+ }
+
+ /**
+ * Test whether a partition of the vertices into two sets is a bipartite partition.
+ *
+ * @param graph the input graph
+ * @param firstPartition the first vertices partition
+ * @param secondPartition the second vertices partition
+ * @return true if the partition is a bipartite partition, false otherwise
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @see BipartitePartitioning#isValidPartitioning(PartitioningAlgorithm.Partitioning)
+ */
+ @SuppressWarnings("unchecked")
+ public static boolean isBipartitePartition(
+ Graph graph, Set extends V> firstPartition, Set extends V> secondPartition)
+ {
+ return new BipartitePartitioning<>(graph).isValidPartitioning(
+ new PartitioningAlgorithm.PartitioningImpl<>(
+ Arrays.asList((Set) firstPartition, (Set) secondPartition)));
+ }
+
+ /**
+ * Tests whether a graph is cubic. A
+ * graph is cubic if all vertices have degree 3.
+ *
+ * @param graph the input graph
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return true if the graph is cubic, false otherwise
+ */
+ public static boolean isCubic(Graph graph)
+ {
+ for (V v : graph.vertexSet())
+ if (graph.degreeOf(v) != 3)
+ return false;
+ return true;
+ }
+
+ /**
+ * Test whether a graph is Eulerian. An undirected graph is Eulerian if it is connected and each
+ * vertex has an even degree. A directed graph is Eulerian if it is strongly connected and each
+ * vertex has the same incoming and outgoing degree. Test whether a graph is Eulerian. An
+ * Eulerian graph is a graph
+ * containing an Eulerian cycle.
+ *
+ * @param graph the input graph
+ * @param the graph vertex type
+ * @param the graph edge type
+ *
+ * @return true if the graph is Eulerian, false otherwise
+ *
+ * @throws NullPointerException if graph is {@code null}
+ *
+ * @see HierholzerEulerianCycle#isEulerian(Graph)
+ */
+ public static boolean isEulerian(Graph graph)
+ {
+ Objects.requireNonNull(graph, GRAPH_CANNOT_BE_NULL);
+ return new HierholzerEulerianCycle().isEulerian(graph);
+ }
+
+ /**
+ * Checks whether a graph is chordal. A
+ * chordal graph is one in which all cycles of four or more vertices have a chord, which is
+ * an edge that is not part of the cycle but connects two vertices of the cycle.
+ *
+ * @param graph the input graph
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return true if the graph is chordal, false otherwise
+ *
+ * @throws NullPointerException if graph is {@code null}
+ *
+ * @see ChordalityInspector#isChordal()
+ */
+ public static boolean isChordal(Graph graph)
+ {
+ Objects.requireNonNull(graph, GRAPH_CANNOT_BE_NULL);
+ return new ChordalityInspector<>(graph).isChordal();
+ }
+
+ /**
+ * Checks whether a graph is weakly
+ * chordal.
+ *
+ * The following definitions are equivalent:
+ *
+ *
A graph is weakly chordal (weakly triangulated) if neither it nor its complement contains
+ * a chordless cycles with five
+ * or more vertices.
+ *
A 2-pair in a graph is a pair of non-adjacent vertices $x$, $y$ such that every chordless
+ * path has exactly two edges. A graph is weakly chordal if every connected
+ * induced subgraph $H$ that is not
+ * a complete graph, contains a 2-pair.
+ *
+ *
+ * @param graph the input graph
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return true if the graph is weakly chordal, false otherwise
+ *
+ * @throws NullPointerException if graph is {@code null}
+ *
+ * @see WeakChordalityInspector#isWeaklyChordal()
+ */
+ public static boolean isWeaklyChordal(Graph graph)
+ {
+ Objects.requireNonNull(graph, GRAPH_CANNOT_BE_NULL);
+ return new WeakChordalityInspector<>(graph).isWeaklyChordal();
+ }
+
+ /**
+ * Tests whether an undirected graph meets Ore's condition to be Hamiltonian.
+ *
+ * Let $G$ be a (finite and simple) graph with $n \geq 3$ vertices. We denote by $deg(v)$ the
+ * degree of a vertex $v$ in $G$, i.e. the number of incident edges in $G$ to $v$. Then, Ore's
+ * theorem states that if $deg(v) + deg(w) \geq n$ for every pair of distinct non-adjacent
+ * vertices $v$ and $w$ of $G$, then $G$ is Hamiltonian.
+ *
+ * @param graph the input graph
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return true if the graph meets Ore's condition, false otherwise
+ *
+ * @throws NullPointerException if graph is {@code null}
+ *
+ * @see org.jgrapht.alg.tour.PalmerHamiltonianCycle
+ */
+ public static boolean hasOreProperty(Graph graph)
+ {
+ requireUndirected(graph);
+
+ final int n = graph.vertexSet().size();
+
+ if (!graph.getType().isSimple() || n < 3)
+ return false;
+
+ List vertexList = new ArrayList<>(graph.vertexSet());
+
+ for (int i = 0; i < vertexList.size(); i++) {
+ for (int j = i + 1; j < vertexList.size(); j++) {
+ V v = vertexList.get(i);
+ V w = vertexList.get(j);
+
+ if (!v.equals(w) && !graph.containsEdge(v, w)
+ && graph.degreeOf(v) + graph.degreeOf(w) < n)
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Tests whether an undirected graph is triangle-free (i.e. no three distinct vertices form a
+ * triangle of edges).
+ *
+ * The implementation of this method uses {@link GraphMetrics#getNumberOfTriangles(Graph)}.
+ *
+ * @param graph the input graph
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return true if the graph is triangle-free, false otherwise
+ */
+ public static boolean isTriangleFree(Graph graph)
+ {
+ return GraphMetrics.getNumberOfTriangles(graph) == 0;
+ }
+
+ /**
+ * Checks that the specified graph is perfect. Due to the Strong Perfect Graph Theorem Berge
+ * Graphs are the same as perfect Graphs. The implementation of this method is delegated to
+ * {@link org.jgrapht.alg.cycle.BergeGraphInspector}
+ *
+ * @param graph the graph reference to check for being perfect or not
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return true if the graph is perfect, false otherwise
+ *
+ * @throws NullPointerException if graph is {@code null}
+ */
+ public static boolean isPerfect(Graph graph)
+ {
+ Objects.requireNonNull(graph, GRAPH_CANNOT_BE_NULL);
+ return new BergeGraphInspector().isBerge(graph);
+ }
+
+ /**
+ * Checks that the specified graph is planar. A graph is
+ * planar if it can be drawn on a
+ * two-dimensional plane without any of its edges crossing. The implementation of the method is
+ * delegated to the {@link org.jgrapht.alg.planar.BoyerMyrvoldPlanarityInspector}. Also, use
+ * this class to get a planar embedding of the graph in case it is planar, or a Kuratowski
+ * subgraph as a certificate of nonplanarity.
+ *
+ * @param graph the graph to test planarity of
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return true if the graph is planar, false otherwise
+ *
+ * @throws NullPointerException if graph is {@code null}
+ *
+ * @see PlanarityTestingAlgorithm
+ * @see BoyerMyrvoldPlanarityInspector
+ */
+ public static boolean isPlanar(Graph graph)
+ {
+ Objects.requireNonNull(graph, GRAPH_CANNOT_BE_NULL);
+ return new BoyerMyrvoldPlanarityInspector<>(graph).isPlanar();
+ }
+
+ /**
+ * Checks whether the {@code graph} is a Kuratowski
+ * subdivision. Effectively checks whether the {@code graph} is a $K_{3,3}$ subdivision or
+ * $K_{5}$ subdivision
+ *
+ * @param graph the graph to test
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return true if the {@code graph} is a Kuratowski subdivision, false otherwise
+ */
+ public static boolean isKuratowskiSubdivision(Graph graph)
+ {
+ return isK33Subdivision(graph) || isK5Subdivision(graph);
+ }
+
+ /**
+ * Checks whether the {@code graph} is a $K_{3,3}$ subdivision.
+ *
+ * @param graph the graph to test
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return true if the {@code graph} is a $K_{3,3}$ subdivision, false otherwise
+ */
+ public static boolean isK33Subdivision(Graph graph)
+ {
+ List degree3 = new ArrayList<>();
+ // collect all vertices with degree 3
+ for (V vertex : graph.vertexSet()) {
+ int degree = graph.degreeOf(vertex);
+ if (degree == 3) {
+ degree3.add(vertex);
+ } else if (degree != 2) {
+ return false;
+ }
+ }
+ if (degree3.size() != 6) {
+ return false;
+ }
+ V vertex = degree3.remove(degree3.size() - 1);
+ Set reachable = reachableWithDegree(graph, vertex, 3);
+ if (reachable.size() != 3) {
+ return false;
+ }
+ degree3.removeAll(reachable);
+ return reachable.equals(reachableWithDegree(graph, degree3.get(0), 3))
+ && reachable.equals(reachableWithDegree(graph, degree3.get(1), 3));
+ }
+
+ /**
+ * Checks whether the {@code graph} is a $K_5$ subdivision.
+ *
+ * @param graph the graph to test
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return true if the {@code graph} is a $K_5$ subdivision, false otherwise
+ */
+ public static boolean isK5Subdivision(Graph graph)
+ {
+ Set degree5 = new HashSet<>();
+ for (V vertex : graph.vertexSet()) {
+ int degree = graph.degreeOf(vertex);
+ if (degree == 4) {
+ degree5.add(vertex);
+ } else if (degree != 2) {
+ return false;
+ }
+ }
+ if (degree5.size() != 5) {
+ return false;
+ }
+ for (V vertex : degree5) {
+ Set reachable = reachableWithDegree(graph, vertex, 4);
+ if (reachable.size() != 4 || !degree5.containsAll(reachable)
+ || reachable.contains(vertex))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Uses BFS to find all vertices of the {@code graph} which have a degree {@code degree}. This
+ * method doesn't advance to new nodes after it finds a node with a degree {@code degree}
+ *
+ * @param graph the graph to search in
+ * @param startVertex the start vertex
+ * @param degree the degree of desired vertices
+ * @param the graph vertex type
+ * @param the graph edge type
+ * @return all vertices of the {@code graph} reachable from {@code startVertex}, which have
+ * degree {@code degree}
+ */
+ private static Set reachableWithDegree(Graph graph, V startVertex, int degree)
+ {
+ Set visited = new HashSet<>();
+ Set reachable = new HashSet<>();
+ Queue queue = new ArrayDeque<>();
+ queue.add(startVertex);
+ while (!queue.isEmpty()) {
+ V current = queue.poll();
+ visited.add(current);
+ for (E e : graph.edgesOf(current)) {
+ V opposite = Graphs.getOppositeVertex(graph, e, current);
+ if (visited.contains(opposite)) {
+ continue;
+ }
+ if (graph.degreeOf(opposite) == degree) {
+ reachable.add(opposite);
+ } else {
+ queue.add(opposite);
+ }
+ }
+ }
+ return reachable;
+ }
+
+ /**
+ * Checks that the specified graph is directed and throws a customized
+ * {@link IllegalArgumentException} if it is not. Also checks that the graph reference is not
+ * {@code null} and throws a {@link NullPointerException} if it is.
+ *
+ * @param graph the graph reference to check for beeing directed and not null
+ * @param message detail message to be used in the event that an exception is thrown
+ * @param the graph vertex type
+ * @param