#!/usr/bin/perl

use warnings;
use Test::More;
use Test::BDD::Cucumber::StepFile;
use Log::Log4perl;
use Data::Dumper;

my $genesis_sha512 = << "GENESIS_SHA512";
e7f37a4eea93d09cdcfdd669a97f7a1ad3c1c96395f9517b33b396af03292fe97f27f630df1ec1d261fcf396e0e2d31f0ded4f50d5181046a0609a4ef0d71450  ./bitcoin/COPYING
9a57fba56bdaf8ac851e2a336013f03f354005dee6f12f6d472882b284dd5cdae09d0f57729d877c0cf7dfee0f8bea8b602492860ae703f3f5934de15c7514ae  ./bitcoin/.gitignore
14321c5769eb37d637e2c911f668edbe20d8b712494ea585d8201345d690b6e82341e2f0c6c4572013ca24208e077c05f0a82a4096017083b2be9709f37498ab  ./bitcoin/src/base58.h
81f78bda68ebe0a6a4f5c0bea8c7c091e6056850bdd7cbb8dd68d9cb3e8662beb143668ba5c3f089d9b4ae32875fca6cb1cfbfffb02865812ba3222ce2fe6778  ./bitcoin/src/bignum.h
a1812ac4e4425986e8574ebf837c6b1a84e4772e01b46e4e1caef098496226f7321a3fabc5249b55ce6365863f2c25fef0005f4bcde7188603b0805c77256bc0  ./bitcoin/src/bitcoinrpc.cpp
59cbcd0388f17cf7c4ea6c69c4034a0ced5c05d1d9ab22a1aaae0af7b95c3d3245657a049110a45ad9dd66f41a793082caab6a8a79441b93fcbfa4b4ce44574d  ./bitcoin/src/bitcoinrpc.h
0b7ca89fd0a4045ef9553ff439c4fd39dddd92069ca97b29decbc31d2f96a004e0015b453dbf4c4669555ed997ffd02f1066c43f346feb8cd0ade0b80772e863  ./bitcoin/src/checkpoints.cpp
8bd5d4bb576d5755203bc207138e556266ba6015d0f673bcd6d94b3272291bd637f019849caee47b6ae64e412439974d1409ec14c784dd430c88f252f856f266  ./bitcoin/src/checkpoints.h
64dddc1348603ea005f4f5297ea6d51074fead3dd8d1256c1a4c2a678fef1abcb58d148ebb9eb3716e200e27abf6d07c19d1cf6fcbb4e1b9dcba59fde8eae324  ./bitcoin/src/crypter.cpp
03b2badb8a68951e41fddea52aa38e5fb3838f1c7f6a9eb7c7297a32455176fa1f75df422dd6a9e41e8e75d61d368d5ef62cc7e558f4d4c32e3cb437a685be2a  ./bitcoin/src/crypter.h
6c7b584c387898ceee4c76d4bc56d7400105807885b5b497089f99849e04f57a2e5c775b206765f5900c3c83967c6e2a0100dab71f314b1d28b01caaa67667cc  ./bitcoin/src/db.cpp
1a4b9bd666180acf944d189ffd5b89da0f1c0d7b60223fe7f16f73a7d90bdd2a75b7d46805738ea3da36ae766b0aa4a5d29283b5f4ef8a77aae991cf990ae0cc  ./bitcoin/src/db.h
bac815c59cd69f09371cbc605c3365056b02529d4fc0cd68026b6dc0304f12dafcda86479f52191f20f14b87c56006306e362020ba7a0651cce2bda87db547ac  ./bitcoin/src/headers.h
9ea336b2061c743c7f9fd590a02546616d8e3fd0dee8c9a15bb9a24e8e6138fb48f9b9be4b7452ce1e0eb4e69e8882d2b5f03ef2d6d0b50fdb9e0a869719ecfc  ./bitcoin/src/init.cpp
b98a9164befdea031d670d65eddf8dda79aa277e71114390b0f83ccefcf580d078b1b85bef27006ba4c429488eb26316f156023c33bf037b82a3283f8ffc3e83  ./bitcoin/src/init.h
fc9388561ae8af72ab6f10816cacd133746de668b500bae02c239b129dc5e190794a94d7569b7ecbd294844bfe3c2a3a2b5c4e2a0a5f3aa3170da498a8d0724b  ./bitcoin/src/irc.cpp
960a1a96aabf8154dfe3619e5198f52cadc493d949ce647cba3dc4cbc69ab03c392f54c71f03a8e2d11070966d35a33eb7fea096d3799439d9583d32d0664e10  ./bitcoin/src/irc.h
54363e1ade4f6518fbec710eec2c62db4d1de18b812b8cdc8059946602f98ffedf47a92444225f8aec3967b86453f984fd1bc6890c41bfbed4b7e2d625cd826a  ./bitcoin/src/json/json_spirit_error_position.h
1499b4cbdae705dfb050f0376961bc5cf0994199f995fbafb37edae20f92bb8fca802627991acdc7216339981b9e00262782d5f59a30403e41769756aef2ba6a  ./bitcoin/src/json/json_spirit.h
78609cf3f6735e920dc08e5b1ff0139b675256471f95aca9659066db7163a264f005128cf7e1be38d34b3828ab313e125a29ba20fa2db69762e22e952a506d93  ./bitcoin/src/json/json_spirit_reader.cpp
28f2d586e50555e9c1c86f6d9cc39288c49de44f90b81793194f6d3af2bb53fe64d8d360e418a50de4d1ad91a02b4b464658847bc343ea5a45d96d5af7628d79  ./bitcoin/src/json/json_spirit_reader.h
2030127c7941b905d7c30163b0333c87b8a517b897113ca6e1564b0fc9a0fc81ef9d973814ddffe2a5bea0f7c0ca0c0bdb43cc035d9587b9147ba6b73c8a6138  ./bitcoin/src/json/json_spirit_reader_template.h
b1e6947f1078775d2b3a0bcc3bba32679012e21a25e47ca6558c43b254fd2b5763e19dce5c47d7d3c4b5d9d8a162d136774f37b6936ea12b91822902664761b2  ./bitcoin/src/json/json_spirit_stream_reader.h
349f1aef927da56ca3c7abf019b5baa230698047cdb2786c812f2f202d7f5d7831453681775d528052a9bc9fcd3182d18885fae8e8ca57f6e69151aa0d17267e  ./bitcoin/src/json/json_spirit_utils.h
c8da4081afddce1a03290639b288bb0c9ee55447aa5b3dfacbda7a6f1c3b2dd1758126d498e08485cbe877222a211e7af8e0169c17170854838e8a2406d67dbf  ./bitcoin/src/json/json_spirit_value.cpp
c2bcdc1e04f52791173bcd0af2c7cfe63b6953ba108b2590f98df767899ca15616c984febc4a9076720586b254d256b8a1c023dd5431dd88df939f9519baf18f  ./bitcoin/src/json/json_spirit_value.h
849c5978099870a2432e75ad7f5cca8c95c6c348ca2f59fc5af2bce1fe162f1e0f9e54230b090cd0a25280b44dd06a94f8e3d607fe253916af080d0e9732909d  ./bitcoin/src/json/json_spirit_writer.cpp
9f6723bd7d02f878bdbf7f1f62e124fcfa1954e26969b99a1295918e2cc822b72b6e3856f4f9a6a806fbf547606d0bc9a1d1c4726b70212d5d445e24be456707  ./bitcoin/src/json/json_spirit_writer.h
786a2ff2f1887f12494a318da01915b682d5b0059bbe0d3fdefc538c911883da54e0a111d2fbf962914c62fda8caaf01613cfaee8fb7fe74f61754d11d4f53b4  ./bitcoin/src/json/json_spirit_writer_template.h
881a2aebb27224d7b4101b97bad2b6dccd833968f2c7bfb5d3b9c06ec0a4f6b68ab10111ca247f1da024f475fb23ab3e96dc5b50226ec5df4dae75f0b98ba71c  ./bitcoin/src/json/LICENSE.txt
6b2389129dec411d013d754eaebc169a23f60b2169dc41cced21248a603ced46dfdc64e016c082a154af87784049333be75c91fb08265306a3bdc2bc0af2e6c5  ./bitcoin/src/key.h
d11a428a6fd4d8431cce1195406dff39b0a585a0f44c6156a07a33e02c61d711220747b25bf9c341e88deae60719c1ddeb03df016f7374b966b3a0b830e6f98a  ./bitcoin/src/keystore.cpp
247c94ea309f95ddc3b90dcd41dd9212bd5269e8772816bb272a1152422cc1c50bead6370495043a9abc924e119c926d55ecd7f39d1022c7d4eb50718188a641  ./bitcoin/src/keystore.h
e37a9eb6a10745a2b0f52aacd915809961d5663185cce5792862579d340d6c98c1633a669a04fcd76835839ee13fda982e9b8ed3f190de24583f1a50167dee3b  ./bitcoin/src/main.cpp
06542e40fa8b01bbfe6964e46b6ffdf605e42f2daad2a14a64c3d70fd72a3adda5ade3adae4d5016397f2c98249583d9b72462ff66e7ea4704e20083a639094a  ./bitcoin/src/main.h
a2bbf273fb5d7681b473c79c9e8ca64eaba740e76b4d7276072cdf2d36726d83e92744344a31016cc05104c54df4a9b030b429f1da32a095243555dcc61af2cc  ./bitcoin/src/makefile.linux-mingw
e7748ee5e13edd5b95c8ffcd5f4909ff4f7cf98961a7581028adaf25f6ff79ca51d520811d06fca8ced7efa1fec31e5f06e90f672b8c37b3d62acf50ee744c01  ./bitcoin/src/makefile.unix
b72b573ba77b095e2497e297ba5b02aa68317f67438ee070fee86e129a95b85dc9b5ca98e96441bb2b3b98263dd88630990c913affbabf890641f349d1c6da47  ./bitcoin/src/net.cpp
ae473b8d2838555df527e16ac7cae7dfff39bfd68769b1fcabb1f847e29e1245af78799942e790016c376a76e112b9ec16d2d7d5f52736e3cc72e45432706d3b  ./bitcoin/src/net.h
a83fd14f7d3fb94e67062c70e789ea554d8ddba74d397a794498fd1e89c18cc7ad37aa32ef4109e9fd0714bd5f418c83d6d0af799556735b8cb9c5d5c3163002  ./bitcoin/src/noui.h
68fbcbebe57013e70f798ec673d6c554cf0b118f41a56baf92d53686f8d24fda670ed6dda23c6cbab630dfaf8cbf6d6a52a6815ac3680b24dad99b1305de6279  ./bitcoin/src/obj/.gitignore
68fbcbebe57013e70f798ec673d6c554cf0b118f41a56baf92d53686f8d24fda670ed6dda23c6cbab630dfaf8cbf6d6a52a6815ac3680b24dad99b1305de6279  ./bitcoin/src/obj/nogui/.gitignore
68fbcbebe57013e70f798ec673d6c554cf0b118f41a56baf92d53686f8d24fda670ed6dda23c6cbab630dfaf8cbf6d6a52a6815ac3680b24dad99b1305de6279  ./bitcoin/src/obj-test/.gitignore
68fbcbebe57013e70f798ec673d6c554cf0b118f41a56baf92d53686f8d24fda670ed6dda23c6cbab630dfaf8cbf6d6a52a6815ac3680b24dad99b1305de6279  ./bitcoin/src/obj/test/.gitignore
09c7f4cc1247b2ec45ffdae139fe2574dae0eb4cd40d0e48cfd5de49033ab1f4242e564020e4af5418b12e7a78430c87d58b1d4829c837b9dae47d1c1cd32382  ./bitcoin/src/protocol.cpp
eb06ffb5a1d9a725cce5c48fabf4ea4e9147aceb065acc54ae21c6d4b4065ebf5715d2dc88d3934312517a15247ff689711ede12328f5b8deadb6e2b43253c35  ./bitcoin/src/protocol.h
2118eed5cb752a2e6556fed97925061c2b9cf87c558bd328a4aba36e51d72255d45ba461889587426db60d2f6405187f9eb387b29666435f984afd1f277dd8d9  ./bitcoin/src/qtui.h
e618531aaceecefe505689a76254da2cad45af6db44de26138e130b166d1d26b6a78d0ccf352b8c9c11878e5549010ce48b2083089e14ee026d949f06cd310f6  ./bitcoin/src/script.cpp
72636dbd07e5917231ee2b62473be7a766e0e62e573315cc48e38b524da2885803b024f0613fa52c347ba0ed19455ca9461e980018e66d5ca9b05ce0bc380693  ./bitcoin/src/script.h
0dcf98014abe06b33ab296a747e42e88770a87f8d4e408be4fc1ebe6b02312695cc129d0b58c0886bf8521b6d2c79bf6f2c33e19c03aee8f5357d8db779829ad  ./bitcoin/src/serialize.h
3dbe10940903e705be537c9b135eef6733629ee3de129c4052e95fa7983ea19416633362ad747bcf9be6ccdc8a0083ba538508afcc05a04d716f8aee752c3863  ./bitcoin/src/strlcpy.h
675daf2bc964697d1e1291e3adc0ca291f813ae5875bb2c00cb796841c16b0c6d2bc92347abbd83472f0a52abebbf596d51548e442289d9b908a148f5157d5a2  ./bitcoin/src/test/base58_tests.cpp
7b9c8bc0ca032326e19db3610e5496671165acc1273017558be36e5b00dd202ead3c6ba5c617832de6a8a5e794c718ddb94577e4becee8ffceaa224273b286ca  ./bitcoin/src/test/base64_tests.cpp
c36c01e4df144c9377d84fbc7c80cc735f42dde2a726a43729362a9efeb9fa15f7efd8d70cf0858a16e091168323067edd5b9c05efea62b6631f010b58f3cf75  ./bitcoin/src/test/Checkpoints_tests.cpp
a025dbc1426005b603c696e86b278ad6f7730e16b91433747844ea7931cb631715a2b50b677f4e96a9682f62a8e65c01673b194b791b9847476fa3406122083a  ./bitcoin/src/test/DoS_tests.cpp
b59e346dcf8e4917f1415c6ce23df63716989b9f8b9182ae767a76900c56f300f75fafc89e879f06b6dd5c5d5d82c37d9b695a1b6218e527d253892dc3a9cf95  ./bitcoin/src/test/miner_tests.cpp
8dc10490739fe1fff46b553121622b8ac1f7b6b90210a56900dde6b85f44fed7287dcc2f773a8d64aded5c1b242f587132d3bc1e37ce21c5fff315af913b8fc1  ./bitcoin/src/test/README
d85bd1a00f042862691d5946713e18c1121680d0c600734a1f3bec3e52c05cbac3c9f4271dcf23c7f29694ef6c348f8acd439558bc6342aac307493881607349  ./bitcoin/src/test/script_tests.cpp
b7d5cd60b26b2c0fe099d55583de367fb296849973cd2a7047107c0ad45c229c7aeabd5a8c533d497c2cecffbdf241c3ea36be2df3854efb7f4ede96169c0700  ./bitcoin/src/test/test_bitcoin.cpp
dd7e9d9bcd4f8b307f869bff0182fcc3a8a8257626d64e156970d51dee4c852f9bfb687f9283367433f2ee05ae34db18557d6f6a54a1c58a575da2e1f4256b6e  ./bitcoin/src/test/transaction_tests.cpp
851f66e402605e8572872fc93840d691f783af2ec35aaf64af077d45537ff171420bc58b49441ce7b0f133aaf216813023bd20776e4baa7821649633feae65e0  ./bitcoin/src/test/uint160_tests.cpp
a492774b18a36458911f28049d0d24027d7398a32da3d9ea5af401fe2229d00a33be948edfbcf2d9b765ae2a83c74e856afb7f4ee3f8f3d411574506911baa20  ./bitcoin/src/test/uint256_tests.cpp
1360397ac0c494d5003656deb41494de4480c56bbe46254a09f193682a9e7813fe133a45c93699835e6de89951c350ad2a7e59bcf8b1307a7670cc1db5f22e24  ./bitcoin/src/test/util_tests.cpp
3436729b55463ebb34788a47a8856d47ba7ebc27f447c5ff73b8727897d7c468716d8313e9b613e7889a7c3dffa6e577d77149ae8c4c415fb41ce3fc5cc6d852  ./bitcoin/src/uint256.h
4b0f7b3a7757336b6e5c349d89170bfc4b4c40a04e0ec3fccf0b155314689c781deb9590ab05daa8af20a123e2f3cad55c5af1244700197a3530d0d4699d32c5  ./bitcoin/src/util.cpp
04d09e92edd13820ea292bc0c0f66a9bc6f31c4020204817de56b7ae795c660dd47d7442d32403ba58fdc75ed1985174f6c507bcde7ee988a70185ba22fbb418  ./bitcoin/src/util.h
dea54bd209fed8405bc3674fddd237414b6c49d00b81969c22fd3f38d24d8a2b95c9e20af3d9a0cfcc32b0d241f9a29b8742379c944dbd8d9c16120693aa4988  ./bitcoin/src/wallet.cpp
86f5e1ca584e6aa01b956278ea06eff4f79b58ca386c490fe605384923f90fcc710fd6bf2f14926d5dfd43e17fc5655a0150b32bc750f05506baf439255c8e30  ./bitcoin/src/wallet.h
GENESIS_SHA512

my $verifyall_sha512 = << "END_VERIFYALL_SHA512";
e7f37a4eea93d09cdcfdd669a97f7a1ad3c1c96395f9517b33b396af03292fe97f27f630df1ec1d261fcf396e0e2d31f0ded4f50d5181046a0609a4ef0d71450  ./bitcoin/COPYING
9a57fba56bdaf8ac851e2a336013f03f354005dee6f12f6d472882b284dd5cdae09d0f57729d877c0cf7dfee0f8bea8b602492860ae703f3f5934de15c7514ae  ./bitcoin/.gitignore
e4fa4700d17d7da955e3ee980c4a4315e44655dafdec0a4657278e174fa92a187de81c121d30b85a86fd0fe4334867ca73090142c58a3d51083f4ebe7dd4b35c  ./bitcoin/src/base58.h
81f78bda68ebe0a6a4f5c0bea8c7c091e6056850bdd7cbb8dd68d9cb3e8662beb143668ba5c3f089d9b4ae32875fca6cb1cfbfffb02865812ba3222ce2fe6778  ./bitcoin/src/bignum.h
ede2e19dd0ce3d03f54689cbeda30b4b36152f7e532b3d34f0f8c55bb292f7d25c149b88162d96a8208997237a32566d0e555aa7105bfed8175983d80ad892e6  ./bitcoin/src/bitcoinrpc.cpp
59cbcd0388f17cf7c4ea6c69c4034a0ced5c05d1d9ab22a1aaae0af7b95c3d3245657a049110a45ad9dd66f41a793082caab6a8a79441b93fcbfa4b4ce44574d  ./bitcoin/src/bitcoinrpc.h
30d21253854354e384e2e900641c6fc7ca94f591487bd685f6e49310da9f63c1b201910fa8882e34c4eba2032a0b8a246d3c5617f215ddfeff3598fbd773e291  ./bitcoin/src/checkpoints.cpp
8bd5d4bb576d5755203bc207138e556266ba6015d0f673bcd6d94b3272291bd637f019849caee47b6ae64e412439974d1409ec14c784dd430c88f252f856f266  ./bitcoin/src/checkpoints.h
195bde01368dc6b69e0f9d5046b2dd83f1f2345393e88382a3838efac8b6635c5992f2f8599d0ad3913b4a4b8c144cad7c7e714e7c2f96aa15a86ba820b27321  ./bitcoin/src/crypter.cpp
03b2badb8a68951e41fddea52aa38e5fb3838f1c7f6a9eb7c7297a32455176fa1f75df422dd6a9e41e8e75d61d368d5ef62cc7e558f4d4c32e3cb437a685be2a  ./bitcoin/src/crypter.h
66f81f6da997109f4d34ca654d30e24cb850fa87a6fbe6a045c6cb1a9f6d47d979fb4e25a0bbb35064c1259cda3c7b5ff12f68d9c22c1acf45299dbb4ed72317  ./bitcoin/src/db.cpp
1a4b9bd666180acf944d189ffd5b89da0f1c0d7b60223fe7f16f73a7d90bdd2a75b7d46805738ea3da36ae766b0aa4a5d29283b5f4ef8a77aae991cf990ae0cc  ./bitcoin/src/db.h
b86114b5b74d2b9e737798f78804439c5cdd0ae42440615c57fc85cb0ac7d8b8a454d2ef44048db6af0ca00a938178173eece431b273462dbc299c1501b86600  ./bitcoin/src/headers.h
ff7009f672bf400a42d1d7afb6e58aaf1c29d9c219fad51c5f17000243a485e92bbb250d3f4bbec3f0717d00fad620c294d537832671f20c0979fb3f1383779b  ./bitcoin/src/init.cpp
b98a9164befdea031d670d65eddf8dda79aa277e71114390b0f83ccefcf580d078b1b85bef27006ba4c429488eb26316f156023c33bf037b82a3283f8ffc3e83  ./bitcoin/src/init.h
54363e1ade4f6518fbec710eec2c62db4d1de18b812b8cdc8059946602f98ffedf47a92444225f8aec3967b86453f984fd1bc6890c41bfbed4b7e2d625cd826a  ./bitcoin/src/json/json_spirit_error_position.h
1499b4cbdae705dfb050f0376961bc5cf0994199f995fbafb37edae20f92bb8fca802627991acdc7216339981b9e00262782d5f59a30403e41769756aef2ba6a  ./bitcoin/src/json/json_spirit.h
78609cf3f6735e920dc08e5b1ff0139b675256471f95aca9659066db7163a264f005128cf7e1be38d34b3828ab313e125a29ba20fa2db69762e22e952a506d93  ./bitcoin/src/json/json_spirit_reader.cpp
28f2d586e50555e9c1c86f6d9cc39288c49de44f90b81793194f6d3af2bb53fe64d8d360e418a50de4d1ad91a02b4b464658847bc343ea5a45d96d5af7628d79  ./bitcoin/src/json/json_spirit_reader.h
2030127c7941b905d7c30163b0333c87b8a517b897113ca6e1564b0fc9a0fc81ef9d973814ddffe2a5bea0f7c0ca0c0bdb43cc035d9587b9147ba6b73c8a6138  ./bitcoin/src/json/json_spirit_reader_template.h
b1e6947f1078775d2b3a0bcc3bba32679012e21a25e47ca6558c43b254fd2b5763e19dce5c47d7d3c4b5d9d8a162d136774f37b6936ea12b91822902664761b2  ./bitcoin/src/json/json_spirit_stream_reader.h
349f1aef927da56ca3c7abf019b5baa230698047cdb2786c812f2f202d7f5d7831453681775d528052a9bc9fcd3182d18885fae8e8ca57f6e69151aa0d17267e  ./bitcoin/src/json/json_spirit_utils.h
c8da4081afddce1a03290639b288bb0c9ee55447aa5b3dfacbda7a6f1c3b2dd1758126d498e08485cbe877222a211e7af8e0169c17170854838e8a2406d67dbf  ./bitcoin/src/json/json_spirit_value.cpp
c2bcdc1e04f52791173bcd0af2c7cfe63b6953ba108b2590f98df767899ca15616c984febc4a9076720586b254d256b8a1c023dd5431dd88df939f9519baf18f  ./bitcoin/src/json/json_spirit_value.h
849c5978099870a2432e75ad7f5cca8c95c6c348ca2f59fc5af2bce1fe162f1e0f9e54230b090cd0a25280b44dd06a94f8e3d607fe253916af080d0e9732909d  ./bitcoin/src/json/json_spirit_writer.cpp
9f6723bd7d02f878bdbf7f1f62e124fcfa1954e26969b99a1295918e2cc822b72b6e3856f4f9a6a806fbf547606d0bc9a1d1c4726b70212d5d445e24be456707  ./bitcoin/src/json/json_spirit_writer.h
786a2ff2f1887f12494a318da01915b682d5b0059bbe0d3fdefc538c911883da54e0a111d2fbf962914c62fda8caaf01613cfaee8fb7fe74f61754d11d4f53b4  ./bitcoin/src/json/json_spirit_writer_template.h
881a2aebb27224d7b4101b97bad2b6dccd833968f2c7bfb5d3b9c06ec0a4f6b68ab10111ca247f1da024f475fb23ab3e96dc5b50226ec5df4dae75f0b98ba71c  ./bitcoin/src/json/LICENSE.txt
6b2389129dec411d013d754eaebc169a23f60b2169dc41cced21248a603ced46dfdc64e016c082a154af87784049333be75c91fb08265306a3bdc2bc0af2e6c5  ./bitcoin/src/key.h
d11a428a6fd4d8431cce1195406dff39b0a585a0f44c6156a07a33e02c61d711220747b25bf9c341e88deae60719c1ddeb03df016f7374b966b3a0b830e6f98a  ./bitcoin/src/keystore.cpp
247c94ea309f95ddc3b90dcd41dd9212bd5269e8772816bb272a1152422cc1c50bead6370495043a9abc924e119c926d55ecd7f39d1022c7d4eb50718188a641  ./bitcoin/src/keystore.h
92038390413f77b55e19439738e87c21bd5b2313dc6edad78bcc8bf722dde82623a31a56a87b0182e75e6824fc709dc216fb9cb159b49a16e212e3a5ded93f58  ./bitcoin/src/main.cpp
ff2bf8f8147dd8df5e1ef1bcea9b0159d3f83c1e30befef56415b99305aa99161ac1c05efb48be87a383ffb6d621fd3761bfb3e4952ca244a6e1398ca3c71dc6  ./bitcoin/src/main.h
929157d5e139336f38e98555f14fc125c4217c23eba941086b648147e39fcec9ecab632567fc3295e58826fedf6239d5cc0cd028f4e78fd56ae868b795d2de02  ./bitcoin/src/makefile.unix
31eb2cbdf4f83f10ae8a7cdd3a69312ba6eafbecfafbeddf7546ce99847bd4f2a674037e2b89a0a7b91c37127d9770501c265a7977edb0ae0b3a5964272692f9  ./bitcoin/src/net.cpp
d18800dfc6abc874cf8f8f3fdf9bbfa000b6611760c571ef64089894b3ac92303c8891aff55d66648d6b8c0033bfab31e40aa6562a0bc75e2a9c0950175a733b  ./bitcoin/src/net.h
a83fd14f7d3fb94e67062c70e789ea554d8ddba74d397a794498fd1e89c18cc7ad37aa32ef4109e9fd0714bd5f418c83d6d0af799556735b8cb9c5d5c3163002  ./bitcoin/src/noui.h
68fbcbebe57013e70f798ec673d6c554cf0b118f41a56baf92d53686f8d24fda670ed6dda23c6cbab630dfaf8cbf6d6a52a6815ac3680b24dad99b1305de6279  ./bitcoin/src/obj/.gitignore
68fbcbebe57013e70f798ec673d6c554cf0b118f41a56baf92d53686f8d24fda670ed6dda23c6cbab630dfaf8cbf6d6a52a6815ac3680b24dad99b1305de6279  ./bitcoin/src/obj/nogui/.gitignore
68fbcbebe57013e70f798ec673d6c554cf0b118f41a56baf92d53686f8d24fda670ed6dda23c6cbab630dfaf8cbf6d6a52a6815ac3680b24dad99b1305de6279  ./bitcoin/src/obj-test/.gitignore
68fbcbebe57013e70f798ec673d6c554cf0b118f41a56baf92d53686f8d24fda670ed6dda23c6cbab630dfaf8cbf6d6a52a6815ac3680b24dad99b1305de6279  ./bitcoin/src/obj/test/.gitignore
35effbc7f73cdbda92148be58171b2337c090a7997eb3b02daf9a88287b4315c80d7fa5edf403be9cf958969c0c7e0c1b578c10f146ee0ea9b2965a1f97971bf  ./bitcoin/src/protocol.cpp
cce0473250e39dd85773246ea0cd40584c77daa7fcba7ff98836d8b9bdbff2f3e229f385c43c73503ca9e244219708b2299600db28d1d7df442c92f22ed74485  ./bitcoin/src/protocol.h
e618531aaceecefe505689a76254da2cad45af6db44de26138e130b166d1d26b6a78d0ccf352b8c9c11878e5549010ce48b2083089e14ee026d949f06cd310f6  ./bitcoin/src/script.cpp
796b2ab92a49e29b5873be0d63d732d1b973855de76062492190687c57fdbefc069091df6306a0eee86ad5717c8fa90774ea9b8589cba2d9138b544c37e7177f  ./bitcoin/src/script.h
bc602bfbc512259fbb6c01f2c1633ff142966bf0752612e9a488cee8a95da7921b98abe646e2f7002243f1981939372e0b53948646398e40525ed442c377f449  ./bitcoin/src/serialize.h
3dbe10940903e705be537c9b135eef6733629ee3de129c4052e95fa7983ea19416633362ad747bcf9be6ccdc8a0083ba538508afcc05a04d716f8aee752c3863  ./bitcoin/src/strlcpy.h
675daf2bc964697d1e1291e3adc0ca291f813ae5875bb2c00cb796841c16b0c6d2bc92347abbd83472f0a52abebbf596d51548e442289d9b908a148f5157d5a2  ./bitcoin/src/test/base58_tests.cpp
7b9c8bc0ca032326e19db3610e5496671165acc1273017558be36e5b00dd202ead3c6ba5c617832de6a8a5e794c718ddb94577e4becee8ffceaa224273b286ca  ./bitcoin/src/test/base64_tests.cpp
c36c01e4df144c9377d84fbc7c80cc735f42dde2a726a43729362a9efeb9fa15f7efd8d70cf0858a16e091168323067edd5b9c05efea62b6631f010b58f3cf75  ./bitcoin/src/test/Checkpoints_tests.cpp
a025dbc1426005b603c696e86b278ad6f7730e16b91433747844ea7931cb631715a2b50b677f4e96a9682f62a8e65c01673b194b791b9847476fa3406122083a  ./bitcoin/src/test/DoS_tests.cpp
b59e346dcf8e4917f1415c6ce23df63716989b9f8b9182ae767a76900c56f300f75fafc89e879f06b6dd5c5d5d82c37d9b695a1b6218e527d253892dc3a9cf95  ./bitcoin/src/test/miner_tests.cpp
8dc10490739fe1fff46b553121622b8ac1f7b6b90210a56900dde6b85f44fed7287dcc2f773a8d64aded5c1b242f587132d3bc1e37ce21c5fff315af913b8fc1  ./bitcoin/src/test/README
d85bd1a00f042862691d5946713e18c1121680d0c600734a1f3bec3e52c05cbac3c9f4271dcf23c7f29694ef6c348f8acd439558bc6342aac307493881607349  ./bitcoin/src/test/script_tests.cpp
b7d5cd60b26b2c0fe099d55583de367fb296849973cd2a7047107c0ad45c229c7aeabd5a8c533d497c2cecffbdf241c3ea36be2df3854efb7f4ede96169c0700  ./bitcoin/src/test/test_bitcoin.cpp
dd7e9d9bcd4f8b307f869bff0182fcc3a8a8257626d64e156970d51dee4c852f9bfb687f9283367433f2ee05ae34db18557d6f6a54a1c58a575da2e1f4256b6e  ./bitcoin/src/test/transaction_tests.cpp
851f66e402605e8572872fc93840d691f783af2ec35aaf64af077d45537ff171420bc58b49441ce7b0f133aaf216813023bd20776e4baa7821649633feae65e0  ./bitcoin/src/test/uint160_tests.cpp
a492774b18a36458911f28049d0d24027d7398a32da3d9ea5af401fe2229d00a33be948edfbcf2d9b765ae2a83c74e856afb7f4ee3f8f3d411574506911baa20  ./bitcoin/src/test/uint256_tests.cpp
1360397ac0c494d5003656deb41494de4480c56bbe46254a09f193682a9e7813fe133a45c93699835e6de89951c350ad2a7e59bcf8b1307a7670cc1db5f22e24  ./bitcoin/src/test/util_tests.cpp
bff76a65e51957209d7753535337d23927a9a1acc829c5bc5d9f266a1b8c004b555daae74e75b616ca0088f8be0739f082d64edc2387495b3675bebd25658fd3  ./bitcoin/src/uint256.h
3dcfe5f29728dcd34a6dfe23e9cd17e5f4a332a8d2e7444355106c8c63436cf54892424df2018756c2e109463fd87728fc668a5a03914a4aa3f30bb90403b433  ./bitcoin/src/util.cpp
44bd62e864ed9400105aeea2e2ef6499f971577fd28b9c8dc52ef72dcdb4d4928168037cd7d7fca718e5d5a2d4d7c19c65f5b45c87d814d6e24c0d014b307477  ./bitcoin/src/util.h
bdc4fc472be4a86fb91fa69368faace04414fdeee5b8c82795e31d37e21581b973caf7f3e9ccc27d487944a5782e3b59615180eab87c8b3e81242901f3039e4d  ./bitcoin/src/wallet.cpp
86f5e1ca584e6aa01b956278ea06eff4f79b58ca386c490fe605384923f90fcc710fd6bf2f14926d5dfd43e17fc5655a0150b32bc750f05506baf439255c8e30  ./bitcoin/src/wallet.h
END_VERIFYALL_SHA512

Given qr/Load the (\S+) Mod/, sub {
  use_ok($1);
};

Then qr/Init the Command Mod/, sub {
  S->{'Command'} = Command->new;
};

Then qr/I set the work directory as "(.*)"/, sub {
  my $cmd = S->{'Command'};
  $cmd->setWorkDir($1);
};

Then qr/I set the path to V as "(.*)"/, sub {
  my $cmd = S->{'Command'};
  $cmd->setBinPath($1);
};

Then qr/I set the home directory/, sub {
  my $cmd = S->{'Command'};
  my $home = `echo \$HOME`; chomp($home);
  $cmd->setHomeDir($home);
};

sub getWorkDir {
  my $cmd = S->{'Command'};
  return $cmd->getWorkDir;
};

sub getBinPath {
  my $cmd     = S->{'Command'};
  my $workDir = getWorkDir();
  return $cmd->getBinPath;
};

sub getHomeDir {
  my $cmd = S->{'Command'};
  return $cmd->getHomeDir;
};

Then qr/validate V output without any flags on first run/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my @got     = `$binPath/v.pl`;

  like($got[0], qr/Unknown or missing option!/, "Validate V without flags, first run test");
};

Then qr/validate option "(.*)" without an argument/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my $option  = $1;
  my @got     = `$binPath/v.pl $option`;

  like($got[0], qr/Option \"$option\" requires arguments!/, "Option without arguments test.");
};

Then qr/validate option "(.*)" with "(.*)" argument/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my $option  = $1;
  my $argNum  = $2;
  my @got     = ();
  if($argNum eq "1") {
    @got = `$binPath/v.pl $option blah`;
    like($got[0], qr/$option requires two arguments/, "Argument count test.");
  }
  if($argNum eq "2") {
    @got = `$binPath/v.pl $option blah blah`;
    like($got[0], qr/$option requires three arguments/, "Argument count test.");
  }
};

Then qr/validate mirrors "(.*)" and sigs from "(.*)"/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my $mirrors = $1;
  my $sigs    = $2;
  my @got     = `$binPath/v.pl m mirror`;

  like($got[0], qr/$sigs/, "Mirrors sig test.");
  like($got[1], qr/$mirrors/, "Mirrors url test.");
};

Then qr/validate init "(.*)" short flag output/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my @got     = `$binPath/v.pl $1`;

  my $got0 = shift @got;
  my $got1 = shift @got;
  like($got0, qr/Full vpatch sync complete to \"$binPath\/patches\"/, "V init patches sync test.");
  like($got1, qr/Seal sync complete to \"$binPath\/\.seals\"/, "V init seals sync test.");
  foreach(@got) {
    if($_ =~ /Usage: v\.pl/) {
      ok(1, "Long help detection.");
    }
  }
};

Then qr/validate init "(.*)" long flag output/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my @got     = `$binPath/v.pl $1`;

  like($got[0], qr/patches dir exists! Skipping initial Vpatch sync/, "V init second patches sync rejected test.");
  like($got[1], qr/$binPath\/\.seals dir exists! Skipping initial Seal sync/, "V init second seals sync rejected test.");
};

Then qr/validate init "(.*)" without option argument/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my $option  = $1;
  my @got     = `$binPath/v.pl $option 2>&1`;

  like($got[0], qr/Option \"$option\" requires arguments!/, "V init no option argument test.");
};

Then qr/validate init "(.*)" with URL "(.*)" with patchdir "(.*)" and sealdir "(.*)"/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my $option  = $1;
  my $URL     = $2;
  my $pdir    = $3;
  my $sdir    = $4;
  my @got     = `$binPath/v.pl $option $URL $pdir $sdir`;

  if(-d $pdir) { ok(1); } else { ok(0); }
  if(-e "$pdir/genesis.vpatch") { ok(1); } else { ok(0); }
  if(-d $sdir) { ok(1); } else { ok(0); }
  if(-e "$sdir/genesis.vpatch.mod6.sig") { ok(1); } else { ok(0); }
};

Then qr/validate help "(.*)" flag output/, sub {
  my $cmd      = S->{'Command'};
  my $binPath  = getBinPath();
  my @got      = `$binPath/v.pl $1`;

  foreach(@got) {
    if($_ =~ /Usage: v\.pl/) { ok(1, "Long Help Message Test"); }
    if($_ =~ /Prints this full help message/) { ok(1, "Long Help Message Test"); }
  }
};

Then qr/validate short help message/, sub {
  my $cmd      = S->{'Command'};
  my $binPath  = getBinPath();
  my @got      = `$binPath/v.pl asdfasdf`;

  like($got[0], qr/Unknown option/, "Short help message test.");
  like($got[$#got-2], qr/.*\(h | \? | help\).*/, "Short help message test.");
};

Then qr/validate version message/, sub {
  my $cmd      = S->{'Command'};
  my $binPath  = getBinPath();
  my @got      = `$binPath/v.pl v`;

  like($got[3], qr/^#\s+Version: 99995 K\s+#$/, "Test Version");
};

Then qr/validate wot "(.*)" flag output/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my @got     = `$binPath/v.pl $1`;
  my @wot = (
    "asciilifeform:17215D118B7239507FAFED98B98228A001ABFFC7:Stanislav Datskovskiy <stas\@loper-os.org>",
    "ben_vulpes:4F7907942CA8B89B01E25A762AFA1A9FD2D031DA:Ben Vulpes <benkay\@gmail.com>",
    "mircea_popescu:6160E1CAC8A3C52966FD76998A736F0E2FB7B452:Mircea Popescu (Acest articol are apriori avantajul aliteralitatii alaturi.) <office\@polimedia.us>",
    "mod6:027A8D7C0FB8A16643720F40721705A8B71EADAF:mod6 (mod6) <modsix\@gmail.com>",
    "punkman:F28E0095843B91CB22E7D65533588BE08B232B13:punkman",
    "trinque:FC66C0C5D98C42A1D4A98B6B42F9985AFAB953C4:Michael Trinque <mike\@trinque.org>"
  );
  foreach my $o (@got) {
    foreach my $w (@wot) {
      if($o eq $w) {
        ok($o eq $w, "WoT flag test.");
        delete $wot[$w];
      }
    }
  }
};

Then qr/validate wot "(.*)" flag output/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my @got     = `$binPath/v.pl $1`;
  my @wot = (
    "asciilifeform-B98228A001ABFFC7:17215D118B7239507FAFED98B98228A001ABFFC7:Stanislav Datskovskiy <stas\@loper-os.org>",
    "ben_vulpes-2AFA1A9FD2D031DA:4F7907942CA8B89B01E25A762AFA1A9FD2D031DA:Ben Vulpes <benkay\@gmail.com>",
    "mircea_popescu-8A736F0E2FB7B452:6160E1CAC8A3C52966FD76998A736F0E2FB7B452:Mircea Popescu (Acest articol are apriori avantajul aliteralitatii alaturi.) <office\@polimedia.us>",
    "mod6-721705A8B71EADAF:027A8D7C0FB8A16643720F40721705A8B71EADAF:mod6 (mod6) <modsix\@gmail.com>",
    "punkman-33588BE08B232B13:F28E0095843B91CB22E7D65533588BE08B232B13:punkman",
    "trinque-42F9985AFAB953C4:FC66C0C5D98C42A1D4A98B6B42F9985AFAB953C4:Michael Trinque <mike\@trinque.org>"
  );
  foreach my $o (@got) {
    foreach my $w (@wot) {
      if($o eq $w) {
        ok($o eq $w, "WoT flag test with finger");
        delete $wot[$w];
      }
    }
  }
};

Then qr/validate roots "(.*)" flag output with signatories "(.*)"/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my @got     = `$binPath/v.pl $1`;
  my $sigs    = $2;
  like($got[0], qr/Root: genesis\.vpatch \($sigs\)/, "Roots flag test.");
};

Then qr/validate leafs "(.*)" flag output with signatories "(.*)"/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my @got     = `$binPath/v.pl $1`;
  my $sigs    = $2;
  like($got[0], qr/Leaf: .*\.vpatch \($sigs\)/, "Leafs flag test.");
};

Then qr/validate antecedents "(.*)" flag output/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my @got     = `$binPath/v.pl $1`;
  like($got[0], qr/Antecedent: .*\.vpatch \(.*\) \[.*\]/, "Antecedent flag test.");
};

Then qr/validate antecedents "(.*)" without option argument/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my $option  = $1;
  my @got     = `$binPath/v.pl $1 2>&1`;

  like($got[0], qr/Option \"$option\" requires arguments!/, "V antecedents no option argument test.");
};

Given qr/vpatch to process/, sub {
  my $cmd = S->{'Command'};
  $cmd->setVpatchToProcess(@_);
};

Given qr/expected antecedents/, sub {
  my $cmd = S->{'Command'};
  $cmd->setExpectedAntecedents(@_);
};

Given qr/expected descendants/, sub {
  my $cmd = S->{'Command'};
  $cmd->setExpectedDescendants(@_);
};

Given qr/expected signatures/, sub {
  my $cmd = S->{'Command'};
  $cmd->setExpectedSignatures(@_);
};

Given qr/expected source files/, sub {
  my $cmd = S->{'Command'};
  $cmd->setExpectedSourceFiles(@_);
};

Then qr/validate output antecedents/, sub {
  my $cmd      = S->{'Command'};
  my $binPath  = getBinPath();

  my @vpdata   = @{$cmd->getVpatchToProcess->{_data}};
  my @antedata = @{$cmd->getExpectedAntecedents->{_data}};
  my @sigdata  = @{$cmd->getExpectedSignatures->{_data}};
  my @srcfiles = @{$cmd->getExpectedSourceFiles->{_data}};

  if(@vpdata == @antedata &&
     @antedata == @sigdata &&
     @sigdata == @srcfiles) {
    for($i = 0; $i < @vpdata; $i++) {
      my @ante = split /!/, $antedata[$i]->{antecedents};
      my @sigs = split /!/, $sigdata[$i]->{signatures};
      my @sf   = split /!/, $srcfiles[$i]->{source_files};

      my @out = `$binPath/v.pl a $vpdata[$i]->{vpatch}`;
      $cmd->logger->info("Test antecedent: $vpdata[$i]->{vpatch}");

      for($j = 0; $j < @out; $j++) {
        like($out[$j], qr/Antecedent: $ante[$j] \($sigs[$j]\) \[ $sf[$j] \]/, "$vpdata[$i]->{vpatch} antecedents validation test.");
      }
    }
  } else { $cmd->logger->info("ERROR: TABLE DATA INPUT SIZES DO NOT MATCH! Fail."); ok(0); }
};

Then qr/validate descendants "(.*)" flag output/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my @got     = `$binPath/v.pl $1`;
  like($got[0], qr/Descendant: .*\.vpatch \(.*\) \[.*\]/, "Descendants flag test.");
};

Then qr/validate descendants "(.*)" without option argument/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my $option  = $1;
  my @got     = `$binPath/v.pl $option 2>&1`;

  like($got[0], qr/Option \"$option\" requires arguments!/, "V descendants no option argument test.");
};

Then qr/validate output descendants/, sub {
  my $cmd      = S->{'Command'};
  my $binPath  = getBinPath();

  my @vpdata   = @{$cmd->getVpatchToProcess->{_data}};
  my @descdata = @{$cmd->getExpectedDescendants->{_data}};
  my @sigdata  = @{$cmd->getExpectedSignatures->{_data}};
  my @srcfiles = @{$cmd->getExpectedSourceFiles->{_data}};

  if(@vpdata == @descdata &&
     @descdata == @sigdata &&
     @sigdata == @srcfiles) {
    for($i = 0; $i < @vpdata; $i++) {
      my @desc = split /!/, $descdata[$i]->{descendants};
      my @sigs = split /!/, $sigdata[$i]->{signatures};
      my @sf   = split /!/, $srcfiles[$i]->{source_files};

      my @out = `$binPath/v.pl d $vpdata[$i]->{vpatch}`;
      $cmd->logger->info("Test descendant: $vpdata[$i]->{vpatch}");

      for($j = 0; $j < @out; $j++) {
        like($out[$j], qr/Descendant: $desc[$j] \($sigs[$j]\) \[ $sf[$j] \]/, "$vpdata[$i]->{vpatch} descendants validation test.");
      }
    }
  } else { $cmd->logger->info("ERROR: TABLE DATA INPUT SIZES DO NOT MATCH! Fail."); ok(0); }
};

Then qr/validate flow "(.*)" flag output/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my @got     = `$binPath/v.pl $1`;

  like($got[0], qr/genesis.vpatch \(asciilifeform, mircea_popescu, mod6, trinque\)/, "Start of flow validation test.");
  like($got[$#got], qr/asciilifeform_maxint_locks_corrected\.vpatch/, "End of flow validation test.");
};

Then qr/validate graphviz "(.*)" flag output/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my @got     = `$binPath/v.pl $1`;

  like($got[0], qr/digraph VPATCH_GRAPH/, "Graphviz flag validation test.");
};

Then qr/validate graphviz "(.*)" flag with output file/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my $flag    = $1;
  my @got     = `$binPath/v.pl $flag`;

  like($got[0], qr/Printed Graphviz dot file to/, "Graphviz flag with output file validation test.");
  my @args    = split / /, $flag;
  my @head    = `head -1 $args[1]`;
  like($head[0], qr/digraph VPATCH_GRAPH/, "Graphviz flag with output file validation test.");
};

Then qr/validate graphviz "(.*)" flag with output html file/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my $flag    = $1;
  my @got     = `$binPath/v.pl $flag`;

  like($got[0], qr/Printed Graphviz dot file to/, "Graphviz flag with output file validation test.");
  my @args    = split / /, $flag;
  my @head    = `head -1 $args[1]`;
  like($head[0], qr/digraph VPATCH_GRAPH/, "Graphviz flag with output file validation test.");

  @head       = `head -6 $args[2] | tail -1`;
  like($head[0], qr/<!-- Title: VPATCH_GRAPH Pages: 1 -->/, "Graphviz flag with html output file validation test.");
};

Then qr/validate sync wot "(.*)" flag output/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my $flag    = $1;
  my @args    = split / /, $flag;
  my @got     = `$binPath/v.pl $flag`;

  if(-d $args[1]) {
    like($got[0], qr/WoT sync complete/, "WoT Sync flag validation test.");
    ok(1, "WoT Sync directory was created.");
  }
};

Then qr/validate sync wot "(.*)" without option argument/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my $option  = $1;
  my @got     = `$binPath/v.pl $option 2>&1`;

  like($got[0], qr/Option \"$option\" requires arguments!/, "V sync-wot no option argument test.");
};

Then qr/validate sync vpatch "(.*)" flag output/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my $flag    = $1;
  my @args    = split / /, $flag;
  my @got     = `$binPath/v.pl $flag`;

  if(-d $args[2]) {
    shift @args; shift @args; my $outdir = shift @args; #remove the first three args, leaving the vpatch file names
    if(@got == @args) {
      for($i = 0; $i < @got; $i++) {
        like($got[$i], qr/$args[$i] sync complete/, "Vpatch sync flag validation.");
        if(-e "$outdir/$args[$i]") { ok(1, "Vpatch file was sync'd and created."); }
        else { ok(0, "Vpatch file not created!"); }
      }
    } else { print "GOT AND ARGS SIZES DO NOT MATCH!\n"; ok(0); }
    ok(1, "Vpatch Sync directory was created.");
  }
};

Then qr/validate sync vpatch "(.*)" without option argument/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my $option  = $1;
  my @got     = `$binPath/v.pl $option 2>&1`;

  like($got[0], qr/Option \"$option\" requires arguments!/, "V sync-vpatches no option argument test.");
};

Then qr/validate sync vpatch fails silently "(.*)" with nonexistant vpatch/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my $flag    = $1;
  my @args    = split / /, $flag;
  my @got     = `$binPath/v.pl $flag`;

  shift @args; shift @args; # remove the first two args, leaving the output dir
  if(!-e "$args[0]/$args[1]") {
    ok(1, "Vpatch sync of non-existant file validation test.");
  } else {
    ok(0, "File was created! Fail.");
  }
};

Then qr/validate sync all flag for "(.*)" vpatches with options "(.*)"/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my $vpcount = $1;
  my $flag    = $2;
  my @args    = split / /, $flag;
  my @got     = `$binPath/v.pl $flag`;

  shift @args; shift @args; # remove first two args, leaving the output dir
  if(-d $args[0]) {
    my $actual = `ls $args[0] | sort | wc -l`;
    ok($vpcount == $actual, "Sync of all vpatches validation test.");
  }
};

Then qr/validate sync all vpatches "(.*)" without option argument/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my $option  = $1;
  my @got     = `$binPath/v.pl $option 2>&1`;

  like($got[0], qr/Option \"$option\" requires arguments!/, "V sync-all-vpatches no option argument test.");
};

Then qr/validate sync seals flag for "(.*)" seals with options "(.*)"/, sub {
  my $cmd      = S->{'Command'};
  my $binPath  = getBinPath();
  my $sigcount = $1;
  my $flag     = $2;
  my @args     = split / /, $flag;
  my @got      = `$binPath/v.pl $flag`;

  shift @args; shift @args; # remove first two args, leaving the output dir
  if(-d $args[0]) {
    my $actual = `ls $args[0] | sort | wc -l`;
    ok($sigcount == $actual, "Sync of all seals validation test.");
  }
};

Then qr/validate sync seals "(.*)" without option argument/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my $option  = $1;
  my @got     = `$binPath/v.pl $option 2>&1`;

  like($got[0], qr/Option \"$option\" requires arguments!/, "V sync-seals no option argument test.");
};

Then qr/validate sync everything flag for "(.*)" vpatches "(.*)" seals with options "(.*)"/, sub {
  my $cmd        = S->{'Command'};
  my $binPath    = getBinPath();
  my $vpcount    = $1;
  my $sealscount = $2;
  my $flag       = $3;
  my @args       = split / /, $flag;
  my @got        = `$binPath/v.pl $flag`;

  shift @args; shift @args; # remove first two args, leaving the output dir
  if(-d $args[0]) {
    my $actual_vp = `ls $args[0] | sort | wc -l`;
    ok($vpcount == $actual_vp, "Sync of everything [vpatches] validation test.");
  }

  if(-d $args[1]) {
    my $actual_seals = `ls $args[1] | sort | wc -l`;
    ok($sealscount == $actual_seals, "Sync of everything [seals] validation test.");
  }
};

Then qr/validate sync everything "(.*)" without option argument/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my $option  = $1;
  my @got     = `$binPath/v.pl $1 2>&1`;

  like($got[0], qr/Option \"$option\" requires arguments!/, "V sync-everything no option argument test.");
};

When qr/delete public key "(.*)" from "(.*)"/, sub {
  my $cmd     = S->{'Command'};
  my $pubkey = $1;
  my $wotdir = $2;

  $res = `rm $wotdir/$pubkey`;
  if($res) {
    ok(0, "Delete public key. Point at new wot dir test.");
    print "Error: $res\n";
  } else {
    ok(1, "Delete public key. Point at new wot dir test.");
  }
};

Then qr/point at wot dir "(.*)" with flag "(.*)" and validate that "(.*)" is no longer in wot "(.*)"/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my $wotdir  = $1;
  my $wdflag  = $2;
  my $wotuid  = $3;
  my $wotflag = $4;
  my @got     = `$binPath/v.pl $wotflag $wdflag $wotdir`;

  my @wot = ();
  if($wotflag =~ /finger/) {
    @wot = (
      "asciilifeform-B98228A001ABFFC7:17215D118B7239507FAFED98B98228A001ABFFC7:Stanislav Datskovskiy <stas\@loper-os.org>",
      "ben_vulpes-2AFA1A9FD2D031DA:4F7907942CA8B89B01E25A762AFA1A9FD2D031DA:Ben Vulpes <benkay\@gmail.com>",
      "mircea_popescu-8A736F0E2FB7B452:6160E1CAC8A3C52966FD76998A736F0E2FB7B452:Mircea Popescu (Acest articol are apriori avantajul aliteralitatii alaturi.) <office\@polimedia.us>",
      "punkman-33588BE08B232B13:F28E0095843B91CB22E7D65533588BE08B232B13:punkman",
      "trinque-42F9985AFAB953C4:FC66C0C5D98C42A1D4A98B6B42F9985AFAB953C4:Michael Trinque <mike\@trinque.org>"
    );
  } else {
    @wot = (
      "asciilifeform:17215D118B7239507FAFED98B98228A001ABFFC7:Stanislav Datskovskiy <stas\@loper-os.org>",
      "ben_vulpes:4F7907942CA8B89B01E25A762AFA1A9FD2D031DA:Ben Vulpes <benkay\@gmail.com>",
      "mircea_popescu:6160E1CAC8A3C52966FD76998A736F0E2FB7B452:Mircea Popescu (Acest articol are apriori avantajul aliteralitatii alaturi.) <office\@polimedia.us>",
      "punkman:F28E0095843B91CB22E7D65533588BE08B232B13:punkman",
      "trinque:FC66C0C5D98C42A1D4A98B6B42F9985AFAB953C4:Michael Trinque <mike\@trinque.org>"
    );
  }

  foreach my $o (@got) {
    foreach my $w (@wot) {
      if($o eq $w) {
        like($o, qr/$w/, "WoT dir flag test.");
        delete $wot[$w];
      }
    }
  }

  my @flow = `$binPath/v.pl f $wdflag $wotdir\n`;
  like($flow[0], qr/genesis.vpatch \(asciilifeform, mircea_popescu, trinque\)/, "Start of wotdir w/flow validation test.");
  like($flow[$#flow], qr/asciilifeform_malleus_mikehearnificarum\.vpatch \(asciilifeform\)/, "End of wotdir w/flow validation test.");
};

When qr/add a test patch to the new patchdir "(.*)"/, sub {
  my $cmd      = S->{'Command'};
  my $binPath  = getBinPath();
  my $patchdir = $1;
  my $vpatch   = << "END_RELEASE_VPATCH";
diff -uNr a/bitcoin/src/db.cpp b/bitcoin/src/db.cpp
--- a/bitcoin/src/db.cpp 565faf3ef371f5e2178ae30c45b08b93415eeb92263486e68f2ac2e8f4c7900056e628804bf5c0707a90be946e0aeaebfcd0a391aab40de2e5d56e6bcbdccb1e
+++ b/bitcoin/src/db.cpp 7562db3fb7351b1dee6e8483b596220f074ed93671ef94f42f4368949b5651b46595f99ea7f8752fb0d0b36a0f043b78d5bf396fe7ffe69b5cf8a6769b024edc
@@ -3,6 +3,8 @@
 // Distributed under the MIT/X11 software license, see the accompanying
 // file license.txt or http://www.opensource.org/licenses/mit-license.php.

+// TEST v0.5.4
+
 #include "headers.h"
 #include "db.h"
 #include "net.h"
diff -uNr a/bitcoin/src/key.h b/bitcoin/src/key.h
--- a/bitcoin/src/key.h afe71ade56fae65b970ff3dfb3f14edacee0af497ae57e2d2502c9a4b4f49f3336f9d3794b72a87d185b92fc01f1a5077e1ccd63a61ac4fa9c4464c6224fd1e4
+++ b/bitcoin/src/key.h 4b36de3831e00c1d78d61174c72bd84cc709372d545ba30cf2e6798ab24cfa6272300035d45b352fbac3a0d9a0b4ce2ccc4f746c1a6c672a1e8d94df50090ffb
@@ -2,6 +2,9 @@
 // Copyright (c) 2009-2012 The Bitcoin developers
 // Distributed under the MIT/X11 software license, see the accompanying
 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
+
+// TEST v0.5.4
+
 #ifndef BITCOIN_KEY_H
 #define BITCOIN_KEY_H

diff -uNr a/bitcoin/src/main.cpp b/bitcoin/src/main.cpp
--- a/bitcoin/src/main.cpp 0ccb0c29c0a3217d57f9bc72d87b497e64116a9f79e69277408750ee3dc95738ce52a70afece7a1054314100d84f93f6525ab514b8abd8ce78ab8ebd50e599a2
+++ b/bitcoin/src/main.cpp 46c36db87ce2f7b37b80b8b5f28dd0260d7374ea9974e1f72d217f1a54591ad2b212fd46577b850db569775bc9e0a38c3e8cc1ab552052b3f0397fdc2dea15da
@@ -2,6 +2,9 @@
 // Copyright (c) 2009-2012 The Bitcoin developers
 // Distributed under the MIT/X11 software license, see the accompanying
 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
+
+// TEST v0.5.4
+
 #include "headers.h"
 #include "checkpoints.h"
 #include "db.h"
END_RELEASE_VPATCH

  my $vpatch_name = "test_release.vpatch";
  my $path = "$patchdir/$vpatch_name";
  open(my $fh, ">", $path); print $fh "$vpatch\n";
  close($fh);
};

Then qr/point v at patch dir "(.*)" with flag "(.*)" and validate/, sub {
  my $cmd      = S->{'Command'};
  my $binPath  = getBinPath();
  my $patchdir = $1;
  my $pdflag   = $2;
  my @flow     = `$binPath/v.pl f $pdflag $patchdir`;
  $cmd->logger->info($flow[$#flow]);
  like($flow[$#flow], qr/test_release\.vpatch \(WILD\)/, "Patchdir pd/patchdir test.");
};

When qr/point v at seals dir "(.*)" and delete all seals from "(.*)"/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my $sealdir = $1;
  my $wotuid  = $2;
  $res = `rm -f $sealdir/*.$wotuid.sig`;
  if($res) {
    ok(0, "Delete seals from alternate seals dir for wotuid: $wotuid");
  }
};

Then qr/point v at seals dir "(.*)" with flag "(.*)" and validate no vpatches with seals by "(.*)"/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my $sealdir = $1;
  my $sdflag  = $2;
  my $wotuid  = $3;
  my @flow    = `$binPath/v.pl f $sdflag $sealdir`;
  foreach(@flow) {
    unlike($_, qr/.*\($wotuid\).*/, "Seal dir test");
  }
};

When qr/add a patch with incorrect hashes to patchdir "(.*)"/, sub {
  my $cmd      = S->{'Command'};
  my $binPath  = getBinPath();
  my $patchdir = $1;
  my $vpatch   = << "END_BAD_VPATCH";
diff -uNr a/bitcoin/src/net.cpp b/bitcoin/src/net.cpp
--- a/bitcoin/src/net.cpp f2413ebc07b49f7a4cb96e4ae82bca531b78e4afe6b2c93be4e00a9c89813cfbb62b0f255dde13ee6e59f883936afc2640b139e49ea7a766868cdb9edc2cd3db
+++ b/bitcoin/src/net.cpp 0f41846e6a31c2636e9836bdd08321c25551ed38e711a667a747d967332cb40c32a757a47599f03ed5ad111405941ac898c3fd6c6a0334fe77808dfe0cc1b443
@@ -577,16 +577,20 @@
     return false;
 }
 
-
-
-
-
-
-
-
-
-
-
+void CNode::CopyStats(CNodeStats &stats)
+{
+    stats.nServices = nServices;
+    stats.nLastSend = nLastSend;
+    stats.nLastRecv = nLastRecv;
+    stats.nTimeConnected = nTimeConnected; 
+    stats.addr = addr; 
+    stats.nVersion = nVersion; 
+    stats.strSubVer = strSubVer; 
+    stats.fInbound = fInbound; 
+    stats.nReleaseTime = nReleaseTime; 
+    stats.nStartingHeight = nStartingHeight; 
+    stats.nMisbehavior = nMisbehavior; 
+}
 
 void ThreadSocketHandler(void* parg)
 {
END_BAD_VPATCH

  my $vpatch_name = "test_bad.vpatch";
  my $path = "$patchdir/$vpatch_name";
  open(my $fh, ">", $path); print $fh "$vpatch\n";
  close($fh);
};

Then qr/validate press "(.*)" to dir "(.*)" with head "(.*)"/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my $option  = $1;
  my $outdir  = $2;
  my $head    = $3;
  my @sha256  = ();

  # DEBUG
  #my @res = `$binPath/v.pl $option --verbose $outdir $head 2>&1`;
  #if(@res) { foreach(@res) { print "$_"; } }

  my @res = `$binPath/v.pl $option $outdir $head`;
  if(!@res) { ok(1); }
  if(!-d $outdir) { ok(0); }

  if($head =~ /genesis\.vpatch/) {
    chdir("$outdir");
    @sha512 = `find . -xtype f -print0 | sort -z | xargs -0 sha512sum`;
    chdir(getBinPath());
    open ORIG, ">$outdir/genesis.vpatch.sha512.orig" or die "$!";
    print ORIG $genesis_sha512;
    close ORIG;
    open NEW, ">$outdir/genesis.vpatch.sha512" or die "$!";
    foreach(@sha512) { print NEW $_; }
    close NEW;
    @diff = `diff -u $outdir/genesis.vpatch.sha512.orig $outdir/genesis.vpatch.sha512`;
    if(!@diff) { ok(1); } else { ok(0); }
  }

  if($head =~ /asciilifeform_add_verifyall_option\.vpatch/) {
    chdir("$outdir");
    @sha512 = `find . -xtype f -print0 | sort -z | xargs -0 sha512sum`;
    chdir(getBinPath());
    open ORIG, ">$outdir/verifyall.vpatch.sha512.orig" or die "$!";
    print ORIG $verifyall_sha512;
    close ORIG;
    open NEW, ">$outdir/verifyall.vpatch.sha512" or die "$!";
    foreach(@sha512) { print NEW $_; }
    close NEW;
    @diff = `diff -u $outdir/verifyall.vpatch.sha512.orig $outdir/verifyall.vpatch.sha512`;
    if(!@diff) { ok(1); } else { ok(0); }
  }
};

Then qr/^press "(.*)" to dir "(.*)" with head "(.*)" from patches dir "(.*)" and seals dir "(.*)"$/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my $option  = $1;
  my $outdir  = $2;
  my $head    = $3;
  my $pdir    = $4;
  my $sdir    = $5;
  my @sha256  = ();

  my @res = `$binPath/v.pl $option v $outdir $head pd $pdir sd $sdir 2>&1`;
  $cmd->logger->info($res[$#res] . "Hash mismatch, passed.");

  like($res[$#res], qr/Pressed file hash did not match expected!/, "Died on bad patch\n");
  if(!-d $outdir) { ok(0); }

};

When qr/user creates new wot directory "(.*)" with one entry "(.*)"/, sub {
  my $cmd    = S->{'Command'};
  my $wotDir = $1;
  my $pubkey = $2;

  `mkdir -p $wotDir`;
  `cp -p .wot/$pubkey $wotDir`;
};

When qr/user creates new seals directory "(.*)" with one entry from a nonexisting WoT member "(.*)"/, sub {
  my $cmd      = S->{'Command'};
  my $sealsDir = $1;
  my $seal     = $2;

  `mkdir -p $sealsDir`;
  `cp -p .seals/$seal $sealsDir`;
};

Then qr/I validate that V will fail when encountering a seal in "(.*)" from an entity not in the current WoT "(.*)"/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my $sealDir = $1;
  my $wotDir  = $2;

  my @got = `$binPath/v.pl f wd $wotDir sd $sealDir`;
  foreach(@got) {
    $cmd->logger->info($_);
    ok(1) if $_ =~ /Check that this user is in your WoT/;
  }

  my @got2 = `$binPath/v.pl f wd $wotDir sd $sealDir`;
  foreach(@got2) {
    $cmd->logger->info($_);
    ok(1) if $_ =~ /Check that this user is in your WoT/;
  }
};

When qr/the user adds a descendant only malformed vpatch into the patches dir "(.*)"/, sub {
  my $cmd      = S->{'Command'};
  my $binPath  = getBinPath();
  my $patchdir = $1;

  my $vpatch = << "END_DESCENDANT_ONLY_VPATCH";
diff -uNr a/bitcoin/src/bitcoinrpc.cpp b/bitcoin/src/bitcoinrpc.cpp
+++ b/bitcoin/src/bitcoinrpc.cpp cd1dcc5febddd45408b193d0b875d8951eed8dc29d342ae5e57330b4ea2b55d959fab19e634696234c698feb4fa79a5702278e83b3896389c425ada5e935cc34
END_DESCENDANT_ONLY_VPATCH

  my $vpatch_name = "test_descendant_only.vpatch";
  my $path = "$patchdir/$vpatch_name";
  open(my $fh, ">", $path); print $fh "$vpatch\n";
  close($fh);
};

Then qr/verify invalid vpatch "(.*)" in patches dir "(.*)" with seals dir "(.*)" with command "(.*)"/, sub {
  my $cmd     = S->{'Command'};
  my $vpatch  = $1;
  my $pdir    = $2;
  my $sdir    = $3;
  my $command = $4;
  my @res = `./v.pl $command pd $pdir sd $sdir 2>&1`;
  $cmd->logger->info($res[0]);
  like($res[0], qr/Error! test_descendant_only\.vpatch is an invalid vpatch file\./, "Invalid Vpatch, descendant only");
};

When qr/the user adds a vpatch "(.*)" in patches dir "(.*)" where hashes are equal/, sub {
  my $cmd         = S->{'Command'};
  my $binPath     = getBinPath();
  my $vpatch_name = $1;
  my $patchdir    = $2;

  my $vpatch = << "END_HASHES_EQUAL_VPATCH";
diff -uNr a/bitcoin/src/db.cpp b/bitcoin/src/db.cpp
--- a/bitcoin/src/db.cpp 565faf3ef371f5e2178ae30c45b08b93415eeb92263486e68f2ac2e8f4c7900056e628804bf5c0707a90be946e0aeaebfcd0a391aab40de2e5d56e6bcbdccb1e
+++ b/bitcoin/src/db.cpp 565faf3ef371f5e2178ae30c45b08b93415eeb92263486e68f2ac2e8f4c7900056e628804bf5c0707a90be946e0aeaebfcd0a391aab40de2e5d56e6bcbdccb1e
@@ -3,6 +3,8 @@
 // Distributed under the MIT/X11 software license, see the accompanying
 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
 
+// TEST v0.5.4
+
 #include "headers.h"
 #include "db.h"
 #include "net.h"
END_HASHES_EQUAL_VPATCH

  my $path = "$patchdir/$vpatch_name";
  open(my $fh, ">", $path); print $fh "$vpatch\n";
  close($fh);
};

Then qr/validate hashes equal error in patches dir "(.*)" with command "(.*)"/, sub {
  my $cmd     = S->{'Command'};
  my $pdir    = $1;
  my $command = $2;
  my @res = `./v.pl $command pd $pdir 2>&1`;
  $cmd->logger->info($res[0]);
  like($res[0], qr/test-equal-hashes\.vpatch is an invalid vpatch\!/, "Invalid Vpatch");
};

Then qr/remove file "(.*)" from directory "(.*)"/, sub {
  my $cmd    = S->{'Command'};
  my $vpatch = $1;
  my $pdir   = $2;

  my @res = `rm $pdir/$vpatch`;
};

When qr/the user adds an empty vpatch "(.*)" into the patches dir "(.*)"/, sub {
  my $cmd    = S->{'Command'};
  my $vpatch = $1;
  my $pdir   = $2;

  my @res = `touch $pdir/$vpatch`;
};

Then qr/^validate empty vpatch "(.*)" in patches dir "(.*)" with seals dir "(.*)" throws error with command "(.*)"$/, sub {
  my $cmd      = S->{'Command'};
  my $vpatch   = $1;
  my $pdir     = $2;
  my $sdir     = $3;
  my $command  = $4;
  my @res = `./v.pl $command pd $pdir sd $sdir 2>&1`;
  $cmd->logger->info($res[0]);
  like($res[0], qr/Error! empty\.vpatch is an invalid vpatch file\./, "Invalid, empty vpatch found.");
};

Then qr/search for hash "(.*)" with command "(.*)"/, sub {
  my $cmd     = S->{'Command'};
  my $hash    = $1; 
  my $command = $2;

  my @res = `./v.pl $command $hash 2>&1`; 
  $cmd->logger->info($res[0]);
  if($hash ne "deadbeef") { 
    like($res[0], qr/Origin: genesis\.vpatch \(asciilifeform, mircea_popescu, mod6, trinque\)/, "");
  } else { 
    like($res[0], qr/No Origin Found by Hash/, "No Origin Found by Hash.");
  }
};

When qr/the user adds and deletes a file with vpatch "(.*)" in patches dir "(.*)"/, sub {
  my $cmd         = S->{'Command'};
  my $binPath     = getBinPath();
  my $vpatch_name = $1;
  my $patchdir    = $2;

  my $vpatch = << "END_DELETE_AND_ADD_FILE_VPATCH";
diff -uNr a/bitcoin/COPYING b/bitcoin/COPYING
--- a/bitcoin/COPYING e7f37a4eea93d09cdcfdd669a97f7a1ad3c1c96395f9517b33b396af03292fe97f27f630df1ec1d261fcf396e0e2d31f0ded4f50d5181046a0609a4ef0d71450
+++ b/bitcoin/COPYING false
@@ -1,19 +0,0 @@
-Copyright (c) 2009-2012 Bitcoin Developers
-
-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 -uNr a/bitcoin/LICENSE b/bitcoin/LICENSE
--- a/bitcoin/LICENSE false
+++ b/bitcoin/LICENSE 3554c8e12cc976d1e08e3249c83a594c30d1abab73fa423803c7a105d123c370f13abb6285b2357586639096c6934fa96be0fd8be584784de6bb5d37651db17b
@@ -0,0 +1,3 @@
+You do not have, nor can you ever acquire the right to use, copy or distribute this software.
+
+Should you use this software for any purpose, or copy and distribute it, to anyone or in any manner, you are breaking the laws of whatever soi-disant jurisdiction, and you promise to continue doing so in the indefinite future.
END_DELETE_AND_ADD_FILE_VPATCH

  my $path = "$patchdir/$vpatch_name";
  open(my $fh, ">", $path); print $fh "$vpatch\n";
  close($fh);
};

Then qr/validate file add & delete functional with patches dir "(.*)" with command "(.*)"/, sub {
  my $cmd     = S->{'Command'};
  my $pdir    = $1;
  my $command = $2;
  my @res = `./v.pl $command pd $pdir 2>&1`;
  $cmd->logger->info($res[0]);
  like($res[$#res-1], qr/ben_vulpes-copyright\.vpatch \(WILD\)/, "Invalid Vpatch");
};

Then qr/I remove "(.*)"/, sub {
  my $cmd     = S->{'Command'};
  my $binPath = getBinPath();
  my $arg     = $1;
  if($arg     =~ /~\/(.*)/) { $arg = getHomeDir() . "/$1"; }
  my @res     = `rm -rf $arg`;
  if(@res) { ok(0, "Clean up $arg"); }
};
