The boost component dependencies blues

I'm not sure what the best place is for this question, but since it is symptomatic for a general theme (which I have complained about a lot in the past), I'll write it here: I'm trying to generate a boost subset that allows me to build boost.python and its dependencies into my own package. To do that, I ran "bcp python ...". I'm surprised to find all these components in the generated source tree: date_time, graph, mpi, regex, serialization, test, thread. And that's only compiled components (content of lib/). There are many more header-only components (i.e. subdirectories under boost/), such as spirit, variant, property_map, property_tree, dynamic_bitset. Is this really a minimal subset to use boost.python ? I can't quite believe it. In particular, what is boost.mpi doing there, and what boost.serialization (and boost.spirit) ? I'm going to great length to be able to use boost in a production environment, but I have to admit that this is quite unacceptable. :-( Stefan -- ...ich hab' noch einen Koffer in Berlin...

On Sat, Dec 12, 2009 at 7:33 AM, Stefan Seefeld <seefeld@sympatico.ca> wrote:
I'm not sure what the best place is for this question, but since it is symptomatic for a general theme (which I have complained about a lot in the past), I'll write it here:
I'm trying to generate a boost subset that allows me to build boost.python and its dependencies into my own package. To do that, I ran "bcp python ...". I'm surprised to find all these components in the generated source tree:
date_time, graph, mpi, regex, serialization, test, thread.
And that's only compiled components (content of lib/). There are many more header-only components (i.e. subdirectories under boost/), such as spirit, variant, property_map, property_tree, dynamic_bitset.
Is this really a minimal subset to use boost.python ? I can't quite believe it. In particular, what is boost.mpi doing there, and what boost.serialization (and boost.spirit) ?
I'm going to great length to be able to use boost in a production environment, but I have to admit that this is quite unacceptable. :-(
Correct. Boost.Python includes a lot of things to properly convert from a large amount of Python types properly as well as for the type registry. I am actually surprised it does not include more...

On Sat, Dec 12, 2009 at 10:33 PM, Stefan Seefeld <seefeld@sympatico.ca> wrote: [snip]
I'm going to great length to be able to use boost in a production environment, but I have to admit that this is quite unacceptable. :-(
I know that one man's production environment is different from another man's production environment, but I don't understand why including the whole boost distribution is not acceptable in a production build. What are your requirements for a production environment and what if the minimal requirement for Boost.Python is a whole slew of other Boost libraries, does that discount it from your requirements? -- Dean Michael Berris blog.cplusplus-soup.com | twitter.com/mikhailberis linkedin.com/in/mikhailberis | facebook.com/dean.berris | deanberris.com

Stefan Seefeld wrote:
In particular, what is boost.mpi doing there
From a quick search through the headers:
The file \libs\python\src\object\inheritance.cpp includes some Graph headers. Some other Graph headers include mpi stuff (for 'Parallel BGL' functionality). So it might just be that it's pulling in the whole of both libs, even if you don't actually need that functionality. I imagine that some of the other deps are the same. Also, the generated source tree includes the python regression tests as well as it's source, which i guess then causes the source for Test (and anything it depends on) to be included as well. -- View this message in context: http://old.nabble.com/The-boost-component-dependencies-blues-tp26758037p2675... Sent from the Boost - Dev mailing list archive at Nabble.com.

I'm not sure what the best place is for this question, but since it is symptomatic for a general theme (which I have complained about a lot in the past), I'll write it here:
I'm trying to generate a boost subset that allows me to build boost.python and its dependencies into my own package. To do that, I ran "bcp python ...". I'm surprised to find all these components in the generated source tree:
date_time, graph, mpi, regex, serialization, test, thread.
And that's only compiled components (content of lib/). There are many more header-only components (i.e. subdirectories under boost/), such as spirit, variant, property_map, property_tree, dynamic_bitset.
Is this really a minimal subset to use boost.python ? I can't quite believe it. In particular, what is boost.mpi doing there, and what boost.serialization (and boost.spirit) ?
OK, there are two issue here... why is the dependency so "fat", and why is component X a dependency of Y? To start with the first one: you've created an unnecessarily "fat" dependency because "bcp python" pulls in all of libs/python and its dependencies - for example all the headers and other libraries that the tests and examples depend upon, and since Boost.Python is a big library it's not surprising that this pulls in almost all of Boost. If you know specifically which headers you are using, then "bcp some-boost-header.hpp" will create a much more slimline dependency tree - or at least it should :-) You can also use bcp with the --scan option to scan your actual source files/headers for their Boost dependencies and just copy those actually used. For the second one, if you use bcp with the --report option, it will create a HTML report rather than actually copying the files, that report contains a full dependency tree, so you could look up say Regex or MPI and track its dependencies back to python. There is one potential SNAFU waiting here... say there is a dependency on foo/bar.hpp and lib foo has source files in libs/foo/src/. Those source files will automatically get included as a dependency (which in turn triggers a whole load of other dependencies), but potentially, for a few libraries at least, header foo/bar.hpp may be a header only component of lib foo. Remember also that bcp is compiler agnostic, so all the compiler workarounds are pulled in, regardless of what actual compiler you may be using. That's a feature not a bug BTW ;-) HTH, John.

John, thanks for your reply (and thanks to everyone else who replied, too). On 12/12/2009 12:02 PM, John Maddock wrote:
Is this really a minimal subset to use boost.python ? I can't quite believe it. In particular, what is boost.mpi doing there, and what boost.serialization (and boost.spirit) ?
OK, there are two issue here... why is the dependency so "fat", and why is component X a dependency of Y?
OK. I think I can see how I got where I am. My point is that this 'bcp' tool is an insufficient tool for the purpose, as it, despite its purpose, reinforces the idea that boost is really huge and (almost) monolithic. I understand that boost.python depends on boost.graph. And I can see that (some of) boost.graph may depend on (some of) mpi, etc. Thus, tracking dependencies on the component level isn't quite enough, if I end up with a huge dependency tree. I do want to use all of boost.python, but I definitely have no need for serialization or mpi. Thanks, Stefan -- ...ich hab' noch einen Koffer in Berlin...

Is this really a minimal subset to use boost.python ? I can't quite believe it. In particular, what is boost.mpi doing there, and what boost.serialization (and boost.spirit) ?
OK, there are two issue here... why is the dependency so "fat", and why is component X a dependency of Y?
OK. I think I can see how I got where I am. My point is that this 'bcp' tool is an insufficient tool for the purpose, as it, despite its purpose, reinforces the idea that boost is really huge and (almost) monolithic.
I understand that boost.python depends on boost.graph. And I can see that (some of) boost.graph may depend on (some of) mpi, etc. Thus, tracking dependencies on the component level isn't quite enough, if I end up with a huge dependency tree. I do want to use all of boost.python, but I definitely have no need for serialization or mpi.
Can you tell me specifically which headers you're #including so I can investigate here? John.

On 12/12/2009 01:17 PM, John Maddock wrote:
Can you tell me specifically which headers you're #including so I can investigate here?
I believe the entire Boost.Python API is accessible through boost/python.hpp, so this is what I'm including. (I expect that if there are Boost.Python headers which are not included in the boost/python.hpp 'hub', it's probably an oversight. I may still need them, at some point. Thanks, Stefan -- ...ich hab' noch einen Koffer in Berlin...

Can you tell me specifically which headers you're #including so I can investigate here?
I believe the entire Boost.Python API is accessible through boost/python.hpp, so this is what I'm including. (I expect that if there are Boost.Python headers which are not included in the boost/python.hpp 'hub', it's probably an oversight. I may still need them, at some point.
OK, there's an update in Boost.Trunk to bcp so that it only considers library source files to be a dependency if a header declares something that's defined in the source. As a result using bcp on python.hpp pulls in a lot less.... but: Serialization still gets pulled in - you may know that you're not using that particular feature, but as it's #included by the python source you're going to get it anyway. MPI still gets pulled in - this is an artifact of some recent changes to boost.graph (which is used by python) to optionally make use of the parallel graph lib depending upon some #define. You may know that you're not using this feature, but you *might* be, so it gets pulled in. HTH, John.

On 12/16/2009 01:32 PM, John Maddock wrote:
Can you tell me specifically which headers you're #including so I can investigate here?
I believe the entire Boost.Python API is accessible through boost/python.hpp, so this is what I'm including. (I expect that if there are Boost.Python headers which are not included in the boost/python.hpp 'hub', it's probably an oversight. I may still need them, at some point.
OK, there's an update in Boost.Trunk to bcp so that it only considers library source files to be a dependency if a header declares something that's defined in the source.
As a result using bcp on python.hpp pulls in a lot less....
Many thanks, that's an important improvement !
but:
Serialization still gets pulled in - you may know that you're not using that particular feature, but as it's #included by the python source you're going to get it anyway.
Out of curiosity, what part of boost.python includes (and uses) serialization ? I can't seem to find it with grep.
MPI still gets pulled in - this is an artifact of some recent changes to boost.graph (which is used by python) to optionally make use of the parallel graph lib depending upon some #define.
I see boost/graph/accounting.hpp includes boost/mpi/config.hpp. Is this the culprit ? Can't that dependency chain be broken up, to not have boost.python depend on boost.mpi ? (I think this is really a general question, not specific to boost.graph. I remember seeing a quite rediculous dependency graph generated by Troy Straszheim, and breaking out of this would probably be a good idea independently from whether someone tries to break out individual components or not. (It may well reduce overall compile time.) Thanks, Stefan -- ...ich hab' noch einen Koffer in Berlin...

MPI still gets pulled in - this is an artifact of some recent changes to boost.graph (which is used by python) to optionally make use of the parallel graph lib depending upon some #define.
I see boost/graph/accounting.hpp includes boost/mpi/config.hpp. Is this the culprit ? Can't that dependency chain be broken up, to not have boost.python depend on boost.mpi ? (I think this is really a general question, not specific to boost.graph. I remember seeing a quite rediculous dependency graph generated by Troy Straszheim, and breaking out of this would probably be a good idea independently from whether someone tries to break out individual components or not. (It may well reduce overall compile time.)
There a bunch of other Boost.Graph files that include things from boost/graph/parallel which uses Boost.MPI. This was done to allow more transparent use of parallel graph data structures and algorithms, just by including <boost/graph/use_mpi.hpp>. -- Jeremiah Willcock

On 12/16/2009 02:10 PM, Jeremiah Willcock wrote:
MPI still gets pulled in - this is an artifact of some recent changes to boost.graph (which is used by python) to optionally make use of the parallel graph lib depending upon some #define.
I see boost/graph/accounting.hpp includes boost/mpi/config.hpp. Is this the culprit ? Can't that dependency chain be broken up, to not have boost.python depend on boost.mpi ? (I think this is really a general question, not specific to boost.graph. I remember seeing a quite rediculous dependency graph generated by Troy Straszheim, and breaking out of this would probably be a good idea independently from whether someone tries to break out individual components or not. (It may well reduce overall compile time.)
There a bunch of other Boost.Graph files that include things from boost/graph/parallel which uses Boost.MPI. This was done to allow more transparent use of parallel graph data structures and algorithms, just by including <boost/graph/use_mpi.hpp>.
OK, but that is different. I'm totally fine with getting a dependency on boost.mpi by explicitly including boost/graph/use_mpi.hpp. I'm not aware of boost.python doing that, however, so I don't want to pay the price for it. Thanks, Stefan -- ...ich hab' noch einen Koffer in Berlin...

There a bunch of other Boost.Graph files that include things from boost/graph/parallel which uses Boost.MPI. This was done to allow more transparent use of parallel graph data structures and algorithms, just by including <boost/graph/use_mpi.hpp>.
Where is this documented? * On a related note: the parallel graph lib does not appear in the library list at http://www.boost.org/doc/libs/1_41_0. * libs/graph-parallel/index.html is broken (points to the wrong location). * I'm having trouble understanding how the infrastructure of the library works from browsing the docs... can't find any mention of boost/graph/use_mpi.hpp, or even any complete examples for that matter. IMO it's desirable to break this dependency if possible, but I can't make any suggestions without understanding what's going on ;-) Cheers, John.

2009/12/17 John Maddock <john@johnmaddock.co.uk>:
* On a related note: the parallel graph lib does not appear in the library list at http://www.boost.org/doc/libs/1_41_0.
Apparently, it's a part of graph, not a library in its own right. From http://lists.boost.org/Archives/boost/2009/08/155277.php 2009/8/21 Jeremiah Willock:
This code could not be directly within libs/graph/ because there would be a circular dependency: graph_parallel depends on mpi, which depends on graph. I had planned to put the parallel graph code into libs/graph/parallel/ (like the headers are within boost/), but the CMake build system for Boost is unable to handle a library that is not at the top level of libs/ as far as I know. I do not believe moving the code to libs/graph/parallel would be a problem for Boost.Build. I am still open to that move (I would actually prefer graph/parallel/) if CMake is not considered to be a problem.
I missed this at the time. This is the kind of thing that the release managers should be told about. Do we need to make that clearer somewhere? I think parallel graph really should be in a subdirectory of graph. Cmake should understand that libraries in subdirectories are separate, we do it in a few other places. Is it too late to move it now? And since it's a part of graph, the main graph documentation should link to it. Probably on the first page of its documentation. Daniel

On Thu, 17 Dec 2009, Daniel James wrote:
2009/12/17 John Maddock <john@johnmaddock.co.uk>:
* On a related note: the parallel graph lib does not appear in the library list at http://www.boost.org/doc/libs/1_41_0.
Apparently, it's a part of graph, not a library in its own right. From http://lists.boost.org/Archives/boost/2009/08/155277.php
2009/8/21 Jeremiah Willock:
This code could not be directly within libs/graph/ because there would be a circular dependency: graph_parallel depends on mpi, which depends on graph. I had planned to put the parallel graph code into libs/graph/parallel/ (like the headers are within boost/), but the CMake build system for Boost is unable to handle a library that is not at the top level of libs/ as far as I know. I do not believe moving the code to libs/graph/parallel would be a problem for Boost.Build. I am still open to that move (I would actually prefer graph/parallel/) if CMake is not considered to be a problem.
I missed this at the time. This is the kind of thing that the release managers should be told about. Do we need to make that clearer somewhere?
I think parallel graph really should be in a subdirectory of graph. Cmake should understand that libraries in subdirectories are separate, we do it in a few other places. Is it too late to move it now?
And since it's a part of graph, the main graph documentation should link to it. Probably on the first page of its documentation.
I don't have a problem with the move; there would probably still need to be two library objects (even though there are no dependencies between the object files for graph and graph_parallel, just the headers), but we can put them in the same source tree and merge the docs. Are there any bjam issues with subdirectories in library directories? The redirect issue is fixed, but the new directory name is graph_parallel. I just added the links to the documentation. -- Jeremiah Willcock

2009/12/17 Jeremiah Willcock <jewillco@osl.iu.edu>:
I don't have a problem with the move; there would probably still need to be two library objects (even though there are no dependencies between the object files for graph and graph_parallel, just the headers), but we can put them in the same source tree and merge the docs. Are there any bjam issues with subdirectories in library directories? The redirect issue is fixed, but the new directory name is graph_parallel.
Since Jamfile is in the 'build' subdirectory your Jamfile won't be implicitly included in its project so I think it'll be okay. If a library has a sub-library we indicate it by putting a file called 'sublibs' in its directory. I think its main purpose is to indicate that the test results should be separate, although it might have other uses. Btw I didn't mean to suggest that there's any urgency to this change, if some time is needed to get cmake working, that's fine in my opinion.
I just added the links to the documentation.
Thanks. Daniel

On Thu, 17 Dec 2009, Daniel James wrote:
2009/12/17 Jeremiah Willcock <jewillco@osl.iu.edu>:
I don't have a problem with the move; there would probably still need to be two library objects (even though there are no dependencies between the object files for graph and graph_parallel, just the headers), but we can put them in the same source tree and merge the docs. Are there any bjam issues with subdirectories in library directories? The redirect issue is fixed, but the new directory name is graph_parallel.
Since Jamfile is in the 'build' subdirectory your Jamfile won't be implicitly included in its project so I think it'll be okay. If a library has a sub-library we indicate it by putting a file called 'sublibs' in its directory. I think its main purpose is to indicate that the test results should be separate, although it might have other uses. Btw I didn't mean to suggest that there's any urgency to this change, if some time is needed to get cmake working, that's fine in my opinion.
I don't know how to get CMake working, and last time I asked him Doug said it wasn't possible. Doing the move otherwise wouldn't be too hard once we come to a firm decision on it. -- Jeremiah Willcock

Jeremiah Willcock wrote:
On Thu, 17 Dec 2009, Daniel James wrote:
2009/12/17 Jeremiah Willcock <jewillco@osl.iu.edu>:
I don't have a problem with the move; there would probably still need to be two library objects (even though there are no dependencies between the object files for graph and graph_parallel, just the headers), but we can put them in the same source tree and merge the docs. Are there any bjam issues with subdirectories in library directories? The redirect issue is fixed, but the new directory name is graph_parallel.
Since Jamfile is in the 'build' subdirectory your Jamfile won't be implicitly included in its project so I think it'll be okay. If a library has a sub-library we indicate it by putting a file called 'sublibs' in its directory. I think its main purpose is to indicate that the test results should be separate, although it might have other uses. Btw I didn't mean to suggest that there's any urgency to this change, if some time is needed to get cmake working, that's fine in my opinion.
I don't know how to get CMake working, and last time I asked him Doug said it wasn't possible. Doing the move otherwise wouldn't be too hard once we come to a firm decision on it.
Everybody can easily guess my opinion, but let me state it none the less. I do not think that technical limitation (whether perceived, or by-design, or implementation complexity) of any random build system should be considered a good reason to deviate from directory structure set forth in boost library requirements. - Volodya

On Fri, 18 Dec 2009, Vladimir Prus wrote:
Jeremiah Willcock wrote:
On Thu, 17 Dec 2009, Daniel James wrote:
2009/12/17 Jeremiah Willcock <jewillco@osl.iu.edu>:
I don't have a problem with the move; there would probably still need to be two library objects (even though there are no dependencies between the object files for graph and graph_parallel, just the headers), but we can put them in the same source tree and merge the docs. Are there any bjam issues with subdirectories in library directories? The redirect issue is fixed, but the new directory name is graph_parallel.
Since Jamfile is in the 'build' subdirectory your Jamfile won't be implicitly included in its project so I think it'll be okay. If a library has a sub-library we indicate it by putting a file called 'sublibs' in its directory. I think its main purpose is to indicate that the test results should be separate, although it might have other uses. Btw I didn't mean to suggest that there's any urgency to this change, if some time is needed to get cmake working, that's fine in my opinion.
I don't know how to get CMake working, and last time I asked him Doug said it wasn't possible. Doing the move otherwise wouldn't be too hard once we come to a firm decision on it.
Everybody can easily guess my opinion, but let me state it none the less. I do not think that technical limitation (whether perceived, or by-design, or implementation complexity) of any random build system should be considered a good reason to deviate from directory structure set forth in boost library requirements.
I have no problem with that. Have we come to a decision that we should do the move? If so, I'll do it (though it may not be until after the holidays). -- Jeremiah Willcock

On Fri, 18 Dec 2009, Vladimir Prus wrote:
Jeremiah Willcock wrote:
On Thu, 17 Dec 2009, Daniel James wrote:
2009/12/17 Jeremiah Willcock <jewillco@osl.iu.edu>:
I don't have a problem with the move; there would probably still need to be two library objects (even though there are no dependencies between the object files for graph and graph_parallel, just the headers), but we can put them in the same source tree and merge the docs. Are there any bjam issues with subdirectories in library directories? The redirect issue is fixed, but the new directory name is graph_parallel.
Since Jamfile is in the 'build' subdirectory your Jamfile won't be implicitly included in its project so I think it'll be okay. If a library has a sub-library we indicate it by putting a file called 'sublibs' in its directory. I think its main purpose is to indicate that the test results should be separate, although it might have other uses. Btw I didn't mean to suggest that there's any urgency to this change, if some time is needed to get cmake working, that's fine in my opinion.
I don't know how to get CMake working, and last time I asked him Doug said it wasn't possible. Doing the move otherwise wouldn't be too hard once we come to a firm decision on it.
Everybody can easily guess my opinion, but let me state it none the less. I do not think that technical limitation (whether perceived, or by-design, or implementation complexity) of any random build system should be considered a good reason to deviate from directory structure set forth in boost library requirements.
OK. Should I go ahead with the move from graph_parallel to graph/parallel? Does anyone have any objections? To be clear, the move is just graph_parallel to graph/parallel, with a separate build system and the same subdirectories that are there now, and still producing two separate libraries (boost_graph and boost_graph_parallel like now). -- Jeremiah Willcock

OK. Should I go ahead with the move from graph_parallel to graph/parallel? Does anyone have any objections? To be clear, the move is just graph_parallel to graph/parallel, with a separate build system and the same subdirectories that are there now, and still producing two separate libraries (boost_graph and boost_graph_parallel like now).
+1 from me. Can you also make sure that the parallel graph lib is linked to from the main graph docs (assuming that's how it's supposed to be "discovered"?) Cheers, John.

On Tue, 19 Jan 2010, John Maddock wrote:
OK. Should I go ahead with the move from graph_parallel to graph/parallel? Does anyone have any objections? To be clear, the move is just graph_parallel to graph/parallel, with a separate build system and the same subdirectories that are there now, and still producing two separate libraries (boost_graph and boost_graph_parallel like now).
+1 from me. Can you also make sure that the parallel graph lib is linked to from the main graph docs (assuming that's how it's supposed to be "discovered"?)
It is linked now -- I fixed that after the first few times that issue was mentioned. -- Jeremiah Willcock

Serialization still gets pulled in - you may know that you're not using that particular feature, but as it's #included by the python source you're going to get it anyway.
Out of curiosity, what part of boost.python includes (and uses) serialization ? I can't seem to find it with grep.
My mistake, it's pulled in by MPI.
MPI still gets pulled in - this is an artifact of some recent changes to boost.graph (which is used by python) to optionally make use of the parallel graph lib depending upon some #define.
I see boost/graph/accounting.hpp includes boost/mpi/config.hpp. Is this the culprit ? Can't that dependency chain be broken up, to not have boost.python depend on boost.mpi ? (I think this is really a general question, not specific to boost.graph. I remember seeing a quite rediculous dependency graph generated by Troy Straszheim, and breaking out of this would probably be a good idea independently from whether someone tries to break out individual components or not. (It may well reduce overall compile time.)
The problem here is present in pretty much every graph and property_map header, something like: #ifdef BOOST_GRAPH_USE_MPI #include <boost/property_map/parallel/distributed_property_map.hpp> #include <boost/property_map/parallel/local_property_map.hpp> //... #endif which means that the MPI dependency is conditional on whether BOOST_GRAPH_USE_MPI is set almost no matter what graph header you include. BTW this has an impact for build tools like bjam (probably others as well) that perform quick regex based dependency analysis rather than preprocessing to build the dependency tree. As a result the graph headers will get marked as out of date if any MPI or serialization header is out of date, even if they're not actually being used :-( John.

On 12/17/2009 07:03 AM, John Maddock wrote:
The problem here is present in pretty much every graph and property_map header, something like:
#ifdef BOOST_GRAPH_USE_MPI #include <boost/property_map/parallel/distributed_property_map.hpp> #include <boost/property_map/parallel/local_property_map.hpp>
//...
#endif
which means that the MPI dependency is conditional on whether BOOST_GRAPH_USE_MPI is set almost no matter what graph header you include.
BTW this has an impact for build tools like bjam (probably others as well) that perform quick regex based dependency analysis rather than preprocessing to build the dependency tree. As a result the graph headers will get marked as out of date if any MPI or serialization header is out of date, even if they're not actually being used :-(
Exactly. And I think this is a problem for packaging, too (which unfortunately boost developers don't seem to care much about): If you were to build a Boost.Graph binary package, what would it contain ? And what would it depend on ? If the above MPI extension was in a separate header, packagers could consider it as part of an extension package, and thus build a Boost.Graph package without it. However, as it stands, such a separation is impossible, so either this feature isn't available at all, or Boost.Graph depends on Boost.MPI (and thus Boost.Serialization, etc. etc.) (I seem to remember similar discussions with respect to dependencies on Boost.Serialization, but I don't recall whether there was any official policy that people agreed upon.) Thanks, Stefan -- ...ich hab' noch einen Koffer in Berlin...

Stefan,
I'm trying to generate a boost subset that allows me to build boost.python and its dependencies into my own package. To do that, I ran "bcp python ...". I'm surprised to find all these components in the generated source tree:
I don't know if this helps, but a while back, I implemented dependency parser (based on regular expressions) based on header file includes. As a demonstration I ran it on boost 1.37.0 and generated dependencies from each library. It works with 1.41.0 too, but I did not yet have the time to generate pictures. Here's the link http://cheind.wordpress.com/2009/12/05/generic-dependency-parser/ Best regards, Christoph
participants (9)
-
Christoph Heindl
-
Daniel James
-
Dean Michael Berris
-
Jeremiah Willcock
-
John Maddock
-
OvermindDL1
-
Richard Webb
-
Stefan Seefeld
-
Vladimir Prus