summary refs log tree commit diff stats
path: root/lib/base/devel
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2008-11-16 22:11:53 +0100
committerAndreas Rumpf <rumpf_a@web.de>2008-11-16 22:11:53 +0100
commit985113a88fe07fa18f0a34ceaa9e8c1c1e04a79b (patch)
tree6a2e56078dd24d29d9031a784917ed94696d24a8 /lib/base/devel
parent8b2a9401a147bd0b26cd2976ae71a1022fbde8cc (diff)
downloadNim-985113a88fe07fa18f0a34ceaa9e8c1c1e04a79b.tar.gz
version 0.7.0
Diffstat (limited to 'lib/base/devel')
-rw-r--r--lib/base/devel/FGInt.pas2199
-rw-r--r--lib/base/devel/bignums.nim1712
-rw-r--r--lib/base/devel/diff.nim460
-rw-r--r--lib/base/devel/lex.nim73
-rw-r--r--lib/base/devel/nregex.nim124
-rw-r--r--lib/base/devel/python.nim1877
-rw-r--r--lib/base/devel/python.pas2205
7 files changed, 8650 insertions, 0 deletions
diff --git a/lib/base/devel/FGInt.pas b/lib/base/devel/FGInt.pas
new file mode 100644
index 000000000..7cb5a8516
--- /dev/null
+++ b/lib/base/devel/FGInt.pas
@@ -0,0 +1,2199 @@
+{License, info, etc

+ ------------------

+

+This implementation is made by me, Walied Othman, to contact me

+mail to Walied.Othman@belgacom.net or Triade@ulyssis.org,

+always mention wether it 's about the FGInt for Delphi or for

+FreePascal, or wether it 's about the 6xs, preferably in the subject line.

+If you 're going to use these implementations, at least mention my

+name or something and notify me so I may even put a link on my page.

+This implementation is freeware and according to the coderpunks'

+manifesto it should remain so, so don 't use these implementations

+in commercial software.  Encryption, as a tool to ensure privacy

+should be free and accessible for anyone.  If you plan to use these

+implementations in a commercial application, contact me before

+doing so, that way you can license the software to use it in commercial

+Software.  If any algorithm is patented in your country, you should

+acquire a license before using this software.  Modified versions of this

+software must contain an acknowledgement of the original author (=me).

+This implementation is available at

+http://triade.studentenweb.org

+

+copyright 2000, Walied Othman

+This header may not be removed.

+}

+

+Unit FGInt;

+

+{$H+}

+

+Interface

+

+Uses SysUtils, Math;

+

+Type

+   TCompare = (Lt, St, Eq, Er);

+   TSign = (negative, positive);

+   TFGInt = Record

+      Sign : TSign;

+      Number : Array Of LongWord;

+   End;

+

+Procedure zeronetochar8(Var g : char; Const x : String);

+Procedure zeronetochar6(Var g : integer; Const x : String);

+Procedure initialize8(Var trans : Array Of String);

+Procedure initialize6(Var trans : Array Of String);

+Procedure initialize6PGP(Var trans : Array Of String);

+Procedure ConvertBase256to64(Const str256 : String; Var str64 : String);

+Procedure ConvertBase64to256(Const str64 : String; Var str256 : String);

+Procedure ConvertBase256to2(Const str256 : String; Var str2 : String);

+Procedure ConvertBase64to2(Const str64 : String; Var str2 : String);

+Procedure ConvertBase2to256(str2 : String; Var str256 : String);

+Procedure ConvertBase2to64(str2 : String; Var str64 : String);

+Procedure ConvertBase256StringToHexString(Str256 : String; Var HexStr : String);

+Procedure ConvertHexStringToBase256String(HexStr : String; Var Str256 : String);

+Procedure PGPConvertBase256to64(Var str256, str64 : String);

+Procedure PGPConvertBase64to256(str64 : String; Var str256 : String);

+Procedure PGPConvertBase64to2(str64 : String; Var str2 : String);

+Procedure FGIntToBase2String(Const FGInt : TFGInt; Var S : String);

+Procedure Base2StringToFGInt(S : String; Var FGInt : TFGInt);

+Procedure FGIntToBase256String(Const FGInt : TFGInt; Var str256 : String);

+Procedure Base256StringToFGInt(str256 : String; Var FGInt : TFGInt);

+Procedure PGPMPIToFGInt(PGPMPI : String; Var FGInt : TFGInt);

+Procedure FGIntToPGPMPI(FGInt : TFGInt; Var PGPMPI : String);

+Procedure Base10StringToFGInt(Base10 : String; Var FGInt : TFGInt);

+Procedure FGIntToBase10String(Const FGInt : TFGInt; Var Base10 : String);

+Procedure FGIntDestroy(Var FGInt : TFGInt);

+Function FGIntCompareAbs(Const FGInt1, FGInt2 : TFGInt) : TCompare;

+Procedure FGIntAdd(Const FGInt1, FGInt2 : TFGInt; Var Sum : TFGInt);

+Procedure FGIntChangeSign(Var FGInt : TFGInt);

+Procedure FGIntSub(Var FGInt1, FGInt2, dif : TFGInt);

+Procedure FGIntMulByInt(Const FGInt : TFGInt; Var res : TFGInt; by : LongWord);

+Procedure FGIntMulByIntbis(Var FGInt : TFGInt; by : LongWord);

+Procedure FGIntDivByInt(Const FGInt : TFGInt; Var res : TFGInt; by : LongWord; Var modres : LongWord);

+Procedure FGIntDivByIntBis(Var FGInt : TFGInt; by : LongWord; Var modres : LongWord);

+Procedure FGIntModByInt(Const FGInt : TFGInt; by : LongWord; Var modres : LongWord);

+Procedure FGIntAbs(Var FGInt : TFGInt);

+Procedure FGIntCopy(Const FGInt1 : TFGInt; Var FGInt2 : TFGInt);

+Procedure FGIntShiftLeft(Var FGInt : TFGInt);

+Procedure FGIntShiftRight(Var FGInt : TFGInt);

+Procedure FGIntShiftRightBy31(Var FGInt : TFGInt);

+Procedure FGIntAddBis(Var FGInt1 : TFGInt; Const FGInt2 : TFGInt);

+Procedure FGIntSubBis(Var FGInt1 : TFGInt; Const FGInt2 : TFGInt);

+Procedure FGIntMul(Const FGInt1, FGInt2 : TFGInt; Var Prod : TFGInt);

+Procedure FGIntSquare(Const FGInt : TFGInt; Var Square : TFGInt);

+Procedure FGIntExp(Const FGInt, exp : TFGInt; Var res : TFGInt);

+Procedure FGIntFac(Const FGInt : TFGInt; Var res : TFGInt);

+Procedure FGIntShiftLeftBy31(Var FGInt : TFGInt);

+Procedure FGIntDivMod(Var FGInt1, FGInt2, QFGInt, MFGInt : TFGInt);

+Procedure FGIntDiv(Var FGInt1, FGInt2, QFGInt : TFGInt);

+Procedure FGIntMod(Var FGInt1, FGInt2, MFGInt : TFGInt);

+Procedure FGIntSquareMod(Var FGInt, Modb, FGIntSM : TFGInt);

+Procedure FGIntAddMod(Var FGInt1, FGInt2, base, FGIntres : TFGInt);

+Procedure FGIntMulMod(Var FGInt1, FGInt2, base, FGIntres : TFGInt);

+Procedure FGIntModExp(Var FGInt, exp, modb, res : TFGInt);

+Procedure FGIntModBis(Const FGInt : TFGInt; Var FGIntOut : TFGInt; b, head : LongWord);

+Procedure FGIntMulModBis(Const FGInt1, FGInt2 : TFGInt; Var Prod : TFGInt; b, head : LongWord);

+Procedure FGIntMontgomeryMod(Const GInt, base, baseInv : TFGInt; Var MGInt : TFGInt; b : Longword; head : LongWord);

+Procedure FGIntMontgomeryModExp(Var FGInt, exp, modb, res : TFGInt);

+Procedure FGIntGCD(Const FGInt1, FGInt2 : TFGInt; Var GCD : TFGInt);

+Procedure FGIntLCM(Const FGInt1, FGInt2 : TFGInt; Var LCM : TFGInt);

+Procedure FGIntTrialDiv9999(Const FGInt : TFGInt; Var ok : boolean);

+Procedure FGIntRandom1(Var Seed, RandomFGInt : TFGInt);

+Procedure FGIntRabinMiller(Var FGIntp : TFGInt; nrtest : Longword; Var ok : boolean);

+Procedure FGIntBezoutBachet(Var FGInt1, FGInt2, a, b : TFGInt);

+Procedure FGIntModInv(Const FGInt1, base : TFGInt; Var Inverse : TFGInt);

+Procedure FGIntPrimetest(Var FGIntp : TFGInt; nrRMtests : integer; Var ok : boolean);

+Procedure FGIntLegendreSymbol(Var a, p : TFGInt; Var L : integer);

+Procedure FGIntSquareRootModP(Square, Prime : TFGInt; Var SquareRoot : TFGInt);

+

+

+

+Implementation

+

+Var

+   primes : Array[1..1228] Of integer =

+      (3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127,

+      131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251,

+      257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389,

+      397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541,

+      547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677,

+      683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839,

+      853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009,

+      1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123,

+      1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279,

+      1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429,

+      1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553,

+      1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693,

+      1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847,

+      1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997,

+      1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131,

+      2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287,

+      2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417,

+      2423, 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593,

+      2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719,

+      2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861,

+      2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, 3019, 3023, 3037,

+      3041, 3049, 3061, 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209,

+      3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 3359,

+      3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527,

+      3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643, 3659,

+      3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821,

+      3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967,

+      3989, 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129,

+      4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 4261, 4271, 4273,

+      4283, 4289, 4297, 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457,

+      4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637,

+      4639, 4643, 4649, 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, 4759, 4783, 4787, 4789,

+      4793, 4799, 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951, 4957,

+      4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101,

+      5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279, 5281,

+      5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443,

+      5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, 5623,

+      5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779,

+      5783, 5791, 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, 5903,

+      5923, 5927, 5939, 5953, 5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 6079, 6089, 6091, 6101,

+      6113, 6121, 6131, 6133, 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, 6257, 6263, 6269,

+      6271, 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379, 6389, 6397,

+      6421, 6427, 6449, 6451, 6469, 6473, 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571, 6577, 6581, 6599,

+      6607, 6619, 6637, 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779,

+      6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947,

+      6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103,

+      7109, 7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, 7283,

+      7297, 7307, 7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487,

+      7489, 7499, 7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 7573, 7577, 7583, 7589, 7591, 7603, 7607,

+      7621, 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, 7759, 7789,

+      7793, 7817, 7823, 7829, 7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, 7927, 7933, 7937, 7949, 7951,

+      7963, 7993, 8009, 8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161,

+      8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291, 8293, 8297, 8311,

+      8317, 8329, 8353, 8363, 8369, 8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443, 8447, 8461, 8467, 8501, 8513, 8521,

+      8527, 8537, 8539, 8543, 8563, 8573, 8581, 8597, 8599, 8609, 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677, 8681,

+      8689, 8693, 8699, 8707, 8713, 8719, 8731, 8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803, 8807, 8819, 8821, 8831,

+      8837, 8839, 8849, 8861, 8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941, 8951, 8963, 8969, 8971, 8999, 9001, 9007,

+      9011, 9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, 9103, 9109, 9127, 9133, 9137, 9151, 9157, 9161, 9173, 9181,

+      9187, 9199, 9203, 9209, 9221, 9227, 9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311, 9319, 9323, 9337, 9341, 9343,

+      9349, 9371, 9377, 9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433, 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491,

+      9497, 9511, 9521, 9533, 9539, 9547, 9551, 9587, 9601, 9613, 9619, 9623, 9629, 9631, 9643, 9649, 9661, 9677, 9679,

+      9689, 9697, 9719, 9721, 9733, 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, 9803, 9811, 9817, 9829, 9833, 9839,

+      9851, 9857, 9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929, 9931, 9941, 9949, 9967, 9973);

+   chr64 : Array[1..64] Of char = ('a', 'A', 'b', 'B', 'c', 'C', 'd', 'D', 'e', 'E', 'f', 'F',

+      'g', 'G', 'h', 'H', 'i', 'I', 'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N', 'o', 'O', 'p',

+      'P', 'q', 'Q', 'r', 'R', 's', 'S', 't', 'T', 'u', 'U', 'v', 'V', 'w', 'W', 'x', 'X', 'y', 'Y',

+      'z', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '=');

+   PGPchr64 : Array[1..64] Of char = ('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',

+      'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',

+      'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',

+      'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/');

+

+

+

+Procedure zeronetochar8(Var g : char; Const x : String);

+Var

+   i : Integer;

+   b : byte;

+Begin

+   b := 0;

+   For i := 1 To 8 Do

+   Begin

+      If copy(x, i, 1) = '1' Then

+         b := b Or (1 Shl (8 - I));

+   End;

+   g := chr(b);

+End;

+

+

+Procedure zeronetochar6(Var g : integer; Const x : String);

+Var

+   I : Integer;

+Begin

+   G := 0;

+   For I := 1 To Length(X) Do

+   Begin

+      If I > 6 Then

+         Break;

+      If X[I] <> '0' Then

+         G := G Or (1 Shl (6 - I));

+   End;

+   Inc(G);

+End;

+

+

+Procedure initialize8(Var trans : Array Of String);

+Var

+   c1, c2, c3, c4, c5, c6, c7, c8 : integer;

+   x : String;

+   g : char;

+Begin

+   For c1 := 0 To 1 Do

+      For c2 := 0 To 1 Do

+         For c3 := 0 To 1 Do

+            For c4 := 0 To 1 Do

+               For c5 := 0 To 1 Do

+                  For c6 := 0 To 1 Do

+                     For c7 := 0 To 1 Do

+                        For c8 := 0 To 1 Do

+                        Begin

+                           x := chr(48+c1) + chr(48+c2) + chr(48+c3) + chr(48+c4) + chr(48+c5) + chr(48+c6) + chr(48+c7) + chr(48+c8);

+                           zeronetochar8(g, x);

+                           trans[ord(g)] := x;

+                        End;

+End;

+

+

+Procedure initialize6(Var trans : Array Of String);

+Var

+   c1, c2, c3, c4, c5, c6 : integer;

+   x : String;

+   g : integer;

+Begin

+   For c1 := 0 To 1 Do

+      For c2 := 0 To 1 Do

+         For c3 := 0 To 1 Do

+            For c4 := 0 To 1 Do

+               For c5 := 0 To 1 Do

+                  For c6 := 0 To 1 Do

+                  Begin

+                     x := chr(48+c1) + chr(48+c2) + chr(48+c3) + chr(48+c4) + chr(48+c5) + chr(48+c6);

+                     zeronetochar6(g, x);

+                     trans[ord(chr64[g])] := x;

+                  End;

+End;

+

+Procedure initialize6PGP(Var trans : Array Of String);

+Var

+   c1, c2, c3, c4, c5, c6 : integer;

+   x : String;

+   g : integer;

+Begin

+   For c1 := 0 To 1 Do

+      For c2 := 0 To 1 Do

+         For c3 := 0 To 1 Do

+            For c4 := 0 To 1 Do

+               For c5 := 0 To 1 Do

+                  For c6 := 0 To 1 Do

+                  Begin

+                     x := chr(48+c1) + chr(48+c2) + chr(48+c3) + chr(48+c4) + chr(48+c5) + chr(48+c6);

+                     zeronetochar6(g, x);

+                     trans[ord(PGPchr64[g])] := x;

+                  End;

+End;

+

+

+// Convert base 8 strings to base 6 strings and visa versa

+

+Procedure ConvertBase256to64(Const str256 : String; Var str64 : String);

+Var

+   temp : String;

+   trans : Array[0..255] Of String;

+   i, len6 : longint;

+   g : integer;

+Begin

+   initialize8(trans);

+   temp := '';

+   For i := 1 To length(str256) Do temp := temp + trans[ord(str256[i])];

+   While (length(temp) Mod 6) <> 0 Do temp := temp + '0';

+   len6 := length(temp) Div 6;

+   str64 := '';

+   For i := 1 To len6 Do

+   Begin

+      zeronetochar6(g, copy(temp, 1, 6));

+      str64 := str64 + chr64[g];

+      delete(temp, 1, 6);

+   End;

+End;

+

+

+Procedure ConvertBase64to256(Const str64 : String; Var str256 : String);

+Var

+   temp : String;

+   trans : Array[0..255] Of String;

+   i, len8 : longint;

+   g : char;

+Begin

+   initialize6(trans);

+   temp := '';

+   For i := 1 To length(str64) Do temp := temp + trans[ord(str64[i])];

+   str256 := '';

+   len8 := length(temp) Div 8;

+   For i := 1 To len8 Do

+   Begin

+      zeronetochar8(g, copy(temp, 1, 8));

+      str256 := str256 + g;

+      delete(temp, 1, 8);

+   End;

+End;

+

+

+// Convert base 8 & 6 bit strings to base 2 strings and visa versa

+

+Procedure ConvertBase256to2(Const str256 : String; Var str2 : String);

+Var

+   trans : Array[0..255] Of String;

+   i : longint;

+Begin

+   str2 := '';

+   initialize8(trans);

+   For i := 1 To length(str256) Do str2 := str2 + trans[ord(str256[i])];

+End;

+

+

+Procedure ConvertBase64to2(Const str64 : String; Var str2 : String);

+Var

+   trans : Array[0..255] Of String;

+   i : longint;

+Begin

+   str2 := '';

+   initialize6(trans);

+   For i := 1 To length(str64) Do str2 := str2 + trans[ord(str64[i])];

+End;

+

+

+Procedure ConvertBase2to256(str2 : String; Var str256 : String);

+Var

+   i, len8 : longint;

+   g : char;

+Begin

+   str256 := '';

+   While (length(str2) Mod 8) <> 0 Do str2 := '0' + str2;

+   len8 := length(str2) Div 8;

+   For i := 1 To len8 Do

+   Begin

+      zeronetochar8(g, copy(str2, 1, 8));

+      str256 := str256 + g;

+      delete(str2, 1, 8);

+   End;

+End;

+

+

+Procedure ConvertBase2to64(str2 : String; Var str64 : String);

+Var

+   i, len6 : longint;

+   g : integer;

+Begin

+   str64 := '';

+   While (length(str2) Mod 6) <> 0 Do str2 := '0' + str2;

+   len6 := length(str2) Div 6;

+   For i := 1 To len6 Do

+   Begin

+      zeronetochar6(g, copy(str2, 1, 6));

+      str64 := str64 + chr64[g];

+      delete(str2, 1, 6);

+   End;

+End;

+

+

+// Convert base 256 strings to base 16 (HexaDecimal) strings and visa versa

+

+Procedure ConvertBase256StringToHexString(Str256 : String; Var HexStr : String);

+Var

+   i : longint;

+   b : byte;

+Begin

+   HexStr := '';

+   For i := 1 To length(str256) Do

+   Begin

+      b := ord(str256[i]);

+      If (b Shr 4) < 10 Then HexStr := HexStr + chr(48 + (b Shr 4))

+      Else HexStr := HexStr + chr(55 + (b Shr 4));

+      If (b And 15) < 10 Then HexStr := HexStr + chr(48 + (b And 15))

+      Else HexStr := HexStr + chr(55 + (b And 15));

+   End;

+End;

+

+

+Procedure ConvertHexStringToBase256String(HexStr : String; Var Str256 : String);

+Var

+   i : longint;

+   b, h1, h2 : byte;

+   temp : string;

+Begin

+   Str256 := '';

+   If (length(Hexstr) mod 2) = 1 Then temp := '0' + HexStr Else temp := HexStr;

+   For i := 1 To (length(temp) Div 2) Do

+   Begin

+      h2 := ord(temp[2 * i]);

+      h1 := ord(temp[2 * i - 1]);

+      If h1 < 58 Then

+         b := ((h1 - 48) Shl 4)

+      Else

+         b := ((h1 - 55) Shl 4);

+      If h2 < 58 Then

+         b := (b Or (h2 - 48))

+      Else

+         b := (b Or ((h2 - 55) and 15));

+      Str256 := Str256 + chr(b);

+   End;

+End;

+

+

+// Convert base 256 strings to base 64 strings and visa versa, PGP style

+

+Procedure PGPConvertBase256to64(Var str256, str64 : String);

+Var

+   temp, x, a : String;

+   i, len6 : longint;

+   g : integer;

+   trans : Array[0..255] Of String;

+Begin

+   initialize8(trans);

+   temp := '';

+   For i := 1 To length(str256) Do temp := temp + trans[ord(str256[i])];

+   If (length(temp) Mod 6) = 0 Then a := '' Else

+      If (length(temp) Mod 6) = 4 Then

+      Begin

+         temp := temp + '00';

+         a := '='

+      End

+      Else

+      Begin

+         temp := temp + '0000';

+         a := '=='

+      End;

+   str64 := '';

+   len6 := length(temp) Div 6;

+   For i := 1 To len6 Do

+   Begin

+      x := copy(temp, 1, 6);

+      zeronetochar6(g, x);

+      str64 := str64 + PGPchr64[g];

+      delete(temp, 1, 6);

+   End;

+   str64 := str64 + a;

+End;

+

+

+Procedure PGPConvertBase64to256(str64 : String; Var str256 : String);

+Var

+   temp, x : String;

+   i, j, len8 : longint;

+   g : char;

+   trans : Array[0..255] Of String;

+Begin

+   initialize6PGP(trans);

+   temp := '';

+   str256 := '';

+   If str64[length(str64) - 1] = '=' Then j := 2 Else

+      If str64[length(str64)] = '=' Then j := 1 Else j := 0;

+   For i := 1 To (length(str64) - j) Do temp := temp + trans[ord(str64[i])];

+   If j <> 0 Then delete(temp, length(temp) - 2 * j + 1, 2 * j);

+   len8 := length(temp) Div 8;

+   For i := 1 To len8 Do

+   Begin

+      x := copy(temp, 1, 8);

+      zeronetochar8(g, x);

+      str256 := str256 + g;

+      delete(temp, 1, 8);

+   End;

+End;

+

+// Convert base 64 strings to base 2 strings, PGP style

+

+

+Procedure PGPConvertBase64to2(str64 : String; Var str2 : String);

+Var

+   i, j : longint;

+   trans : Array[0..255] Of String;

+Begin

+   str2 := '';

+   initialize6(trans);

+   If str64[length(str64) - 1] = '=' Then j := 2 Else

+      If str64[length(str64)] = '=' Then j := 1 Else j := 0;

+   For i := 1 To (length(str64) - j) Do str2 := str2 + trans[ord(str64[i])];

+   delete(str2, length(str2) - 2 * j + 1, 2 * j);

+End;

+

+

+// Convert a FGInt to a binary string (base 2) & visa versa

+

+Procedure FGIntToBase2String(Const FGInt : TFGInt; Var S : String);

+Var

+   i : LongWord;

+   j : integer;

+Begin

+   S := '';

+   For i := 1 To FGInt.Number[0] Do

+   Begin

+      For j := 0 To 30 Do

+         If (1 And (FGInt.Number[i] Shr j)) = 1 Then

+            S := '1' + S

+         Else

+            S := '0' + S;

+   End;

+   While (length(S) > 1) And (S[1] = '0') Do

+      delete(S, 1, 1);

+   If S = '' Then S := '0';

+End;

+

+

+Procedure Base2StringToFGInt(S : String; Var FGInt : TFGInt);

+Var

+   i, j, size : LongWord;

+Begin

+   While (S[1] = '0') And (length(S) > 1) Do

+      delete(S, 1, 1);

+   size := length(S) Div 31;

+   If (length(S) Mod 31) <> 0 Then size := size + 1;

+   SetLength(FGInt.Number, (size + 1));

+   FGInt.Number[0] := size;

+   j := 1;

+   FGInt.Number[j] := 0;

+   i := 0;

+   While length(S) > 0 Do

+   Begin

+      If S[length(S)] = '1' Then

+         FGInt.Number[j] := FGInt.Number[j] Or (1 Shl i);

+      i := i + 1;

+      If i = 31 Then

+      Begin

+         i := 0;

+         j := j + 1;

+         If j <= size Then FGInt.Number[j] := 0;

+      End;

+      delete(S, length(S), 1);

+   End;

+   FGInt.Sign := positive;

+End;

+

+

+// Convert a FGInt to an base 256 string & visa versa

+

+Procedure FGIntToBase256String(Const FGInt : TFGInt; Var str256 : String);

+Var

+   temp1 : String;

+   i, len8 : LongWord;

+   g : char;

+Begin

+   FGIntToBase2String(FGInt, temp1);

+   While (length(temp1) Mod 8) <> 0 Do temp1 := '0' + temp1;

+   len8 := length(temp1) Div 8;

+   str256 := '';

+   For i := 1 To len8 Do

+   Begin

+      zeronetochar8(g, copy(temp1, 1, 8));

+      str256 := str256 + g;

+      delete(temp1, 1, 8);

+   End;

+End;

+

+

+Procedure Base256StringToFGInt(str256 : String; Var FGInt : TFGInt);

+Var

+   temp1 : String;

+   i : longint;

+   trans : Array[0..255] Of String;

+Begin

+   temp1 := '';

+   initialize8(trans);

+   For i := 1 To length(str256) Do temp1 := temp1 + trans[ord(str256[i])];

+   While (temp1[1] = '0') And (temp1 <> '0') Do delete(temp1, 1, 1);

+   Base2StringToFGInt(temp1, FGInt);

+End;

+

+// Convert an MPI (Multiple Precision Integer, PGP style) to an FGInt &

+// visa versa

+

+Procedure PGPMPIToFGInt(PGPMPI : String; Var FGInt : TFGInt);

+Var

+   temp : String;

+Begin

+   temp := PGPMPI;

+   delete(temp, 1, 2);

+   Base256StringToFGInt(temp, FGInt);

+End;

+

+

+Procedure FGIntToPGPMPI(FGInt : TFGInt; Var PGPMPI : String);

+Var

+   len, i : word;

+   c : char;

+   b : byte;

+Begin

+   FGIntToBase256String(FGInt, PGPMPI);

+   len := length(PGPMPI) * 8;

+   c := PGPMPI[1];

+   For i := 7 Downto 0 Do If (ord(c) Shr i) = 0 Then len := len - 1 Else break;

+   b := len Mod 256;

+   PGPMPI := chr(b) + PGPMPI;

+   b := len Div 256;

+   PGPMPI := chr(b) + PGPMPI;

+End;

+

+

+// Convert a base 10 string to a FGInt

+// NESTED

+Procedure GIntDivByIntBis1(Var GInt : TFGInt; by : LongWord; Var modres : word);

+Var

+   i, size, rest, temp : LongWord;

+Begin

+   size := GInt.Number[0];

+   temp := 0;

+   For i := size Downto 1 Do

+   Begin

+      temp := temp * 10000;

+      rest := temp + GInt.Number[i];

+      GInt.Number[i] := rest Div by;

+      temp := rest Mod by;

+   End;

+     modres := temp;

+   While (GInt.Number[size] = 0) And (size > 1) Do

+      size := size - 1;

+   If size <> GInt.Number[0] Then

+   Begin

+      SetLength(GInt.Number, size + 1);

+      GInt.Number[0] := size;

+   End;

+End;

+

+Procedure Base10StringToFGInt(Base10 : String; Var FGInt : TFGInt);

+Var

+   i, size : LongWord;

+   j : word;

+   S, x : String;

+   sign : TSign;

+

+

+Begin

+   While (Not (Base10[1] In ['-', '0'..'9'])) And (length(Base10) > 1) Do

+      delete(Base10, 1, 1);

+   If copy(Base10, 1, 1) = '-' Then

+   Begin

+      Sign := negative;

+      delete(Base10, 1, 1);

+   End

+   Else

+      Sign := positive;

+   While (length(Base10) > 1) And (copy(Base10, 1, 1) = '0') Do

+      delete(Base10, 1, 1);

+   size := length(Base10) Div 4;

+   If (length(Base10) Mod 4) <> 0 Then size := size + 1;

+   SetLength(FGInt.Number, size + 1);

+   FGInt.Number[0] := size;

+   For i := 1 To (size - 1) Do

+   Begin

+      x := copy(Base10, length(Base10) - 3, 4);

+      FGInt.Number[i] := StrToInt(x);

+      delete(Base10, length(Base10) - 3, 4);

+   End;

+   FGInt.Number[size] := StrToInt(Base10);

+

+   S := '';

+   While (FGInt.Number[0] <> 1) Or (FGInt.Number[1] <> 0) Do

+   Begin

+      GIntDivByIntBis1(FGInt, 2, j);

+      S := inttostr(j) + S;

+   End;

+   If S = '' Then S := '0';

+   FGIntDestroy(FGInt);

+   Base2StringToFGInt(S, FGInt);

+   FGInt.Sign := sign;

+End;

+

+

+// Convert a FGInt to a base 10 string

+

+Procedure FGIntToBase10String(Const FGInt : TFGInt; Var Base10 : String);

+Var

+   S : String;

+   j : LongWord;

+   temp : TFGInt;

+Begin

+   FGIntCopy(FGInt, temp);

+   Base10 := '';

+   While (temp.Number[0] > 1) Or (temp.Number[1] > 0) Do

+   Begin

+      FGIntDivByIntBis(temp, 10000, j);

+      S := IntToStr(j);

+      While Length(S) < 4 Do

+         S := '0' + S;

+      Base10 := S + Base10;

+   End;

+   Base10 := '0' + Base10;

+   While (length(Base10) > 1) And (Base10[1] = '0') Do

+      delete(Base10, 1, 1);

+   If FGInt.Sign = negative Then Base10 := '-' + Base10;

+End;

+

+

+// Destroy a FGInt to free memory

+

+Procedure FGIntDestroy(Var FGInt : TFGInt);

+Begin

+   FGInt.Number := Nil;

+End;

+

+

+// Compare 2 FGInts in absolute value, returns

+// Lt if FGInt1 > FGInt2, St if FGInt1 < FGInt2, Eq if FGInt1 = FGInt2,

+// Er otherwise

+

+Function FGIntCompareAbs(Const FGInt1, FGInt2 : TFGInt) : TCompare;

+Var

+   size1, size2, i : LongWord;

+Begin

+   FGIntCompareAbs := Er;

+   size1 := FGInt1.Number[0];

+   size2 := FGInt2.Number[0];

+   If size1 > size2 Then FGIntCompareAbs := Lt Else

+      If size1 < size2 Then FGIntCompareAbs := St Else

+      Begin

+         i := size2;

+         While (FGInt1.Number[i] = FGInt2.Number[i]) And (i > 1) Do i := i - 1;

+         If FGInt1.Number[i] = FGInt2.Number[i] Then FGIntCompareAbs := Eq Else

+            If FGInt1.Number[i] < FGInt2.Number[i] Then FGIntCompareAbs := St Else

+               If FGInt1.Number[i] > FGInt2.Number[i] Then FGIntCompareAbs := Lt;

+      End;

+End;

+

+

+// Add 2 FGInts, FGInt1 + FGInt2 = Sum

+

+Procedure FGIntAdd(Const FGInt1, FGInt2 : TFGInt; Var Sum : TFGInt);

+Var

+   i, size1, size2, size, rest, Trest : LongWord;

+Begin

+   size1 := FGInt1.Number[0];

+   size2 := FGInt2.Number[0];

+   If size1 < size2 Then

+      FGIntAdd(FGInt2, FGInt1, Sum)

+   Else

+   Begin

+      If FGInt1.Sign = FGInt2.Sign Then

+      Begin

+         Sum.Sign := FGInt1.Sign;

+         setlength(Sum.Number, (size1 + 2));

+         rest := 0;

+         For i := 1 To size2 Do

+         Begin

+            Trest := FGInt1.Number[i];

+            Trest := Trest + FGInt2.Number[i];

+            Trest := Trest + rest;

+            Sum.Number[i] := Trest And 2147483647;

+            rest := Trest Shr 31;

+         End;

+         For i := (size2 + 1) To size1 Do

+         Begin

+            Trest := FGInt1.Number[i] + rest;

+            Sum.Number[i] := Trest And 2147483647;

+            rest := Trest Shr 31;

+         End;

+         size := size1 + 1;

+         Sum.Number[0] := size;

+         Sum.Number[size] := rest;

+         While (Sum.Number[size] = 0) And (size > 1) Do

+            size := size - 1;

+         If Sum.Number[0] <> size Then SetLength(Sum.Number, size + 1);

+         Sum.Number[0] := size;

+      End

+      Else

+      Begin

+         If FGIntCompareAbs(FGInt2, FGInt1) = Lt Then

+            FGIntAdd(FGInt2, FGInt1, Sum)

+         Else

+         Begin

+            SetLength(Sum.Number, (size1 + 1));

+            rest := 0;

+            For i := 1 To size2 Do

+            Begin

+               Trest := $80000000; // 2147483648;

+               TRest := Trest + FGInt1.Number[i];

+               TRest := Trest - FGInt2.Number[i];

+               TRest := Trest - rest;

+               Sum.Number[i] := Trest And 2147483647;

+               If (Trest > 2147483647) Then

+                  rest := 0

+               Else

+                  rest := 1;

+            End;

+            For i := (size2 + 1) To size1 Do

+            Begin

+               Trest := $80000000;

+               TRest := Trest + FGInt1.Number[i];

+               TRest := Trest - rest;

+               Sum.Number[i] := Trest And 2147483647;

+               If (Trest > 2147483647) Then

+                  rest := 0

+               Else

+                  rest := 1;

+            End;

+            size := size1;

+            While (Sum.Number[size] = 0) And (size > 1) Do

+               size := size - 1;

+            If size <> size1 Then SetLength(Sum.Number, size + 1);

+            Sum.Number[0] := size;

+            Sum.Sign := FGInt1.Sign;

+         End;

+      End;

+   End;

+End;

+

+

+

+Procedure FGIntChangeSign(Var FGInt : TFGInt);

+Begin

+   If FGInt.Sign = negative Then FGInt.Sign := positive Else FGInt.Sign := negative;

+End;

+

+

+// Substract 2 FGInts, FGInt1 - FGInt2 = dif

+

+Procedure FGIntSub(Var FGInt1, FGInt2, dif : TFGInt);

+Begin

+   FGIntChangeSign(FGInt2);

+   FGIntAdd(FGInt1, FGInt2, dif);

+   FGIntChangeSign(FGInt2);

+End;

+

+

+// multiply a FGInt by an integer, FGInt * by = res, by < 2147483648

+

+Procedure FGIntMulByInt(Const FGInt : TFGInt; Var res : TFGInt; by : LongWord);

+Var

+   i, size, rest : LongWord;

+   Trest : int64;

+Begin

+   size := FGInt.Number[0];

+   setlength(res.Number, (size + 2));

+   rest := 0;

+   For i := 1 To size Do

+   Begin

+      Trest := FGInt.Number[i];

+      TRest := Trest * by;

+      TRest := Trest + rest;

+      res.Number[i] := Trest And 2147483647;

+      rest := Trest Shr 31;

+   End;

+   If rest <> 0 Then

+   Begin

+      size := size + 1;

+      Res.Number[size] := rest;

+   End

+   Else

+      SetLength(Res.Number, size + 1);

+   Res.Number[0] := size;

+   Res.Sign := FGInt.Sign;

+End;

+

+

+// multiply a FGInt by an integer, FGInt * by = res, by < 1000000000

+

+Procedure FGIntMulByIntbis(Var FGInt : TFGInt; by : LongWord);

+Var

+   i, size, rest : LongWord;

+   Trest : int64;

+Begin

+   size := FGInt.Number[0];

+   Setlength(FGInt.Number, size + 2);

+   rest := 0;

+   For i := 1 To size Do

+   Begin

+      Trest := FGInt.Number[i];

+      TRest := Trest * by;

+      TRest := Trest + rest;

+      FGInt.Number[i] := Trest And 2147483647;

+      rest := Trest Shr 31;

+   End;

+   If rest <> 0 Then

+   Begin

+      size := size + 1;

+      FGInt.Number[size] := rest;

+   End

+   Else

+      SetLength(FGInt.Number, size + 1);

+   FGInt.Number[0] := size;

+End;

+

+

+// divide a FGInt by an integer, FGInt = res * by + modres

+

+Procedure FGIntDivByInt(Const FGInt : TFGInt; Var res : TFGInt; by : LongWord; Var modres : LongWord);

+Var

+   i, size : LongWord;

+   rest : int64;

+Begin

+   size := FGInt.Number[0];

+   setlength(res.Number, (size + 1));

+   modres := 0;

+   For i := size Downto 1 Do

+   Begin

+      rest := modres;

+      rest := rest Shl 31;

+      rest := rest Or FGInt.Number[i];

+      res.Number[i] := rest Div by;

+      modres := rest Mod by;

+   End;

+   While (res.Number[size] = 0) And (size > 1) Do

+      size := size - 1;

+   If size <> FGInt.Number[0] Then SetLength(res.Number, size + 1);

+   res.Number[0] := size;

+   Res.Sign := FGInt.Sign;

+   If FGInt.sign = negative Then modres := by - modres;

+End;

+                                                         

+

+// divide a FGInt by an integer, FGInt = FGInt * by + modres

+

+Procedure FGIntDivByIntBis(Var FGInt : TFGInt; by : LongWord; Var modres : LongWord);

+Var

+   i, size : LongWord;

+   temp, rest : int64;

+Begin

+   size := FGInt.Number[0];

+   temp := 0;

+   For i := size Downto 1 Do

+   Begin

+      temp := temp Shl 31;

+      rest := temp Or FGInt.Number[i];

+      FGInt.Number[i] := rest Div by;

+      temp := rest Mod by;

+   End;

+   modres := temp;

+   While (FGInt.Number[size] = 0) And (size > 1) Do

+      size := size - 1;

+   If size <> FGInt.Number[0] Then

+   Begin

+      SetLength(FGInt.Number, size + 1);

+      FGInt.Number[0] := size;

+   End;

+End;

+

+

+// Reduce a FGInt modulo by (=an integer), FGInt mod by = modres

+

+Procedure FGIntModByInt(Const FGInt : TFGInt; by : LongWord; Var modres : LongWord);

+Var

+   i, size : LongWord;

+   temp, rest : int64;

+Begin

+   size := FGInt.Number[0];

+   temp := 0;

+   For i := size Downto 1 Do

+   Begin

+      temp := temp Shl 31;

+      rest := temp Or FGInt.Number[i];

+      temp := rest Mod by;

+   End;

+   modres := temp;

+   If FGInt.sign = negative Then modres := by - modres;

+End;

+

+

+// Returns the FGInt in absolute value

+

+Procedure FGIntAbs(Var FGInt : TFGInt);

+Begin

+   FGInt.Sign := positive;

+End;

+

+

+// Copy a FGInt1 into FGInt2

+

+Procedure FGIntCopy(Const FGInt1 : TFGInt; Var FGInt2 : TFGInt);

+Begin

+   FGInt2.Sign := FGInt1.Sign;

+   FGInt2.Number := Nil;

+   FGInt2.Number := Copy(FGInt1.Number, 0, FGInt1.Number[0] + 1);

+End;

+

+

+// Shift the FGInt to the left in base 2 notation, ie FGInt = FGInt * 2

+

+Procedure FGIntShiftLeft(Var FGInt : TFGInt);

+Var

+   l, m, i, size : LongWord;

+Begin

+   size := FGInt.Number[0];

+   l := 0;

+   For i := 1 To Size Do

+   Begin

+      m := FGInt.Number[i] Shr 30;

+      FGInt.Number[i] := ((FGInt.Number[i] Shl 1) Or l) And 2147483647;

+      l := m;

+   End;

+   If l <> 0 Then

+   Begin

+      setlength(FGInt.Number, size + 2);

+      FGInt.Number[size + 1] := l;

+      FGInt.Number[0] := size + 1;

+   End;

+End;

+

+

+// Shift the FGInt to the right in base 2 notation, ie FGInt = FGInt div 2

+

+Procedure FGIntShiftRight(Var FGInt : TFGInt);

+Var

+   l, m, i, size : LongWord;

+Begin

+   size := FGInt.Number[0];

+   l := 0;

+   For i := size Downto 1 Do

+   Begin

+      m := FGInt.Number[i] And 1;

+      FGInt.Number[i] := (FGInt.Number[i] Shr 1) Or l;

+      l := m Shl 30;

+   End;

+   If (FGInt.Number[size] = 0) And (size > 1) Then

+   Begin

+      setlength(FGInt.Number, size);

+      FGInt.Number[0] := size - 1;

+   End;

+End;

+

+

+// FGInt = FGInt / 2147483648

+

+Procedure FGIntShiftRightBy31(Var FGInt : TFGInt);

+Var

+   size, i : LongWord;

+Begin

+   size := FGInt.Number[0];

+   If size > 1 Then

+   Begin

+      For i := 1 To size - 1 Do

+      Begin

+         FGInt.Number[i] := FGInt.Number[i + 1];

+      End;

+      SetLength(FGInt.Number, Size);

+      FGInt.Number[0] := size - 1;

+   End

+   Else

+      FGInt.Number[1] := 0;

+End;

+

+

+// FGInt1 = FGInt1 + FGInt2, FGInt1 > FGInt2

+

+Procedure FGIntAddBis(Var FGInt1 : TFGInt; Const FGInt2 : TFGInt);

+Var

+   i, size1, size2, Trest, rest : LongWord;

+Begin

+   size1 := FGInt1.Number[0];

+   size2 := FGInt2.Number[0];

+   rest := 0;

+   For i := 1 To size2 Do

+   Begin

+      Trest := FGInt1.Number[i] + FGInt2.Number[i] + rest;

+      rest := Trest Shr 31;

+      FGInt1.Number[i] := Trest And 2147483647;

+   End;

+   For i := size2 + 1 To size1 Do

+   Begin

+      Trest := FGInt1.Number[i] + rest;

+      rest := Trest Shr 31;

+      FGInt1.Number[i] := Trest And 2147483647;

+   End;

+   If rest <> 0 Then

+   Begin

+      SetLength(FGInt1.Number, size1 + 2);

+      FGInt1.Number[0] := size1 + 1;

+      FGInt1.Number[size1 + 1] := rest;

+   End;

+End;

+

+

+// FGInt1 = FGInt1 - FGInt2, use only when 0 < FGInt2 < FGInt1

+

+Procedure FGIntSubBis(Var FGInt1 : TFGInt; Const FGInt2 : TFGInt);

+Var

+   i, size1, size2, rest, Trest : LongWord;

+Begin

+   size1 := FGInt1.Number[0];

+   size2 := FGInt2.Number[0];

+   rest := 0;

+   For i := 1 To size2 Do

+   Begin

+      Trest := ($80000000 Or FGInt1.Number[i]) - FGInt2.Number[i] - rest;

+      If (Trest > 2147483647) Then

+         rest := 0

+      Else

+         rest := 1;

+      FGInt1.Number[i] := Trest And 2147483647;

+   End;

+   For i := size2 + 1 To size1 Do

+   Begin

+      Trest := ($80000000 Or FGInt1.Number[i]) - rest;

+      If (Trest > 2147483647) Then

+         rest := 0

+      Else

+         rest := 1;

+      FGInt1.Number[i] := Trest And 2147483647;

+   End;

+   i := size1;

+   While (FGInt1.Number[i] = 0) And (i > 1) Do

+      i := i - 1;

+   If i <> size1 Then

+   Begin

+      SetLength(FGInt1.Number, i + 1);

+      FGInt1.Number[0] := i;

+   End;

+End;

+

+

+// Multiply 2 FGInts, FGInt1 * FGInt2 = Prod

+

+Procedure FGIntMul(Const FGInt1, FGInt2 : TFGInt; Var Prod : TFGInt);

+Var

+   i, j, size, size1, size2, rest : LongWord;

+   Trest : int64;

+Begin

+   size1 := FGInt1.Number[0];

+   size2 := FGInt2.Number[0];

+   size := size1 + size2;

+   SetLength(Prod.Number, (size + 1));

+   For i := 1 To size Do

+      Prod.Number[i] := 0;

+

+   For i := 1 To size2 Do

+   Begin

+      rest := 0;

+      For j := 1 To size1 Do

+      Begin

+         Trest := FGInt1.Number[j];

+         Trest := Trest * FGInt2.Number[i];

+         Trest := Trest + Prod.Number[j + i - 1];

+         Trest := Trest + rest;

+         Prod.Number[j + i - 1] := Trest And 2147483647;

+         rest := Trest Shr 31;

+      End;

+      Prod.Number[i + size1] := rest;

+   End;

+

+   Prod.Number[0] := size;

+   While (Prod.Number[size] = 0) And (size > 1) Do

+      size := size - 1;

+   If size <> Prod.Number[0] Then

+   Begin

+      SetLength(Prod.Number, size + 1);

+      Prod.Number[0] := size;

+   End;

+   If FGInt1.Sign = FGInt2.Sign Then

+      Prod.Sign := Positive

+   Else

+      prod.Sign := negative;

+End;

+

+

+// Square a FGInt, FGInt² = Square

+

+Procedure FGIntSquare(Const FGInt : TFGInt; Var Square : TFGInt);

+Var

+   size, size1, i, j, rest : LongWord;

+   Trest : int64;

+Begin

+   size1 := FGInt.Number[0];

+   size := 2 * size1;

+   SetLength(Square.Number, (size + 1));

+   Square.Number[0] := size;

+   For i := 1 To size Do

+      Square.Number[i] := 0;

+   For i := 1 To size1 Do

+   Begin

+      Trest := FGInt.Number[i];

+      Trest := Trest * FGInt.Number[i];

+      Trest := Trest + Square.Number[2 * i - 1];

+      Square.Number[2 * i - 1] := Trest And 2147483647;

+      rest := Trest Shr 31;

+      For j := i + 1 To size1 Do

+      Begin

+         Trest := FGInt.Number[i] Shl 1;

+         Trest := Trest * FGInt.Number[j];

+         Trest := Trest + Square.Number[i + j - 1];

+         Trest := Trest + rest;

+         Square.Number[i + j - 1] := Trest And 2147483647;

+         rest := Trest Shr 31;

+      End;

+      Square.Number[i + size1] := rest;

+   End;

+   Square.Sign := positive;

+   While (Square.Number[size] = 0) And (size > 1) Do

+      size := size - 1;

+   If size <> (2 * size1) Then

+   Begin

+      SetLength(Square.Number, size + 1);

+      Square.Number[0] := size;

+   End;

+End;

+

+

+// Exponentiate a FGInt, FGInt^exp = res

+

+Procedure FGIntExp(Const FGInt, exp : TFGInt; Var res : TFGInt);

+Var

+   temp2, temp3 : TFGInt;

+   S : String;

+   i : LongWord;

+Begin

+   FGIntToBase2String(exp, S);

+   If S[length(S)] = '0' Then Base10StringToFGInt('1', res) Else FGIntCopy(FGInt, res);

+   FGIntCopy(FGInt, temp2);

+   If length(S) > 1 Then

+      For i := (length(S) - 1) Downto 1 Do

+      Begin

+         FGIntSquare(temp2, temp3);

+         FGIntCopy(temp3, temp2);

+         If S[i] = '1' Then

+         Begin

+            FGIntMul(res, temp2, temp3);

+            FGIntCopy(temp3, res);

+         End;

+      End;

+End;

+

+

+// Compute FGInt! = FGInt * (FGInt - 1) * (FGInt - 2) * ... * 3 * 2 * 1

+

+Procedure FGIntFac(Const FGInt : TFGInt; Var res : TFGInt);

+Var

+   one, temp, temp1 : TFGInt;

+Begin

+   FGIntCopy(FGInt, temp);

+   Base10StringToFGInt('1', res);

+   Base10StringToFGInt('1', one);

+

+   While Not (FGIntCompareAbs(temp, one) = Eq) Do

+   Begin

+      FGIntMul(temp, res, temp1);

+      FGIntCopy(temp1, res);

+      FGIntSubBis(temp, one);

+   End;

+

+   FGIntDestroy(one);

+   FGIntDestroy(temp);

+End;

+

+

+// FGInt = FGInt * 2147483648

+

+Procedure FGIntShiftLeftBy31(Var FGInt : TFGInt);

+Var

+   f1, f2 : LongWord;

+   i, size : longint;

+Begin

+   size := FGInt.Number[0];

+   SetLength(FGInt.Number, size + 2);

+   f1 := 0;

+   For i := 1 To (size + 1) Do

+   Begin

+      f2 := FGInt.Number[i];

+      FGInt.Number[i] := f1;

+      f1 := f2;

+   End;

+   FGInt.Number[0] := size + 1;

+End;

+

+

+// Divide 2 FGInts, FGInt1 = FGInt2 * QFGInt + MFGInt, MFGInt is always positive

+

+Procedure FGIntDivMod(Var FGInt1, FGInt2, QFGInt, MFGInt : TFGInt);

+Var

+   one, zero, temp1, temp2 : TFGInt;

+   s1, s2 : TSign;

+   j, s, t : LongWord;

+   i : int64;

+Begin

+   s1 := FGInt1.Sign;

+   s2 := FGInt2.Sign;

+   FGIntAbs(FGInt1);

+   FGIntAbs(FGInt2);

+   FGIntCopy(FGInt1, MFGInt);

+   FGIntCopy(FGInt2, temp1);

+

+   If FGIntCompareAbs(FGInt1, FGInt2) <> St Then

+   Begin

+      s := FGInt1.Number[0] - FGInt2.Number[0];

+      SetLength(QFGInt.Number, (s + 2));

+      QFGInt.Number[0] := s + 1;

+      For t := 1 To s Do

+      Begin

+         FGIntShiftLeftBy31(temp1);

+         QFGInt.Number[t] := 0;

+      End;

+      j := s + 1;

+      QFGInt.Number[j] := 0;

+      While FGIntCompareAbs(MFGInt, FGInt2) <> St Do

+      Begin

+         While FGIntCompareAbs(MFGInt, temp1) <> St Do

+         Begin

+            If MFGInt.Number[0] > temp1.Number[0] Then

+            Begin

+               i := MFGInt.Number[MFGInt.Number[0]];

+               i := i Shl 31;

+               i := i + MFGInt.Number[MFGInt.Number[0] - 1];

+               i := i Div (temp1.Number[temp1.Number[0]] + 1);

+            End

+            Else

+               i := MFGInt.Number[MFGInt.Number[0]] Div (temp1.Number[temp1.Number[0]] + 1);

+            If (i <> 0) Then

+            Begin

+               FGIntCopy(temp1, temp2);

+               FGIntMulByIntBis(temp2, i);

+               FGIntSubBis(MFGInt, temp2);

+               QFGInt.Number[j] := QFGInt.Number[j] + i;

+               If FGIntCompareAbs(MFGInt, temp2) <> St Then

+               Begin

+                  QFGInt.Number[j] := QFGInt.Number[j] + i;

+                  FGIntSubBis(MFGInt, temp2);

+               End;

+               FGIntDestroy(temp2);

+            End

+            Else

+            Begin

+               QFGInt.Number[j] := QFGInt.Number[j] + 1;

+               FGIntSubBis(MFGInt, temp1);

+            End;

+         End;

+         If MFGInt.Number[0] <= temp1.Number[0] Then

+            If FGIntCompareAbs(temp1, FGInt2) <> Eq Then

+            Begin

+               FGIntShiftRightBy31(temp1);

+               j := j - 1;

+            End;

+      End;

+   End

+   Else

+      Base10StringToFGInt('0', QFGInt);

+   s := QFGInt.Number[0];

+   While (s > 1) And (QFGInt.Number[s] = 0) Do

+      s := s - 1;

+   If s < QFGInt.Number[0] Then

+   Begin

+      setlength(QFGInt.Number, s + 1);

+      QFGInt.Number[0] := s;

+   End;

+   QFGInt.Sign := positive;

+

+   FGIntDestroy(temp1);

+   Base10StringToFGInt('0', zero);

+   Base10StringToFGInt('1', one);

+   If s1 = negative Then

+   Begin

+      If FGIntCompareAbs(MFGInt, zero) <> Eq Then

+      Begin

+         FGIntadd(QFGInt, one, temp1);

+         FGIntDestroy(QFGInt);

+         FGIntCopy(temp1, QFGInt);

+         FGIntDestroy(temp1);

+         FGIntsub(FGInt2, MFGInt, temp1);

+         FGIntDestroy(MFGInt);

+         FGIntCopy(temp1, MFGInt);

+         FGIntDestroy(temp1);

+      End;

+      If s2 = positive Then QFGInt.Sign := negative;

+   End

+   Else

+      QFGInt.Sign := s2;

+   FGIntDestroy(one);

+   FGIntDestroy(zero);

+

+   FGInt1.Sign := s1;

+   FGInt2.Sign := s2;

+End;

+

+

+// Same as above but doesn 't compute MFGInt

+

+Procedure FGIntDiv(Var FGInt1, FGInt2, QFGInt : TFGInt);

+Var

+   one, zero, temp1, temp2, MFGInt : TFGInt;

+   s1, s2 : TSign;

+   j, s, t : LongWord;

+   i : int64;

+Begin

+   s1 := FGInt1.Sign;

+   s2 := FGInt2.Sign;

+   FGIntAbs(FGInt1);

+   FGIntAbs(FGInt2);

+   FGIntCopy(FGInt1, MFGInt);

+   FGIntCopy(FGInt2, temp1);

+

+   If FGIntCompareAbs(FGInt1, FGInt2) <> St Then

+   Begin

+      s := FGInt1.Number[0] - FGInt2.Number[0];

+      SetLength(QFGInt.Number, (s + 2));

+      QFGInt.Number[0] := s + 1;

+      For t := 1 To s Do

+      Begin

+         FGIntShiftLeftBy31(temp1);

+         QFGInt.Number[t] := 0;

+      End;

+      j := s + 1;

+      QFGInt.Number[j] := 0;

+      While FGIntCompareAbs(MFGInt, FGInt2) <> St Do

+      Begin

+         While FGIntCompareAbs(MFGInt, temp1) <> St Do

+         Begin

+            If MFGInt.Number[0] > temp1.Number[0] Then

+            Begin

+               i := MFGInt.Number[MFGInt.Number[0]];

+               i := i Shl 31;

+               i := i + MFGInt.Number[MFGInt.Number[0] - 1];

+               i := i Div (temp1.Number[temp1.Number[0]] + 1);

+            End

+            Else

+               i := MFGInt.Number[MFGInt.Number[0]] Div (temp1.Number[temp1.Number[0]] + 1);

+            If (i <> 0) Then

+            Begin

+               FGIntCopy(temp1, temp2);

+               FGIntMulByIntBis(temp2, i);

+               FGIntSubBis(MFGInt, temp2);

+               QFGInt.Number[j] := QFGInt.Number[j] + i;

+               If FGIntCompareAbs(MFGInt, temp2) <> St Then

+               Begin

+                  QFGInt.Number[j] := QFGInt.Number[j] + i;

+                  FGIntSubBis(MFGInt, temp2);

+               End;

+               FGIntDestroy(temp2);

+            End

+            Else

+            Begin

+               QFGInt.Number[j] := QFGInt.Number[j] + 1;

+               FGIntSubBis(MFGInt, temp1);

+            End;

+         End;

+         If MFGInt.Number[0] <= temp1.Number[0] Then

+            If FGIntCompareAbs(temp1, FGInt2) <> Eq Then

+            Begin

+               FGIntShiftRightBy31(temp1);

+               j := j - 1;

+            End;

+      End;

+   End

+   Else

+      Base10StringToFGInt('0', QFGInt);

+   s := QFGInt.Number[0];

+   While (s > 1) And (QFGInt.Number[s] = 0) Do

+      s := s - 1;

+   If s < QFGInt.Number[0] Then

+   Begin

+      setlength(QFGInt.Number, s + 1);

+      QFGInt.Number[0] := s;

+   End;

+   QFGInt.Sign := positive;

+

+   FGIntDestroy(temp1);

+   Base10StringToFGInt('0', zero);

+   Base10StringToFGInt('1', one);

+   If s1 = negative Then

+   Begin

+      If FGIntCompareAbs(MFGInt, zero) <> Eq Then

+      Begin

+         FGIntadd(QFGInt, one, temp1);

+         FGIntDestroy(QFGInt);

+         FGIntCopy(temp1, QFGInt);

+         FGIntDestroy(temp1);

+         FGIntsub(FGInt2, MFGInt, temp1);

+         FGIntDestroy(MFGInt);

+         FGIntCopy(temp1, MFGInt);

+         FGIntDestroy(temp1);

+      End;

+      If s2 = positive Then QFGInt.Sign := negative;

+   End

+   Else

+      QFGInt.Sign := s2;

+   FGIntDestroy(one);

+   FGIntDestroy(zero);

+   FGIntDestroy(MFGInt);

+

+   FGInt1.Sign := s1;

+   FGInt2.Sign := s2;

+End;

+

+

+

+// Same as above but this computes MFGInt in stead of QFGInt

+// MFGInt = FGInt1 mod FGInt2

+

+Procedure FGIntMod(Var FGInt1, FGInt2, MFGInt : TFGInt);

+Var

+   one, zero, temp1, temp2 : TFGInt;

+   s1, s2 : TSign;

+   s, t : LongWord;

+   i : int64;

+Begin

+   s1 := FGInt1.Sign;

+   s2 := FGInt2.Sign;

+   FGIntAbs(FGInt1);

+   FGIntAbs(FGInt2);

+   FGIntCopy(FGInt1, MFGInt);

+   FGIntCopy(FGInt2, temp1);

+

+   If FGIntCompareAbs(FGInt1, FGInt2) <> St Then

+   Begin

+      s := FGInt1.Number[0] - FGInt2.Number[0];

+      For t := 1 To s Do

+         FGIntShiftLeftBy31(temp1);

+      While FGIntCompareAbs(MFGInt, FGInt2) <> St Do

+      Begin

+         While FGIntCompareAbs(MFGInt, temp1) <> St Do

+         Begin

+            If MFGInt.Number[0] > temp1.Number[0] Then

+            Begin

+               i := MFGInt.Number[MFGInt.Number[0]];

+               i := i Shl 31;

+               i := i + MFGInt.Number[MFGInt.Number[0] - 1];

+               i := i Div (temp1.Number[temp1.Number[0]] + 1);

+            End

+            Else

+               i := MFGInt.Number[MFGInt.Number[0]] Div (temp1.Number[temp1.Number[0]] + 1);

+            If (i <> 0) Then

+            Begin

+               FGIntCopy(temp1, temp2);

+               FGIntMulByIntBis(temp2, i);

+               FGIntSubBis(MFGInt, temp2);

+               If FGIntCompareAbs(MFGInt, temp2) <> St Then FGIntSubBis(MFGInt, temp2);

+               FGIntDestroy(temp2);

+            End

+            Else

+               FGIntSubBis(MFGInt, temp1);

+//         If FGIntCompareAbs(MFGInt, temp1) <> St Then FGIntSubBis(MFGInt,temp1);

+         End;

+         If MFGInt.Number[0] <= temp1.Number[0] Then

+            If FGIntCompareAbs(temp1, FGInt2) <> Eq Then FGIntShiftRightBy31(temp1);

+      End;

+   End;

+

+   FGIntDestroy(temp1);

+   Base10StringToFGInt('0', zero);

+   Base10StringToFGInt('1', one);

+   If s1 = negative Then

+   Begin

+      If FGIntCompareAbs(MFGInt, zero) <> Eq Then

+      Begin

+         FGIntSub(FGInt2, MFGInt, temp1);

+         FGIntDestroy(MFGInt);

+         FGIntCopy(temp1, MFGInt);

+         FGIntDestroy(temp1);

+      End;

+   End;

+   FGIntDestroy(one);

+   FGIntDestroy(zero);

+

+   FGInt1.Sign := s1;

+   FGInt2.Sign := s2;

+End;

+

+

+// Square a FGInt modulo Modb, FGInt^2 mod Modb = FGIntSM

+

+Procedure FGIntSquareMod(Var FGInt, Modb, FGIntSM : TFGInt);

+Var

+   temp : TFGInt;

+Begin

+   FGIntSquare(FGInt, temp);

+   FGIntMod(temp, Modb, FGIntSM);

+   FGIntDestroy(temp);

+End;

+

+

+// Add 2 FGInts modulo base, (FGInt1 + FGInt2) mod base = FGIntres

+

+Procedure FGIntAddMod(Var FGInt1, FGInt2, base, FGIntres : TFGInt);

+Var

+   temp : TFGInt;

+Begin

+   FGIntadd(FGInt1, FGInt2, temp);

+   FGIntMod(temp, base, FGIntres);

+   FGIntDestroy(temp);

+End;

+

+

+// Multiply 2 FGInts modulo base, (FGInt1 * FGInt2) mod base = FGIntres

+

+Procedure FGIntMulMod(Var FGInt1, FGInt2, base, FGIntres : TFGInt);

+Var

+   temp : TFGInt;

+Begin

+   FGIntMul(FGInt1, FGInt2, temp);

+   FGIntMod(temp, base, FGIntres);

+   FGIntDestroy(temp);

+End;

+

+

+// Exponentiate 2 FGInts modulo base, (FGInt1 ^ FGInt2) mod modb = res

+

+Procedure FGIntModExp(Var FGInt, exp, modb, res : TFGInt);

+Var

+   temp2, temp3 : TFGInt;

+   i : LongWord;

+   S : String;

+Begin

+   If (Modb.Number[1] Mod 2) = 1 Then

+   Begin

+      FGIntMontgomeryModExp(FGInt, exp, modb, res);

+      exit;

+   End;

+   FGIntToBase2String(exp, S);

+   Base10StringToFGInt('1', res);

+   FGIntcopy(FGInt, temp2);

+

+   For i := length(S) Downto 1 Do

+   Begin

+      If S[i] = '1' Then

+      Begin

+         FGIntmulMod(res, temp2, modb, temp3);

+         FGIntCopy(temp3, res);

+      End;

+      FGIntSquareMod(temp2, Modb, temp3);

+      FGIntCopy(temp3, temp2);

+   End;

+   FGIntDestroy(temp2);

+End;

+

+

+// Procedures for Montgomery Exponentiation

+

+Procedure FGIntModBis(Const FGInt : TFGInt; Var FGIntOut : TFGInt; b, head : LongWord);

+Var

+   i : LongWord;

+Begin

+   If b <= FGInt.Number[0] Then

+   Begin

+      SetLength(FGIntOut.Number, (b + 1));

+      For i := 0 To b Do

+         FGIntOut.Number[i] := FGInt.Number[i];

+      FGIntOut.Number[b] := FGIntOut.Number[b] And head;

+      i := b;

+      While (FGIntOut.Number[i] = 0) And (i > 1) Do

+         i := i - 1;

+      If i < b Then SetLength(FGIntOut.Number, i + 1);

+      FGIntOut.Number[0] := i;

+      FGIntOut.Sign := positive;

+   End

+   Else

+      FGIntCopy(FGInt, FGIntOut);

+End;

+

+

+Procedure FGIntMulModBis(Const FGInt1, FGInt2 : TFGInt; Var Prod : TFGInt; b, head : LongWord);

+Var

+   i, j, size, size1, size2, t, rest : LongWord;

+   Trest : int64;

+Begin

+   size1 := FGInt1.Number[0];

+   size2 := FGInt2.Number[0];

+   size := min(b, size1 + size2);

+   SetLength(Prod.Number, (size + 1));

+   For i := 1 To size Do

+      Prod.Number[i] := 0;

+

+   For i := 1 To size2 Do

+   Begin

+      rest := 0;

+      t := min(size1, b - i + 1);

+      For j := 1 To t Do

+      Begin

+         Trest := FGInt1.Number[j];

+	   Trest := Trest * FGInt2.Number[i];

+	   Trest := Trest + Prod.Number[j + i - 1];

+	   Trest := Trest + rest;

+         Prod.Number[j + i - 1] := Trest And 2147483647;

+         rest := Trest Shr 31;

+      End;

+      If (i + size1) <= b Then Prod.Number[i + size1] := rest;

+   End;

+

+   Prod.Number[0] := size;

+   If size = b Then Prod.Number[b] := Prod.Number[b] And head;

+   While (Prod.Number[size] = 0) And (size > 1) Do

+      size := size - 1;

+   If size < Prod.Number[0] Then

+   Begin

+      SetLength(Prod.Number, size + 1);

+      Prod.Number[0] := size;

+   End;

+   If FGInt1.Sign = FGInt2.Sign Then

+      Prod.Sign := Positive

+   Else

+      prod.Sign := negative;

+End;

+

+

+Procedure FGIntMontgomeryMod(Const GInt, base, baseInv : TFGInt; Var MGInt : TFGInt; b : Longword; head : LongWord);

+Var

+   m, temp, temp1 : TFGInt;

+   r : LongWord;

+Begin

+   FGIntModBis(GInt, temp, b, head);

+   FGIntMulModBis(temp, baseInv, m, b, head);

+   FGIntMul(m, base, temp1);

+   FGIntDestroy(temp);

+   FGIntAdd(temp1, GInt, temp);

+   FGIntDestroy(temp1);

+   MGInt.Number := copy(temp.Number, b - 1, temp.Number[0] - b + 2);

+   MGInt.Sign := positive;

+   MGInt.Number[0] := temp.Number[0] - b + 1;

+   FGIntDestroy(temp);

+   If (head Shr 30) = 0 Then FGIntDivByIntBis(MGInt, head + 1, r)

+   Else FGIntShiftRightBy31(MGInt);

+   If FGIntCompareAbs(MGInt, base) <> St Then FGIntSubBis(MGInt, base);

+   FGIntDestroy(temp);

+   FGIntDestroy(m);

+End;

+

+

+Procedure FGIntMontgomeryModExp(Var FGInt, exp, modb, res : TFGInt);

+Var

+   temp2, temp3, baseInv, r, zero : TFGInt;

+   i, j, t, b, head : LongWord;

+   S : String;

+Begin

+   Base2StringToFGInt('0', zero);

+   FGIntMod(FGInt, modb, res);

+   If FGIntCompareAbs(res, zero)=Eq then

+	Begin

+	  FGIntDestroy(zero);

+	  Exit;

+	End else FGIntDestroy(res);

+   FGIntDestroy(zero);

+

+   FGIntToBase2String(exp, S);

+   t := modb.Number[0];

+   b := t;

+

+   If (modb.Number[t] Shr 30) = 1 Then t := t + 1;

+   SetLength(r.Number, (t + 1));

+   r.Number[0] := t;

+   r.Sign := positive;

+   For i := 1 To t Do

+      r.Number[i] := 0;

+   If t = modb.Number[0] Then

+   Begin

+      head := 2147483647;

+      For j := 29 Downto 0 Do

+      Begin

+         head := head Shr 1;

+         If (modb.Number[t] Shr j) = 1 Then

+         Begin

+            r.Number[t] := 1 Shl (j + 1);

+            break;

+         End;

+      End;

+   End

+   Else

+   Begin

+      r.Number[t] := 1;

+      head := 2147483647;

+   End;

+

+   FGIntModInv(modb, r, temp2);

+   If temp2.Sign = negative Then

+      FGIntCopy(temp2, BaseInv)

+   Else

+   Begin

+      FGIntCopy(r, BaseInv);

+      FGIntSubBis(BaseInv, temp2);

+   End;

+//   FGIntBezoutBachet(r, modb, temp2, BaseInv);

+   FGIntAbs(BaseInv);

+   FGIntDestroy(temp2);

+   FGIntMod(r, modb, res);

+   FGIntMulMod(FGInt, res, modb, temp2);

+   FGIntDestroy(r);

+

+   For i := length(S) Downto 1 Do

+   Begin

+      If S[i] = '1' Then

+      Begin

+         FGIntmul(res, temp2, temp3);

+         FGIntDestroy(res);

+         FGIntMontgomeryMod(temp3, modb, baseinv, res, b, head);

+         FGIntDestroy(temp3);

+      End;

+      FGIntSquare(temp2, temp3);

+      FGIntDestroy(temp2);

+      FGIntMontgomeryMod(temp3, modb, baseinv, temp2, b, head);

+      FGIntDestroy(temp3);

+   End;

+   FGIntDestroy(temp2);

+   FGIntMontgomeryMod(res, modb, baseinv, temp3, b, head);

+   FGIntCopy(temp3, res);

+   FGIntDestroy(temp3);

+   FGIntDestroy(baseinv);

+End;

+

+

+// Compute the Greatest Common Divisor of 2 FGInts

+

+Procedure FGIntGCD(Const FGInt1, FGInt2 : TFGInt; Var GCD : TFGInt);

+Var

+   k : TCompare;

+   zero, temp1, temp2, temp3 : TFGInt;

+Begin

+   k := FGIntCompareAbs(FGInt1, FGInt2);

+   If (k = Eq) Then FGIntCopy(FGInt1, GCD) Else

+      If (k = St) Then FGIntGCD(FGInt2, FGInt1, GCD) Else

+      Begin

+         Base10StringToFGInt('0', zero);

+         FGIntCopy(FGInt1, temp1);

+         FGIntCopy(FGInt2, temp2);

+         While (temp2.Number[0] <> 1) Or (temp2.Number[1] <> 0) Do

+         Begin

+            FGIntMod(temp1, temp2, temp3);

+            FGIntCopy(temp2, temp1);

+            FGIntCopy(temp3, temp2);

+            FGIntDestroy(temp3);

+         End;

+         FGIntCopy(temp1, GCD);

+         FGIntDestroy(temp2);

+         FGIntDestroy(zero);

+      End;

+End;

+

+

+// Compute the Least Common Multiple of 2 FGInts

+

+Procedure FGIntLCM(Const FGInt1, FGInt2 : TFGInt; Var LCM : TFGInt);

+Var

+   temp1, temp2 : TFGInt;

+Begin

+   FGIntGCD(FGInt1, FGInt2, temp1);

+   FGIntmul(FGInt1, FGInt2, temp2);

+   FGIntdiv(temp2, temp1, LCM);

+   FGIntDestroy(temp1);

+   FGIntDestroy(temp2);

+End;

+

+

+// Trialdivision of a FGInt upto 9999 and stopping when a divisor is found, returning ok=false

+

+Procedure FGIntTrialDiv9999(Const FGInt : TFGInt; Var ok : boolean);

+Var

+   j : LongWord;

+   i : integer;

+Begin

+   If ((FGInt.Number[1] Mod 2) = 0) Then ok := false

+   Else

+   Begin

+      i := 0;

+      ok := true;

+      While ok And (i < 1228) Do

+      Begin

+         i := i + 1;

+         FGIntmodbyint(FGInt, primes[i], j);

+         If j = 0 Then ok := false;

+      End;

+   End;

+End;

+

+

+// A prng

+

+Procedure FGIntRandom1(Var Seed, RandomFGInt : TFGInt);

+Var

+   temp, base : TFGInt;

+Begin

+   Base10StringToFGInt('281474976710656', base);

+   Base10StringToFGInt('44485709377909', temp);

+   FGIntMulMod(seed, temp, base, RandomFGInt);

+   FGIntDestroy(temp);

+   FGIntDestroy(base);

+End;

+

+

+// Perform a Rabin Miller Primality Test nrtest times on FGIntp, returns ok=true when FGIntp passes the test

+

+Procedure FGIntRabinMiller(Var FGIntp : TFGInt; nrtest : Longword; Var ok : boolean);

+Var

+   j, b, i : LongWord;

+   m, z, temp1, temp2, temp3, zero, one, two, pmin1 : TFGInt;

+   ok1, ok2 : boolean;

+Begin

+   randomize;

+   j := 0;

+   Base10StringToFGInt('0', zero);

+   Base10StringToFGInt('1', one);

+   Base10StringToFGInt('2', two);

+   FGIntsub(FGIntp, one, temp1);

+   FGIntsub(FGIntp, one, pmin1);

+

+   b := 0;

+   While (temp1.Number[1] Mod 2) = 0 Do

+   Begin

+      b := b + 1;

+      FGIntShiftRight(temp1);

+   End;

+   m := temp1;

+

+   i := 0;

+   ok := true;

+   Randomize;

+   While (i < nrtest) And ok Do

+   Begin

+      i := i + 1;

+      Base10StringToFGInt(inttostr(Primes[Random(1227) + 1]), temp2);

+      FGIntMontGomeryModExp(temp2, m, FGIntp, z);

+      FGIntDestroy(temp2);

+      ok1 := (FGIntCompareAbs(z, one) = Eq);

+      ok2 := (FGIntCompareAbs(z, pmin1) = Eq);

+      If Not (ok1 Or ok2) Then

+      Begin

+

+         While (ok And (j < b)) Do

+         Begin

+            If (j > 0) And ok1 Then ok := false

+            Else

+            Begin

+               j := j + 1;

+               If (j < b) And (Not ok2) Then

+               Begin

+                  FGIntSquaremod(z, FGIntp, temp3);

+                  FGIntCopy(temp3, z);

+                  ok1 := (FGIntCompareAbs(z, one) = Eq);

+                  ok2 := (FGIntCompareAbs(z, pmin1) = Eq);

+                  If ok2 Then j := b;

+               End

+               Else If (Not ok2) And (j >= b) Then ok := false;

+            End;

+         End;

+

+      End

+   End;

+

+   FGIntDestroy(zero);

+   FGIntDestroy(one);

+   FGIntDestroy(two);

+   FGIntDestroy(m);

+   FGIntDestroy(z);

+   FGIntDestroy(pmin1);

+End;

+

+

+// Compute the coefficients from the Bezout Bachet theorem, FGInt1 * a + FGInt2 * b = GCD(FGInt1, FGInt2)

+

+Procedure FGIntBezoutBachet(Var FGInt1, FGInt2, a, b : TFGInt);

+Var

+   zero, r1, r2, r3, ta, gcd, temp, temp1, temp2 : TFGInt;

+Begin

+   If FGIntCompareAbs(FGInt1, FGInt2) <> St Then

+   Begin

+      FGIntcopy(FGInt1, r1);

+      FGIntcopy(FGInt2, r2);

+      Base10StringToFGInt('0', zero);

+      Base10StringToFGInt('1', a);

+      Base10StringToFGInt('0', ta);

+

+      Repeat

+         FGIntdivmod(r1, r2, temp, r3);

+         FGIntDestroy(r1);

+         r1 := r2;

+         r2 := r3;

+

+         FGIntmul(ta, temp, temp1);

+         FGIntsub(a, temp1, temp2);

+         FGIntCopy(ta, a);

+         FGIntCopy(temp2, ta);

+         FGIntDestroy(temp1);

+

+         FGIntDestroy(temp);

+      Until FGIntCompareAbs(r3, zero) = Eq;

+

+      FGIntGCD(FGInt1, FGInt2, gcd);

+      FGIntmul(a, FGInt1, temp1);

+      FGIntsub(gcd, temp1, temp2);

+      FGIntDestroy(temp1);

+      FGIntdiv(temp2, FGInt2, b);

+      FGIntDestroy(temp2);

+

+      FGIntDestroy(ta);

+      FGIntDestroy(r1);

+      FGIntDestroy(r2);

+      FGIntDestroy(gcd);

+   End

+   Else FGIntBezoutBachet(FGInt2, FGInt1, b, a);

+End;

+

+

+// Find the (multiplicative) Modular inverse of a FGInt in a finite ring

+// of additive order base

+

+Procedure FGIntModInv(Const FGInt1, base : TFGInt; Var Inverse : TFGInt);

+Var

+   zero, one, r1, r2, r3, tb, gcd, temp, temp1, temp2 : TFGInt;

+Begin

+   Base10StringToFGInt('1', one);

+   FGIntGCD(FGInt1, base, gcd);

+   If FGIntCompareAbs(one, gcd) = Eq Then

+   Begin

+      FGIntcopy(base, r1);

+      FGIntcopy(FGInt1, r2);

+      Base10StringToFGInt('0', zero);

+      Base10StringToFGInt('0', inverse);

+      Base10StringToFGInt('1', tb);

+

+      Repeat

+         FGIntDestroy(r3);

+         FGIntdivmod(r1, r2, temp, r3);

+         FGIntCopy(r2, r1);

+         FGIntCopy(r3, r2);

+

+         FGIntmul(tb, temp, temp1);

+         FGIntsub(inverse, temp1, temp2);

+         FGIntDestroy(inverse);

+         FGIntDestroy(temp1);

+         FGIntCopy(tb, inverse);

+         FGIntCopy(temp2, tb);

+

+         FGIntDestroy(temp);

+      Until FGIntCompareAbs(r3, zero) = Eq;

+

+      If inverse.Sign = negative Then

+      Begin

+         FGIntadd(base, inverse, temp);

+         FGIntCopy(temp, inverse);

+      End;

+

+      FGIntDestroy(tb);

+      FGIntDestroy(r1);

+      FGIntDestroy(r2);

+   End;

+   FGIntDestroy(gcd);

+   FGIntDestroy(one);

+End;

+

+

+// Perform a (combined) primality test on FGIntp consisting of a trialdivision upto 8192,

+// if the FGInt passes perform nrRMtests Rabin Miller primality tests, returns ok when a

+// FGInt is probably prime

+

+Procedure FGIntPrimetest(Var FGIntp : TFGInt; nrRMtests : integer; Var ok : boolean);

+Begin

+   FGIntTrialdiv9999(FGIntp, ok);

+   If ok Then FGIntRabinMiller(FGIntp, nrRMtests, ok);

+End;

+

+

+// Computes the Legendre symbol for a any number and

+// p a prime, returns 0 if p divides a, 1 if a is a

+// quadratic residu mod p, -1 if a is a quadratic

+// nonresidu mod p

+

+Procedure FGIntLegendreSymbol(Var a, p : TFGInt; Var L : integer);

+Var

+   temp1, temp2, temp3, temp4, temp5, zero, one : TFGInt;

+   i : LongWord;

+   ok1, ok2 : boolean;

+Begin

+   Base10StringToFGInt('0', zero);

+   Base10StringToFGInt('1', one);

+   FGIntMod(a, p, temp1);

+   If FGIntCompareAbs(zero, temp1) = Eq Then

+   Begin

+      FGIntDestroy(temp1);

+      L := 0;

+   End

+   Else

+   Begin

+      FGIntDestroy(temp1);

+      FGIntCopy(p, temp1);

+      FGIntCopy(a, temp2);

+      L := 1;

+      While FGIntCompareAbs(temp2, one) <> Eq Do

+      Begin

+         If (temp2.Number[1] Mod 2) = 0 Then

+         Begin

+            FGIntSquare(temp1, temp3);

+            FGIntSub(temp3, one, temp4);

+            FGIntDestroy(temp3);

+            FGIntDivByInt(temp4, temp3, 8, i);

+            If (temp3.Number[1] Mod 2) = 0 Then ok1 := false Else ok1 := true;

+            FGIntDestroy(temp3);

+            FGIntDestroy(temp4);

+            If ok1 = true Then L := L * (-1);

+            FGIntDivByIntBis(temp2, 2, i);

+         End

+         Else

+         Begin

+            FGIntSub(temp1, one, temp3);

+            FGIntSub(temp2, one, temp4);

+            FGIntMul(temp3, temp4, temp5);

+            FGIntDestroy(temp3);

+            FGIntDestroy(temp4);

+            FGIntDivByInt(temp5, temp3, 4, i);

+            If (temp3.Number[1] Mod 2) = 0 Then ok2 := false Else ok2 := true;

+            FGIntDestroy(temp5);

+            FGIntDestroy(temp3);

+            If ok2 = true Then L := L * (-1);

+            FGIntMod(temp1, temp2, temp3);

+            FGIntCopy(temp2, temp1);

+            FGIntCopy(temp3, temp2);

+         End;

+      End;

+      FGIntDestroy(temp1);

+      FGIntDestroy(temp2);

+   End;

+   FGIntDestroy(zero);

+   FGIntDestroy(one);

+End;

+

+

+// Compute a square root modulo a prime number

+// SquareRoot^2 mod Prime = Square

+

+Procedure FGIntSquareRootModP(Square, Prime : TFGInt; Var SquareRoot : TFGInt);

+Var

+   one, n, b, s, r, temp, temp1, temp2, temp3 : TFGInt;

+   a, i, j : longint;

+   L : Integer;

+Begin

+   Base2StringToFGInt('1', one);

+   Base2StringToFGInt('10', n);

+   a := 0;

+   FGIntLegendreSymbol(n, Prime, L);

+   While L <> -1 Do

+   Begin

+      FGIntAddBis(n, one);

+      FGIntLegendreSymbol(n, Prime, L);

+   End;

+   FGIntCopy(Prime, s);

+   s.Number[1] := s.Number[1] - 1;

+   While (s.Number[1] Mod 2) = 0 Do

+   Begin

+      FGIntShiftRight(s);

+      a := a + 1;

+   End;

+   FGIntMontgomeryModExp(n, s, Prime, b);

+   FGIntAdd(s, one, temp);

+   FGIntShiftRight(temp);

+   FGIntMontgomeryModExp(Square, temp, Prime, r);

+   FGIntDestroy(temp);

+   FGIntModInv(Square, Prime, temp1);

+

+   For i := 0 To (a - 2) Do

+   Begin

+      FGIntSquareMod(r, Prime, temp2);

+      FGIntMulMod(temp1, temp2, Prime, temp);

+      FGIntDestroy(temp2);

+      For j := 1 To (a - i - 2) Do

+      Begin

+         FGIntSquareMod(temp, Prime, temp2);

+         FGIntDestroy(temp);

+         FGIntCopy(temp2, temp);

+         FGIntDestroy(temp2);

+      End;

+      If FGIntCompareAbs(temp, one) <> Eq Then

+      Begin

+         FGIntMulMod(r, b, Prime, temp3);

+         FGIntDestroy(r);

+         FGIntCopy(temp3, r);

+         FGIntDestroy(temp3);

+      End;

+      FGIntDestroy(temp);

+      FGIntDestroy(temp2);

+      If i = (a - 2) Then break;

+      FGIntSquareMod(b, Prime, temp3);

+      FGIntDestroy(b);

+      FGIntCopy(temp3, b);

+      FGIntDestroy(temp3);

+   End;

+

+   FGIntCopy(r, SquareRoot);

+   FGIntDestroy(r);

+   FGIntDestroy(s);

+   FGIntDestroy(b);

+   FGIntDestroy(temp1);

+   FGIntDestroy(one);

+   FGIntDestroy(n);

+End;

+

+

+End.

diff --git a/lib/base/devel/bignums.nim b/lib/base/devel/bignums.nim
new file mode 100644
index 000000000..1d2b3685d
--- /dev/null
+++ b/lib/base/devel/bignums.nim
@@ -0,0 +1,1712 @@
+#
+#
+#            Nimrod's Runtime Library
+#        (c) Copyright 2008 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+## This module implements big integers for Nimrod.
+## This module is an adaptation of the FGInt module for Pascal by Walied
+## Othman: http://triade.studentenweb.org
+
+
+# License, info, etc
+# ------------------
+#
+# This implementation is made by me, Walied Othman, to contact me
+# mail to Walied.Othman@belgacom.net or Triade@ulyssis.org,
+# always mention wether it 's about the FGInt for Delphi or for
+# FreePascal, or wether it 's about the 6xs, preferably in the subject line.
+# If you 're going to use these implementations, at least mention my
+# name or something and notify me so I may even put a link on my page.
+# This implementation is freeware and according to the coderpunks'
+# manifesto it should remain so, so don 't use these implementations
+# in commercial software.  Encryption, as a tool to ensure privacy
+# should be free and accessible for anyone.  If you plan to use these
+# implementations in a commercial application, contact me before
+# doing so, that way you can license the software to use it in commercial
+# Software.  If any algorithm is patented in your country, you should
+# acquire a license before using this software.  Modified versions of this
+# software must contain an acknowledgement of the original author (=me).
+# This implementation is available at
+# http://triade.studentenweb.org
+#
+# copyright 2000, Walied Othman
+# This header may not be removed.
+#
+
+type
+  TBigInt* {.final.} = object ## type that represent an arbitrary long
+                              ## signed integer
+    s: int       # sign: -1 or 1
+    n: seq[int]  # the number part
+
+proc len(x: TBigInt): int {.inline.} = return x.n.len
+
+proc CompareAbs(a, b: TBigInt): int = 
+  result = a.len - b.len
+  if result == 0:
+    var i = b.len-1
+    while (i > 0) and a.n[i] == b.n[i]: dec(i)
+    result = a.n[i] - b.n[i]
+  
+const
+  bitMask = high(int)
+  bitshift = sizeof(int)*8 - 1
+  
+proc cutZeros(a: var TBigInt) =
+  var L = a.len
+  while a.len > 0 and a[L-1] == 0: dec(L)
+  setLen(a.n, L)
+  
+proc addAux(a, b: TBigInt, bSign: int): TBigInt
+  if a.len < b.len:
+    result = addAux(b, a, bSign)
+  elif a.s == bSign:
+    result.s = a.s
+    result.n = []
+    setlen(result.n, a.len+1)
+    var rest = 0
+    for i in 0..b.len-1:
+      var trest = a.n[i]
+      trest = trest +% b.n[i] +% rest
+      result.n[i] = trest and bitMask
+      rest = trest shr bitshift
+    for i in b.len .. a.len-1:
+      var trest = a.n[i] +% rest
+      result.n[i] = trest and bitMask
+      rest = trest shr bitshift
+    result.n[a.len] = rest
+    cutZeros(result)
+  elif compareAbs(a, b) > 0:
+    result = addAux(b, a, bSign)
+  else:
+    setlen(result.n, a.len+1)
+    result.s = a.s
+    var rest = 0
+    for i in 0..b.len-1: 
+      var Trest = low(int)
+      TRest = Trest +% a.n[i] -% b.n[i] -% rest
+      result.n[i] = Trest and bitmask
+      if Trest >% bitMask: rest = 0 else: rest = 1
+    for i in b.len .. a.len-1: 
+      var Trest = low(int)
+      TRest = Trest +% a.n[i] -% rest
+      result.n[i] = Trest and bitmask
+      if (Trest >% bitmask): rest = 0 else: rest = 1
+    cutZeros(result)
+
+proc `+` *(a, b: TBigInt): TBigInt =
+  ## the `+` operator for bigints
+  result = addAux(a, b, +1)
+
+proc `-` *(a, b: TBigInt): TBigInt =
+  ## the `-` operator for bigints
+  result = addAux(a, b, -1)
+
+proc mulInPlace(a: var TBigInt, b: int) = 
+  var 
+    size, rest: int32
+    Trest: int64
+  size = FGInt.Number[0]
+  setlen(FGInt.Number, size + 2)
+  rest = 0
+  for i in countup(1, size): 
+    Trest = FGInt.Number[i]
+    TRest = Trest * by
+    TRest = Trest + rest
+    FGInt.Number[i] = Trest And 2147483647
+    rest = Trest Shr 31
+  if rest != 0: 
+    size = size + 1
+    FGInt.Number[size] = rest
+  else: 
+    setlen(FGInt.Number, size + 1)
+  FGInt.Number[0] = size
+
+
+import 
+  SysUtils, Math
+
+type 
+  TCompare* = enum 
+    Lt, St, Eq, Er
+  TSign = enum 
+    negative, positive
+  TBigInt* {.final.} = object 
+    Sign: TSign
+    Number: seq[int32]
+
+
+proc zeronetochar8*(g: var char, x: String)
+proc zeronetochar6*(g: var int, x: String)
+proc initialize8*(trans: var openarray[String])
+proc initialize6*(trans: var openarray[String])
+proc initialize6PGP*(trans: var openarray[String])
+proc ConvertBase256to64*(str256: String, str64: var String)
+proc ConvertBase64to256*(str64: String, str256: var String)
+proc ConvertBase256to2*(str256: String, str2: var String)
+proc ConvertBase64to2*(str64: String, str2: var String)
+proc ConvertBase2to256*(str2: String, str256: var String)
+proc ConvertBase2to64*(str2: String, str64: var String)
+proc ConvertBase256StringToHexString*(Str256: String, HexStr: var String)
+proc ConvertHexStringToBase256String*(HexStr: String, Str256: var String)
+proc PGPConvertBase256to64*(str256, str64: var String)
+proc PGPConvertBase64to256*(str64: String, str256: var String)
+proc PGPConvertBase64to2*(str64: String, str2: var String)
+proc FGIntToBase2String*(FGInt: TBigInt, S: var String)
+proc Base2StringToFGInt*(S: String, FGInt: var TBigInt)
+proc FGIntToBase256String*(FGInt: TBigInt, str256: var String)
+proc Base256StringToFGInt*(str256: String, FGInt: var TBigInt)
+proc PGPMPIToFGInt*(PGPMPI: String, FGInt: var TBigInt)
+proc FGIntToPGPMPI*(FGInt: TBigInt, PGPMPI: var String)
+proc Base10StringToFGInt*(Base10: String, FGInt: var TBigInt)
+proc FGIntToBase10String*(FGInt: TBigInt, Base10: var String)
+proc FGIntDestroy*(FGInt: var TBigInt)
+proc FGIntCompareAbs*(FGInt1, FGInt2: TBigInt): TCompare
+proc FGIntAdd*(FGInt1, FGInt2: TBigInt, Sum: var TBigInt)
+proc FGIntChangeSign*(FGInt: var TBigInt)
+proc FGIntSub*(FGInt1, FGInt2, dif: var TBigInt)
+proc FGIntMulByInt*(FGInt: TBigInt, res: var TBigInt, by: int32)
+proc FGIntMulByIntbis*(FGInt: var TBigInt, by: int32)
+proc FGIntDivByInt*(FGInt: TBigInt, res: var TBigInt, by: int32, modres: var int32)
+proc FGIntDivByIntBis*(FGInt: var TBigInt, by: int32, modres: var int32)
+proc FGIntModByInt*(FGInt: TBigInt, by: int32, modres: var int32)
+proc FGIntAbs*(FGInt: var TBigInt)
+proc FGIntCopy*(FGInt1: TBigInt, FGInt2: var TBigInt)
+proc FGIntShiftLeft*(FGInt: var TBigInt)
+proc FGIntShiftRight*(FGInt: var TBigInt)
+proc FGIntShiftRightBy31*(FGInt: var TBigInt)
+proc FGIntAddBis*(FGInt1: var TBigInt, FGInt2: TBigInt)
+proc FGIntSubBis*(FGInt1: var TBigInt, FGInt2: TBigInt)
+proc FGIntMul*(FGInt1, FGInt2: TBigInt, Prod: var TBigInt)
+proc FGIntSquare*(FGInt: TBigInt, Square: var TBigInt)
+proc FGIntExp*(FGInt, exp: TBigInt, res: var TBigInt)
+proc FGIntFac*(FGInt: TBigInt, res: var TBigInt)
+proc FGIntShiftLeftBy31*(FGInt: var TBigInt)
+proc FGIntDivMod*(FGInt1, FGInt2, QFGInt, MFGInt: var TBigInt)
+proc FGIntDiv*(FGInt1, FGInt2, QFGInt: var TBigInt)
+proc FGIntMod*(FGInt1, FGInt2, MFGInt: var TBigInt)
+proc FGIntSquareMod*(FGInt, Modb, FGIntSM: var TBigInt)
+proc FGIntAddMod*(FGInt1, FGInt2, base, FGIntres: var TBigInt)
+proc FGIntMulMod*(FGInt1, FGInt2, base, FGIntres: var TBigInt)
+proc FGIntModExp*(FGInt, exp, modb, res: var TBigInt)
+proc FGIntModBis*(FGInt: TBigInt, FGIntOut: var TBigInt, b, head: int32)
+proc FGIntMulModBis*(FGInt1, FGInt2: TBigInt, Prod: var TBigInt, b, head: int32)
+proc FGIntMontgomeryMod*(GInt, base, baseInv: TBigInt, MGInt: var TBigInt, 
+                         b: int32, head: int32)
+proc FGIntMontgomeryModExp*(FGInt, exp, modb, res: var TBigInt)
+proc FGIntGCD*(FGInt1, FGInt2: TBigInt, GCD: var TBigInt)
+proc FGIntLCM*(FGInt1, FGInt2: TBigInt, LCM: var TBigInt)
+proc FGIntTrialDiv9999*(FGInt: TBigInt, ok: var bool)
+proc FGIntRandom1*(Seed, RandomFGInt: var TBigInt)
+proc FGIntRabinMiller*(FGIntp: var TBigInt, nrtest: int32, ok: var bool)
+proc FGIntBezoutBachet*(FGInt1, FGInt2, a, b: var TBigInt)
+proc FGIntModInv*(FGInt1, base: TBigInt, Inverse: var TBigInt)
+proc FGIntPrimetest*(FGIntp: var TBigInt, nrRMtests: int, ok: var bool)
+proc FGIntLegendreSymbol*(a, p: var TBigInt, L: var int)
+proc FGIntSquareRootModP*(Square, Prime: TBigInt, SquareRoot: var TBigInt)
+# implementation
+
+var 
+  primes: array[1..1228, int] = [3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 
+                                 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 
+                                 101, 103, 107, 109, 113, 127, 131, 137, 139, 
+                                 149, 151, 157, 163, 167, 173, 179, 181, 191, 
+                                 193, 197, 199, 211, 223, 227, 229, 233, 239, 
+                                 241, 251, 257, 263, 269, 271, 277, 281, 283, 
+                                 293, 307, 311, 313, 317, 331, 337, 347, 349, 
+                                 353, 359, 367, 373, 379, 383, 389, 397, 401, 
+                                 409, 419, 421, 431, 433, 439, 443, 449, 457, 
+                                 461, 463, 467, 479, 487, 491, 499, 503, 509, 
+                                 521, 523, 541, 547, 557, 563, 569, 571, 577, 
+                                 587, 593, 599, 601, 607, 613, 617, 619, 631, 
+                                 641, 643, 647, 653, 659, 661, 673, 677, 683, 
+                                 691, 701, 709, 719, 727, 733, 739, 743, 751, 
+                                 757, 761, 769, 773, 787, 797, 809, 811, 821, 
+                                 823, 827, 829, 839, 853, 857, 859, 863, 877, 
+                                 881, 883, 887, 907, 911, 919, 929, 937, 941, 
+                                 947, 953, 967, 971, 977, 983, 991, 997, 1009, 
+                                 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 
+                                 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 
+                                 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 
+                                 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 
+                                 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 
+                                 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 
+                                 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 
+                                 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 
+                                 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 
+                                 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 
+                                 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 
+                                 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 
+                                 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 
+                                 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 
+                                 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 
+                                 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 
+                                 1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 
+                                 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 
+                                 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 
+                                 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 
+                                 2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269, 
+                                 2273, 2281, 2287, 2293, 2297, 2309, 2311, 2333, 
+                                 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, 
+                                 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 
+                                 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 
+                                 2531, 2539, 2543, 2549, 2551, 2557, 2579, 2591, 
+                                 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659, 
+                                 2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 
+                                 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749, 
+                                 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 
+                                 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 
+                                 2887, 2897, 2903, 2909, 2917, 2927, 2939, 2953, 
+                                 2957, 2963, 2969, 2971, 2999, 3001, 3011, 3019, 
+                                 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083, 
+                                 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 
+                                 3181, 3187, 3191, 3203, 3209, 3217, 3221, 3229, 
+                                 3251, 3253, 3257, 3259, 3271, 3299, 3301, 3307, 
+                                 3313, 3319, 3323, 3329, 3331, 3343, 3347, 3359, 
+                                 3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 
+                                 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 
+                                 3511, 3517, 3527, 3529, 3533, 3539, 3541, 3547, 
+                                 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 
+                                 3617, 3623, 3631, 3637, 3643, 3659, 3671, 3673, 
+                                 3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733, 
+                                 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 
+                                 3821, 3823, 3833, 3847, 3851, 3853, 3863, 3877, 
+                                 3881, 3889, 3907, 3911, 3917, 3919, 3923, 3929, 
+                                 3931, 3943, 3947, 3967, 3989, 4001, 4003, 4007, 
+                                 4013, 4019, 4021, 4027, 4049, 4051, 4057, 4073, 
+                                 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 
+                                 4139, 4153, 4157, 4159, 4177, 4201, 4211, 4217, 
+                                 4219, 4229, 4231, 4241, 4243, 4253, 4259, 4261, 
+                                 4271, 4273, 4283, 4289, 4297, 4327, 4337, 4339, 
+                                 4349, 4357, 4363, 4373, 4391, 4397, 4409, 4421, 
+                                 4423, 4441, 4447, 4451, 4457, 4463, 4481, 4483, 
+                                 4493, 4507, 4513, 4517, 4519, 4523, 4547, 4549, 
+                                 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 
+                                 4639, 4643, 4649, 4651, 4657, 4663, 4673, 4679, 
+                                 4691, 4703, 4721, 4723, 4729, 4733, 4751, 4759, 
+                                 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 
+                                 4831, 4861, 4871, 4877, 4889, 4903, 4909, 4919, 
+                                 4931, 4933, 4937, 4943, 4951, 4957, 4967, 4969, 
+                                 4973, 4987, 4993, 4999, 5003, 5009, 5011, 5021, 
+                                 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 
+                                 5101, 5107, 5113, 5119, 5147, 5153, 5167, 5171, 
+                                 5179, 5189, 5197, 5209, 5227, 5231, 5233, 5237, 
+                                 5261, 5273, 5279, 5281, 5297, 5303, 5309, 5323, 
+                                 5333, 5347, 5351, 5381, 5387, 5393, 5399, 5407, 
+                                 5413, 5417, 5419, 5431, 5437, 5441, 5443, 5449, 
+                                 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 
+                                 5521, 5527, 5531, 5557, 5563, 5569, 5573, 5581, 
+                                 5591, 5623, 5639, 5641, 5647, 5651, 5653, 5657, 
+                                 5659, 5669, 5683, 5689, 5693, 5701, 5711, 5717, 
+                                 5737, 5741, 5743, 5749, 5779, 5783, 5791, 5801, 
+                                 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 
+                                 5857, 5861, 5867, 5869, 5879, 5881, 5897, 5903, 
+                                 5923, 5927, 5939, 5953, 5981, 5987, 6007, 6011, 
+                                 6029, 6037, 6043, 6047, 6053, 6067, 6073, 6079, 
+                                 6089, 6091, 6101, 6113, 6121, 6131, 6133, 6143, 
+                                 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 
+                                 6221, 6229, 6247, 6257, 6263, 6269, 6271, 6277, 
+                                 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337, 
+                                 6343, 6353, 6359, 6361, 6367, 6373, 6379, 6389, 
+                                 6397, 6421, 6427, 6449, 6451, 6469, 6473, 6481, 
+                                 6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 
+                                 6571, 6577, 6581, 6599, 6607, 6619, 6637, 6653, 
+                                 6659, 6661, 6673, 6679, 6689, 6691, 6701, 6703, 
+                                 6709, 6719, 6733, 6737, 6761, 6763, 6779, 6781, 
+                                 6791, 6793, 6803, 6823, 6827, 6829, 6833, 6841, 
+                                 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 
+                                 6917, 6947, 6949, 6959, 6961, 6967, 6971, 6977, 
+                                 6983, 6991, 6997, 7001, 7013, 7019, 7027, 7039, 
+                                 7043, 7057, 7069, 7079, 7103, 7109, 7121, 7127, 
+                                 7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, 
+                                 7213, 7219, 7229, 7237, 7243, 7247, 7253, 7283, 
+                                 7297, 7307, 7309, 7321, 7331, 7333, 7349, 7351, 
+                                 7369, 7393, 7411, 7417, 7433, 7451, 7457, 7459, 
+                                 7477, 7481, 7487, 7489, 7499, 7507, 7517, 7523, 
+                                 7529, 7537, 7541, 7547, 7549, 7559, 7561, 7573, 
+                                 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 
+                                 7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 
+                                 7703, 7717, 7723, 7727, 7741, 7753, 7757, 7759, 
+                                 7789, 7793, 7817, 7823, 7829, 7841, 7853, 7867, 
+                                 7873, 7877, 7879, 7883, 7901, 7907, 7919, 7927, 
+                                 7933, 7937, 7949, 7951, 7963, 7993, 8009, 8011, 
+                                 8017, 8039, 8053, 8059, 8069, 8081, 8087, 8089, 
+                                 8093, 8101, 8111, 8117, 8123, 8147, 8161, 8167, 
+                                 8171, 8179, 8191, 8209, 8219, 8221, 8231, 8233, 
+                                 8237, 8243, 8263, 8269, 8273, 8287, 8291, 8293, 
+                                 8297, 8311, 8317, 8329, 8353, 8363, 8369, 8377, 
+                                 8387, 8389, 8419, 8423, 8429, 8431, 8443, 8447, 
+                                 8461, 8467, 8501, 8513, 8521, 8527, 8537, 8539, 
+                                 8543, 8563, 8573, 8581, 8597, 8599, 8609, 8623, 
+                                 8627, 8629, 8641, 8647, 8663, 8669, 8677, 8681, 
+                                 8689, 8693, 8699, 8707, 8713, 8719, 8731, 8737, 
+                                 8741, 8747, 8753, 8761, 8779, 8783, 8803, 8807, 
+                                 8819, 8821, 8831, 8837, 8839, 8849, 8861, 8863, 
+                                 8867, 8887, 8893, 8923, 8929, 8933, 8941, 8951, 
+                                 8963, 8969, 8971, 8999, 9001, 9007, 9011, 9013, 
+                                 9029, 9041, 9043, 9049, 9059, 9067, 9091, 9103, 
+                                 9109, 9127, 9133, 9137, 9151, 9157, 9161, 9173, 
+                                 9181, 9187, 9199, 9203, 9209, 9221, 9227, 9239, 
+                                 9241, 9257, 9277, 9281, 9283, 9293, 9311, 9319, 
+                                 9323, 9337, 9341, 9343, 9349, 9371, 9377, 9391, 
+                                 9397, 9403, 9413, 9419, 9421, 9431, 9433, 9437, 
+                                 9439, 9461, 9463, 9467, 9473, 9479, 9491, 9497, 
+                                 9511, 9521, 9533, 9539, 9547, 9551, 9587, 9601, 
+                                 9613, 9619, 9623, 9629, 9631, 9643, 9649, 9661, 
+                                 9677, 9679, 9689, 9697, 9719, 9721, 9733, 9739, 
+                                 9743, 9749, 9767, 9769, 9781, 9787, 9791, 9803, 
+                                 9811, 9817, 9829, 9833, 9839, 9851, 9857, 9859, 
+                                 9871, 9883, 9887, 9901, 9907, 9923, 9929, 9931, 
+                                 9941, 9949, 9967, 9973]
+  chr64: array[1..64, char] = ['a', 'A', 'b', 'B', 'c', 'C', 'd', 'D', 'e', 'E', 
+                               'f', 'F', 'g', 'G', 'h', 'H', 'i', 'I', 'j', 'J', 
+                               'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N', 'o', 'O', 
+                               'p', 'P', 'q', 'Q', 'r', 'R', 's', 'S', 't', 'T', 
+                               'u', 'U', 'v', 'V', 'w', 'W', 'x', 'X', 'y', 'Y', 
+                               'z', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', 
+                               '8', '9', '+', '=']
+  PGPchr64: array[1..64, char] = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 
+                                  'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 
+                                  'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 
+                                  'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 
+                                  'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 
+                                  't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', 
+                                  '2', '3', '4', '5', '6', '7', '8', '9', '+', 
+                                  '/']
+
+proc zeronetochar8(g: var char, x: String) = 
+  var b: int8
+  b = 0
+  for i in countup(1, 8): 
+    if copy(x, i, 1) == '1': b = b Or (1 Shl (8 - I))
+  g = chr(b)
+
+proc zeronetochar6(g: var int, x: String) = 
+  G = 0
+  for I in countup(1, len(X)): 
+    if I > 6: break 
+    if X[I] != '0': G = G Or (1 Shl (6 - I))
+  Inc(G)
+
+proc initialize8(trans: var openarray[String]) = 
+  var 
+    x: String
+    g: char
+  for c1 in countup(0, 1): 
+    for c2 in countup(0, 1): 
+      for c3 in countup(0, 1): 
+        for c4 in countup(0, 1): 
+          for c5 in countup(0, 1): 
+            for c6 in countup(0, 1): 
+              for c7 in countup(0, 1): 
+                for c8 in countup(0, 1): 
+                  x = chr(48 + c1) + chr(48 + c2) + chr(48 + c3) + chr(48 + c4) +
+                      chr(48 + c5) + chr(48 + c6) + chr(48 + c7) + chr(48 + c8)
+                  zeronetochar8(g, x)
+                  trans[ord(g)] = x
+  
+proc initialize6(trans: var openarray[String]) = 
+  var 
+    x: String
+    g: int
+  for c1 in countup(0, 1): 
+    for c2 in countup(0, 1): 
+      for c3 in countup(0, 1): 
+        for c4 in countup(0, 1): 
+          for c5 in countup(0, 1): 
+            for c6 in countup(0, 1): 
+              x = chr(48 + c1) + chr(48 + c2) + chr(48 + c3) + chr(48 + c4) +
+                  chr(48 + c5) + chr(48 + c6)
+              zeronetochar6(g, x)
+              trans[ord(chr64[g])] = x
+  
+proc initialize6PGP(trans: var openarray[String]) = 
+  var 
+    x: String
+    g: int
+  for c1 in countup(0, 1): 
+    for c2 in countup(0, 1): 
+      for c3 in countup(0, 1): 
+        for c4 in countup(0, 1): 
+          for c5 in countup(0, 1): 
+            for c6 in countup(0, 1): 
+              x = chr(48 + c1) + chr(48 + c2) + chr(48 + c3) + chr(48 + c4) +
+                  chr(48 + c5) + chr(48 + c6)
+              zeronetochar6(g, x)
+              trans[ord(PGPchr64[g])] = x
+  
+proc ConvertBase256to64(str256: String, str64: var String) = 
+  var 
+    temp: String
+    trans: array[0..255, String]
+    len6: int32
+    g: int
+  initialize8(trans)
+  temp = ""
+  for i in countup(1, len(str256)): temp = temp + trans[ord(str256[i])]
+  while (len(temp) Mod 6) != 0: temp = temp & '0'
+  len6 = len(temp) Div 6
+  str64 = ""
+  for i in countup(1, len6): 
+    zeronetochar6(g, copy(temp, 1, 6))
+    str64 = str64 + chr64[g]
+    delete(temp, 1, 6)
+
+proc ConvertBase64to256(str64: String, str256: var String) = 
+  var 
+    temp: String
+    trans: array[0..255, String]
+    len8: int32
+    g: char
+  initialize6(trans)
+  temp = ""
+  for i in countup(1, len(str64)): temp = temp + trans[ord(str64[i])]
+  str256 = ""
+  len8 = len(temp) Div 8
+  for i in countup(1, len8): 
+    zeronetochar8(g, copy(temp, 1, 8))
+    str256 = str256 + g
+    delete(temp, 1, 8)
+
+proc ConvertBase256to2(str256: String, str2: var String) = 
+  var trans: array[0..255, String]
+  str2 = ""
+  initialize8(trans)
+  for i in countup(1, len(str256)): str2 = str2 + trans[ord(str256[i])]
+  
+proc ConvertBase64to2(str64: String, str2: var String) = 
+  var trans: array[0..255, String]
+  str2 = ""
+  initialize6(trans)
+  for i in countup(1, len(str64)): str2 = str2 + trans[ord(str64[i])]
+  
+proc ConvertBase2to256(str2: String, str256: var String) = 
+  var 
+    len8: int32
+    g: char
+  str256 = ""
+  while (len(str2) Mod 8) != 0: str2 = '0' & str2
+  len8 = len(str2) Div 8
+  for i in countup(1, len8): 
+    zeronetochar8(g, copy(str2, 1, 8))
+    str256 = str256 + g
+    delete(str2, 1, 8)
+
+proc ConvertBase2to64(str2: String, str64: var String) = 
+  var 
+    len6: int32
+    g: int
+  str64 = ""
+  while (len(str2) Mod 6) != 0: str2 = '0' & str2
+  len6 = len(str2) Div 6
+  for i in countup(1, len6): 
+    zeronetochar6(g, copy(str2, 1, 6))
+    str64 = str64 + chr64[g]
+    delete(str2, 1, 6)
+
+proc ConvertBase256StringToHexString(Str256: String, HexStr: var String) = 
+  var b: int8
+  HexStr = ""
+  for i in countup(1, len(str256)): 
+    b = ord(str256[i])
+    if (b Shr 4) < 10: HexStr = HexStr + chr(48 + (b Shr 4))
+    else: HexStr = HexStr + chr(55 + (b Shr 4))
+    if (b And 15) < 10: HexStr = HexStr + chr(48 + (b And 15))
+    else: HexStr = HexStr + chr(55 + (b And 15))
+  
+proc ConvertHexStringToBase256String(HexStr: String, Str256: var String) = 
+  var 
+    b, h1, h2: int8
+    temp: string
+  Str256 = ""
+  if (len(Hexstr) mod 2) == 1: temp = '0' & HexStr
+  else: temp = HexStr
+  for i in countup(1, (len(temp) Div 2)): 
+    h2 = ord(temp[2 * i])
+    h1 = ord(temp[2 * i - 1])
+    if h1 < 58: b = ((h1 - 48) Shl 4)
+    else: b = ((h1 - 55) Shl 4)
+    if h2 < 58: b = (b Or (h2 - 48))
+    else: b = (b Or ((h2 - 55) and 15))
+    Str256 = Str256 + chr(b)
+
+proc PGPConvertBase256to64(str256, str64: var String) = 
+  var 
+    temp, x, a: String
+    len6: int32
+    g: int
+    trans: array[0..255, String]
+  initialize8(trans)
+  temp = ""
+  for i in countup(1, len(str256)): temp = temp + trans[ord(str256[i])]
+  if (len(temp) Mod 6) == 0: 
+    a = ""
+  elif (len(temp) Mod 6) == 4: 
+    temp = temp & "00"
+    a = '='
+  else: 
+    temp = temp & "0000"
+    a = "=="
+  str64 = ""
+  len6 = len(temp) Div 6
+  for i in countup(1, len6): 
+    x = copy(temp, 1, 6)
+    zeronetochar6(g, x)
+    str64 = str64 + PGPchr64[g]
+    delete(temp, 1, 6)
+  str64 = str64 + a
+
+proc PGPConvertBase64to256(str64: String, str256: var String) = 
+  var 
+    temp, x: String
+    j, len8: int32
+    g: char
+    trans: array[0..255, String]
+  initialize6PGP(trans)
+  temp = ""
+  str256 = ""
+  if str64[len(str64) - 1] == '=': j = 2
+  elif str64[len(str64)] == '=': j = 1
+  else: j = 0
+  for i in countup(1, (len(str64) - j)): temp = temp + trans[ord(str64[i])]
+  if j != 0: delete(temp, len(temp) - 2 * j + 1, 2 * j)
+  len8 = len(temp) Div 8
+  for i in countup(1, len8): 
+    x = copy(temp, 1, 8)
+    zeronetochar8(g, x)
+    str256 = str256 + g
+    delete(temp, 1, 8)
+
+proc PGPConvertBase64to2(str64: String, str2: var String) = 
+  var 
+    j: int32
+    trans: array[0..255, String]
+  str2 = ""
+  initialize6(trans)
+  if str64[len(str64) - 1] == '=': j = 2
+  elif str64[len(str64)] == '=': j = 1
+  else: j = 0
+  for i in countup(1, (len(str64) - j)): str2 = str2 + trans[ord(str64[i])]
+  delete(str2, len(str2) - 2 * j + 1, 2 * j)
+
+proc FGIntToBase2String(FGInt: TBigInt, S: var String) = 
+  S = ""
+  for i in countup(1, FGInt.Number[0]): 
+    for j in countup(0, 30): 
+      if (1 And (FGInt.Number[i] Shr j)) == 1: S = '1' & S
+      else: S = '0' & S
+  while (len(S) > 1) And (S[1] == '0'): delete(S, 1, 1)
+  if S == "": S = '0'
+  
+proc Base2StringToFGInt(S: String, FGInt: var TBigInt) = 
+  var i, j, size: int32
+  while (S[1] == '0') And (len(S) > 1): delete(S, 1, 1)
+  size = len(S) Div 31
+  if (len(S) Mod 31) != 0: size = size + 1
+  setlen(FGInt.Number, (size + 1))
+  FGInt.Number[0] = size
+  j = 1
+  FGInt.Number[j] = 0
+  i = 0
+  while len(S) > 0: 
+    if S[len(S)] == '1': FGInt.Number[j] = FGInt.Number[j] Or (1 Shl i)
+    i = i + 1
+    if i == 31: 
+      i = 0
+      j = j + 1
+      if j <= size: FGInt.Number[j] = 0
+    delete(S, len(S), 1)
+  FGInt.Sign = positive
+
+proc FGIntToBase256String(FGInt: TBigInt, str256: var String) = 
+  var 
+    temp1: String
+    len8: int32
+    g: char
+  FGIntToBase2String(FGInt, temp1)
+  while (len(temp1) Mod 8) != 0: temp1 = '0' & temp1
+  len8 = len(temp1) Div 8
+  str256 = ""
+  for i in countup(1, len8): 
+    zeronetochar8(g, copy(temp1, 1, 8))
+    str256 = str256 + g
+    delete(temp1, 1, 8)
+
+proc Base256StringToFGInt(str256: String, FGInt: var TBigInt) = 
+  var 
+    temp1: String
+    trans: array[0..255, String]
+  temp1 = ""
+  initialize8(trans)
+  for i in countup(1, len(str256)): temp1 = temp1 + trans[ord(str256[i])]
+  while (temp1[1] == '0') And (temp1 != '0'): delete(temp1, 1, 1)
+  Base2StringToFGInt(temp1, FGInt)
+
+proc PGPMPIToFGInt(PGPMPI: String, FGInt: var TBigInt) = 
+  var temp: String
+  temp = PGPMPI
+  delete(temp, 1, 2)
+  Base256StringToFGInt(temp, FGInt)
+
+proc FGIntToPGPMPI(FGInt: TBigInt, PGPMPI: var String) = 
+  var 
+    length: int16
+    c: char
+    b: int8
+  FGIntToBase256String(FGInt, PGPMPI)
+  length = len(PGPMPI) * 8
+  c = PGPMPI[1]
+  for i in countdown(7, 0): 
+    if (ord(c) Shr i) == 0: length = length - 1
+    else: break 
+  b = length Mod 256
+  PGPMPI = chr(b) + PGPMPI
+  b = length Div 256
+  PGPMPI = chr(b) + PGPMPI
+
+proc GIntDivByIntBis1(GInt: var TBigInt, by: int32, modres: var int16) = 
+  var size, rest, temp: int32
+  size = GInt.Number[0]
+  temp = 0
+  for i in countdown(size, 1): 
+    temp = temp * 10000
+    rest = temp + GInt.Number[i]
+    GInt.Number[i] = rest Div by
+    temp = rest Mod by
+  modres = temp
+  while (GInt.Number[size] == 0) And (size > 1): size = size - 1
+  if size != GInt.Number[0]: 
+    setlen(GInt.Number, size + 1)
+    GInt.Number[0] = size
+
+proc Base10StringToFGInt(Base10: String, FGInt: var TBigInt) = 
+  var 
+    size: int32
+    j: int16
+    S, x: String
+    sign: TSign
+  while (Not (Base10[1] In {'-', '0'..'9'})) And (len(Base10) > 1): 
+    delete(Base10, 1, 1)
+  if copy(Base10, 1, 1) == '-': 
+    Sign = negative
+    delete(Base10, 1, 1)
+  else: 
+    Sign = positive
+  while (len(Base10) > 1) And (copy(Base10, 1, 1) == '0'): delete(Base10, 1, 1)
+  size = len(Base10) Div 4
+  if (len(Base10) Mod 4) != 0: size = size + 1
+  setlen(FGInt.Number, size + 1)
+  FGInt.Number[0] = size
+  for i in countup(1, (size - 1)): 
+    x = copy(Base10, len(Base10) - 3, 4)
+    FGInt.Number[i] = StrToInt(x)
+    delete(Base10, len(Base10) - 3, 4)
+  FGInt.Number[size] = StrToInt(Base10)
+  S = ""
+  while (FGInt.Number[0] != 1) Or (FGInt.Number[1] != 0): 
+    GIntDivByIntBis1(FGInt, 2, j)
+    S = inttostr(j) + S
+  if S == "": S = '0'
+  FGIntDestroy(FGInt)
+  Base2StringToFGInt(S, FGInt)
+  FGInt.Sign = sign
+
+proc FGIntToBase10String(FGInt: TBigInt, Base10: var String) = 
+  var 
+    S: String
+    j: int32
+    temp: TBigInt
+  FGIntCopy(FGInt, temp)
+  Base10 = ""
+  while (temp.Number[0] > 1) Or (temp.Number[1] > 0): 
+    FGIntDivByIntBis(temp, 10000, j)
+    S = IntToStr(j)
+    while len(S) < 4: S = '0' & S
+    Base10 = S + Base10
+  Base10 = '0' & Base10
+  while (len(Base10) > 1) And (Base10[1] == '0'): delete(Base10, 1, 1)
+  if FGInt.Sign == negative: Base10 = '-' & Base10
+  
+proc FGIntDestroy(FGInt: var TBigInt) = 
+  FGInt.Number = nil
+
+proc FGIntCompareAbs(FGInt1, FGInt2: TBigInt): TCompare = 
+  var size1, size2, i: int32
+  FGIntCompareAbs = Er
+  size1 = FGInt1.Number[0]
+  size2 = FGInt2.Number[0]
+  if size1 > size2: 
+    FGIntCompareAbs = Lt
+  elif size1 < size2: 
+    FGIntCompareAbs = St
+  else: 
+    i = size2
+    while (FGInt1.Number[i] == FGInt2.Number[i]) And (i > 1): i = i - 1
+    if FGInt1.Number[i] == FGInt2.Number[i]: FGIntCompareAbs = Eq
+    elif FGInt1.Number[i] < FGInt2.Number[i]: FGIntCompareAbs = St
+    elif FGInt1.Number[i] > FGInt2.Number[i]: FGIntCompareAbs = Lt
+  
+proc FGIntAdd(FGInt1, FGInt2: TBigInt, Sum: var TBigInt) = 
+  var size1, size2, size, rest, Trest: int32
+  size1 = FGInt1.Number[0]
+  size2 = FGInt2.Number[0]
+  if size1 < size2: 
+    FGIntAdd(FGInt2, FGInt1, Sum)
+  else: 
+    if FGInt1.Sign == FGInt2.Sign: 
+      Sum.Sign = FGInt1.Sign
+      setlen(Sum.Number, (size1 + 2))
+      rest = 0
+      for i in countup(1, size2): 
+        Trest = FGInt1.Number[i]
+        Trest = Trest + FGInt2.Number[i]
+        Trest = Trest + rest
+        Sum.Number[i] = Trest And 2147483647
+        rest = Trest Shr 31
+      for i in countup((size2 + 1), size1): 
+        Trest = FGInt1.Number[i] + rest
+        Sum.Number[i] = Trest And 2147483647
+        rest = Trest Shr 31
+      size = size1 + 1
+      Sum.Number[0] = size
+      Sum.Number[size] = rest
+      while (Sum.Number[size] == 0) And (size > 1): size = size - 1
+      if Sum.Number[0] != size: setlen(Sum.Number, size + 1)
+      Sum.Number[0] = size
+    else: 
+      if FGIntCompareAbs(FGInt2, FGInt1) == Lt: 
+        FGIntAdd(FGInt2, FGInt1, Sum)
+      else: 
+        setlen(Sum.Number, (size1 + 1))
+        rest = 0
+        for i in countup(1, size2): 
+          Trest = 0x80000000  # 2147483648;
+          TRest = Trest + FGInt1.Number[i]
+          TRest = Trest - FGInt2.Number[i]
+          TRest = Trest - rest
+          Sum.Number[i] = Trest And 2147483647
+          if (Trest > 2147483647): rest = 0
+          else: rest = 1
+        for i in countup((size2 + 1), size1): 
+          Trest = 0x80000000
+          TRest = Trest + FGInt1.Number[i]
+          TRest = Trest - rest
+          Sum.Number[i] = Trest And 2147483647
+          if (Trest > 2147483647): rest = 0
+          else: rest = 1
+        size = size1
+        while (Sum.Number[size] == 0) And (size > 1): size = size - 1
+        if size != size1: setlen(Sum.Number, size + 1)
+        Sum.Number[0] = size
+        Sum.Sign = FGInt1.Sign
+
+proc FGIntChangeSign(FGInt: var TBigInt) = 
+  if FGInt.Sign == negative: FGInt.Sign = positive
+  else: FGInt.Sign = negative
+  
+proc FGIntSub(FGInt1, FGInt2, dif: var TBigInt) = 
+  FGIntChangeSign(FGInt2)
+  FGIntAdd(FGInt1, FGInt2, dif)
+  FGIntChangeSign(FGInt2)
+
+proc FGIntMulByInt(FGInt: TBigInt, res: var TBigInt, by: int32) = 
+  var 
+    size, rest: int32
+    Trest: int64
+  size = FGInt.Number[0]
+  setlen(res.Number, (size + 2))
+  rest = 0
+  for i in countup(1, size): 
+    Trest = FGInt.Number[i]
+    TRest = Trest * by
+    TRest = Trest + rest
+    res.Number[i] = Trest And 2147483647
+    rest = Trest Shr 31
+  if rest != 0: 
+    size = size + 1
+    Res.Number[size] = rest
+  else: 
+    setlen(Res.Number, size + 1)
+  Res.Number[0] = size
+  Res.Sign = FGInt.Sign
+
+proc FGIntMulByIntbis(FGInt: var TBigInt, by: int32) = 
+  var 
+    size, rest: int32
+    Trest: int64
+  size = FGInt.Number[0]
+  setlen(FGInt.Number, size + 2)
+  rest = 0
+  for i in countup(1, size): 
+    Trest = FGInt.Number[i]
+    TRest = Trest * by
+    TRest = Trest + rest
+    FGInt.Number[i] = Trest And 2147483647
+    rest = Trest Shr 31
+  if rest != 0: 
+    size = size + 1
+    FGInt.Number[size] = rest
+  else: 
+    setlen(FGInt.Number, size + 1)
+  FGInt.Number[0] = size
+
+proc FGIntDivByInt(FGInt: TBigInt, res: var TBigInt, by: int32, modres: var int32) = 
+  var 
+    size: int32
+    rest: int64
+  size = FGInt.Number[0]
+  setlen(res.Number, (size + 1))
+  modres = 0
+  for i in countdown(size, 1): 
+    rest = modres
+    rest = rest Shl 31
+    rest = rest Or FGInt.Number[i]
+    res.Number[i] = rest Div by
+    modres = rest Mod by
+  while (res.Number[size] == 0) And (size > 1): size = size - 1
+  if size != FGInt.Number[0]: setlen(res.Number, size + 1)
+  res.Number[0] = size
+  Res.Sign = FGInt.Sign
+  if FGInt.sign == negative: modres = by - modres
+  
+proc FGIntDivByIntBis(FGInt: var TBigInt, by: int32, modres: var int32) = 
+  var 
+    size: int32
+    temp, rest: int64
+  size = FGInt.Number[0]
+  temp = 0
+  for i in countdown(size, 1): 
+    temp = temp Shl 31
+    rest = temp Or FGInt.Number[i]
+    FGInt.Number[i] = rest Div by
+    temp = rest Mod by
+  modres = temp
+  while (FGInt.Number[size] == 0) And (size > 1): size = size - 1
+  if size != FGInt.Number[0]: 
+    setlen(FGInt.Number, size + 1)
+    FGInt.Number[0] = size
+
+proc FGIntModByInt(FGInt: TBigInt, by: int32, modres: var int32) = 
+  var 
+    size: int32
+    temp, rest: int64
+  size = FGInt.Number[0]
+  temp = 0
+  for i in countdown(size, 1): 
+    temp = temp Shl 31
+    rest = temp Or FGInt.Number[i]
+    temp = rest Mod by
+  modres = temp
+  if FGInt.sign == negative: modres = by - modres
+  
+proc FGIntAbs(FGInt: var TBigInt) = 
+  FGInt.Sign = positive
+
+proc FGIntCopy(FGInt1: TBigInt, FGInt2: var TBigInt) = 
+  FGInt2.Sign = FGInt1.Sign
+  FGInt2.Number = nil
+  FGInt2.Number = Copy(FGInt1.Number, 0, FGInt1.Number[0] + 1)
+
+proc FGIntShiftLeft(FGInt: var TBigInt) = 
+  var l, m, size: int32
+  size = FGInt.Number[0]
+  l = 0
+  for i in countup(1, Size): 
+    m = FGInt.Number[i] Shr 30
+    FGInt.Number[i] = ((FGInt.Number[i] Shl 1) Or l) And 2147483647
+    l = m
+  if l != 0: 
+    setlen(FGInt.Number, size + 2)
+    FGInt.Number[size + 1] = l
+    FGInt.Number[0] = size + 1
+
+proc FGIntShiftRight(FGInt: var TBigInt) = 
+  var l, m, size: int32
+  size = FGInt.Number[0]
+  l = 0
+  for i in countdown(size, 1): 
+    m = FGInt.Number[i] And 1
+    FGInt.Number[i] = (FGInt.Number[i] Shr 1) Or l
+    l = m Shl 30
+  if (FGInt.Number[size] == 0) And (size > 1): 
+    setlen(FGInt.Number, size)
+    FGInt.Number[0] = size - 1
+
+proc FGIntShiftRightBy31(FGInt: var TBigInt) = 
+  var size: int32
+  size = FGInt.Number[0]
+  if size > 1: 
+    for i in countup(1, size - 1): 
+      FGInt.Number[i] = FGInt.Number[i + 1]
+    setlen(FGInt.Number, Size)
+    FGInt.Number[0] = size - 1
+  else: 
+    FGInt.Number[1] = 0
+  
+proc FGIntAddBis(FGInt1: var TBigInt, FGInt2: TBigInt) = 
+  var size1, size2, Trest, rest: int32
+  size1 = FGInt1.Number[0]
+  size2 = FGInt2.Number[0]
+  rest = 0
+  for i in countup(1, size2): 
+    Trest = FGInt1.Number[i] + FGInt2.Number[i] + rest
+    rest = Trest Shr 31
+    FGInt1.Number[i] = Trest And 2147483647
+  for i in countup(size2 + 1, size1): 
+    Trest = FGInt1.Number[i] + rest
+    rest = Trest Shr 31
+    FGInt1.Number[i] = Trest And 2147483647
+  if rest != 0: 
+    setlen(FGInt1.Number, size1 + 2)
+    FGInt1.Number[0] = size1 + 1
+    FGInt1.Number[size1 + 1] = rest
+
+proc FGIntSubBis(FGInt1: var TBigInt, FGInt2: TBigInt) = 
+  var size1, size2, rest, Trest: int32
+  size1 = FGInt1.Number[0]
+  size2 = FGInt2.Number[0]
+  rest = 0
+  for i in countup(1, size2): 
+    Trest = (0x80000000 Or FGInt1.Number[i]) - FGInt2.Number[i] - rest
+    if (Trest > 2147483647): rest = 0
+    else: rest = 1
+    FGInt1.Number[i] = Trest And 2147483647
+  for i in countup(size2 + 1, size1): 
+    Trest = (0x80000000 Or FGInt1.Number[i]) - rest
+    if (Trest > 2147483647): rest = 0
+    else: rest = 1
+    FGInt1.Number[i] = Trest And 2147483647
+  i = size1
+  while (FGInt1.Number[i] == 0) And (i > 1): i = i - 1
+  if i != size1: 
+    setlen(FGInt1.Number, i + 1)
+    FGInt1.Number[0] = i
+
+proc FGIntMul(FGInt1, FGInt2: TBigInt, Prod: var TBigInt) = 
+  var 
+    size, size1, size2, rest: int32
+    Trest: int64
+  size1 = FGInt1.Number[0]
+  size2 = FGInt2.Number[0]
+  size = size1 + size2
+  setlen(Prod.Number, (size + 1))
+  for i in countup(1, size): Prod.Number[i] = 0
+  for i in countup(1, size2): 
+    rest = 0
+    for j in countup(1, size1): 
+      Trest = FGInt1.Number[j]
+      Trest = Trest * FGInt2.Number[i]
+      Trest = Trest + Prod.Number[j + i - 1]
+      Trest = Trest + rest
+      Prod.Number[j + i - 1] = Trest And 2147483647
+      rest = Trest Shr 31
+    Prod.Number[i + size1] = rest
+  Prod.Number[0] = size
+  while (Prod.Number[size] == 0) And (size > 1): size = size - 1
+  if size != Prod.Number[0]: 
+    setlen(Prod.Number, size + 1)
+    Prod.Number[0] = size
+  if FGInt1.Sign == FGInt2.Sign: Prod.Sign = Positive
+  else: prod.Sign = negative
+  
+proc FGIntSquare(FGInt: TBigInt, Square: var TBigInt) = 
+  var 
+    size, size1, rest: int32
+    Trest: int64
+  size1 = FGInt.Number[0]
+  size = 2 * size1
+  setlen(Square.Number, (size + 1))
+  Square.Number[0] = size
+  for i in countup(1, size): Square.Number[i] = 0
+  for i in countup(1, size1): 
+    Trest = FGInt.Number[i]
+    Trest = Trest * FGInt.Number[i]
+    Trest = Trest + Square.Number[2 * i - 1]
+    Square.Number[2 * i - 1] = Trest And 2147483647
+    rest = Trest Shr 31
+    for j in countup(i + 1, size1): 
+      Trest = FGInt.Number[i] Shl 1
+      Trest = Trest * FGInt.Number[j]
+      Trest = Trest + Square.Number[i + j - 1]
+      Trest = Trest + rest
+      Square.Number[i + j - 1] = Trest And 2147483647
+      rest = Trest Shr 31
+    Square.Number[i + size1] = rest
+  Square.Sign = positive
+  while (Square.Number[size] == 0) And (size > 1): size = size - 1
+  if size != (2 * size1): 
+    setlen(Square.Number, size + 1)
+    Square.Number[0] = size
+
+proc FGIntExp(FGInt, exp: TBigInt, res: var TBigInt) = 
+  var 
+    temp2, temp3: TBigInt
+    S: String
+  FGIntToBase2String(exp, S)
+  if S[len(S)] == '0': Base10StringToFGInt('1', res)
+  else: FGIntCopy(FGInt, res)
+  FGIntCopy(FGInt, temp2)
+  if len(S) > 1: 
+    for i in countdown((len(S) - 1), 1): 
+      FGIntSquare(temp2, temp3)
+      FGIntCopy(temp3, temp2)
+      if S[i] == '1': 
+        FGIntMul(res, temp2, temp3)
+        FGIntCopy(temp3, res)
+  
+proc FGIntFac(FGInt: TBigInt, res: var TBigInt) = 
+  var one, temp, temp1: TBigInt
+  FGIntCopy(FGInt, temp)
+  Base10StringToFGInt('1', res)
+  Base10StringToFGInt('1', one)
+  while Not (FGIntCompareAbs(temp, one) == Eq): 
+    FGIntMul(temp, res, temp1)
+    FGIntCopy(temp1, res)
+    FGIntSubBis(temp, one)
+  FGIntDestroy(one)
+  FGIntDestroy(temp)
+
+proc FGIntShiftLeftBy31(FGInt: var TBigInt) = 
+  var 
+    f1, f2: int32
+    size: int32
+  size = FGInt.Number[0]
+  setlen(FGInt.Number, size + 2)
+  f1 = 0
+  for i in countup(1, (size + 1)): 
+    f2 = FGInt.Number[i]
+    FGInt.Number[i] = f1
+    f1 = f2
+  FGInt.Number[0] = size + 1
+
+proc FGIntDivMod(FGInt1, FGInt2, QFGInt, MFGInt: var TBigInt) = 
+  var 
+    one, zero, temp1, temp2: TBigInt
+    s1, s2: TSign
+    j, s: int32
+    i: int64
+  s1 = FGInt1.Sign
+  s2 = FGInt2.Sign
+  FGIntAbs(FGInt1)
+  FGIntAbs(FGInt2)
+  FGIntCopy(FGInt1, MFGInt)
+  FGIntCopy(FGInt2, temp1)
+  if FGIntCompareAbs(FGInt1, FGInt2) != St: 
+    s = FGInt1.Number[0] - FGInt2.Number[0]
+    setlen(QFGInt.Number, (s + 2))
+    QFGInt.Number[0] = s + 1
+    for t in countup(1, s): 
+      FGIntShiftLeftBy31(temp1)
+      QFGInt.Number[t] = 0
+    j = s + 1
+    QFGInt.Number[j] = 0
+    while FGIntCompareAbs(MFGInt, FGInt2) != St: 
+      while FGIntCompareAbs(MFGInt, temp1) != St: 
+        if MFGInt.Number[0] > temp1.Number[0]: 
+          i = MFGInt.Number[MFGInt.Number[0]]
+          i = i Shl 31
+          i = i + MFGInt.Number[MFGInt.Number[0] - 1]
+          i = i Div (temp1.Number[temp1.Number[0]] + 1)
+        else: 
+          i = MFGInt.Number[MFGInt.Number[0]] Div
+              (temp1.Number[temp1.Number[0]] + 1)
+        if (i != 0): 
+          FGIntCopy(temp1, temp2)
+          FGIntMulByIntBis(temp2, i)
+          FGIntSubBis(MFGInt, temp2)
+          QFGInt.Number[j] = QFGInt.Number[j] + i
+          if FGIntCompareAbs(MFGInt, temp2) != St: 
+            QFGInt.Number[j] = QFGInt.Number[j] + i
+            FGIntSubBis(MFGInt, temp2)
+          FGIntDestroy(temp2)
+        else: 
+          QFGInt.Number[j] = QFGInt.Number[j] + 1
+          FGIntSubBis(MFGInt, temp1)
+      if MFGInt.Number[0] <= temp1.Number[0]: 
+        if FGIntCompareAbs(temp1, FGInt2) != Eq: 
+          FGIntShiftRightBy31(temp1)
+          j = j - 1
+  else: 
+    Base10StringToFGInt('0', QFGInt)
+  s = QFGInt.Number[0]
+  while (s > 1) And (QFGInt.Number[s] == 0): s = s - 1
+  if s < QFGInt.Number[0]: 
+    setlen(QFGInt.Number, s + 1)
+    QFGInt.Number[0] = s
+  QFGInt.Sign = positive
+  FGIntDestroy(temp1)
+  Base10StringToFGInt('0', zero)
+  Base10StringToFGInt('1', one)
+  if s1 == negative: 
+    if FGIntCompareAbs(MFGInt, zero) != Eq: 
+      FGIntadd(QFGInt, one, temp1)
+      FGIntDestroy(QFGInt)
+      FGIntCopy(temp1, QFGInt)
+      FGIntDestroy(temp1)
+      FGIntsub(FGInt2, MFGInt, temp1)
+      FGIntDestroy(MFGInt)
+      FGIntCopy(temp1, MFGInt)
+      FGIntDestroy(temp1)
+    if s2 == positive: QFGInt.Sign = negative
+  else: 
+    QFGInt.Sign = s2
+  FGIntDestroy(one)
+  FGIntDestroy(zero)
+  FGInt1.Sign = s1
+  FGInt2.Sign = s2
+
+proc FGIntDiv(FGInt1, FGInt2, QFGInt: var TBigInt) = 
+  var 
+    one, zero, temp1, temp2, MFGInt: TBigInt
+    s1, s2: TSign
+    j, s: int32
+    i: int64
+  s1 = FGInt1.Sign
+  s2 = FGInt2.Sign
+  FGIntAbs(FGInt1)
+  FGIntAbs(FGInt2)
+  FGIntCopy(FGInt1, MFGInt)
+  FGIntCopy(FGInt2, temp1)
+  if FGIntCompareAbs(FGInt1, FGInt2) != St: 
+    s = FGInt1.Number[0] - FGInt2.Number[0]
+    setlen(QFGInt.Number, (s + 2))
+    QFGInt.Number[0] = s + 1
+    for t in countup(1, s): 
+      FGIntShiftLeftBy31(temp1)
+      QFGInt.Number[t] = 0
+    j = s + 1
+    QFGInt.Number[j] = 0
+    while FGIntCompareAbs(MFGInt, FGInt2) != St: 
+      while FGIntCompareAbs(MFGInt, temp1) != St: 
+        if MFGInt.Number[0] > temp1.Number[0]: 
+          i = MFGInt.Number[MFGInt.Number[0]]
+          i = i Shl 31
+          i = i + MFGInt.Number[MFGInt.Number[0] - 1]
+          i = i Div (temp1.Number[temp1.Number[0]] + 1)
+        else: 
+          i = MFGInt.Number[MFGInt.Number[0]] Div
+              (temp1.Number[temp1.Number[0]] + 1)
+        if (i != 0): 
+          FGIntCopy(temp1, temp2)
+          FGIntMulByIntBis(temp2, i)
+          FGIntSubBis(MFGInt, temp2)
+          QFGInt.Number[j] = QFGInt.Number[j] + i
+          if FGIntCompareAbs(MFGInt, temp2) != St: 
+            QFGInt.Number[j] = QFGInt.Number[j] + i
+            FGIntSubBis(MFGInt, temp2)
+          FGIntDestroy(temp2)
+        else: 
+          QFGInt.Number[j] = QFGInt.Number[j] + 1
+          FGIntSubBis(MFGInt, temp1)
+      if MFGInt.Number[0] <= temp1.Number[0]: 
+        if FGIntCompareAbs(temp1, FGInt2) != Eq: 
+          FGIntShiftRightBy31(temp1)
+          j = j - 1
+  else: 
+    Base10StringToFGInt('0', QFGInt)
+  s = QFGInt.Number[0]
+  while (s > 1) And (QFGInt.Number[s] == 0): s = s - 1
+  if s < QFGInt.Number[0]: 
+    setlen(QFGInt.Number, s + 1)
+    QFGInt.Number[0] = s
+  QFGInt.Sign = positive
+  FGIntDestroy(temp1)
+  Base10StringToFGInt('0', zero)
+  Base10StringToFGInt('1', one)
+  if s1 == negative: 
+    if FGIntCompareAbs(MFGInt, zero) != Eq: 
+      FGIntadd(QFGInt, one, temp1)
+      FGIntDestroy(QFGInt)
+      FGIntCopy(temp1, QFGInt)
+      FGIntDestroy(temp1)
+      FGIntsub(FGInt2, MFGInt, temp1)
+      FGIntDestroy(MFGInt)
+      FGIntCopy(temp1, MFGInt)
+      FGIntDestroy(temp1)
+    if s2 == positive: QFGInt.Sign = negative
+  else: 
+    QFGInt.Sign = s2
+  FGIntDestroy(one)
+  FGIntDestroy(zero)
+  FGIntDestroy(MFGInt)
+  FGInt1.Sign = s1
+  FGInt2.Sign = s2
+
+proc FGIntMod(FGInt1, FGInt2, MFGInt: var TBigInt) = 
+  var 
+    one, zero, temp1, temp2: TBigInt
+    s1, s2: TSign
+    s: int32
+    i: int64
+  s1 = FGInt1.Sign
+  s2 = FGInt2.Sign
+  FGIntAbs(FGInt1)
+  FGIntAbs(FGInt2)
+  FGIntCopy(FGInt1, MFGInt)
+  FGIntCopy(FGInt2, temp1)
+  if FGIntCompareAbs(FGInt1, FGInt2) != St: 
+    s = FGInt1.Number[0] - FGInt2.Number[0]
+    for t in countup(1, s): FGIntShiftLeftBy31(temp1)
+    while FGIntCompareAbs(MFGInt, FGInt2) != St: 
+      while FGIntCompareAbs(MFGInt, temp1) != St: 
+        if MFGInt.Number[0] > temp1.Number[0]: 
+          i = MFGInt.Number[MFGInt.Number[0]]
+          i = i Shl 31
+          i = i + MFGInt.Number[MFGInt.Number[0] - 1]
+          i = i Div (temp1.Number[temp1.Number[0]] + 1)
+        else: 
+          i = MFGInt.Number[MFGInt.Number[0]] Div
+              (temp1.Number[temp1.Number[0]] + 1)
+        if (i != 0): 
+          FGIntCopy(temp1, temp2)
+          FGIntMulByIntBis(temp2, i)
+          FGIntSubBis(MFGInt, temp2)
+          if FGIntCompareAbs(MFGInt, temp2) != St: FGIntSubBis(MFGInt, temp2)
+          FGIntDestroy(temp2)
+        else: 
+          FGIntSubBis(MFGInt, temp1) #         If FGIntCompareAbs(MFGInt, temp1) <> St Then FGIntSubBis(MFGInt,temp1);
+      if MFGInt.Number[0] <= temp1.Number[0]: 
+        if FGIntCompareAbs(temp1, FGInt2) != Eq: FGIntShiftRightBy31(temp1)
+  FGIntDestroy(temp1)
+  Base10StringToFGInt('0', zero)
+  Base10StringToFGInt('1', one)
+  if s1 == negative: 
+    if FGIntCompareAbs(MFGInt, zero) != Eq: 
+      FGIntSub(FGInt2, MFGInt, temp1)
+      FGIntDestroy(MFGInt)
+      FGIntCopy(temp1, MFGInt)
+      FGIntDestroy(temp1)
+  FGIntDestroy(one)
+  FGIntDestroy(zero)
+  FGInt1.Sign = s1
+  FGInt2.Sign = s2
+
+proc FGIntSquareMod(FGInt, Modb, FGIntSM: var TBigInt) = 
+  var temp: TBigInt
+  FGIntSquare(FGInt, temp)
+  FGIntMod(temp, Modb, FGIntSM)
+  FGIntDestroy(temp)
+
+proc FGIntAddMod(FGInt1, FGInt2, base, FGIntres: var TBigInt) = 
+  var temp: TBigInt
+  FGIntadd(FGInt1, FGInt2, temp)
+  FGIntMod(temp, base, FGIntres)
+  FGIntDestroy(temp)
+
+proc FGIntMulMod(FGInt1, FGInt2, base, FGIntres: var TBigInt) = 
+  var temp: TBigInt
+  FGIntMul(FGInt1, FGInt2, temp)
+  FGIntMod(temp, base, FGIntres)
+  FGIntDestroy(temp)
+
+proc FGIntModExp(FGInt, exp, modb, res: var TBigInt) = 
+  var 
+    temp2, temp3: TBigInt
+    S: String
+  if (Modb.Number[1] Mod 2) == 1: 
+    FGIntMontgomeryModExp(FGInt, exp, modb, res)
+    return 
+  FGIntToBase2String(exp, S)
+  Base10StringToFGInt('1', res)
+  FGIntcopy(FGInt, temp2)
+  for i in countdown(len(S), 1): 
+    if S[i] == '1': 
+      FGIntmulMod(res, temp2, modb, temp3)
+      FGIntCopy(temp3, res)
+    FGIntSquareMod(temp2, Modb, temp3)
+    FGIntCopy(temp3, temp2)
+  FGIntDestroy(temp2)
+
+proc FGIntModBis(FGInt: TBigInt, FGIntOut: var TBigInt, b, head: int32) = 
+  if b <= FGInt.Number[0]: 
+    setlen(FGIntOut.Number, (b + 1))
+    for i in countup(0, b): FGIntOut.Number[i] = FGInt.Number[i]
+    FGIntOut.Number[b] = FGIntOut.Number[b] And head
+    i = b
+    while (FGIntOut.Number[i] == 0) And (i > 1): i = i - 1
+    if i < b: setlen(FGIntOut.Number, i + 1)
+    FGIntOut.Number[0] = i
+    FGIntOut.Sign = positive
+  else: 
+    FGIntCopy(FGInt, FGIntOut)
+  
+proc FGIntMulModBis(FGInt1, FGInt2: TBigInt, Prod: var TBigInt, b, head: int32) = 
+  var 
+    size, size1, size2, t, rest: int32
+    Trest: int64
+  size1 = FGInt1.Number[0]
+  size2 = FGInt2.Number[0]
+  size = min(b, size1 + size2)
+  setlen(Prod.Number, (size + 1))
+  for i in countup(1, size): Prod.Number[i] = 0
+  for i in countup(1, size2): 
+    rest = 0
+    t = min(size1, b - i + 1)
+    for j in countup(1, t): 
+      Trest = FGInt1.Number[j]
+      Trest = Trest * FGInt2.Number[i]
+      Trest = Trest + Prod.Number[j + i - 1]
+      Trest = Trest + rest
+      Prod.Number[j + i - 1] = Trest And 2147483647
+      rest = Trest Shr 31
+    if (i + size1) <= b: Prod.Number[i + size1] = rest
+  Prod.Number[0] = size
+  if size == b: Prod.Number[b] = Prod.Number[b] And head
+  while (Prod.Number[size] == 0) And (size > 1): size = size - 1
+  if size < Prod.Number[0]: 
+    setlen(Prod.Number, size + 1)
+    Prod.Number[0] = size
+  if FGInt1.Sign == FGInt2.Sign: Prod.Sign = Positive
+  else: prod.Sign = negative
+  
+proc FGIntMontgomeryMod(GInt, base, baseInv: TBigInt, MGInt: var TBigInt, 
+                        b: int32, head: int32) = 
+  var 
+    m, temp, temp1: TBigInt
+    r: int32
+  FGIntModBis(GInt, temp, b, head)
+  FGIntMulModBis(temp, baseInv, m, b, head)
+  FGIntMul(m, base, temp1)
+  FGIntDestroy(temp)
+  FGIntAdd(temp1, GInt, temp)
+  FGIntDestroy(temp1)
+  MGInt.Number = copy(temp.Number, b - 1, temp.Number[0] - b + 2)
+  MGInt.Sign = positive
+  MGInt.Number[0] = temp.Number[0] - b + 1
+  FGIntDestroy(temp)
+  if (head Shr 30) == 0: FGIntDivByIntBis(MGInt, head + 1, r)
+  else: FGIntShiftRightBy31(MGInt)
+  if FGIntCompareAbs(MGInt, base) != St: FGIntSubBis(MGInt, base)
+  FGIntDestroy(temp)
+  FGIntDestroy(m)
+
+proc FGIntMontgomeryModExp(FGInt, exp, modb, res: var TBigInt) = 
+  var 
+    temp2, temp3, baseInv, r, zero: TBigInt
+    t, b, head: int32
+    S: String
+  Base2StringToFGInt('0', zero)
+  FGIntMod(FGInt, modb, res)
+  if FGIntCompareAbs(res, zero) == Eq: 
+    FGIntDestroy(zero)
+    return 
+  else: 
+    FGIntDestroy(res)
+  FGIntDestroy(zero)
+  FGIntToBase2String(exp, S)
+  t = modb.Number[0]
+  b = t
+  if (modb.Number[t] Shr 30) == 1: t = t + 1
+  setlen(r.Number, (t + 1))
+  r.Number[0] = t
+  r.Sign = positive
+  for i in countup(1, t): r.Number[i] = 0
+  if t == modb.Number[0]: 
+    head = 2147483647
+    for j in countdown(29, 0): 
+      head = head Shr 1
+      if (modb.Number[t] Shr j) == 1: 
+        r.Number[t] = 1 Shl (j + 1)
+        break 
+  else: 
+    r.Number[t] = 1
+    head = 2147483647
+  FGIntModInv(modb, r, temp2)
+  if temp2.Sign == negative: 
+    FGIntCopy(temp2, BaseInv)
+  else: 
+    FGIntCopy(r, BaseInv)
+    FGIntSubBis(BaseInv, temp2)
+  FGIntAbs(BaseInv)
+  FGIntDestroy(temp2)
+  FGIntMod(r, modb, res)
+  FGIntMulMod(FGInt, res, modb, temp2)
+  FGIntDestroy(r)
+  for i in countdown(len(S), 1): 
+    if S[i] == '1': 
+      FGIntmul(res, temp2, temp3)
+      FGIntDestroy(res)
+      FGIntMontgomeryMod(temp3, modb, baseinv, res, b, head)
+      FGIntDestroy(temp3)
+    FGIntSquare(temp2, temp3)
+    FGIntDestroy(temp2)
+    FGIntMontgomeryMod(temp3, modb, baseinv, temp2, b, head)
+    FGIntDestroy(temp3)
+  FGIntDestroy(temp2)
+  FGIntMontgomeryMod(res, modb, baseinv, temp3, b, head)
+  FGIntCopy(temp3, res)
+  FGIntDestroy(temp3)
+  FGIntDestroy(baseinv)
+
+proc FGIntGCD(FGInt1, FGInt2: TBigInt, GCD: var TBigInt) = 
+  var 
+    k: TCompare
+    zero, temp1, temp2, temp3: TBigInt
+  k = FGIntCompareAbs(FGInt1, FGInt2)
+  if (k == Eq): 
+    FGIntCopy(FGInt1, GCD)
+  elif (k == St): 
+    FGIntGCD(FGInt2, FGInt1, GCD)
+  else: 
+    Base10StringToFGInt('0', zero)
+    FGIntCopy(FGInt1, temp1)
+    FGIntCopy(FGInt2, temp2)
+    while (temp2.Number[0] != 1) Or (temp2.Number[1] != 0): 
+      FGIntMod(temp1, temp2, temp3)
+      FGIntCopy(temp2, temp1)
+      FGIntCopy(temp3, temp2)
+      FGIntDestroy(temp3)
+    FGIntCopy(temp1, GCD)
+    FGIntDestroy(temp2)
+    FGIntDestroy(zero)
+
+proc FGIntLCM(FGInt1, FGInt2: TBigInt, LCM: var TBigInt) = 
+  var temp1, temp2: TBigInt
+  FGIntGCD(FGInt1, FGInt2, temp1)
+  FGIntmul(FGInt1, FGInt2, temp2)
+  FGIntdiv(temp2, temp1, LCM)
+  FGIntDestroy(temp1)
+  FGIntDestroy(temp2)
+
+proc FGIntTrialDiv9999(FGInt: TBigInt, ok: var bool) = 
+  var 
+    j: int32
+    i: int
+  if ((FGInt.Number[1] Mod 2) == 0): 
+    ok = false
+  else: 
+    i = 0
+    ok = true
+    while ok And (i < 1228): 
+      i = i + 1
+      FGIntmodbyint(FGInt, primes[i], j)
+      if j == 0: ok = false
+  
+proc FGIntRandom1(Seed, RandomFGInt: var TBigInt) = 
+  var temp, base: TBigInt
+  Base10StringToFGInt("281474976710656", base)
+  Base10StringToFGInt("44485709377909", temp)
+  FGIntMulMod(seed, temp, base, RandomFGInt)
+  FGIntDestroy(temp)
+  FGIntDestroy(base)
+
+proc FGIntRabinMiller(FGIntp: var TBigInt, nrtest: int32, ok: var bool) = 
+  var 
+    j, b, i: int32
+    m, z, temp1, temp2, temp3, zero, one, two, pmin1: TBigInt
+    ok1, ok2: bool
+  randomize
+  j = 0
+  Base10StringToFGInt('0', zero)
+  Base10StringToFGInt('1', one)
+  Base10StringToFGInt('2', two)
+  FGIntsub(FGIntp, one, temp1)
+  FGIntsub(FGIntp, one, pmin1)
+  b = 0
+  while (temp1.Number[1] Mod 2) == 0: 
+    b = b + 1
+    FGIntShiftRight(temp1)
+  m = temp1
+  i = 0
+  ok = true
+  Randomize
+  while (i < nrtest) And ok: 
+    i = i + 1
+    Base10StringToFGInt(inttostr(Primes[Random(1227) + 1]), temp2)
+    FGIntMontGomeryModExp(temp2, m, FGIntp, z)
+    FGIntDestroy(temp2)
+    ok1 = (FGIntCompareAbs(z, one) == Eq)
+    ok2 = (FGIntCompareAbs(z, pmin1) == Eq)
+    if Not (ok1 Or ok2): 
+      while (ok And (j < b)): 
+        if (j > 0) And ok1: 
+          ok = false
+        else: 
+          j = j + 1
+          if (j < b) And (Not ok2): 
+            FGIntSquaremod(z, FGIntp, temp3)
+            FGIntCopy(temp3, z)
+            ok1 = (FGIntCompareAbs(z, one) == Eq)
+            ok2 = (FGIntCompareAbs(z, pmin1) == Eq)
+            if ok2: j = b
+          elif (Not ok2) And (j >= b): 
+            ok = false
+  FGIntDestroy(zero)
+  FGIntDestroy(one)
+  FGIntDestroy(two)
+  FGIntDestroy(m)
+  FGIntDestroy(z)
+  FGIntDestroy(pmin1)
+
+proc FGIntBezoutBachet(FGInt1, FGInt2, a, b: var TBigInt) = 
+  var zero, r1, r2, r3, ta, gcd, temp, temp1, temp2: TBigInt
+  if FGIntCompareAbs(FGInt1, FGInt2) != St: 
+    FGIntcopy(FGInt1, r1)
+    FGIntcopy(FGInt2, r2)
+    Base10StringToFGInt('0', zero)
+    Base10StringToFGInt('1', a)
+    Base10StringToFGInt('0', ta)
+    while true: 
+      FGIntdivmod(r1, r2, temp, r3)
+      FGIntDestroy(r1)
+      r1 = r2
+      r2 = r3
+      FGIntmul(ta, temp, temp1)
+      FGIntsub(a, temp1, temp2)
+      FGIntCopy(ta, a)
+      FGIntCopy(temp2, ta)
+      FGIntDestroy(temp1)
+      FGIntDestroy(temp)
+      if FGIntCompareAbs(r3, zero) == Eq: break 
+    FGIntGCD(FGInt1, FGInt2, gcd)
+    FGIntmul(a, FGInt1, temp1)
+    FGIntsub(gcd, temp1, temp2)
+    FGIntDestroy(temp1)
+    FGIntdiv(temp2, FGInt2, b)
+    FGIntDestroy(temp2)
+    FGIntDestroy(ta)
+    FGIntDestroy(r1)
+    FGIntDestroy(r2)
+    FGIntDestroy(gcd)
+  else: 
+    FGIntBezoutBachet(FGInt2, FGInt1, b, a)
+  
+proc FGIntModInv(FGInt1, base: TBigInt, Inverse: var TBigInt) = 
+  var zero, one, r1, r2, r3, tb, gcd, temp, temp1, temp2: TBigInt
+  Base10StringToFGInt('1', one)
+  FGIntGCD(FGInt1, base, gcd)
+  if FGIntCompareAbs(one, gcd) == Eq: 
+    FGIntcopy(base, r1)
+    FGIntcopy(FGInt1, r2)
+    Base10StringToFGInt('0', zero)
+    Base10StringToFGInt('0', inverse)
+    Base10StringToFGInt('1', tb)
+    while true: 
+      FGIntDestroy(r3)
+      FGIntdivmod(r1, r2, temp, r3)
+      FGIntCopy(r2, r1)
+      FGIntCopy(r3, r2)
+      FGIntmul(tb, temp, temp1)
+      FGIntsub(inverse, temp1, temp2)
+      FGIntDestroy(inverse)
+      FGIntDestroy(temp1)
+      FGIntCopy(tb, inverse)
+      FGIntCopy(temp2, tb)
+      FGIntDestroy(temp)
+      if FGIntCompareAbs(r3, zero) == Eq: break 
+    if inverse.Sign == negative: 
+      FGIntadd(base, inverse, temp)
+      FGIntCopy(temp, inverse)
+    FGIntDestroy(tb)
+    FGIntDestroy(r1)
+    FGIntDestroy(r2)
+  FGIntDestroy(gcd)
+  FGIntDestroy(one)
+
+proc FGIntPrimetest(FGIntp: var TBigInt, nrRMtests: int, ok: var bool) = 
+  FGIntTrialdiv9999(FGIntp, ok)
+  if ok: FGIntRabinMiller(FGIntp, nrRMtests, ok)
+  
+proc FGIntLegendreSymbol(a, p: var TBigInt, L: var int) = 
+  var 
+    temp1, temp2, temp3, temp4, temp5, zero, one: TBigInt
+    i: int32
+    ok1, ok2: bool
+  Base10StringToFGInt('0', zero)
+  Base10StringToFGInt('1', one)
+  FGIntMod(a, p, temp1)
+  if FGIntCompareAbs(zero, temp1) == Eq: 
+    FGIntDestroy(temp1)
+    L = 0
+  else: 
+    FGIntDestroy(temp1)
+    FGIntCopy(p, temp1)
+    FGIntCopy(a, temp2)
+    L = 1
+    while FGIntCompareAbs(temp2, one) != Eq: 
+      if (temp2.Number[1] Mod 2) == 0: 
+        FGIntSquare(temp1, temp3)
+        FGIntSub(temp3, one, temp4)
+        FGIntDestroy(temp3)
+        FGIntDivByInt(temp4, temp3, 8, i)
+        if (temp3.Number[1] Mod 2) == 0: ok1 = false
+        else: ok1 = true
+        FGIntDestroy(temp3)
+        FGIntDestroy(temp4)
+        if ok1 == true: L = L * (- 1)
+        FGIntDivByIntBis(temp2, 2, i)
+      else: 
+        FGIntSub(temp1, one, temp3)
+        FGIntSub(temp2, one, temp4)
+        FGIntMul(temp3, temp4, temp5)
+        FGIntDestroy(temp3)
+        FGIntDestroy(temp4)
+        FGIntDivByInt(temp5, temp3, 4, i)
+        if (temp3.Number[1] Mod 2) == 0: ok2 = false
+        else: ok2 = true
+        FGIntDestroy(temp5)
+        FGIntDestroy(temp3)
+        if ok2 == true: L = L * (- 1)
+        FGIntMod(temp1, temp2, temp3)
+        FGIntCopy(temp2, temp1)
+        FGIntCopy(temp3, temp2)
+    FGIntDestroy(temp1)
+    FGIntDestroy(temp2)
+  FGIntDestroy(zero)
+  FGIntDestroy(one)
+
+proc FGIntSquareRootModP(Square, Prime: TBigInt, SquareRoot: var TBigInt) = 
+  var 
+    one, n, b, s, r, temp, temp1, temp2, temp3: TBigInt
+    a: int32
+    L: int
+  Base2StringToFGInt('1', one)
+  Base2StringToFGInt("10", n)
+  a = 0
+  FGIntLegendreSymbol(n, Prime, L)
+  while L != - 1: 
+    FGIntAddBis(n, one)
+    FGIntLegendreSymbol(n, Prime, L)
+  FGIntCopy(Prime, s)
+  s.Number[1] = s.Number[1] - 1
+  while (s.Number[1] Mod 2) == 0: 
+    FGIntShiftRight(s)
+    a = a + 1
+  FGIntMontgomeryModExp(n, s, Prime, b)
+  FGIntAdd(s, one, temp)
+  FGIntShiftRight(temp)
+  FGIntMontgomeryModExp(Square, temp, Prime, r)
+  FGIntDestroy(temp)
+  FGIntModInv(Square, Prime, temp1)
+  for i in countup(0, (a - 2)): 
+    FGIntSquareMod(r, Prime, temp2)
+    FGIntMulMod(temp1, temp2, Prime, temp)
+    FGIntDestroy(temp2)
+    for j in countup(1, (a - i - 2)): 
+      FGIntSquareMod(temp, Prime, temp2)
+      FGIntDestroy(temp)
+      FGIntCopy(temp2, temp)
+      FGIntDestroy(temp2)
+    if FGIntCompareAbs(temp, one) != Eq: 
+      FGIntMulMod(r, b, Prime, temp3)
+      FGIntDestroy(r)
+      FGIntCopy(temp3, r)
+      FGIntDestroy(temp3)
+    FGIntDestroy(temp)
+    FGIntDestroy(temp2)
+    if i == (a - 2): break 
+    FGIntSquareMod(b, Prime, temp3)
+    FGIntDestroy(b)
+    FGIntCopy(temp3, b)
+    FGIntDestroy(temp3)
+  FGIntCopy(r, SquareRoot)
+  FGIntDestroy(r)
+  FGIntDestroy(s)
+  FGIntDestroy(b)
+  FGIntDestroy(temp1)
+  FGIntDestroy(one)
+  FGIntDestroy(n)
diff --git a/lib/base/devel/diff.nim b/lib/base/devel/diff.nim
new file mode 100644
index 000000000..4fda69b45
--- /dev/null
+++ b/lib/base/devel/diff.nim
@@ -0,0 +1,460 @@
+#
+#
+#            Nimrod's Runtime Library
+#        (c) Copyright 2008 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+## This module implements the Difference Algorithm published in
+## "An O(ND) Difference Algorithm and its Variations" by Eugene Myers
+## Algorithmica Vol. 1 No. 2, 1986, p 251.  
+
+## This implementation is based on:
+##
+## diff.cs: A port of the algorythm to C#
+## Copyright (c) by Matthias Hertel, http://www.mathertel.de
+## This work is licensed under a BSD style license. 
+## See http://www.mathertel.de/License.aspx
+
+{.push debugger:off .} # the user does not want to trace a part
+                       # of the standard library!
+
+import 
+  strutils
+
+type
+  TResultItem* = object of TObject
+    startA*: int ## start of line number in A
+    startB*: int ## start of line number in B
+    deletedA*: int ## number of deletions in A
+    deletedB*: int ## number of deletions in B
+
+  SMSRD = tuple[x, y: int] ## shortest middle snake return data
+  
+  TDiffData {.final.} = object 
+    len: int
+    data: seq[int]
+    modified: seq[bool]
+  
+proc diffText*(a, b: seq[string], 
+               eq: proc (x, y: string): bool): seq[TResultItem] =
+  ## returns the difference of two texts `a` and `b`. The texts are compared
+  ## line by line with the `eq` proc.
+  nil
+
+proc diffText*(a, b: string, eq: proc (x, y: string): bool): seq[TResultItem] =
+  ## returns the difference of two texts `a` and `b`. The texts are compared
+  ## line by line with the `eq` proc.
+  result = diffText(linesSeq(a), linesSeq(b), eq)
+
+    /// <summary>details of one difference.</summary>
+    public struct Item
+    {
+      /// <summary>Start Line number in Data A.</summary>
+      public int StartA;
+      /// <summary>Start Line number in Data B.</summary>
+      public int StartB;
+
+      /// <summary>Number of changes in Data A.</summary>
+      public int deletedA;
+      /// <summary>Number of changes in Data B.</summary>
+      public int insertedB;
+    } // Item
+
+    /// <summary>
+    /// Shortest Middle Snake Return Data
+    /// </summary>
+    private struct SMSRD
+    {
+      internal int x, y;
+      // internal int u, v;  // 2002.09.20: no need for 2 points 
+    }
+
+
+    /// <summary>
+    /// Find the difference in 2 texts, comparing by textlines.
+    /// </summary>
+    /// <param name="TextA">A-version of the text (usualy the old one)</param>
+    /// <param name="TextB">B-version of the text (usualy the new one)</param>
+    /// <returns>Returns a array of Items that describe the differences.</returns>
+    public Item[] DiffText(string TextA, string TextB) {
+      return (DiffText(TextA, TextB, false, false, false));
+    } // DiffText
+
+
+    /// <summary>
+    /// Find the difference in 2 text documents, comparing by textlines.
+    /// The algorithm itself is comparing 2 arrays of numbers so when comparing 2 text documents
+    /// each line is converted into a (hash) number. This hash-value is computed by storing all
+    /// textlines into a common hashtable so i can find dublicates in there, and generating a 
+    /// new number each time a new textline is inserted.
+    /// </summary>
+    /// <param name="TextA">A-version of the text (usualy the old one)</param>
+    /// <param name="TextB">B-version of the text (usualy the new one)</param>
+    /// <param name="trimSpace">When set to true, all leading and trailing whitespace characters are stripped out before the comparation is done.</param>
+    /// <param name="ignoreSpace">When set to true, all whitespace characters are converted to a single space character before the comparation is done.</param>
+    /// <param name="ignoreCase">When set to true, all characters are converted to their lowercase equivivalence before the comparation is done.</param>
+    /// <returns>Returns a array of Items that describe the differences.</returns>
+    public static Item[] DiffText(string TextA, string TextB, bool trimSpace, bool ignoreSpace, bool ignoreCase) {
+      // prepare the input-text and convert to comparable numbers.
+      Hashtable h = new Hashtable(TextA.Length + TextB.Length);
+
+      // The A-Version of the data (original data) to be compared.
+      DiffData DataA = new DiffData(DiffCodes(TextA, h, trimSpace, ignoreSpace, ignoreCase));
+
+      // The B-Version of the data (modified data) to be compared.
+      DiffData DataB = new DiffData(DiffCodes(TextB, h, trimSpace, ignoreSpace, ignoreCase));
+
+      h = null; // free up hashtable memory (maybe)
+
+      int MAX = DataA.Length + DataB.Length + 1;
+      /// vector for the (0,0) to (x,y) search
+      int[] DownVector = new int[2 * MAX + 2];
+      /// vector for the (u,v) to (N,M) search
+      int[] UpVector = new int[2 * MAX + 2];
+
+      LCS(DataA, 0, DataA.Length, DataB, 0, DataB.Length, DownVector, UpVector);
+
+      Optimize(DataA);
+      Optimize(DataB);
+      return CreateDiffs(DataA, DataB);
+    } // DiffText
+
+
+proc Optimize(d: var TDiffData) =
+  ## If a sequence of modified lines starts with a line that contains the 
+  ## same content as the line that appends the changes, the difference sequence
+  ## is modified so that the appended line and not the starting line is marked
+  ## as modified. This leads to more readable diff sequences when comparing
+  ## text files.
+  var startPos = 0
+  while startPos < d.len:
+    while StartPos < d.len and not d.modified[StartPos]: inc(startPos)
+    var endPos = startPos
+    while EndPos < d.len and d.modified[EndPos]: inc(endPos)
+    if EndPos < d.len and d.data[StartPos] == d.data[EndPos]:
+      d.modified[StartPos] = false
+      d.modified[EndPos] = true
+    else:
+      StartPos = EndPos
+
+
+    /// <summary>
+    /// Find the difference in 2 arrays of integers.
+    /// </summary>
+    /// <param name="ArrayA">A-version of the numbers (usualy the old one)</param>
+    /// <param name="ArrayB">B-version of the numbers (usualy the new one)</param>
+    /// <returns>Returns a array of Items that describe the differences.</returns>
+    public static Item[] DiffInt(int[] ArrayA, int[] ArrayB) {
+      // The A-Version of the data (original data) to be compared.
+      DiffData DataA = new DiffData(ArrayA);
+
+      // The B-Version of the data (modified data) to be compared.
+      DiffData DataB = new DiffData(ArrayB);
+
+      int MAX = DataA.Length + DataB.Length + 1;
+      /// vector for the (0,0) to (x,y) search
+      int[] DownVector = new int[2 * MAX + 2];
+      /// vector for the (u,v) to (N,M) search
+      int[] UpVector = new int[2 * MAX + 2];
+
+      LCS(DataA, 0, DataA.Length, DataB, 0, DataB.Length, DownVector, UpVector);
+      return CreateDiffs(DataA, DataB);
+    } // Diff
+
+
+    /// <summary>
+    /// This function converts all textlines of the text into unique numbers for every unique textline
+    /// so further work can work only with simple numbers.
+    /// </summary>
+    /// <param name="aText">the input text</param>
+    /// <param name="h">This extern initialized hashtable is used for storing all ever used textlines.</param>
+    /// <param name="trimSpace">ignore leading and trailing space characters</param>
+    /// <returns>a array of integers.</returns>
+    private static int[] DiffCodes(string aText, Hashtable h, bool trimSpace, bool ignoreSpace, bool ignoreCase) {
+      // get all codes of the text
+      string[] Lines;
+      int[] Codes;
+      int lastUsedCode = h.Count;
+      object aCode;
+      string s;
+
+      // strip off all cr, only use lf as textline separator.
+      aText = aText.Replace("\r", "");
+      Lines = aText.Split('\n');
+
+      Codes = new int[Lines.Length];
+
+      for (int i = 0; i < Lines.Length; ++i) {
+        s = Lines[i];
+        if (trimSpace)
+          s = s.Trim();
+
+        if (ignoreSpace) {
+          s = Regex.Replace(s, "\\s+", " ");            // TODO: optimization: faster blank removal.
+        }
+
+        if (ignoreCase)
+          s = s.ToLower();
+
+        aCode = h[s];
+        if (aCode == null) {
+          lastUsedCode++;
+          h[s] = lastUsedCode;
+          Codes[i] = lastUsedCode;
+        } else {
+          Codes[i] = (int)aCode;
+        } // if
+      } // for
+      return (Codes);
+    } // DiffCodes
+
+
+    /// <summary>
+    /// This is the algorithm to find the Shortest Middle Snake (SMS).
+    /// </summary>
+    /// <param name="DataA">sequence A</param>
+    /// <param name="LowerA">lower bound of the actual range in DataA</param>
+    /// <param name="UpperA">upper bound of the actual range in DataA (exclusive)</param>
+    /// <param name="DataB">sequence B</param>
+    /// <param name="LowerB">lower bound of the actual range in DataB</param>
+    /// <param name="UpperB">upper bound of the actual range in DataB (exclusive)</param>
+    /// <param name="DownVector">a vector for the (0,0) to (x,y) search. Passed as a parameter for speed reasons.</param>
+    /// <param name="UpVector">a vector for the (u,v) to (N,M) search. Passed as a parameter for speed reasons.</param>
+    /// <returns>a MiddleSnakeData record containing x,y and u,v</returns>
+    private static SMSRD SMS(DiffData DataA, int LowerA, int UpperA, DiffData DataB, int LowerB, int UpperB,
+      int[] DownVector, int[] UpVector) {
+
+      SMSRD ret;
+      int MAX = DataA.Length + DataB.Length + 1;
+
+      int DownK = LowerA - LowerB; // the k-line to start the forward search
+      int UpK = UpperA - UpperB; // the k-line to start the reverse search
+
+      int Delta = (UpperA - LowerA) - (UpperB - LowerB);
+      bool oddDelta = (Delta & 1) != 0;
+
+      // The vectors in the publication accepts negative indexes. the vectors implemented here are 0-based
+      // and are access using a specific offset: UpOffset UpVector and DownOffset for DownVektor
+      int DownOffset = MAX - DownK;
+      int UpOffset = MAX - UpK;
+
+      int MaxD = ((UpperA - LowerA + UpperB - LowerB) / 2) + 1;
+
+      // Debug.Write(2, "SMS", String.Format("Search the box: A[{0}-{1}] to B[{2}-{3}]", LowerA, UpperA, LowerB, UpperB));
+
+      // init vectors
+      DownVector[DownOffset + DownK + 1] = LowerA;
+      UpVector[UpOffset + UpK - 1] = UpperA;
+
+      for (int D = 0; D <= MaxD; D++) {
+
+        // Extend the forward path.
+        for (int k = DownK - D; k <= DownK + D; k += 2) {
+          // Debug.Write(0, "SMS", "extend forward path " + k.ToString());
+
+          // find the only or better starting point
+          int x, y;
+          if (k == DownK - D) {
+            x = DownVector[DownOffset + k + 1]; // down
+          } else {
+            x = DownVector[DownOffset + k - 1] + 1; // a step to the right
+            if ((k < DownK + D) && (DownVector[DownOffset + k + 1] >= x))
+              x = DownVector[DownOffset + k + 1]; // down
+          }
+          y = x - k;
+
+          // find the end of the furthest reaching forward D-path in diagonal k.
+          while ((x < UpperA) && (y < UpperB) && (DataA.data[x] == DataB.data[y])) {
+            x++; y++;
+          }
+          DownVector[DownOffset + k] = x;
+
+          // overlap ?
+          if (oddDelta && (UpK - D < k) && (k < UpK + D)) {
+            if (UpVector[UpOffset + k] <= DownVector[DownOffset + k]) {
+              ret.x = DownVector[DownOffset + k];
+              ret.y = DownVector[DownOffset + k] - k;
+              // ret.u = UpVector[UpOffset + k];      // 2002.09.20: no need for 2 points 
+              // ret.v = UpVector[UpOffset + k] - k;
+              return (ret);
+            } // if
+          } // if
+
+        } // for k
+
+        // Extend the reverse path.
+        for (int k = UpK - D; k <= UpK + D; k += 2) {
+          // Debug.Write(0, "SMS", "extend reverse path " + k.ToString());
+
+          // find the only or better starting point
+          int x, y;
+          if (k == UpK + D) {
+            x = UpVector[UpOffset + k - 1]; // up
+          } else {
+            x = UpVector[UpOffset + k + 1] - 1; // left
+            if ((k > UpK - D) && (UpVector[UpOffset + k - 1] < x))
+              x = UpVector[UpOffset + k - 1]; // up
+          } // if
+          y = x - k;
+
+          while ((x > LowerA) && (y > LowerB) && (DataA.data[x - 1] == DataB.data[y - 1])) {
+            x--; y--; // diagonal
+          }
+          UpVector[UpOffset + k] = x;
+
+          // overlap ?
+          if (!oddDelta && (DownK - D <= k) && (k <= DownK + D)) {
+            if (UpVector[UpOffset + k] <= DownVector[DownOffset + k]) {
+              ret.x = DownVector[DownOffset + k];
+              ret.y = DownVector[DownOffset + k] - k;
+              // ret.u = UpVector[UpOffset + k];     // 2002.09.20: no need for 2 points 
+              // ret.v = UpVector[UpOffset + k] - k;
+              return (ret);
+            } // if
+          } // if
+
+        } // for k
+
+      } // for D
+
+      throw new ApplicationException("the algorithm should never come here.");
+    } // SMS
+
+
+    /// <summary>
+    /// This is the divide-and-conquer implementation of the longes common-subsequence (LCS) 
+    /// algorithm.
+    /// The published algorithm passes recursively parts of the A and B sequences.
+    /// To avoid copying these arrays the lower and upper bounds are passed while the sequences stay constant.
+    /// </summary>
+    /// <param name="DataA">sequence A</param>
+    /// <param name="LowerA">lower bound of the actual range in DataA</param>
+    /// <param name="UpperA">upper bound of the actual range in DataA (exclusive)</param>
+    /// <param name="DataB">sequence B</param>
+    /// <param name="LowerB">lower bound of the actual range in DataB</param>
+    /// <param name="UpperB">upper bound of the actual range in DataB (exclusive)</param>
+    /// <param name="DownVector">a vector for the (0,0) to (x,y) search. Passed as a parameter for speed reasons.</param>
+    /// <param name="UpVector">a vector for the (u,v) to (N,M) search. Passed as a parameter for speed reasons.</param>
+    private static void LCS(DiffData DataA, int LowerA, int UpperA, DiffData DataB, int LowerB, int UpperB, int[] DownVector, int[] UpVector) {
+      // Debug.Write(2, "LCS", String.Format("Analyse the box: A[{0}-{1}] to B[{2}-{3}]", LowerA, UpperA, LowerB, UpperB));
+
+      // Fast walkthrough equal lines at the start
+      while (LowerA < UpperA && LowerB < UpperB && DataA.data[LowerA] == DataB.data[LowerB]) {
+        LowerA++; LowerB++;
+      }
+
+      // Fast walkthrough equal lines at the end
+      while (LowerA < UpperA && LowerB < UpperB && DataA.data[UpperA - 1] == DataB.data[UpperB - 1]) {
+        --UpperA; --UpperB;
+      }
+
+      if (LowerA == UpperA) {
+        // mark as inserted lines.
+        while (LowerB < UpperB)
+          DataB.modified[LowerB++] = true;
+
+      } else if (LowerB == UpperB) {
+        // mark as deleted lines.
+        while (LowerA < UpperA)
+          DataA.modified[LowerA++] = true;
+
+      } else {
+        // Find the middle snakea and length of an optimal path for A and B
+        SMSRD smsrd = SMS(DataA, LowerA, UpperA, DataB, LowerB, UpperB, DownVector, UpVector);
+        // Debug.Write(2, "MiddleSnakeData", String.Format("{0},{1}", smsrd.x, smsrd.y));
+
+        // The path is from LowerX to (x,y) and (x,y) to UpperX
+        LCS(DataA, LowerA, smsrd.x, DataB, LowerB, smsrd.y, DownVector, UpVector);
+        LCS(DataA, smsrd.x, UpperA, DataB, smsrd.y, UpperB, DownVector, UpVector);  // 2002.09.20: no need for 2 points 
+      }
+    } // LCS()
+
+
+    /// <summary>Scan the tables of which lines are inserted and deleted,
+    /// producing an edit script in forward order.  
+    /// </summary>
+    /// dynamic array
+    private static Item[] CreateDiffs(DiffData DataA, DiffData DataB) {
+      ArrayList a = new ArrayList();
+      Item aItem;
+      Item[] result;
+
+      int StartA, StartB;
+      int LineA, LineB;
+
+      LineA = 0;
+      LineB = 0;
+      while (LineA < DataA.Length || LineB < DataB.Length) {
+        if ((LineA < DataA.Length) && (!DataA.modified[LineA])
+          && (LineB < DataB.Length) && (!DataB.modified[LineB])) {
+          // equal lines
+          LineA++;
+          LineB++;
+
+        } else {
+          // maybe deleted and/or inserted lines
+          StartA = LineA;
+          StartB = LineB;
+
+          while (LineA < DataA.Length && (LineB >= DataB.Length || DataA.modified[LineA]))
+            // while (LineA < DataA.Length && DataA.modified[LineA])
+            LineA++;
+
+          while (LineB < DataB.Length && (LineA >= DataA.Length || DataB.modified[LineB]))
+            // while (LineB < DataB.Length && DataB.modified[LineB])
+            LineB++;
+
+          if ((StartA < LineA) || (StartB < LineB)) {
+            // store a new difference-item
+            aItem = new Item();
+            aItem.StartA = StartA;
+            aItem.StartB = StartB;
+            aItem.deletedA = LineA - StartA;
+            aItem.insertedB = LineB - StartB;
+            a.Add(aItem);
+          } // if
+        } // if
+      } // while
+
+      result = new Item[a.Count];
+      a.CopyTo(result);
+
+      return (result);
+    }
+
+  } // class Diff
+
+  /// <summary>Data on one input file being compared.  
+  /// </summary>
+  internal class DiffData
+  {
+
+    /// <summary>Number of elements (lines).</summary>
+    internal int Length;
+
+    /// <summary>Buffer of numbers that will be compared.</summary>
+    internal int[] data;
+
+    /// <summary>
+    /// Array of booleans that flag for modified data.
+    /// This is the result of the diff.
+    /// This means deletedA in the first Data or inserted in the second Data.
+    /// </summary>
+    internal bool[] modified;
+
+    /// <summary>
+    /// Initialize the Diff-Data buffer.
+    /// </summary>
+    /// <param name="data">reference to the buffer</param>
+    internal DiffData(int[] initData) {
+      data = initData;
+      Length = initData.Length;
+      modified = new bool[Length + 2];
+    } // DiffData
+
+  } // class DiffData
+
+{.pop.}
diff --git a/lib/base/devel/lex.nim b/lib/base/devel/lex.nim
new file mode 100644
index 000000000..34f0c32a8
--- /dev/null
+++ b/lib/base/devel/lex.nim
@@ -0,0 +1,73 @@
+# Lexer generator for Nimrod
+#   (c) 2008 Andreas Rumpf
+
+# Stress testing for the macro feature
+
+# the syntax that should be supported is:
+
+# template numpostfix = 
+#   '\'' & 'F'|'f'|'i'|'I' & "32"|"64"|"8"|"16"
+# template edigits = 
+#   'e'|'E' & +digits
+# tokens(
+#   tkIdent: +UniIdentStart & *UniIdentRest,
+#   tkHexNumber: '0' & ('x'|'X') & +hexDigits & ?( numpostfix ),
+#   tkOctNumber: '0' & ('c'|'C') & +octDigits & ?( numpostfix ),
+#   tkBinNumber: '0' & ('b'|'B') & +binDigits & ?( numpostfix ),
+#   tkIntNumber: +digits & ?( numpostfix ), 
+#   tkFloatNumber: +digits & ('.' & +digits & ?(edigits) | edigits) & ?(numpostfix),
+#   
+# )
+# actions(
+#   tkIdent: lookup
+# ) 
+# 
+
+#
+#  match inputstream
+#  of +('A'..'Z' | '_' | 'a'..'z') *('A'..'Z' | '_' | 'a'..'z' | '0'..'9') :
+#    
+#    x = inputstream[pos..length]
+#  of '0' 'x' +('0'..'9' | 'a'..'f' | '_' | 'A'..'F') : 
+#    y = ...
+
+const
+  AsciiLetter = {'A'..'Z', 'a'..'z'}
+  uniLetter = AsciiLetter + {'\128'..'\255'}
+  digits = {'0'..'9'}
+  hexDigits = {'0'..'9', 'a'..'f', 'A'..'F'}
+  octDigits = {'0'..'7'}
+  binDigits = {'0'..'1'}
+  AsciiIdentStart = AsciiLetter + {'_'} 
+  AsciiIdentRest = AsciiIdentStart + Digits
+  UniIdentStart = UniLetter + {'_'} 
+  UniIdentRest = UniIdentStart + Digits
+
+# --> if match(s, +AsciiIdentStart & *AsciiIdentRest): 
+
+#  Regular expressions in Nimrod itself!
+#  -------------------------------------
+#  
+#  'a' -- matches the character a
+#  'a'..'z'  -- range operator '-'
+#  'A' | 'B' -- alternative operator |
+#  * 'a' -- prefix * is needed
+#  + 'a' -- prefix + is needed
+#  ? 'a' -- prefix ? is needed
+#  *? prefix is needed
+#  +? prefix is needed
+#  letter  -- character classes with real names!
+#  letters
+#  white
+#  whites
+#  any   -- any character
+#  ()    -- are Nimrod syntax
+#  ! 'a'-'z'
+#  
+#  -- concatentation via proc call:
+#  
+#  re('A' 'Z' *word  )
+
+macro re(n: expr): expr = 
+  
+  result = newCall("magic_re", x)
diff --git a/lib/base/devel/nregex.nim b/lib/base/devel/nregex.nim
new file mode 100644
index 000000000..77afb8421
--- /dev/null
+++ b/lib/base/devel/nregex.nim
@@ -0,0 +1,124 @@
+# new implementation of regular expressions
+
+type
+  TRegexKind = enum 
+    regNone,
+    regChar, 
+    regSet,
+    regConc,
+    regAlt,
+    regStar,
+    regPlus,
+    regMN,
+    regNewline
+  
+  TRegex = object of TObject
+    case kind: TRegexKind
+    of regChar: c: char
+    of regSet: s: ref set[char]
+    else: a, b: PRegEx
+    
+  PRegEx* = ref TRegEx
+
+  TRegExFlag* = enum   ## Flags concerning the semantics of regular expressions
+    reCaseInsensitive, ## case insensitive match 
+    reStyleInsensitive ## style insensitive match
+    
+    
+  TRegExFlags* = set[TRegExFlag]
+    ## Flags concerning the semantics of regular expressions
+    
+proc raiseRegex(msg: string) {.noreturn.} = 
+  var e: ref Exception
+  new(e)
+  e.msg = msg
+  raise e
+
+proc compileAux(i: int, s: string, r: PRegEx): int
+    
+proc compileBackslash(i: int, s: string, r: PRegEx): int = 
+  var i = i
+  inc(i)
+  case s[i]
+  of 'A'..'Z': 
+  of 'a'..'z':
+  of '0':
+  of '1'..'9': 
+  
+  else:
+    r.kind = regChar
+    r.c = s[i]
+  inc(i)
+  result = i
+
+proc compileAtom(i: int, s: string, r: PRegEx): int = 
+  var i = i
+  case s[i]
+  of '[':
+    inc(i)
+    var inverse = s[i] == '^'
+    if inverse: inc(i)
+    r.kind = regSet
+    new(r.s)
+    while true: 
+      case s[i]
+      of '\\': i = compileBackslash(i, s, r)
+      of ']': 
+        inc(i)
+        break
+      of '\0': 
+        raiseRegex("']' expected")
+      elif s[i+1] == '-':
+        var x = s[i]
+        inc(i, 2)
+        var y = s[i]
+        inc(i)
+        r.s = r.s + {x..y}
+      else:
+        incl(r.s, s[i])
+        inc(i)
+    if inverse:
+      r.s = {'\0'..'\255'} - r.s
+  of '\\':
+    inc(i)
+    i = compileBackslash(i, s, r)
+  of '.':
+    r.kind = regAny
+    inc(i)
+  of '(': 
+    inc(i)
+    i = compileAux(i, s, r)
+    if s[i] = ')': inc(i)
+    else: raiseRegex("')' expected")
+  of '\0': nil # do nothing
+  else:
+    r.kind = regChar
+    r.c = s[i]
+    inc(i)
+  result = i
+    
+proc compilePostfix(i: int, s: string, r: PRegEx): int = 
+  var i = compileAtom(i, s, r)
+  var a: PRegEx
+  case s[i]
+  of '*':
+  of '+':
+  of '?':
+  else: nil
+
+proc compileAux(i: int, s: string, r: PRegEx): int = 
+  var i = i
+  i = compileAtom(i, s, r)
+  
+  while s[i] != '\0':
+    
+  result = i
+    
+proc compile*(regex: string, flags: TRegExFlags = {}): PRegEx = 
+  ## Compiles the string `regex` that represents a regular expression into 
+  ## an internal data structure that can be used for matching.
+  new(result)
+  var i = compileAux(0, regex, result)
+  if i < len(regex)-1:
+    # not all characters used for the regular expression?
+    raiseRegEx("invalid regular expression")
diff --git a/lib/base/devel/python.nim b/lib/base/devel/python.nim
new file mode 100644
index 000000000..d9e87af8c
--- /dev/null
+++ b/lib/base/devel/python.nim
@@ -0,0 +1,1877 @@
+#
+#    Light-weight binding for the Python interpreter
+#       (c) 2008 Andreas Rumpf 
+#    Based on 'PythonEngine' module by Dr. Dietmar Budelsky
+#
+#
+#************************************************************************
+#                                                                        
+# Module:  Unit 'PythonEngine'     Copyright (c) 1997                    
+#                                                                        
+# Version: 3.0                     Dr. Dietmar Budelsky                  
+# Sub-Version: 0.25                dbudelsky@web.de                      
+#                                  Germany                               
+#                                                                        
+#                                  Morgan Martinet                       
+#                                  4721 rue Brebeuf                      
+#                                  H2J 3L2 MONTREAL (QC)                 
+#                                  CANADA                                
+#                                  e-mail: mmm@free.fr                   
+#                                                                        
+#  look our page at: http://www.multimania.com/marat                     
+#************************************************************************
+#  Functionality:  Delphi Components that provide an interface to the    
+#                  Python language (see python.txt for more infos on     
+#                  Python itself).                                       
+#                                                                        
+#************************************************************************
+#  Contributors:                                                         
+#      Grzegorz Makarewicz (mak@mikroplan.com.pl)                        
+#      Andrew Robinson (andy@hps1.demon.co.uk)                           
+#      Mark Watts(mark_watts@hotmail.com)                                
+#      Olivier Deckmyn (olivier.deckmyn@mail.dotcom.fr)                  
+#      Sigve Tjora (public@tjora.no)                                     
+#      Mark Derricutt (mark@talios.com)                                  
+#      Igor E. Poteryaev (jah@mail.ru)                                   
+#      Yuri Filimonov (fil65@mail.ru)                                    
+#      Stefan Hoffmeister (Stefan.Hoffmeister@Econos.de)                 
+#************************************************************************
+# This source code is distributed with no WARRANTY, for no reason or use.
+# Everyone is allowed to use and change this code free for his own tasks 
+# and projects, as long as this header and its copyright text is intact. 
+# For changed versions of this code, which are public distributed the    
+# following additional conditions have to be fullfilled:                 
+# 1) The header has to contain a comment on the change and the author of 
+#    it.                                                                 
+# 2) A copy of the changed source has to be sent to the above E-Mail     
+#    address or my then valid address, if this is possible to the        
+#    author.                                                             
+# The second condition has the target to maintain an up to date central  
+# version of the component. If this condition is not acceptable for      
+# confidential or legal reasons, everyone is free to derive a component  
+# or to generate a diff file to my or other original sources.            
+# Dr. Dietmar Budelsky, 1997-11-17                                       
+#************************************************************************
+
+import 
+  dyncalls
+
+when defined(windows): 
+  const 
+    DllName* = "python24.dll"
+else: 
+  const 
+    DllName* = "libpython2.4.so" # for UNIX systems
+const 
+  PYT_METHOD_BUFFER_INCREASE* = 10
+  PYT_MEMBER_BUFFER_INCREASE* = 10
+  PYT_GETSET_BUFFER_INCREASE* = 10
+  METH_VARARGS* = 0x0001
+  METH_KEYWORDS* = 0x0002 # Masks for the co_flags field of PyCodeObject
+  CO_OPTIMIZED* = 0x0001
+  CO_NEWLOCALS* = 0x0002
+  CO_VARARGS* = 0x0004
+  CO_VARKEYWORDS* = 0x0008
+
+type                          # Rich comparison opcodes introduced in version 2.1
+  TRichComparisonOpcode* = enum 
+    pyLT, pyLE, pyEQ, pyNE, pyGT, pyGE
+
+const
+  Py_TPFLAGS_HAVE_GETCHARBUFFER* = (1 shl 0) # PySequenceMethods contains sq_contains
+  Py_TPFLAGS_HAVE_SEQUENCE_IN* = (1 shl 1) # Objects which participate in garbage collection (see objimp.h)
+  Py_TPFLAGS_GC* = (1 shl 2)  # PySequenceMethods and PyNumberMethods contain in-place operators
+  Py_TPFLAGS_HAVE_INPLACEOPS* = (1 shl 3) # PyNumberMethods do their own coercion */
+  Py_TPFLAGS_CHECKTYPES* = (1 shl 4)
+  Py_TPFLAGS_HAVE_RICHCOMPARE* = (1 shl 5) # Objects which are weakly referencable if their tp_weaklistoffset is >0
+                                           # XXX Should this have the same value as Py_TPFLAGS_HAVE_RICHCOMPARE?
+                                           # These both indicate a feature that appeared in the same alpha release.
+  Py_TPFLAGS_HAVE_WEAKREFS* = (1 shl 6) # tp_iter is defined
+  Py_TPFLAGS_HAVE_ITER* = (1 shl 7) # New members introduced by Python 2.2 exist
+  Py_TPFLAGS_HAVE_CLASS* = (1 shl 8) # Set if the type object is dynamically allocated
+  Py_TPFLAGS_HEAPTYPE* = (1 shl 9) # Set if the type allows subclassing
+  Py_TPFLAGS_BASETYPE* = (1 shl 10) # Set if the type is 'ready' -- fully initialized
+  Py_TPFLAGS_READY* = (1 shl 12) # Set while the type is being 'readied', to prevent recursive ready calls
+  Py_TPFLAGS_READYING* = (1 shl 13) # Objects support garbage collection (see objimp.h)
+  Py_TPFLAGS_HAVE_GC* = (1 shl 14)
+  Py_TPFLAGS_DEFAULT* = Py_TPFLAGS_HAVE_GETCHARBUFFER or
+      Py_TPFLAGS_HAVE_SEQUENCE_IN or Py_TPFLAGS_HAVE_INPLACEOPS or
+      Py_TPFLAGS_HAVE_RICHCOMPARE or Py_TPFLAGS_HAVE_WEAKREFS or
+      Py_TPFLAGS_HAVE_ITER or Py_TPFLAGS_HAVE_CLASS 
+
+type 
+  TPFlag* = enum 
+    tpfHaveGetCharBuffer, tpfHaveSequenceIn, tpfGC, tpfHaveInplaceOps, 
+    tpfCheckTypes, tpfHaveRichCompare, tpfHaveWeakRefs, tpfHaveIter, 
+    tpfHaveClass, tpfHeapType, tpfBaseType, tpfReady, tpfReadying, tpfHaveGC
+  TPFlags* = set[TPFlag]
+
+const 
+  TPFLAGS_DEFAULT* = {tpfHaveGetCharBuffer, tpfHaveSequenceIn, 
+    tpfHaveInplaceOps, tpfHaveRichCompare, tpfHaveWeakRefs, tpfHaveIter, 
+    tpfHaveClass}
+
+const # Python opcodes
+  single_input* = 256 
+  file_input* = 257
+  eval_input* = 258
+  funcdef* = 259
+  parameters* = 260
+  varargslist* = 261
+  fpdef* = 262
+  fplist* = 263
+  stmt* = 264
+  simple_stmt* = 265
+  small_stmt* = 266
+  expr_stmt* = 267
+  augassign* = 268
+  print_stmt* = 269
+  del_stmt* = 270
+  pass_stmt* = 271
+  flow_stmt* = 272
+  break_stmt* = 273
+  continue_stmt* = 274
+  return_stmt* = 275
+  raise_stmt* = 276
+  import_stmt* = 277
+  import_as_name* = 278
+  dotted_as_name* = 279
+  dotted_name* = 280
+  global_stmt* = 281
+  exec_stmt* = 282
+  assert_stmt* = 283
+  compound_stmt* = 284
+  if_stmt* = 285
+  while_stmt* = 286
+  for_stmt* = 287
+  try_stmt* = 288
+  except_clause* = 289
+  suite* = 290
+  test* = 291
+  and_test* = 291
+  not_test* = 293
+  comparison* = 294
+  comp_op* = 295
+  expr* = 296
+  xor_expr* = 297
+  and_expr* = 298
+  shift_expr* = 299
+  arith_expr* = 300
+  term* = 301
+  factor* = 302
+  power* = 303
+  atom* = 304
+  listmaker* = 305
+  lambdef* = 306
+  trailer* = 307
+  subscriptlist* = 308
+  subscript* = 309
+  sliceop* = 310
+  exprlist* = 311
+  testlist* = 312
+  dictmaker* = 313
+  classdef* = 314
+  arglist* = 315
+  argument* = 316
+  list_iter* = 317
+  list_for* = 318
+  list_if* = 319
+
+const 
+  T_SHORT* = 0
+  T_INT* = 1
+  T_LONG* = 2
+  T_FLOAT* = 3
+  T_DOUBLE* = 4
+  T_STRING* = 5
+  T_OBJECT* = 6
+  T_CHAR* = 7                 # 1-character string
+  T_BYTE* = 8                 # 8-bit signed int
+  T_UBYTE* = 9
+  T_USHORT* = 10
+  T_UINT* = 11
+  T_ULONG* = 12
+  T_STRING_INPLACE* = 13
+  T_OBJECT_EX* = 16 
+  READONLY* = 1
+  RO* = READONLY              # Shorthand 
+  READ_RESTRICTED* = 2
+  WRITE_RESTRICTED* = 4
+  RESTRICTED* = (READ_RESTRICTED or WRITE_RESTRICTED)
+
+type 
+  TPyMemberType* = enum 
+    mtShort, mtInt, mtLong, mtFloat, mtDouble, mtString, mtObject, mtChar, 
+    mtByte, mtUByte, mtUShort, mtUInt, mtULong, mtStringInplace, mtObjectEx
+  TPyMemberFlag* = enum 
+    mfDefault, mfReadOnly, mfReadRestricted, mfWriteRestricted, mfRestricted
+
+type 
+  TPChar* = array[0..16000, cstring]
+  PPChar* = ptr TPChar
+  PInt* = ptr int
+  PDouble* = ptr float64
+  PFloat* = ptr float
+  PLong* = ptr int32
+  PShort* = ptr int8
+  PString* = ptr cstring 
+  
+type 
+  PP_frozen* = ptr Pfrozen
+  P_frozen* = ptr Tfrozen
+  PPyObject* = ptr PyObject
+  PPPyObject* = ptr PPyObject
+  PPPPyObject* = ptr PPPyObject
+  PPyIntObject* = ptr PyIntObject
+  PPyTypeObject* = ptr PyTypeObject
+  PPySliceObject* = ptr PySliceObject
+  TPyCFunction* = proc (self, args: PPyObject): PPyObject{.cdecl.}
+  Tunaryfunc* = proc (ob1: PPyObject): PPyObject{.cdecl.}
+  Tbinaryfunc* = proc (ob1, ob2: PPyObject): PPyObject{.cdecl.}
+  Tternaryfunc* = proc (ob1, ob2, ob3: PPyObject): PPyObject{.cdecl.}
+  Tinquiry* = proc (ob1: PPyObject): int{.cdecl.}
+  Tcoercion* = proc (ob1, ob2: PPPyObject): int{.cdecl.}
+  Tintargfunc* = proc (ob1: PPyObject, i: int): PPyObject{.cdecl.}
+  Tintintargfunc* = proc (ob1: PPyObject, i1, i2: int): PPyObject{.cdecl.}
+  Tintobjargproc* = proc (ob1: PPyObject, i: int, ob2: PPyObject): int{.cdecl.}
+  Tintintobjargproc* = proc (ob1: PPyObject, i1, i2: int, ob2: PPyObject): int{.
+      cdecl.}
+  Tobjobjargproc* = proc (ob1, ob2, ob3: PPyObject): int{.cdecl.}
+  Tpydestructor* = proc (ob: PPyObject){.cdecl.}
+  Tprintfunc* = proc (ob: PPyObject, f: var file, i: int): int{.cdecl.}
+  Tgetattrfunc* = proc (ob1: PPyObject, name: cstring): PPyObject{.cdecl.}
+  Tsetattrfunc* = proc (ob1: PPyObject, name: cstring, ob2: PPyObject): int{.
+      cdecl.}
+  Tcmpfunc* = proc (ob1, ob2: PPyObject): int{.cdecl.}
+  Treprfunc* = proc (ob: PPyObject): PPyObject{.cdecl.}
+  Thashfunc* = proc (ob: PPyObject): int32{.cdecl.}
+  Tgetattrofunc* = proc (ob1, ob2: PPyObject): PPyObject{.cdecl.}
+  Tsetattrofunc* = proc (ob1, ob2, ob3: PPyObject): int{.cdecl.} 
+  Tgetreadbufferproc* = proc (ob1: PPyObject, i: int, ptr: Pointer): int{.cdecl.}
+  Tgetwritebufferproc* = proc (ob1: PPyObject, i: int, ptr: Pointer): int{.cdecl.}
+  Tgetsegcountproc* = proc (ob1: PPyObject, i: int): int{.cdecl.}
+  Tgetcharbufferproc* = proc (ob1: PPyObject, i: int, pstr: cstring): int{.cdecl.}
+  Tobjobjproc* = proc (ob1, ob2: PPyObject): int{.cdecl.}
+  Tvisitproc* = proc (ob1: PPyObject, ptr: Pointer): int{.cdecl.}
+  Ttraverseproc* = proc (ob1: PPyObject, proc: visitproc, ptr: Pointer): int{.
+      cdecl.}
+  Trichcmpfunc* = proc (ob1, ob2: PPyObject, i: int): PPyObject{.cdecl.}
+  Tgetiterfunc* = proc (ob1: PPyObject): PPyObject{.cdecl.}
+  Titernextfunc* = proc (ob1: PPyObject): PPyObject{.cdecl.}
+  Tdescrgetfunc* = proc (ob1, ob2, ob3: PPyObject): PPyObject{.cdecl.}
+  Tdescrsetfunc* = proc (ob1, ob2, ob3: PPyObject): int{.cdecl.}
+  Tinitproc* = proc (self, args, kwds: PPyObject): int{.cdecl.}
+  Tnewfunc* = proc (subtype: PPyTypeObject, args, kwds: PPyObject): PPyObject{.
+      cdecl.}
+  Tallocfunc* = proc (self: PPyTypeObject, nitems: int): PPyObject{.cdecl.}
+  TPyNumberMethods*{.final.} = object 
+    nb_add*: Tbinaryfunc
+    nb_substract*: Tbinaryfunc
+    nb_multiply*: Tbinaryfunc
+    nb_divide*: Tbinaryfunc
+    nb_remainder*: Tbinaryfunc
+    nb_divmod*: Tbinaryfunc
+    nb_power*: Tternaryfunc
+    nb_negative*: Tunaryfunc
+    nb_positive*: Tunaryfunc
+    nb_absolute*: Tunaryfunc
+    nb_nonzero*: Tinquiry
+    nb_invert*: Tunaryfunc
+    nb_lshift*: Tbinaryfunc
+    nb_rshift*: Tbinaryfunc
+    nb_and*: Tbinaryfunc
+    nb_xor*: Tbinaryfunc
+    nb_or*: Tbinaryfunc
+    nb_coerce*: Tcoercion
+    nb_int*: Tunaryfunc
+    nb_long*: Tunaryfunc
+    nb_float*: Tunaryfunc
+    nb_oct*: Tunaryfunc
+    nb_hex*: Tunaryfunc       #/ jah 29-sep-2000: updated for python 2.0
+                              #/                   added from .h
+    nb_inplace_add*: Tbinaryfunc
+    nb_inplace_subtract*: Tbinaryfunc
+    nb_inplace_multiply*: Tbinaryfunc
+    nb_inplace_divide*: Tbinaryfunc
+    nb_inplace_remainder*: Tbinaryfunc
+    nb_inplace_power*: Tternaryfunc
+    nb_inplace_lshift*: Tbinaryfunc
+    nb_inplace_rshift*: Tbinaryfunc
+    nb_inplace_and*: Tbinaryfunc
+    nb_inplace_xor*: Tbinaryfunc
+    nb_inplace_or*: Tbinaryfunc # Added in release 2.2
+                                # The following require the Py_TPFLAGS_HAVE_CLASS flag
+    nb_floor_divide*: Tbinaryfunc
+    nb_true_divide*: Tbinaryfunc
+    nb_inplace_floor_divide*: Tbinaryfunc
+    nb_inplace_true_divide*: Tbinaryfunc
+
+  PPyNumberMethods* = ptr TPyNumberMethods
+  TPySequenceMethods*{.final.} = object 
+    sq_length*: Tinquiry
+    sq_concat*: Tbinaryfunc
+    sq_repeat*: Tintargfunc
+    sq_item*: Tintargfunc
+    sq_slice*: Tintintargfunc
+    sq_ass_item*: Tintobjargproc
+    sq_ass_slice*: Tintintobjargproc #/ jah 29-sep-2000: updated for python 2.0
+                                     #/                   added from .h
+    sq_contains*: Tobjobjproc
+    sq_inplace_concat*: Tbinaryfunc
+    sq_inplace_repeat*: Tintargfunc
+
+  PPySequenceMethods* = ptr TPySequenceMethods
+  TPyMappingMethods*{.final.} = object 
+    mp_length*: Tinquiry
+    mp_subscript*: Tbinaryfunc
+    mp_ass_subscript*: Tobjobjargproc
+
+  PPyMappingMethods* = ptr PyMappingMethods #/ jah 29-sep-2000: updated for python 2.0
+                                            #/                   added from .h
+  TPyBufferProcs*{.final.} = object 
+    bf_getreadbuffer*: Tgetreadbufferproc
+    bf_getwritebuffer*: Tgetwritebufferproc
+    bf_getsegcount*: Tgetsegcountproc
+    bf_getcharbuffer*: Tgetcharbufferproc
+
+  PPyBufferProcs* = ptr TPyBufferProcs
+  TPy_complex*{.final.} = object 
+    float*: float64
+    imag*: float64
+
+  TPyObject*{.pure.} = object 
+    ob_refcnt*: int
+    ob_type*: PPyTypeObject
+
+  TPyIntObject* = object of TPyObject
+    ob_ival*: int32
+
+  PByte* = ptr int8
+  Tfrozen*{.final.} = object 
+    name*: cstring
+    code*: PByte
+    size*: int
+
+  TPySliceObject* = object of TPyObject
+    start*, stop*, step*: PPyObject
+
+  PPyMethodDef* = ptr TPyMethodDef
+  TPyMethodDef*{.final.} = object  # structmember.h
+    ml_name*: cstring
+    ml_meth*: TPyCFunction
+    ml_flags*: int
+    ml_doc*: cstring
+
+  PPyMemberDef* = ptr TPyMemberDef
+  TPyMemberDef*{.final.} = object  # descrobject.h
+                                   # Descriptors
+    name*: cstring
+    theType*: int
+    offset*: int
+    flags*: int
+    doc*: cstring
+
+  Tgetter* = proc (obj: PPyObject, context: Pointer): PPyObject{.cdecl.}
+  Tsetter* = proc (obj, value: PPyObject, context: Pointer): int{.cdecl.}
+  PPyGetSetDef* = ptr TPyGetSetDef
+  TPyGetSetDef*{.final.} = object 
+    name*: cstring
+    get*: Tgetter
+    set_*: Tsetter
+    doc*: cstring
+    closure*: Pointer
+
+  Twrapperfunc* = proc (self, args: PPyObject, wrapped: Pointer): PPyObject{.
+      cdecl.}
+  pwrapperbase* = ptr Twrapperbase
+  Twrapperbase*{.final.} = object  # Various kinds of descriptor objects
+                                   ##define PyDescr_COMMON \
+                                   #          PyObject_HEAD \
+                                   #          PyTypeObject *d_type; \
+                                   #          PyObject *d_name
+                                   #  
+    name*: cstring
+    wrapper*: Twrapperfunc
+    doc*: cstring
+
+  PPyDescrObject* = ptr TPyDescrObject
+  TPyDescrObject* = object of TPyObject
+    d_type*: PPyTypeObject
+    d_name*: PPyObject
+
+  PPyMethodDescrObject* = ptr TPyMethodDescrObject
+  TPyMethodDescrObject* = object of TPyDescrObject
+    d_method*: PPyMethodDef
+
+  PPyMemberDescrObject* = ptr TPyMemberDescrObject
+  TPyMemberDescrObject* = object of TPyDescrObject
+    d_member*: PPyMemberDef
+
+  PPyGetSetDescrObject* = ptr TPyGetSetDescrObject
+  TPyGetSetDescrObject* = object of TPyDescrObject
+    d_getset*: PPyGetSetDef
+
+  PPyWrapperDescrObject* = ptr TPyWrapperDescrObject
+  TPyWrapperDescrObject* = object of TPyDescrObject # object.h
+    d_base*: pwrapperbase
+    d_wrapped*: Pointer       # This can be any function pointer
+  
+  TPyTypeObject* = object of TPyObject
+    ob_size*: int             # Number of items in variable part
+    tp_name*: cstring         # For printing
+    tp_basicsize*, tp_itemsize*: int # For allocation
+                                     # Methods to implement standard operations
+    tp_dealloc*: Tpydestructor
+    tp_print*: Tprintfunc
+    tp_getattr*: Tgetattrfunc
+    tp_setattr*: Tsetattrfunc
+    tp_compare*: Tcmpfunc
+    tp_repr*: Treprfunc       # Method suites for standard classes
+    tp_as_number*: PPyNumberMethods
+    tp_as_sequence*: PPySequenceMethods
+    tp_as_mapping*: PPyMappingMethods # More standard operations (here for binary compatibility)
+    tp_hash*: Thashfunc
+    tp_call*: Tternaryfunc
+    tp_str*: Treprfunc
+    tp_getattro*: Tgetattrofunc
+    tp_setattro*: Tsetattrofunc #/ jah 29-sep-2000: updated for python 2.0
+                                # Functions to access object as input/output buffer
+    tp_as_buffer*: PPyBufferProcs # Flags to define presence of optional/expanded features
+    tp_flags*: int32
+    tp_doc*: cstring          # Documentation string
+                              # call function for all accessible objects
+    tp_traverse*: Ttraverseproc # delete references to contained objects
+    tp_clear*: Tinquiry       # rich comparisons
+    tp_richcompare*: Trichcmpfunc # weak reference enabler
+    tp_weaklistoffset*: int32 # Iterators
+    tp_iter*: Tgetiterfunc
+    tp_iternext*: Titernextfunc # Attribute descriptor and subclassing stuff
+    tp_methods*: PPyMethodDef
+    tp_members*: PPyMemberDef
+    tp_getset*: PPyGetSetDef
+    tp_base*: PPyTypeObject
+    tp_dict*: PPyObject
+    tp_descr_get*: Tdescrgetfunc
+    tp_descr_set*: Tdescrsetfunc
+    tp_dictoffset*: int32
+    tp_init*: Tinitproc
+    tp_alloc*: Tallocfunc
+    tp_new*: Tnewfunc
+    tp_free*: Tpydestructor   # Low-level free-memory routine
+    tp_is_gc*: Tinquiry       # For PyObject_IS_GC
+    tp_bases*: PPyObject
+    tp_mro*: PPyObject        # method resolution order
+    tp_cache*: PPyObject
+    tp_subclasses*: PPyObject
+    tp_weaklist*: PPyObject   #More spares
+    tp_xxx7*: pointer
+    tp_xxx8*: pointer
+
+  PPyMethodChain* = ptr TPyMethodChain
+  TPyMethodChain*{.final.} = object 
+    methods*: PPyMethodDef
+    link*: PPyMethodChain
+
+  PPyClassObject* = ptr TPyClassObject
+  TPyClassObject* = object of TPyObject
+    cl_bases*: PPyObject      # A tuple of class objects
+    cl_dict*: PPyObject       # A dictionary
+    cl_name*: PPyObject       # A string
+                              # The following three are functions or NULL
+    cl_getattr*: PPyObject
+    cl_setattr*: PPyObject
+    cl_delattr*: PPyObject
+
+  PPyInstanceObject* = ptr TPyInstanceObject
+  TPyInstanceObject* = object of TPyObject # Instance method objects are used for two purposes:
+                                           #   (a) as bound instance methods (returned by instancename.methodname)
+                                           #   (b) as unbound methods (returned by ClassName.methodname)
+                                           #   In case (b), im_self is NULL
+                                           #
+    in_class*: PPyClassObject # The class object
+    in_dict*: PPyObject       # A dictionary
+  
+  PPyMethodObject* = ptr TPyMethodObject
+  TPyMethodObject* = object of TPyObject # Bytecode object, compile.h
+    im_func*: PPyObject       # The function implementing the method
+    im_self*: PPyObject       # The instance it is bound to, or NULL
+    im_class*: PPyObject      # The class that defined the method
+  
+  PPyCodeObject* = ptr TPyCodeObject
+  TPyCodeObject* = object of TPyObject # from pystate.h
+    co_argcount*: int         # #arguments, except *args
+    co_nlocals*: int          # #local variables
+    co_stacksize*: int        # #entries needed for evaluation stack
+    co_flags*: int            # CO_..., see below
+    co_code*: PPyObject       # instruction opcodes (it hides a PyStringObject)
+    co_consts*: PPyObject     # list (constants used)
+    co_names*: PPyObject      # list of strings (names used)
+    co_varnames*: PPyObject   # tuple of strings (local variable names)
+    co_freevars*: PPyObject   # tuple of strings (free variable names)
+    co_cellvars*: PPyObject   # tuple of strings (cell variable names)
+                              # The rest doesn't count for hash/cmp
+    co_filename*: PPyObject   # string (where it was loaded from)
+    co_name*: PPyObject       # string (name, for reference)
+    co_firstlineno*: int      # first source line number
+    co_lnotab*: PPyObject     # string (encoding addr<->lineno mapping)
+  
+  PPyInterpreterState* = ptr TPyInterpreterState
+  PPyThreadState* = ptr TPyThreadState
+  PPyFrameObject* = ptr TPyFrameObject # Interpreter environments
+  TPyInterpreterState*{.final.} = object  # Thread specific information
+    next*: PPyInterpreterState
+    tstate_head*: PPyThreadState
+    modules*: PPyObject
+    sysdict*: PPyObject
+    builtins*: PPyObject
+    checkinterval*: int
+
+  TPyThreadState*{.final.} = object  # from frameobject.h
+    next*: PPyThreadState
+    interp*: PPyInterpreterState
+    frame*: PPyFrameObject
+    recursion_depth*: int
+    ticker*: int
+    tracing*: int
+    sys_profilefunc*: PPyObject
+    sys_tracefunc*: PPyObject
+    curexc_type*: PPyObject
+    curexc_value*: PPyObject
+    curexc_traceback*: PPyObject
+    exc_type*: PPyObject
+    exc_value*: PPyObject
+    exc_traceback*: PPyObject
+    dict*: PPyObject
+
+  PPyTryBlock* = ptr TPyTryBlock
+  TPyTryBlock*{.final.} = object 
+    b_type*: int              # what kind of block this is
+    b_handler*: int           # where to jump to find handler
+    b_level*: int             # value stack level to pop to
+  
+  CO_MAXBLOCKS* = range[0..19]
+  TPyFrameObject* = object of TPyObject # start of the VAR_HEAD of an object
+                                        # From traceback.c
+    ob_size*: int             # Number of items in variable part
+                              # End of the Head of an object
+    f_back*: PPyFrameObject   # previous frame, or NULL
+    f_code*: PPyCodeObject    # code segment
+    f_builtins*: PPyObject    # builtin symbol table (PyDictObject)
+    f_globals*: PPyObject     # global symbol table (PyDictObject)
+    f_locals*: PPyObject      # local symbol table (PyDictObject)
+    f_valuestack*: PPPyObject # points after the last local
+                              # Next free slot in f_valuestack.  Frame creation sets to f_valuestack.
+                              #       Frame evaluation usually NULLs it, but a frame that yields sets it
+                              #       to the current stack top. 
+    f_stacktop*: PPPyObject
+    f_trace*: PPyObject       # Trace function
+    f_exc_type*, f_exc_value*, f_exc_traceback*: PPyObject
+    f_tstate*: PPyThreadState
+    f_lasti*: int             # Last instruction if called
+    f_lineno*: int            # Current line number
+    f_restricted*: int        # Flag set if restricted operations
+                              # in this scope
+    f_iblock*: int            # index in f_blockstack
+    f_blockstack*: array[CO_MAXBLOCKS, PyTryBlock] # for try and loop blocks
+    f_nlocals*: int           # number of locals
+    f_ncells*: int
+    f_nfreevars*: int
+    f_stacksize*: int         # size of value stack
+    f_localsplus*: array[0..0, PPyObject] # locals+stack, dynamically sized
+  
+  PPyTraceBackObject* = ptr TPyTraceBackObject
+  TPyTraceBackObject* = object of TPyObject # Parse tree node interface
+    tb_next*: PPyTraceBackObject
+    tb_frame*: PPyFrameObject
+    tb_lasti*: int
+    tb_lineno*: int
+
+  PNode* = ptr Tnode
+  Tnode*{.final.} = object    # From weakrefobject.h
+    n_type*: int16
+    n_str*: cstring
+    n_lineno*: int16
+    n_nchildren*: int16
+    n_child*: PNode
+
+  PPyWeakReference* = ptr TPyWeakReference
+  TPyWeakReference* = object of TPyObject # from datetime.h
+                                          #* Fields are packed into successive bytes, each viewed as unsigned and
+                                          # * big-endian, unless otherwise noted:
+                                          # *
+                                          # * byte offset
+                                          # *  0 		year     2 bytes, 1-9999
+                                          # *  2	  	month    1 byte,  1-12
+                                          # *  3 		day      1 byte,  1-31
+                                          # *  4     hour     1 byte,  0-23
+                                          # *  5 		minute   1 byte,  0-59
+                                          # *  6 		second   1 byte,  0-59
+                                          # *  7 		usecond  3 bytes, 0-999999
+                                          # * 10
+                                          # *
+    wr_object*: PPyObject
+    wr_callback*: PPyObject
+    hash*: int32
+    wr_prev*: PPyWeakReference
+    wr_next*: PPyWeakReference
+
+
+const                         # # of bytes for year, month, and day. 
+  PyDateTime_DATE_DATASIZE* = 4 # # of bytes for hour, minute, second, and usecond. 
+  PyDateTime_TIME_DATASIZE* = 6 # # of bytes for year, month, day, hour, minute, second, and usecond. 
+  PyDateTime_DATETIME_DATASIZE* = 10
+
+type 
+  TPyDateTime_Delta* = object of TPyObject
+    hashcode*: int            # -1 when unknown
+    days*: int                # -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS
+    seconds*: int             # 0 <= seconds < 24*3600 is invariant
+    microseconds*: int        # 0 <= microseconds < 1000000 is invariant
+  
+  PPyDateTime_Delta* = ptr TPyDateTime_Delta
+  TPyDateTime_TZInfo* = object of TPyObject # a pure abstract base clase
+  PPyDateTime_TZInfo* = ptr TPyDateTime_TZInfo #
+                                               #/* The datetime and time types have hashcodes, and an optional tzinfo member,
+                                               # * present if and only if hastzinfo is true.
+                                               # */
+                                               ##define _PyTZINFO_HEAD		\
+                                               #	PyObject_HEAD		\
+                                               #	long hashcode;		\
+                                               #	char hastzinfo;		/* boolean flag */
+                                               #
+                                               #* No _PyDateTime_BaseTZInfo is allocated; it's just to have something
+                                               # * convenient to cast to, when getting at the hastzinfo member of objects
+                                               # * starting with _PyTZINFO_HEAD.
+                                               # *
+  TPyDateTime_BaseTZInfo* = object of TPyObject
+    hashcode*: int
+    hastzinfo*: bool          # boolean flag
+  
+  PPyDateTime_BaseTZInfo* = ptr TPyDateTime_BaseTZInfo #* All time objects are of PyDateTime_TimeType, but that can be allocated
+                                                       # * in two ways, with or without a tzinfo member.  Without is the same as
+                                                       # * tzinfo == None, but consumes less memory.  _PyDateTime_BaseTime is an
+                                                       # * internal struct used to allocate the right amount of space for the
+                                                       # * "without" case.
+                                                       # *
+                                                       ##define _PyDateTime_TIMEHEAD	\
+                                                       #	_PyTZINFO_HEAD		\
+                                                       #	unsigned char data[_PyDateTime_TIME_DATASIZE];
+                                                       #
+  TPyDateTime_BaseTime* = object of TPyDateTime_BaseTZInfo
+    data*: array[0..Pred(PyDateTime_TIME_DATASIZE), int8]
+
+  PPyDateTime_BaseTime* = ptr TPyDateTime_BaseTime
+  TPyDateTime_Time* = object of TPyDateTime_BaseTime # hastzinfo true
+    tzinfo*: PPyObject
+
+  PPyDateTime_Time* = ptr PyDateTime_Time #* All datetime objects are of PyDateTime_DateTimeType, but that can be
+                                          # * allocated in two ways too, just like for time objects above.  In addition,
+                                          # * the plain date type is a base class for datetime, so it must also have
+                                          # * a hastzinfo member (although it's unused there).
+                                          # *
+  TPyDateTime_Date* = object of TPyDateTime_BaseTZInfo
+    data*: array[0..Pred(PyDateTime_DATE_DATASIZE), int8]
+
+  PPyDateTime_Date* = ptr TPyDateTime_Date #
+                                           ##define _PyDateTime_DATETIMEHEAD	\
+                                           #	_PyTZINFO_HEAD			\
+                                           #	unsigned char data[_PyDateTime_DATETIME_DATASIZE];
+                                           #
+  TPyDateTime_BaseDateTime* = object of TPyDateTime_BaseTZInfo # hastzinfo false
+    data*: array[0..Pred(PyDateTime_DATETIME_DATASIZE), int8]
+
+  PPyDateTime_BaseDateTime* = ptr TPyDateTime_BaseDateTime
+  TPyDateTime_DateTime* = object of TPyDateTime_BaseTZInfo # hastzinfo true
+    data*: array[0..Pred(PyDateTime_DATETIME_DATASIZE), int8]
+    tzinfo*: PPyObject
+
+  PPyDateTime_DateTime* = ptr TPyDateTime_DateTime 
+
+########################################################
+###                                                   ##
+###         New exception classes                     ##
+###                                                   ##
+########################################################
+#
+#  // Python's exceptions
+#  EPythonError   = object(Exception)
+#      EName: String;
+#      EValue: String;
+#  end;
+#  EPyExecError   = object(EPythonError)
+#  end;
+#
+#  // Standard exception classes of Python
+#
+#/// jah 29-sep-2000: updated for python 2.0
+#///                   base classes updated according python documentation
+#
+#{ Hierarchy of Python exceptions, Python 2.3, copied from <INSTALL>\Python\exceptions.c
+#
+#Exception\n\
+# |\n\
+# +-- SystemExit\n\
+# +-- StopIteration\n\
+# +-- StandardError\n\
+# |    |\n\
+# |    +-- KeyboardInterrupt\n\
+# |    +-- ImportError\n\
+# |    +-- EnvironmentError\n\
+# |    |    |\n\
+# |    |    +-- IOError\n\
+# |    |    +-- OSError\n\
+# |    |         |\n\
+# |    |         +-- WindowsError\n\
+# |    |         +-- VMSError\n\
+# |    |\n\
+# |    +-- EOFError\n\
+# |    +-- RuntimeError\n\
+# |    |    |\n\
+# |    |    +-- NotImplementedError\n\
+# |    |\n\
+# |    +-- NameError\n\
+# |    |    |\n\
+# |    |    +-- UnboundLocalError\n\
+# |    |\n\
+# |    +-- AttributeError\n\
+# |    +-- SyntaxError\n\
+# |    |    |\n\
+# |    |    +-- IndentationError\n\
+# |    |         |\n\
+# |    |         +-- TabError\n\
+# |    |\n\
+# |    +-- TypeError\n\
+# |    +-- AssertionError\n\
+# |    +-- LookupError\n\
+# |    |    |\n\
+# |    |    +-- IndexError\n\
+# |    |    +-- KeyError\n\
+# |    |\n\
+# |    +-- ArithmeticError\n\
+# |    |    |\n\
+# |    |    +-- OverflowError\n\
+# |    |    +-- ZeroDivisionError\n\
+# |    |    +-- FloatingPointError\n\
+# |    |\n\
+# |    +-- ValueError\n\
+# |    |    |\n\
+# |    |    +-- UnicodeError\n\
+# |    |        |\n\
+# |    |        +-- UnicodeEncodeError\n\
+# |    |        +-- UnicodeDecodeError\n\
+# |    |        +-- UnicodeTranslateError\n\
+# |    |\n\
+# |    +-- ReferenceError\n\
+# |    +-- SystemError\n\
+# |    +-- MemoryError\n\
+# |\n\
+# +---Warning\n\
+#      |\n\
+#      +-- UserWarning\n\
+#      +-- DeprecationWarning\n\
+#      +-- PendingDeprecationWarning\n\
+#      +-- SyntaxWarning\n\
+#      +-- OverflowWarning\n\
+#      +-- RuntimeWarning\n\
+#      +-- FutureWarning"
+#}
+#   EPyException = class (EPythonError);
+#   EPyStandardError = class (EPyException);
+#   EPyArithmeticError = class (EPyStandardError);
+#   EPyLookupError = class (EPyStandardError);
+#   EPyAssertionError = class (EPyStandardError);
+#   EPyAttributeError = class (EPyStandardError);
+#   EPyEOFError = class (EPyStandardError);
+#   EPyFloatingPointError = class (EPyArithmeticError);
+#   EPyEnvironmentError = class (EPyStandardError);
+#   EPyIOError = class (EPyEnvironmentError);
+#   EPyOSError = class (EPyEnvironmentError);
+#   EPyImportError = class (EPyStandardError);
+#   EPyIndexError = class (EPyLookupError);
+#   EPyKeyError = class (EPyLookupError);
+#   EPyKeyboardInterrupt = class (EPyStandardError);
+#   EPyMemoryError = class (EPyStandardError);
+#   EPyNameError = class (EPyStandardError);
+#   EPyOverflowError = class (EPyArithmeticError);
+#   EPyRuntimeError = class (EPyStandardError);
+#   EPyNotImplementedError = class (EPyRuntimeError);
+#   EPySyntaxError = class (EPyStandardError)
+#   public
+#      EFileName: string;
+#      ELineStr: string;
+#      ELineNumber: Integer;
+#      EOffset: Integer;
+#   end;
+#   EPyIndentationError = class (EPySyntaxError);
+#   EPyTabError = class (EPyIndentationError);
+#   EPySystemError = class (EPyStandardError);
+#   EPySystemExit = class (EPyException);
+#   EPyTypeError = class (EPyStandardError);
+#   EPyUnboundLocalError = class (EPyNameError);
+#   EPyValueError = class (EPyStandardError);
+#   EPyUnicodeError = class (EPyValueError);
+#   UnicodeEncodeError = class (EPyUnicodeError);
+#   UnicodeDecodeError = class (EPyUnicodeError);
+#   UnicodeTranslateError = class (EPyUnicodeError);
+#   EPyZeroDivisionError = class (EPyArithmeticError);
+#   EPyStopIteration = class(EPyException);
+#   EPyWarning = class (EPyException);
+#   EPyUserWarning = class (EPyWarning);
+#   EPyDeprecationWarning = class (EPyWarning);
+#   PendingDeprecationWarning = class (EPyWarning);
+#   FutureWarning = class (EPyWarning);
+#   EPySyntaxWarning = class (EPyWarning);
+#   EPyOverflowWarning = class (EPyWarning);
+#   EPyRuntimeWarning = class (EPyWarning);
+#   EPyReferenceError = class (EPyStandardError);
+#
+
+var 
+  PyArg_Parse*: proc (args: PPyObject, format: cstring): int{.cdecl, varargs.} 
+  PyArg_ParseTuple*: proc (args: PPyObject, format: cstring, x1: Pointer = nil, 
+                           x2: Pointer = nil, x3: Pointer = nil): int{.cdecl, varargs.} 
+  Py_BuildValue*: proc (format: cstring): PPyObject{.cdecl, varargs.} 
+  PyCode_Addr2Line*: proc (co: PPyCodeObject, addrq: int): int{.cdecl.}
+  DLL_Py_GetBuildInfo*: proc (): cstring{.cdecl.} # define Python flags. See file pyDebug.h
+  Py_DebugFlag*: PInt
+  Py_VerboseFlag*: PInt
+  Py_InteractiveFlag*: PInt
+  Py_OptimizeFlag*: PInt
+  Py_NoSiteFlag*: PInt
+  Py_UseClassExceptionsFlag*: PInt
+  Py_FrozenFlag*: PInt
+  Py_TabcheckFlag*: PInt
+  Py_UnicodeFlag*: PInt
+  Py_IgnoreEnvironmentFlag*: PInt
+  Py_DivisionWarningFlag*: PInt #_PySys_TraceFunc:    PPPyObject;
+                                #_PySys_ProfileFunc: PPPPyObject;
+  PyImport_FrozenModules*: PP_frozen
+  Py_None*: PPyObject
+  Py_Ellipsis*: PPyObject
+  Py_False*: PPyIntObject
+  Py_True*: PPyIntObject
+  Py_NotImplemented*: PPyObject
+  PyExc_AttributeError*: PPPyObject
+  PyExc_EOFError*: PPPyObject
+  PyExc_IOError*: PPPyObject
+  PyExc_ImportError*: PPPyObject
+  PyExc_IndexError*: PPPyObject
+  PyExc_KeyError*: PPPyObject
+  PyExc_KeyboardInterrupt*: PPPyObject
+  PyExc_MemoryError*: PPPyObject
+  PyExc_NameError*: PPPyObject
+  PyExc_OverflowError*: PPPyObject
+  PyExc_RuntimeError*: PPPyObject
+  PyExc_SyntaxError*: PPPyObject
+  PyExc_SystemError*: PPPyObject
+  PyExc_SystemExit*: PPPyObject
+  PyExc_TypeError*: PPPyObject
+  PyExc_ValueError*: PPPyObject
+  PyExc_ZeroDivisionError*: PPPyObject
+  PyExc_ArithmeticError*: PPPyObject
+  PyExc_Exception*: PPPyObject
+  PyExc_FloatingPointError*: PPPyObject
+  PyExc_LookupError*: PPPyObject
+  PyExc_StandardError*: PPPyObject
+  PyExc_AssertionError*: PPPyObject
+  PyExc_EnvironmentError*: PPPyObject
+  PyExc_IndentationError*: PPPyObject
+  PyExc_MemoryErrorInst*: PPPyObject
+  PyExc_NotImplementedError*: PPPyObject
+  PyExc_OSError*: PPPyObject
+  PyExc_TabError*: PPPyObject
+  PyExc_UnboundLocalError*: PPPyObject
+  PyExc_UnicodeError*: PPPyObject
+  PyExc_Warning*: PPPyObject
+  PyExc_DeprecationWarning*: PPPyObject
+  PyExc_RuntimeWarning*: PPPyObject
+  PyExc_SyntaxWarning*: PPPyObject
+  PyExc_UserWarning*: PPPyObject
+  PyExc_OverflowWarning*: PPPyObject
+  PyExc_ReferenceError*: PPPyObject
+  PyExc_StopIteration*: PPPyObject
+  PyExc_FutureWarning*: PPPyObject
+  PyExc_PendingDeprecationWarning*: PPPyObject
+  PyExc_UnicodeDecodeError*: PPPyObject
+  PyExc_UnicodeEncodeError*: PPPyObject
+  PyExc_UnicodeTranslateError*: PPPyObject
+  PyType_Type*: PPyTypeObject
+  PyCFunction_Type*: PPyTypeObject
+  PyCObject_Type*: PPyTypeObject
+  PyClass_Type*: PPyTypeObject
+  PyCode_Type*: PPyTypeObject
+  PyComplex_Type*: PPyTypeObject
+  PyDict_Type*: PPyTypeObject
+  PyFile_Type*: PPyTypeObject
+  PyFloat_Type*: PPyTypeObject
+  PyFrame_Type*: PPyTypeObject
+  PyFunction_Type*: PPyTypeObject
+  PyInstance_Type*: PPyTypeObject
+  PyInt_Type*: PPyTypeObject
+  PyList_Type*: PPyTypeObject
+  PyLong_Type*: PPyTypeObject
+  PyMethod_Type*: PPyTypeObject
+  PyModule_Type*: PPyTypeObject
+  PyObject_Type*: PPyTypeObject
+  PyRange_Type*: PPyTypeObject
+  PySlice_Type*: PPyTypeObject
+  PyString_Type*: PPyTypeObject
+  PyTuple_Type*: PPyTypeObject
+  PyBaseObject_Type*: PPyTypeObject
+  PyBuffer_Type*: PPyTypeObject
+  PyCallIter_Type*: PPyTypeObject
+  PyCell_Type*: PPyTypeObject
+  PyClassMethod_Type*: PPyTypeObject
+  PyProperty_Type*: PPyTypeObject
+  PySeqIter_Type*: PPyTypeObject
+  PyStaticMethod_Type*: PPyTypeObject
+  PySuper_Type*: PPyTypeObject
+  PySymtableEntry_Type*: PPyTypeObject
+  PyTraceBack_Type*: PPyTypeObject
+  PyUnicode_Type*: PPyTypeObject
+  PyWrapperDescr_Type*: PPyTypeObject
+  PyBaseString_Type*: PPyTypeObject
+  PyBool_Type*: PPyTypeObject
+  PyEnum_Type*: PPyTypeObject #PyArg_GetObject: function(args: PPyObject; nargs, i: integer; p_a: PPPyObject): integer; cdecl;
+                              #PyArg_GetLong:   function(args: PPyObject; nargs, i: integer; p_a: PLong): integer; cdecl;
+                              #PyArg_GetShort:  function(args: PPyObject; nargs, i: integer; p_a: PShort): integer; cdecl;
+                              #PyArg_GetFloat:  function(args: PPyObject; nargs, i: integer; p_a: PFloat): integer; cdecl;
+                              #PyArg_GetString: function(args: PPyObject; nargs, i: integer; p_a: PString): integer; cdecl;
+                              #PyArgs_VaParse:  function (args: PPyObject; format: PChar; va_list: array of const): integer; cdecl;
+                              # Does not work!
+                              # Py_VaBuildValue: function (format: PChar; va_list: array of const): PPyObject; cdecl;
+                              #PyBuiltin_Init:     procedure; cdecl;
+  PyComplex_FromCComplex*: proc (c: TPy_complex): PPyObject{.cdecl.}
+  PyComplex_FromDoubles*: proc (realv, imag: float64): PPyObject{.cdecl.}
+  PyComplex_RealAsDouble*: proc (op: PPyObject): float64{.cdecl.}
+  PyComplex_ImagAsDouble*: proc (op: PPyObject): float64{.cdecl.}
+  PyComplex_AsCComplex*: proc (op: PPyObject): TPy_complex{.cdecl.}
+  PyCFunction_GetFunction*: proc (ob: PPyObject): Pointer{.cdecl.}
+  PyCFunction_GetSelf*: proc (ob: PPyObject): PPyObject{.cdecl.}
+  PyCallable_Check*: proc (ob: PPyObject): int{.cdecl.}
+  PyCObject_FromVoidPtr*: proc (cobj, destruct: Pointer): PPyObject{.cdecl.}
+  PyCObject_AsVoidPtr*: proc (ob: PPyObject): Pointer{.cdecl.}
+  PyClass_New*: proc (ob1, ob2, ob3: PPyObject): PPyObject{.cdecl.}
+  PyClass_IsSubclass*: proc (ob1, ob2: PPyObject): int{.cdecl.}
+  Py_InitModule4*: proc (name: cstring, methods: PPyMethodDef, doc: cstring, 
+                         passthrough: PPyObject, Api_Version: int): PPyObject{.
+      cdecl.}
+  PyErr_BadArgument*: proc (): int{.cdecl.}
+  PyErr_BadInternalCall*: proc (){.cdecl.}
+  PyErr_CheckSignals*: proc (): int{.cdecl.}
+  PyErr_Clear*: proc (){.cdecl.}
+  PyErr_Fetch*: proc (errtype, errvalue, errtraceback: PPPyObject){.cdecl.}
+  PyErr_NoMemory*: proc (): PPyObject{.cdecl.}
+  PyErr_Occurred*: proc (): PPyObject{.cdecl.}
+  PyErr_Print*: proc (){.cdecl.}
+  PyErr_Restore*: proc (errtype, errvalue, errtraceback: PPyObject){.cdecl.}
+  PyErr_SetFromErrno*: proc (ob: PPyObject): PPyObject{.cdecl.}
+  PyErr_SetNone*: proc (value: PPyObject){.cdecl.}
+  PyErr_SetObject*: proc (ob1, ob2: PPyObject){.cdecl.}
+  PyErr_SetString*: proc (ErrorObject: PPyObject, text: cstring){.cdecl.}
+  PyImport_GetModuleDict*: proc (): PPyObject{.cdecl.}
+  PyInt_FromLong*: proc (x: int32): PPyObject{.cdecl.}
+  Py_Initialize*: proc (){.cdecl.}
+  Py_Exit*: proc (RetVal: int){.cdecl.}
+  PyEval_GetBuiltins*: proc (): PPyObject{.cdecl.}
+  PyDict_GetItem*: proc (mp, key: PPyObject): PPyObject{.cdecl.}
+  PyDict_SetItem*: proc (mp, key, item: PPyObject): int{.cdecl.}
+  PyDict_DelItem*: proc (mp, key: PPyObject): int{.cdecl.}
+  PyDict_Clear*: proc (mp: PPyObject){.cdecl.}
+  PyDict_Next*: proc (mp: PPyObject, pos: PInt, key, value: PPPyObject): int{.
+      cdecl.}
+  PyDict_Keys*: proc (mp: PPyObject): PPyObject{.cdecl.}
+  PyDict_Values*: proc (mp: PPyObject): PPyObject{.cdecl.}
+  PyDict_Items*: proc (mp: PPyObject): PPyObject{.cdecl.}
+  PyDict_Size*: proc (mp: PPyObject): int{.cdecl.}
+  PyDict_DelItemString*: proc (dp: PPyObject, key: cstring): int{.cdecl.}
+  PyDict_New*: proc (): PPyObject{.cdecl.}
+  PyDict_GetItemString*: proc (dp: PPyObject, key: cstring): PPyObject{.cdecl.}
+  PyDict_SetItemString*: proc (dp: PPyObject, key: cstring, item: PPyObject): int{.
+      cdecl.}
+  PyDictProxy_New*: proc (obj: PPyObject): PPyObject{.cdecl.}
+  PyModule_GetDict*: proc (module: PPyObject): PPyObject{.cdecl.}
+  PyObject_Str*: proc (v: PPyObject): PPyObject{.cdecl.}
+  PyRun_String*: proc (str: cstring, start: int, globals: PPyObject, 
+                       locals: PPyObject): PPyObject{.cdecl.}
+  PyRun_SimpleString*: proc (str: cstring): int{.cdecl.}
+  PyString_AsString*: proc (ob: PPyObject): cstring{.cdecl.}
+  PyString_FromString*: proc (str: cstring): PPyObject{.cdecl.}
+  PySys_SetArgv*: proc (argc: int, argv: PPChar){.cdecl.} #+ means, Grzegorz or me has tested his non object version of this function
+                                                          #+
+  PyCFunction_New*: proc (md: PPyMethodDef, ob: PPyObject): PPyObject{.cdecl.} #+
+  PyEval_CallObject*: proc (ob1, ob2: PPyObject): PPyObject{.cdecl.} #-
+  PyEval_CallObjectWithKeywords*: proc (ob1, ob2, ob3: PPyObject): PPyObject{.
+      cdecl.}                 #-
+  PyEval_GetFrame*: proc (): PPyObject{.cdecl.} #-
+  PyEval_GetGlobals*: proc (): PPyObject{.cdecl.} #-
+  PyEval_GetLocals*: proc (): PPyObject{.cdecl.} #-
+                                                 #PyEval_GetOwner:function:PPyObject; cdecl;
+                                                 #-
+  PyEval_GetRestricted*: proc (): int{.cdecl.} #-
+  PyEval_InitThreads*: proc (){.cdecl.} #-
+  PyEval_RestoreThread*: proc (tstate: PPyThreadState){.cdecl.} #-
+  PyEval_SaveThread*: proc (): PPyThreadState{.cdecl.} #-
+  PyFile_FromString*: proc (pc1, pc2: cstring): PPyObject{.cdecl.} #-
+  PyFile_GetLine*: proc (ob: PPyObject, i: int): PPyObject{.cdecl.} #-
+  PyFile_Name*: proc (ob: PPyObject): PPyObject{.cdecl.} #-
+  PyFile_SetBufSize*: proc (ob: PPyObject, i: int){.cdecl.} #-
+  PyFile_SoftSpace*: proc (ob: PPyObject, i: int): int{.cdecl.} #-
+  PyFile_WriteObject*: proc (ob1, ob2: PPyObject, i: int): int{.cdecl.} #-
+  PyFile_WriteString*: proc (s: cstring, ob: PPyObject){.cdecl.} #+
+  PyFloat_AsDouble*: proc (ob: PPyObject): float64{.cdecl.} #+
+  PyFloat_FromDouble*: proc (db: float64): PPyObject{.cdecl.} #-
+  PyFunction_GetCode*: proc (ob: PPyObject): PPyObject{.cdecl.} #-
+  PyFunction_GetGlobals*: proc (ob: PPyObject): PPyObject{.cdecl.} #-
+  PyFunction_New*: proc (ob1, ob2: PPyObject): PPyObject{.cdecl.} #-
+  PyImport_AddModule*: proc (name: cstring): PPyObject{.cdecl.} #-
+  PyImport_Cleanup*: proc (){.cdecl.} #-
+  PyImport_GetMagicNumber*: proc (): int32{.cdecl.} #+
+  PyImport_ImportFrozenModule*: proc (key: cstring): int{.cdecl.} #+
+  PyImport_ImportModule*: proc (name: cstring): PPyObject{.cdecl.} #+
+  PyImport_Import*: proc (name: PPyObject): PPyObject{.cdecl.} #-
+                                                               #PyImport_Init:procedure; cdecl;
+                                                               #-
+  PyImport_ReloadModule*: proc (ob: PPyObject): PPyObject{.cdecl.} #-
+  PyInstance_New*: proc (obClass, obArg, obKW: PPyObject): PPyObject{.cdecl.} #+
+  PyInt_AsLong*: proc (ob: PPyObject): int32{.cdecl.} #-
+  PyList_Append*: proc (ob1, ob2: PPyObject): int{.cdecl.} #-
+  PyList_AsTuple*: proc (ob: PPyObject): PPyObject{.cdecl.} #+
+  PyList_GetItem*: proc (ob: PPyObject, i: int): PPyObject{.cdecl.} #-
+  PyList_GetSlice*: proc (ob: PPyObject, i1, i2: int): PPyObject{.cdecl.} #-
+  PyList_Insert*: proc (dp: PPyObject, idx: int, item: PPyObject): int{.cdecl.} #-
+  PyList_New*: proc (size: int): PPyObject{.cdecl.} #-
+  PyList_Reverse*: proc (ob: PPyObject): int{.cdecl.} #-
+  PyList_SetItem*: proc (dp: PPyObject, idx: int, item: PPyObject): int{.cdecl.} #-
+  PyList_SetSlice*: proc (ob: PPyObject, i1, i2: int, ob2: PPyObject): int{.
+      cdecl.}                 #+
+  PyList_Size*: proc (ob: PPyObject): int{.cdecl.} #-
+  PyList_Sort*: proc (ob: PPyObject): int{.cdecl.} #-
+  PyLong_AsDouble*: proc (ob: PPyObject): float64{.cdecl.} #+
+  PyLong_AsLong*: proc (ob: PPyObject): int32{.cdecl.} #+
+  PyLong_FromDouble*: proc (db: float64): PPyObject{.cdecl.} #+
+  PyLong_FromLong*: proc (l: int32): PPyObject{.cdecl.} #-
+  PyLong_FromString*: proc (pc: cstring, ppc: var cstring, i: int): PPyObject{.
+      cdecl.}                 #-
+  PyLong_FromUnsignedLong*: proc (val: int): PPyObject{.cdecl.} #-
+  PyLong_AsUnsignedLong*: proc (ob: PPyObject): int{.cdecl.} #-
+  PyLong_FromUnicode*: proc (ob: PPyObject, a, b: int): PPyObject{.cdecl.} #-
+  PyLong_FromLongLong*: proc (val: Int64): PPyObject{.cdecl.} #-
+  PyLong_AsLongLong*: proc (ob: PPyObject): Int64{.cdecl.} #-
+  PyMapping_Check*: proc (ob: PPyObject): int{.cdecl.} #-
+  PyMapping_GetItemString*: proc (ob: PPyObject, key: cstring): PPyObject{.cdecl.} #-
+  PyMapping_HasKey*: proc (ob, key: PPyObject): int{.cdecl.} #-
+  PyMapping_HasKeyString*: proc (ob: PPyObject, key: cstring): int{.cdecl.} #-
+  PyMapping_Length*: proc (ob: PPyObject): int{.cdecl.} #-
+  PyMapping_SetItemString*: proc (ob: PPyObject, key: cstring, value: PPyObject): int{.
+      cdecl.}                 #-
+  PyMethod_Class*: proc (ob: PPyObject): PPyObject{.cdecl.} #-
+  PyMethod_Function*: proc (ob: PPyObject): PPyObject{.cdecl.} #-
+  PyMethod_New*: proc (ob1, ob2, ob3: PPyObject): PPyObject{.cdecl.} #-
+  PyMethod_Self*: proc (ob: PPyObject): PPyObject{.cdecl.} #-
+  PyModule_GetName*: proc (ob: PPyObject): cstring{.cdecl.} #-
+  PyModule_New*: proc (key: cstring): PPyObject{.cdecl.} #-
+  PyNumber_Absolute*: proc (ob: PPyObject): PPyObject{.cdecl.} #-
+  PyNumber_Add*: proc (ob1, ob2: PPyObject): PPyObject{.cdecl.} #-
+  PyNumber_And*: proc (ob1, ob2: PPyObject): PPyObject{.cdecl.} #-
+  PyNumber_Check*: proc (ob: PPyObject): int{.cdecl.} #-
+  PyNumber_Coerce*: proc (ob1, ob2: var PPyObject): int{.cdecl.} #-
+  PyNumber_Divide*: proc (ob1, ob2: PPyObject): PPyObject{.cdecl.} #-
+  PyNumber_FloorDivide*: proc (ob1, ob2: PPyObject): PPyObject{.cdecl.} #-
+  PyNumber_TrueDivide*: proc (ob1, ob2: PPyObject): PPyObject{.cdecl.} #-
+  PyNumber_Divmod*: proc (ob1, ob2: PPyObject): PPyObject{.cdecl.} #-
+  PyNumber_Float*: proc (ob: PPyObject): PPyObject{.cdecl.} #-
+  PyNumber_Int*: proc (ob: PPyObject): PPyObject{.cdecl.} #-
+  PyNumber_Invert*: proc (ob: PPyObject): PPyObject{.cdecl.} #-
+  PyNumber_Long*: proc (ob: PPyObject): PPyObject{.cdecl.} #-
+  PyNumber_Lshift*: proc (ob1, ob2: PPyObject): PPyObject{.cdecl.} #-
+  PyNumber_Multiply*: proc (ob1, ob2: PPyObject): PPyObject{.cdecl.} #-
+  PyNumber_Negative*: proc (ob: PPyObject): PPyObject{.cdecl.} #-
+  PyNumber_Or*: proc (ob1, ob2: PPyObject): PPyObject{.cdecl.} #-
+  PyNumber_Positive*: proc (ob: PPyObject): PPyObject{.cdecl.} #-
+  PyNumber_Power*: proc (ob1, ob2, ob3: PPyObject): PPyObject{.cdecl.} #-
+  PyNumber_Remainder*: proc (ob1, ob2: PPyObject): PPyObject{.cdecl.} #-
+  PyNumber_Rshift*: proc (ob1, ob2: PPyObject): PPyObject{.cdecl.} #-
+  PyNumber_Subtract*: proc (ob1, ob2: PPyObject): PPyObject{.cdecl.} #-
+  PyNumber_Xor*: proc (ob1, ob2: PPyObject): PPyObject{.cdecl.} #-
+  PyOS_InitInterrupts*: proc (){.cdecl.} #-
+  PyOS_InterruptOccurred*: proc (): int{.cdecl.} #-
+  PyObject_CallObject*: proc (ob, args: PPyObject): PPyObject{.cdecl.} #-
+  PyObject_Compare*: proc (ob1, ob2: PPyObject): int{.cdecl.} #-
+  PyObject_GetAttr*: proc (ob1, ob2: PPyObject): PPyObject{.cdecl.} #+
+  PyObject_GetAttrString*: proc (ob: PPyObject, c: cstring): PPyObject{.cdecl.} #-
+  PyObject_GetItem*: proc (ob, key: PPyObject): PPyObject{.cdecl.} #-
+  PyObject_DelItem*: proc (ob, key: PPyObject): PPyObject{.cdecl.} #-
+  PyObject_HasAttrString*: proc (ob: PPyObject, key: cstring): int{.cdecl.} #-
+  PyObject_Hash*: proc (ob: PPyObject): int32{.cdecl.} #-
+  PyObject_IsTrue*: proc (ob: PPyObject): int{.cdecl.} #-
+  PyObject_Length*: proc (ob: PPyObject): int{.cdecl.} #-
+  PyObject_Repr*: proc (ob: PPyObject): PPyObject{.cdecl.} #-
+  PyObject_SetAttr*: proc (ob1, ob2, ob3: PPyObject): int{.cdecl.} #-
+  PyObject_SetAttrString*: proc (ob: PPyObject, key: cstring, value: PPyObject): int{.
+      cdecl.}                 #-
+  PyObject_SetItem*: proc (ob1, ob2, ob3: PPyObject): int{.cdecl.} #-
+  PyObject_Init*: proc (ob: PPyObject, t: PPyTypeObject): PPyObject{.cdecl.} #-
+  PyObject_InitVar*: proc (ob: PPyObject, t: PPyTypeObject, size: int): PPyObject{.
+      cdecl.}                 #-
+  PyObject_New*: proc (t: PPyTypeObject): PPyObject{.cdecl.} #-
+  PyObject_NewVar*: proc (t: PPyTypeObject, size: int): PPyObject{.cdecl.}
+  PyObject_Free*: proc (ob: PPyObject){.cdecl.} #-
+  PyObject_IsInstance*: proc (inst, cls: PPyObject): int{.cdecl.} #-
+  PyObject_IsSubclass*: proc (derived, cls: PPyObject): int{.cdecl.}
+  PyObject_GenericGetAttr*: proc (obj, name: PPyObject): PPyObject{.cdecl.}
+  PyObject_GenericSetAttr*: proc (obj, name, value: PPyObject): int{.cdecl.} #-
+  PyObject_GC_Malloc*: proc (size: int): PPyObject{.cdecl.} #-
+  PyObject_GC_New*: proc (t: PPyTypeObject): PPyObject{.cdecl.} #-
+  PyObject_GC_NewVar*: proc (t: PPyTypeObject, size: int): PPyObject{.cdecl.} #-
+  PyObject_GC_Resize*: proc (t: PPyObject, newsize: int): PPyObject{.cdecl.} #-
+  PyObject_GC_Del*: proc (ob: PPyObject){.cdecl.} #-
+  PyObject_GC_Track*: proc (ob: PPyObject){.cdecl.} #-
+  PyObject_GC_UnTrack*: proc (ob: PPyObject){.cdecl.} #-
+  PyRange_New*: proc (l1, l2, l3: int32, i: int): PPyObject{.cdecl.} #-
+  PySequence_Check*: proc (ob: PPyObject): int{.cdecl.} #-
+  PySequence_Concat*: proc (ob1, ob2: PPyObject): PPyObject{.cdecl.} #-
+  PySequence_Count*: proc (ob1, ob2: PPyObject): int{.cdecl.} #-
+  PySequence_GetItem*: proc (ob: PPyObject, i: int): PPyObject{.cdecl.} #-
+  PySequence_GetSlice*: proc (ob: PPyObject, i1, i2: int): PPyObject{.cdecl.} #-
+  PySequence_In*: proc (ob1, ob2: PPyObject): int{.cdecl.} #-
+  PySequence_Index*: proc (ob1, ob2: PPyObject): int{.cdecl.} #-
+  PySequence_Length*: proc (ob: PPyObject): int{.cdecl.} #-
+  PySequence_Repeat*: proc (ob: PPyObject, count: int): PPyObject{.cdecl.} #-
+  PySequence_SetItem*: proc (ob: PPyObject, i: int, value: PPyObject): int{.
+      cdecl.}                 #-
+  PySequence_SetSlice*: proc (ob: PPyObject, i1, i2: int, value: PPyObject): int{.
+      cdecl.}                 #-
+  PySequence_DelSlice*: proc (ob: PPyObject, i1, i2: int): int{.cdecl.} #-
+  PySequence_Tuple*: proc (ob: PPyObject): PPyObject{.cdecl.} #-
+  PySequence_Contains*: proc (ob, value: PPyObject): int{.cdecl.} #-
+  PySlice_GetIndices*: proc (ob: PPySliceObject, len: int, 
+                             start, stop, step: var int): int{.cdecl.} #-
+  PySlice_GetIndicesEx*: proc (ob: PPySliceObject, len: int, 
+                               start, stop, step, slicelength: var int): int{.
+      cdecl.}                 #-
+  PySlice_New*: proc (start, stop, step: PPyObject): PPyObject{.cdecl.} #-
+  PyString_Concat*: proc (ob1: var PPyObject, ob2: PPyObject){.cdecl.} #-
+  PyString_ConcatAndDel*: proc (ob1: var PPyObject, ob2: PPyObject){.cdecl.} #-
+  PyString_Format*: proc (ob1, ob2: PPyObject): PPyObject{.cdecl.} #-
+  PyString_FromStringAndSize*: proc (s: cstring, i: int): PPyObject{.cdecl.} #-
+  PyString_Size*: proc (ob: PPyObject): int{.cdecl.} #-
+  PyString_DecodeEscape*: proc (s: cstring, length: int, errors: cstring, 
+                                unicode: int, recode_encoding: cstring): PPyObject{.
+      cdecl.}                 #-
+  PyString_Repr*: proc (ob: PPyObject, smartquotes: int): PPyObject{.cdecl.} #+
+  PySys_GetObject*: proc (s: cstring): PPyObject{.cdecl.} #-
+                                                          #PySys_Init:procedure; cdecl;
+                                                          #-
+  PySys_SetObject*: proc (s: cstring, ob: PPyObject): int{.cdecl.} #-
+  PySys_SetPath*: proc (path: cstring){.cdecl.} #-
+                                                #PyTraceBack_Fetch:function:PPyObject; cdecl;
+                                                #-
+  PyTraceBack_Here*: proc (p: pointer): int{.cdecl.} #-
+  PyTraceBack_Print*: proc (ob1, ob2: PPyObject): int{.cdecl.} #-
+                                                               #PyTraceBack_Store:function (ob:PPyObject):integer; cdecl;
+                                                               #+
+  PyTuple_GetItem*: proc (ob: PPyObject, i: int): PPyObject{.cdecl.} #-
+  PyTuple_GetSlice*: proc (ob: PPyObject, i1, i2: int): PPyObject{.cdecl.} #+
+  PyTuple_New*: proc (size: int): PPyObject{.cdecl.} #+
+  PyTuple_SetItem*: proc (ob: PPyObject, key: int, value: PPyObject): int{.cdecl.} #+
+  PyTuple_Size*: proc (ob: PPyObject): int{.cdecl.} #+
+  PyType_IsSubtype*: proc (a, b: PPyTypeObject): int{.cdecl.}
+  PyType_GenericAlloc*: proc (atype: PPyTypeObject, nitems: int): PPyObject{.
+      cdecl.}
+  PyType_GenericNew*: proc (atype: PPyTypeObject, args, kwds: PPyObject): PPyObject{.
+      cdecl.}
+  PyType_Ready*: proc (atype: PPyTypeObject): int{.cdecl.} #+
+  PyUnicode_FromWideChar*: proc (w: PWideChar, size: int): PPyObject{.cdecl.} #+
+  PyUnicode_AsWideChar*: proc (unicode: PPyObject, w: PWideChar, size: int): int{.
+      cdecl.}                 #-
+  PyUnicode_FromOrdinal*: proc (ordinal: int): PPyObject{.cdecl.}
+  PyWeakref_GetObject*: proc (ref: PPyObject): PPyObject{.cdecl.}
+  PyWeakref_NewProxy*: proc (ob, callback: PPyObject): PPyObject{.cdecl.}
+  PyWeakref_NewRef*: proc (ob, callback: PPyObject): PPyObject{.cdecl.}
+  PyWrapper_New*: proc (ob1, ob2: PPyObject): PPyObject{.cdecl.}
+  PyBool_FromLong*: proc (ok: int): PPyObject{.cdecl.} #-
+  Py_AtExit*: proc (proc: proc ()): int{.cdecl.} #-
+                                                 #Py_Cleanup:procedure; cdecl;
+                                                 #-
+  Py_CompileString*: proc (s1, s2: cstring, i: int): PPyObject{.cdecl.} #-
+  Py_FatalError*: proc (s: cstring){.cdecl.} #-
+  Py_FindMethod*: proc (md: PPyMethodDef, ob: PPyObject, key: cstring): PPyObject{.
+      cdecl.}                 #-
+  Py_FindMethodInChain*: proc (mc: PPyMethodChain, ob: PPyObject, key: cstring): PPyObject{.
+      cdecl.}                 #-
+  Py_FlushLine*: proc (){.cdecl.} #+
+  Py_Finalize*: proc (){.cdecl.} #-
+  PyErr_ExceptionMatches*: proc (exc: PPyObject): int{.cdecl.} #-
+  PyErr_GivenExceptionMatches*: proc (raised_exc, exc: PPyObject): int{.cdecl.} #-
+  PyEval_EvalCode*: proc (co: PPyCodeObject, globals, locals: PPyObject): PPyObject{.
+      cdecl.}                 #+
+  Py_GetVersion*: proc (): cstring{.cdecl.} #+
+  Py_GetCopyright*: proc (): cstring{.cdecl.} #+
+  Py_GetExecPrefix*: proc (): cstring{.cdecl.} #+
+  Py_GetPath*: proc (): cstring{.cdecl.} #+
+  Py_GetPrefix*: proc (): cstring{.cdecl.} #+
+  Py_GetProgramName*: proc (): cstring{.cdecl.} #-
+  PyParser_SimpleParseString*: proc (str: cstring, start: int): PNode{.cdecl.} #-
+  PyNode_Free*: proc (n: PNode){.cdecl.} #-
+  PyErr_NewException*: proc (name: cstring, base, dict: PPyObject): PPyObject{.
+      cdecl.}                 #-
+  Py_Malloc*: proc (size: int): Pointer #-
+  PyMem_Malloc*: proc (size: int): Pointer #-
+  PyObject_CallMethod*: proc (obj: PPyObject, method, format: cstring): PPyObject{.
+      cdecl.}                 #New exported Objects in Python 1.5
+  Py_SetProgramName*: proc (name: cstring){.cdecl.}
+  Py_IsInitialized*: proc (): int{.cdecl.}
+  Py_GetProgramFullPath*: proc (): cstring{.cdecl.}
+  Py_NewInterpreter*: proc (): PPyThreadState{.cdecl.}
+  Py_EndInterpreter*: proc (tstate: PPyThreadState){.cdecl.}
+  PyEval_AcquireLock*: proc (){.cdecl.}
+  PyEval_ReleaseLock*: proc (){.cdecl.}
+  PyEval_AcquireThread*: proc (tstate: PPyThreadState){.cdecl.}
+  PyEval_ReleaseThread*: proc (tstate: PPyThreadState){.cdecl.}
+  PyInterpreterState_New*: proc (): PPyInterpreterState{.cdecl.}
+  PyInterpreterState_Clear*: proc (interp: PPyInterpreterState){.cdecl.}
+  PyInterpreterState_Delete*: proc (interp: PPyInterpreterState){.cdecl.}
+  PyThreadState_New*: proc (interp: PPyInterpreterState): PPyThreadState{.cdecl.}
+  PyThreadState_Clear*: proc (tstate: PPyThreadState){.cdecl.}
+  PyThreadState_Delete*: proc (tstate: PPyThreadState){.cdecl.}
+  PyThreadState_Get*: proc (): PPyThreadState{.cdecl.}
+  PyThreadState_Swap*: proc (tstate: PPyThreadState): PPyThreadState{.cdecl.} 
+
+#Further exported Objects, may be implemented later
+#
+#    PyCode_New: Pointer;
+#    PyErr_SetInterrupt: Pointer;
+#    PyFile_AsFile: Pointer;
+#    PyFile_FromFile: Pointer;
+#    PyFloat_AsString: Pointer;
+#    PyFrame_BlockPop: Pointer;
+#    PyFrame_BlockSetup: Pointer;
+#    PyFrame_ExtendStack: Pointer;
+#    PyFrame_FastToLocals: Pointer;
+#    PyFrame_LocalsToFast: Pointer;
+#    PyFrame_New: Pointer;
+#    PyGrammar_AddAccelerators: Pointer;
+#    PyGrammar_FindDFA: Pointer;
+#    PyGrammar_LabelRepr: Pointer;
+#    PyInstance_DoBinOp: Pointer;
+#    PyInt_GetMax: Pointer;
+#    PyMarshal_Init: Pointer;
+#    PyMarshal_ReadLongFromFile: Pointer;
+#    PyMarshal_ReadObjectFromFile: Pointer;
+#    PyMarshal_ReadObjectFromString: Pointer;
+#    PyMarshal_WriteLongToFile: Pointer;
+#    PyMarshal_WriteObjectToFile: Pointer;
+#    PyMember_Get: Pointer;
+#    PyMember_Set: Pointer;
+#    PyNode_AddChild: Pointer;
+#    PyNode_Compile: Pointer;
+#    PyNode_New: Pointer;
+#    PyOS_GetLastModificationTime: Pointer;
+#    PyOS_Readline: Pointer;
+#    PyOS_strtol: Pointer;
+#    PyOS_strtoul: Pointer;
+#    PyObject_CallFunction: Pointer;
+#    PyObject_CallMethod: Pointer;
+#    PyObject_Print: Pointer;
+#    PyParser_AddToken: Pointer;
+#    PyParser_Delete: Pointer;
+#    PyParser_New: Pointer;
+#    PyParser_ParseFile: Pointer;
+#    PyParser_ParseString: Pointer;
+#    PyParser_SimpleParseFile: Pointer;
+#    PyRun_AnyFile: Pointer;
+#    PyRun_File: Pointer;
+#    PyRun_InteractiveLoop: Pointer;
+#    PyRun_InteractiveOne: Pointer;
+#    PyRun_SimpleFile: Pointer;
+#    PySys_GetFile: Pointer;
+#    PyToken_OneChar: Pointer;
+#    PyToken_TwoChars: Pointer;
+#    PyTokenizer_Free: Pointer;
+#    PyTokenizer_FromFile: Pointer;
+#    PyTokenizer_FromString: Pointer;
+#    PyTokenizer_Get: Pointer;
+#    Py_Main: Pointer;
+#    _PyObject_NewVar: Pointer;
+#    _PyParser_Grammar: Pointer;
+#    _PyParser_TokenNames: Pointer;
+#    _PyThread_Started: Pointer;
+#    _Py_c_diff: Pointer;
+#    _Py_c_neg: Pointer;
+#    _Py_c_pow: Pointer;
+#    _Py_c_prod: Pointer;
+#    _Py_c_quot: Pointer;
+#    _Py_c_sum: Pointer;
+#
+
+# This function handles all cardinals, pointer types (with no adjustment of pointers!)
+# (Extended) floats, which are handled as Python doubles and currencies, handled
+# as (normalized) Python doubles.
+proc PyImport_ExecCodeModule*(name: String, codeobject: PPyObject): PPyObject
+proc PyString_Check*(obj: PPyObject): bool
+proc PyString_CheckExact*(obj: PPyObject): bool
+proc PyFloat_Check*(obj: PPyObject): bool
+proc PyFloat_CheckExact*(obj: PPyObject): bool
+proc PyInt_Check*(obj: PPyObject): bool
+proc PyInt_CheckExact*(obj: PPyObject): bool
+proc PyLong_Check*(obj: PPyObject): bool
+proc PyLong_CheckExact*(obj: PPyObject): bool
+proc PyTuple_Check*(obj: PPyObject): bool
+proc PyTuple_CheckExact*(obj: PPyObject): bool
+proc PyInstance_Check*(obj: PPyObject): bool
+proc PyClass_Check*(obj: PPyObject): bool
+proc PyMethod_Check*(obj: PPyObject): bool
+proc PyList_Check*(obj: PPyObject): bool
+proc PyList_CheckExact*(obj: PPyObject): bool
+proc PyDict_Check*(obj: PPyObject): bool
+proc PyDict_CheckExact*(obj: PPyObject): bool
+proc PyModule_Check*(obj: PPyObject): bool
+proc PyModule_CheckExact*(obj: PPyObject): bool
+proc PySlice_Check*(obj: PPyObject): bool
+proc PyFunction_Check*(obj: PPyObject): bool
+proc PyUnicode_Check*(obj: PPyObject): bool
+proc PyUnicode_CheckExact*(obj: PPyObject): bool
+proc PyType_IS_GC*(t: PPyTypeObject): bool
+proc PyObject_IS_GC*(obj: PPyObject): bool
+proc PyWeakref_Check*(obj: PPyObject): bool
+proc PyWeakref_CheckRef*(obj: PPyObject): bool
+proc PyWeakref_CheckProxy*(obj: PPyObject): bool
+proc PyBool_Check*(obj: PPyObject): bool
+proc PyBaseString_Check*(obj: PPyObject): bool
+proc PyEnum_Check*(obj: PPyObject): bool
+proc PyObject_TypeCheck*(obj: PPyObject, t: PPyTypeObject): bool
+proc Py_InitModule*(name: cstring, md: PPyMethodDef): PPyObject
+proc PyType_HasFeature*(AType: PPyTypeObject, AFlag: int): bool
+# implementation
+
+proc Py_INCREF*(op: PPyObject) {.inline.} = 
+  Inc(op.ob_refcnt)
+
+proc Py_DECREF*(op: PPyObject) {.inline.} = 
+  Dec(op.ob_refcnt)
+  if op.ob_refcnt == 0: 
+    op.ob_type.tp_dealloc(op)
+
+proc Py_XINCREF*(op: PPyObject) {.inline.} = 
+  if op != nil: Py_INCREF(op)
+  
+proc Py_XDECREF*(op: PPyObject) {.inline.} = 
+  if op != nil: Py_DECREF(op)
+  
+proc PyImport_ExecCodeModule(name: String, codeobject: PPyObject): PPyObject = 
+  var m, d, v, modules: PPyObject
+  m = PyImport_AddModule(cstring(name))
+  if m == nil: 
+    return nil
+  d = PyModule_GetDict(m)
+  if PyDict_GetItemString(d, "__builtins__") == nil: 
+    if PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins) != 0: 
+      return nil
+  if PyDict_SetItemString(d, "__file__", PPyCodeObject(codeobject).co_filename) !=
+      0: 
+    PyErr_Clear()             # Not important enough to report
+  v = PyEval_EvalCode(PPyCodeObject(codeobject), d, d) # XXX owner ?
+  if v == nil: 
+    return nil
+  Py_XDECREF(v)
+  modules = PyImport_GetModuleDict()
+  if PyDict_GetItemString(modules, cstring(name)) == nil: 
+    PyErr_SetString(PyExc_ImportError^ , cstring(
+        Format("Loaded module %.200s not found in sys.modules", [name])))
+    return nil
+  Py_XINCREF(m)
+  Result = m
+
+proc PyString_Check(obj: PPyObject): bool = 
+  Result = PyObject_TypeCheck(obj, PyString_Type)
+
+proc PyString_CheckExact(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj.ob_type == PPyTypeObject(PyString_Type))
+
+proc PyFloat_Check(obj: PPyObject): bool = 
+  Result = PyObject_TypeCheck(obj, PyFloat_Type)
+
+proc PyFloat_CheckExact(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj.ob_type == PPyTypeObject(PyFloat_Type))
+
+proc PyInt_Check(obj: PPyObject): bool = 
+  Result = PyObject_TypeCheck(obj, PyInt_Type)
+
+proc PyInt_CheckExact(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj.ob_type == PPyTypeObject(PyInt_Type))
+
+proc PyLong_Check(obj: PPyObject): bool = 
+  Result = PyObject_TypeCheck(obj, PyLong_Type)
+
+proc PyLong_CheckExact(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj.ob_type == PPyTypeObject(PyLong_Type))
+
+proc PyTuple_Check(obj: PPyObject): bool = 
+  Result = PyObject_TypeCheck(obj, PyTuple_Type)
+
+proc PyTuple_CheckExact(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj^ .ob_type == PPyTypeObject(PyTuple_Type))
+
+proc PyInstance_Check(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj^ .ob_type == PPyTypeObject(PyInstance_Type))
+
+proc PyClass_Check(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj^ .ob_type == PPyTypeObject(PyClass_Type))
+
+proc PyMethod_Check(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj^ .ob_type == PPyTypeObject(PyMethod_Type))
+
+proc PyList_Check(obj: PPyObject): bool = 
+  Result = PyObject_TypeCheck(obj, PyList_Type)
+
+proc PyList_CheckExact(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj^ .ob_type == PPyTypeObject(PyList_Type))
+
+proc PyDict_Check(obj: PPyObject): bool = 
+  Result = PyObject_TypeCheck(obj, PyDict_Type)
+
+proc PyDict_CheckExact(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj^ .ob_type == PPyTypeObject(PyDict_Type))
+
+proc PyModule_Check(obj: PPyObject): bool = 
+  Result = PyObject_TypeCheck(obj, PyModule_Type)
+
+proc PyModule_CheckExact(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj^ .ob_type == PPyTypeObject(PyModule_Type))
+
+proc PySlice_Check(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj^ .ob_type == PPyTypeObject(PySlice_Type))
+
+proc PyFunction_Check(obj: PPyObject): bool = 
+  Result = (obj != nil) and
+      ((obj.ob_type == PPyTypeObject(PyCFunction_Type)) or
+      (obj.ob_type == PPyTypeObject(PyFunction_Type)))
+
+proc PyUnicode_Check(obj: PPyObject): bool = 
+  Result = PyObject_TypeCheck(obj, PyUnicode_Type)
+
+proc PyUnicode_CheckExact(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj^ .ob_type == PPyTypeObject(PyUnicode_Type))
+
+proc PyType_IS_GC(t: PPyTypeObject): bool = 
+  Result = PyType_HasFeature(t, Py_TPFLAGS_HAVE_GC)
+
+proc PyObject_IS_GC(obj: PPyObject): bool = 
+  Result = PyType_IS_GC(obj.ob_type) and
+      ((obj.ob_type.tp_is_gc == nil) or (obj.ob_type.tp_is_gc(obj) == 1))
+
+proc PyWeakref_Check(obj: PPyObject): bool = 
+  Result = (obj != nil) and
+      (PyWeakref_CheckRef(obj) or PyWeakref_CheckProxy(obj))
+
+proc PyWeakref_CheckRef(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj.ob_type == PPyTypeObject(PyWeakref_RefType))
+
+proc PyWeakref_CheckProxy(obj: PPyObject): bool = 
+  Result = (obj != nil) and
+      ((obj.ob_type == PPyTypeObject(PyWeakref_ProxyType)) or
+      (obj.ob_type == PPyTypeObject(PyWeakref_CallableProxyType)))
+
+proc PyBool_Check(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj.ob_type == PPyTypeObject(PyBool_Type))
+
+proc PyBaseString_Check(obj: PPyObject): bool = 
+  Result = PyObject_TypeCheck(obj, PyBaseString_Type)
+
+proc PyEnum_Check(obj: PPyObject): bool = 
+  Result = (obj != nil) and (obj.ob_type == PPyTypeObject(PyEnum_Type))
+
+proc PyObject_TypeCheck(obj: PPyObject, t: PPyTypeObject): bool = 
+  Result = (obj != nil) and (obj.ob_type == t)
+  if not Result and (obj != nil) and (t != nil): 
+    Result = PyType_IsSubtype(obj.ob_type, t) == 1
+  
+proc Py_InitModule(name: cstring, md: PPyMethodDef): PPyObject = 
+  result = Py_InitModule4(name, md, nil, nil, 1012)
+
+proc PyType_HasFeature(AType: PPyTypeObject, AFlag: int): bool = 
+  #(((t)->tp_flags & (f)) != 0)
+  Result = (AType.tp_flags and AFlag) != 0
+
+proc init(lib: TLibHandle) = 
+  Py_DebugFlag = getProcAddr(lib, "Py_DebugFlag")
+  Py_VerboseFlag = getProcAddr(lib, "Py_VerboseFlag")
+  Py_InteractiveFlag = getProcAddr(lib, "Py_InteractiveFlag")
+  Py_OptimizeFlag = getProcAddr(lib, "Py_OptimizeFlag")
+  Py_NoSiteFlag = getProcAddr(lib, "Py_NoSiteFlag")
+  Py_UseClassExceptionsFlag = getProcAddr(lib, "Py_UseClassExceptionsFlag")
+  Py_FrozenFlag = getProcAddr(lib, "Py_FrozenFlag")
+  Py_TabcheckFlag = getProcAddr(lib, "Py_TabcheckFlag")
+  Py_UnicodeFlag = getProcAddr(lib, "Py_UnicodeFlag")
+  Py_IgnoreEnvironmentFlag = getProcAddr(lib, "Py_IgnoreEnvironmentFlag")
+  Py_DivisionWarningFlag = getProcAddr(lib, "Py_DivisionWarningFlag")
+  Py_None = getProcAddr(lib, "_Py_NoneStruct")
+  Py_Ellipsis = getProcAddr(lib, "_Py_EllipsisObject")
+  Py_False = getProcAddr(lib, "_Py_ZeroStruct")
+  Py_True = getProcAddr(lib, "_Py_TrueStruct")
+  Py_NotImplemented = getProcAddr(lib, "_Py_NotImplementedStruct")
+  PyImport_FrozenModules = getProcAddr(lib, "PyImport_FrozenModules")
+  PyExc_AttributeError = getProcAddr(lib, "PyExc_AttributeError")
+  PyExc_EOFError = getProcAddr(lib, "PyExc_EOFError")
+  PyExc_IOError = getProcAddr(lib, "PyExc_IOError")
+  PyExc_ImportError = getProcAddr(lib, "PyExc_ImportError")
+  PyExc_IndexError = getProcAddr(lib, "PyExc_IndexError")
+  PyExc_KeyError = getProcAddr(lib, "PyExc_KeyError")
+  PyExc_KeyboardInterrupt = getProcAddr(lib, "PyExc_KeyboardInterrupt")
+  PyExc_MemoryError = getProcAddr(lib, "PyExc_MemoryError")
+  PyExc_NameError = getProcAddr(lib, "PyExc_NameError")
+  PyExc_OverflowError = getProcAddr(lib, "PyExc_OverflowError")
+  PyExc_RuntimeError = getProcAddr(lib, "PyExc_RuntimeError")
+  PyExc_SyntaxError = getProcAddr(lib, "PyExc_SyntaxError")
+  PyExc_SystemError = getProcAddr(lib, "PyExc_SystemError")
+  PyExc_SystemExit = getProcAddr(lib, "PyExc_SystemExit")
+  PyExc_TypeError = getProcAddr(lib, "PyExc_TypeError")
+  PyExc_ValueError = getProcAddr(lib, "PyExc_ValueError")
+  PyExc_ZeroDivisionError = getProcAddr(lib, "PyExc_ZeroDivisionError")
+  PyExc_ArithmeticError = getProcAddr(lib, "PyExc_ArithmeticError")
+  PyExc_Exception = getProcAddr(lib, "PyExc_Exception")
+  PyExc_FloatingPointError = getProcAddr(lib, "PyExc_FloatingPointError")
+  PyExc_LookupError = getProcAddr(lib, "PyExc_LookupError")
+  PyExc_StandardError = getProcAddr(lib, "PyExc_StandardError")
+  PyExc_AssertionError = getProcAddr(lib, "PyExc_AssertionError")
+  PyExc_EnvironmentError = getProcAddr(lib, "PyExc_EnvironmentError")
+  PyExc_IndentationError = getProcAddr(lib, "PyExc_IndentationError")
+  PyExc_MemoryErrorInst = getProcAddr(lib, "PyExc_MemoryErrorInst")
+  PyExc_NotImplementedError = getProcAddr(lib, "PyExc_NotImplementedError")
+  PyExc_OSError = getProcAddr(lib, "PyExc_OSError")
+  PyExc_TabError = getProcAddr(lib, "PyExc_TabError")
+  PyExc_UnboundLocalError = getProcAddr(lib, "PyExc_UnboundLocalError")
+  PyExc_UnicodeError = getProcAddr(lib, "PyExc_UnicodeError")
+  PyExc_Warning = getProcAddr(lib, "PyExc_Warning")
+  PyExc_DeprecationWarning = getProcAddr(lib, "PyExc_DeprecationWarning")
+  PyExc_RuntimeWarning = getProcAddr(lib, "PyExc_RuntimeWarning")
+  PyExc_SyntaxWarning = getProcAddr(lib, "PyExc_SyntaxWarning")
+  PyExc_UserWarning = getProcAddr(lib, "PyExc_UserWarning")
+  PyExc_OverflowWarning = getProcAddr(lib, "PyExc_OverflowWarning")
+  PyExc_ReferenceError = getProcAddr(lib, "PyExc_ReferenceError")
+  PyExc_StopIteration = getProcAddr(lib, "PyExc_StopIteration")
+  PyExc_FutureWarning = getProcAddr(lib, "PyExc_FutureWarning")
+  PyExc_PendingDeprecationWarning = getProcAddr(lib, 
+      "PyExc_PendingDeprecationWarning")
+  PyExc_UnicodeDecodeError = getProcAddr(lib, "PyExc_UnicodeDecodeError")
+  PyExc_UnicodeEncodeError = getProcAddr(lib, "PyExc_UnicodeEncodeError")
+  PyExc_UnicodeTranslateError = getProcAddr(lib, "PyExc_UnicodeTranslateError")
+  PyType_Type = getProcAddr(lib, "PyType_Type")
+  PyCFunction_Type = getProcAddr(lib, "PyCFunction_Type")
+  PyCObject_Type = getProcAddr(lib, "PyCObject_Type")
+  PyClass_Type = getProcAddr(lib, "PyClass_Type")
+  PyCode_Type = getProcAddr(lib, "PyCode_Type")
+  PyComplex_Type = getProcAddr(lib, "PyComplex_Type")
+  PyDict_Type = getProcAddr(lib, "PyDict_Type")
+  PyFile_Type = getProcAddr(lib, "PyFile_Type")
+  PyFloat_Type = getProcAddr(lib, "PyFloat_Type")
+  PyFrame_Type = getProcAddr(lib, "PyFrame_Type")
+  PyFunction_Type = getProcAddr(lib, "PyFunction_Type")
+  PyInstance_Type = getProcAddr(lib, "PyInstance_Type")
+  PyInt_Type = getProcAddr(lib, "PyInt_Type")
+  PyList_Type = getProcAddr(lib, "PyList_Type")
+  PyLong_Type = getProcAddr(lib, "PyLong_Type")
+  PyMethod_Type = getProcAddr(lib, "PyMethod_Type")
+  PyModule_Type = getProcAddr(lib, "PyModule_Type")
+  PyObject_Type = getProcAddr(lib, "PyObject_Type")
+  PyRange_Type = getProcAddr(lib, "PyRange_Type")
+  PySlice_Type = getProcAddr(lib, "PySlice_Type")
+  PyString_Type = getProcAddr(lib, "PyString_Type")
+  PyTuple_Type = getProcAddr(lib, "PyTuple_Type")
+  PyUnicode_Type = getProcAddr(lib, "PyUnicode_Type")
+  PyBaseObject_Type = getProcAddr(lib, "PyBaseObject_Type")
+  PyBuffer_Type = getProcAddr(lib, "PyBuffer_Type")
+  PyCallIter_Type = getProcAddr(lib, "PyCallIter_Type")
+  PyCell_Type = getProcAddr(lib, "PyCell_Type")
+  PyClassMethod_Type = getProcAddr(lib, "PyClassMethod_Type")
+  PyProperty_Type = getProcAddr(lib, "PyProperty_Type")
+  PySeqIter_Type = getProcAddr(lib, "PySeqIter_Type")
+  PyStaticMethod_Type = getProcAddr(lib, "PyStaticMethod_Type")
+  PySuper_Type = getProcAddr(lib, "PySuper_Type")
+  PySymtableEntry_Type = getProcAddr(lib, "PySymtableEntry_Type")
+  PyTraceBack_Type = getProcAddr(lib, "PyTraceBack_Type")
+  PyWrapperDescr_Type = getProcAddr(lib, "PyWrapperDescr_Type")
+  PyBaseString_Type = getProcAddr(lib, "PyBaseString_Type")
+  PyBool_Type = getProcAddr(lib, "PyBool_Type")
+  PyEnum_Type = getProcAddr(lib, "PyEnum_Type") #PyArg_GetObject           := getProcAddr(lib, 'PyArg_GetObject');
+                                                #PyArg_GetLong             := getProcAddr(lib, 'PyArg_GetLong');
+                                                #PyArg_GetShort            := getProcAddr(lib, 'PyArg_GetShort');
+                                                #PyArg_GetFloat            := getProcAddr(lib, 'PyArg_GetFloat');
+                                                #PyArg_GetString           := getProcAddr(lib, 'PyArg_GetString');
+                                                #PyArgs_VaParse            := getProcAddr(lib, 'PyArgs_VaParse');
+                                                #Py_VaBuildValue           := getProcAddr(lib, 'Py_VaBuildValue');
+                                                #PyBuiltin_Init            := getProcAddr(lib, 'PyBuiltin_Init');
+  PyComplex_FromCComplex = getProcAddr(lib, "PyComplex_FromCComplex")
+  PyComplex_FromDoubles = getProcAddr(lib, "PyComplex_FromDoubles")
+  PyComplex_RealAsDouble = getProcAddr(lib, "PyComplex_RealAsDouble")
+  PyComplex_ImagAsDouble = getProcAddr(lib, "PyComplex_ImagAsDouble")
+  PyComplex_AsCComplex = getProcAddr(lib, "PyComplex_AsCComplex")
+  PyCFunction_GetFunction = getProcAddr(lib, "PyCFunction_GetFunction")
+  PyCFunction_GetSelf = getProcAddr(lib, "PyCFunction_GetSelf")
+  PyCallable_Check = getProcAddr(lib, "PyCallable_Check")
+  PyCObject_FromVoidPtr = getProcAddr(lib, "PyCObject_FromVoidPtr")
+  PyCObject_AsVoidPtr = getProcAddr(lib, "PyCObject_AsVoidPtr")
+  PyClass_New = getProcAddr(lib, "PyClass_New")
+  PyClass_IsSubclass = getProcAddr(lib, "PyClass_IsSubclass")
+  PyDict_GetItem = getProcAddr(lib, "PyDict_GetItem")
+  PyDict_SetItem = getProcAddr(lib, "PyDict_SetItem")
+  PyDict_DelItem = getProcAddr(lib, "PyDict_DelItem")
+  PyDict_Clear = getProcAddr(lib, "PyDict_Clear")
+  PyDict_Next = getProcAddr(lib, "PyDict_Next")
+  PyDict_Keys = getProcAddr(lib, "PyDict_Keys")
+  PyDict_Values = getProcAddr(lib, "PyDict_Values")
+  PyDict_Items = getProcAddr(lib, "PyDict_Items")
+  PyDict_Size = getProcAddr(lib, "PyDict_Size")
+  PyDict_DelItemString = getProcAddr(lib, "PyDict_DelItemString")
+  PyDictProxy_New = getProcAddr(lib, "PyDictProxy_New")
+  Py_InitModule4 = getProcAddr(lib, "Py_InitModule4")
+  PyErr_Print = getProcAddr(lib, "PyErr_Print")
+  PyErr_SetNone = getProcAddr(lib, "PyErr_SetNone")
+  PyErr_SetObject = getProcAddr(lib, "PyErr_SetObject")
+  PyErr_Restore = getProcAddr(lib, "PyErr_Restore")
+  PyErr_BadArgument = getProcAddr(lib, "PyErr_BadArgument")
+  PyErr_NoMemory = getProcAddr(lib, "PyErr_NoMemory")
+  PyErr_SetFromErrno = getProcAddr(lib, "PyErr_SetFromErrno")
+  PyErr_BadInternalCall = getProcAddr(lib, "PyErr_BadInternalCall")
+  PyErr_CheckSignals = getProcAddr(lib, "PyErr_CheckSignals")
+  PyErr_Occurred = getProcAddr(lib, "PyErr_Occurred")
+  PyErr_Clear = getProcAddr(lib, "PyErr_Clear")
+  PyErr_Fetch = getProcAddr(lib, "PyErr_Fetch")
+  PyErr_SetString = getProcAddr(lib, "PyErr_SetString")
+  PyEval_GetBuiltins = getProcAddr(lib, "PyEval_GetBuiltins")
+  PyImport_GetModuleDict = getProcAddr(lib, "PyImport_GetModuleDict")
+  PyInt_FromLong = getProcAddr(lib, "PyInt_FromLong")
+  PyArg_ParseTuple = getProcAddr(lib, "PyArg_ParseTuple")
+  PyArg_Parse = getProcAddr(lib, "PyArg_Parse")
+  Py_BuildValue = getProcAddr(lib, "Py_BuildValue")
+  Py_Initialize = getProcAddr(lib, "Py_Initialize")
+  PyDict_New = getProcAddr(lib, "PyDict_New")
+  PyDict_SetItemString = getProcAddr(lib, "PyDict_SetItemString")
+  PyModule_GetDict = getProcAddr(lib, "PyModule_GetDict")
+  PyObject_Str = getProcAddr(lib, "PyObject_Str")
+  PyRun_String = getProcAddr(lib, "PyRun_String")
+  PyRun_SimpleString = getProcAddr(lib, "PyRun_SimpleString")
+  PyDict_GetItemString = getProcAddr(lib, "PyDict_GetItemString")
+  PyString_AsString = getProcAddr(lib, "PyString_AsString")
+  PyString_FromString = getProcAddr(lib, "PyString_FromString")
+  PySys_SetArgv = getProcAddr(lib, "PySys_SetArgv")
+  Py_Exit = getProcAddr(lib, "Py_Exit")
+  PyCFunction_New = getProcAddr(lib, "PyCFunction_New")
+  PyEval_CallObject = getProcAddr(lib, "PyEval_CallObject")
+  PyEval_CallObjectWithKeywords = getProcAddr(lib, 
+      "PyEval_CallObjectWithKeywords")
+  PyEval_GetFrame = getProcAddr(lib, "PyEval_GetFrame")
+  PyEval_GetGlobals = getProcAddr(lib, "PyEval_GetGlobals")
+  PyEval_GetLocals = getProcAddr(lib, "PyEval_GetLocals") #PyEval_GetOwner           :=getProcAddr(lib, 'PyEval_GetOwner');
+  PyEval_GetRestricted = getProcAddr(lib, "PyEval_GetRestricted")
+  PyEval_InitThreads = getProcAddr(lib, "PyEval_InitThreads")
+  PyEval_RestoreThread = getProcAddr(lib, "PyEval_RestoreThread")
+  PyEval_SaveThread = getProcAddr(lib, "PyEval_SaveThread")
+  PyFile_FromString = getProcAddr(lib, "PyFile_FromString")
+  PyFile_GetLine = getProcAddr(lib, "PyFile_GetLine")
+  PyFile_Name = getProcAddr(lib, "PyFile_Name")
+  PyFile_SetBufSize = getProcAddr(lib, "PyFile_SetBufSize")
+  PyFile_SoftSpace = getProcAddr(lib, "PyFile_SoftSpace")
+  PyFile_WriteObject = getProcAddr(lib, "PyFile_WriteObject")
+  PyFile_WriteString = getProcAddr(lib, "PyFile_WriteString")
+  PyFloat_AsDouble = getProcAddr(lib, "PyFloat_AsDouble")
+  PyFloat_FromDouble = getProcAddr(lib, "PyFloat_FromDouble")
+  PyFunction_GetCode = getProcAddr(lib, "PyFunction_GetCode")
+  PyFunction_GetGlobals = getProcAddr(lib, "PyFunction_GetGlobals")
+  PyFunction_New = getProcAddr(lib, "PyFunction_New")
+  PyImport_AddModule = getProcAddr(lib, "PyImport_AddModule")
+  PyImport_Cleanup = getProcAddr(lib, "PyImport_Cleanup")
+  PyImport_GetMagicNumber = getProcAddr(lib, "PyImport_GetMagicNumber")
+  PyImport_ImportFrozenModule = getProcAddr(lib, "PyImport_ImportFrozenModule")
+  PyImport_ImportModule = getProcAddr(lib, "PyImport_ImportModule")
+  PyImport_Import = getProcAddr(lib, "PyImport_Import") #@PyImport_Init             :=getProcAddr(lib, 'PyImport_Init');
+  PyImport_ReloadModule = getProcAddr(lib, "PyImport_ReloadModule")
+  PyInstance_New = getProcAddr(lib, "PyInstance_New")
+  PyInt_AsLong = getProcAddr(lib, "PyInt_AsLong")
+  PyList_Append = getProcAddr(lib, "PyList_Append")
+  PyList_AsTuple = getProcAddr(lib, "PyList_AsTuple")
+  PyList_GetItem = getProcAddr(lib, "PyList_GetItem")
+  PyList_GetSlice = getProcAddr(lib, "PyList_GetSlice")
+  PyList_Insert = getProcAddr(lib, "PyList_Insert")
+  PyList_New = getProcAddr(lib, "PyList_New")
+  PyList_Reverse = getProcAddr(lib, "PyList_Reverse")
+  PyList_SetItem = getProcAddr(lib, "PyList_SetItem")
+  PyList_SetSlice = getProcAddr(lib, "PyList_SetSlice")
+  PyList_Size = getProcAddr(lib, "PyList_Size")
+  PyList_Sort = getProcAddr(lib, "PyList_Sort")
+  PyLong_AsDouble = getProcAddr(lib, "PyLong_AsDouble")
+  PyLong_AsLong = getProcAddr(lib, "PyLong_AsLong")
+  PyLong_FromDouble = getProcAddr(lib, "PyLong_FromDouble")
+  PyLong_FromLong = getProcAddr(lib, "PyLong_FromLong")
+  PyLong_FromString = getProcAddr(lib, "PyLong_FromString")
+  PyLong_FromString = getProcAddr(lib, "PyLong_FromString")
+  PyLong_FromUnsignedLong = getProcAddr(lib, "PyLong_FromUnsignedLong")
+  PyLong_AsUnsignedLong = getProcAddr(lib, "PyLong_AsUnsignedLong")
+  PyLong_FromUnicode = getProcAddr(lib, "PyLong_FromUnicode")
+  PyLong_FromLongLong = getProcAddr(lib, "PyLong_FromLongLong")
+  PyLong_AsLongLong = getProcAddr(lib, "PyLong_AsLongLong")
+  PyMapping_Check = getProcAddr(lib, "PyMapping_Check")
+  PyMapping_GetItemString = getProcAddr(lib, "PyMapping_GetItemString")
+  PyMapping_HasKey = getProcAddr(lib, "PyMapping_HasKey")
+  PyMapping_HasKeyString = getProcAddr(lib, "PyMapping_HasKeyString")
+  PyMapping_Length = getProcAddr(lib, "PyMapping_Length")
+  PyMapping_SetItemString = getProcAddr(lib, "PyMapping_SetItemString")
+  PyMethod_Class = getProcAddr(lib, "PyMethod_Class")
+  PyMethod_Function = getProcAddr(lib, "PyMethod_Function")
+  PyMethod_New = getProcAddr(lib, "PyMethod_New")
+  PyMethod_Self = getProcAddr(lib, "PyMethod_Self")
+  PyModule_GetName = getProcAddr(lib, "PyModule_GetName")
+  PyModule_New = getProcAddr(lib, "PyModule_New")
+  PyNumber_Absolute = getProcAddr(lib, "PyNumber_Absolute")
+  PyNumber_Add = getProcAddr(lib, "PyNumber_Add")
+  PyNumber_And = getProcAddr(lib, "PyNumber_And")
+  PyNumber_Check = getProcAddr(lib, "PyNumber_Check")
+  PyNumber_Coerce = getProcAddr(lib, "PyNumber_Coerce")
+  PyNumber_Divide = getProcAddr(lib, "PyNumber_Divide")
+  PyNumber_FloorDivide = getProcAddr(lib, "PyNumber_FloorDivide")
+  PyNumber_TrueDivide = getProcAddr(lib, "PyNumber_TrueDivide")
+  PyNumber_Divmod = getProcAddr(lib, "PyNumber_Divmod")
+  PyNumber_Float = getProcAddr(lib, "PyNumber_Float")
+  PyNumber_Int = getProcAddr(lib, "PyNumber_Int")
+  PyNumber_Invert = getProcAddr(lib, "PyNumber_Invert")
+  PyNumber_Long = getProcAddr(lib, "PyNumber_Long")
+  PyNumber_Lshift = getProcAddr(lib, "PyNumber_Lshift")
+  PyNumber_Multiply = getProcAddr(lib, "PyNumber_Multiply")
+  PyNumber_Negative = getProcAddr(lib, "PyNumber_Negative")
+  PyNumber_Or = getProcAddr(lib, "PyNumber_Or")
+  PyNumber_Positive = getProcAddr(lib, "PyNumber_Positive")
+  PyNumber_Power = getProcAddr(lib, "PyNumber_Power")
+  PyNumber_Remainder = getProcAddr(lib, "PyNumber_Remainder")
+  PyNumber_Rshift = getProcAddr(lib, "PyNumber_Rshift")
+  PyNumber_Subtract = getProcAddr(lib, "PyNumber_Subtract")
+  PyNumber_Xor = getProcAddr(lib, "PyNumber_Xor")
+  PyOS_InitInterrupts = getProcAddr(lib, "PyOS_InitInterrupts")
+  PyOS_InterruptOccurred = getProcAddr(lib, "PyOS_InterruptOccurred")
+  PyObject_CallObject = getProcAddr(lib, "PyObject_CallObject")
+  PyObject_Compare = getProcAddr(lib, "PyObject_Compare")
+  PyObject_GetAttr = getProcAddr(lib, "PyObject_GetAttr")
+  PyObject_GetAttrString = getProcAddr(lib, "PyObject_GetAttrString")
+  PyObject_GetItem = getProcAddr(lib, "PyObject_GetItem")
+  PyObject_DelItem = getProcAddr(lib, "PyObject_DelItem")
+  PyObject_HasAttrString = getProcAddr(lib, "PyObject_HasAttrString")
+  PyObject_Hash = getProcAddr(lib, "PyObject_Hash")
+  PyObject_IsTrue = getProcAddr(lib, "PyObject_IsTrue")
+  PyObject_Length = getProcAddr(lib, "PyObject_Length")
+  PyObject_Repr = getProcAddr(lib, "PyObject_Repr")
+  PyObject_SetAttr = getProcAddr(lib, "PyObject_SetAttr")
+  PyObject_SetAttrString = getProcAddr(lib, "PyObject_SetAttrString")
+  PyObject_SetItem = getProcAddr(lib, "PyObject_SetItem")
+  PyObject_Init = getProcAddr(lib, "PyObject_Init")
+  PyObject_InitVar = getProcAddr(lib, "PyObject_InitVar")
+  PyObject_New = getProcAddr(lib, "_PyObject_New")
+  PyObject_NewVar = getProcAddr(lib, "_PyObject_NewVar")
+  PyObject_Free = getProcAddr(lib, "PyObject_Free")
+  PyObject_IsInstance = getProcAddr(lib, "PyObject_IsInstance")
+  PyObject_IsSubclass = getProcAddr(lib, "PyObject_IsSubclass")
+  PyObject_GenericGetAttr = getProcAddr(lib, "PyObject_GenericGetAttr")
+  PyObject_GenericSetAttr = getProcAddr(lib, "PyObject_GenericSetAttr")
+  PyObject_GC_Malloc = getProcAddr(lib, "_PyObject_GC_Malloc")
+  PyObject_GC_New = getProcAddr(lib, "_PyObject_GC_New")
+  PyObject_GC_NewVar = getProcAddr(lib, "_PyObject_GC_NewVar")
+  PyObject_GC_Resize = getProcAddr(lib, "_PyObject_GC_Resize")
+  PyObject_GC_Del = getProcAddr(lib, "PyObject_GC_Del")
+  PyObject_GC_Track = getProcAddr(lib, "PyObject_GC_Track")
+  PyObject_GC_UnTrack = getProcAddr(lib, "PyObject_GC_UnTrack")
+  PyRange_New = getProcAddr(lib, "PyRange_New")
+  PySequence_Check = getProcAddr(lib, "PySequence_Check")
+  PySequence_Concat = getProcAddr(lib, "PySequence_Concat")
+  PySequence_Count = getProcAddr(lib, "PySequence_Count")
+  PySequence_GetItem = getProcAddr(lib, "PySequence_GetItem")
+  PySequence_GetSlice = getProcAddr(lib, "PySequence_GetSlice")
+  PySequence_In = getProcAddr(lib, "PySequence_In")
+  PySequence_Index = getProcAddr(lib, "PySequence_Index")
+  PySequence_Length = getProcAddr(lib, "PySequence_Length")
+  PySequence_Repeat = getProcAddr(lib, "PySequence_Repeat")
+  PySequence_SetItem = getProcAddr(lib, "PySequence_SetItem")
+  PySequence_SetSlice = getProcAddr(lib, "PySequence_SetSlice")
+  PySequence_DelSlice = getProcAddr(lib, "PySequence_DelSlice")
+  PySequence_Tuple = getProcAddr(lib, "PySequence_Tuple")
+  PySequence_Contains = getProcAddr(lib, "PySequence_Contains")
+  PySlice_GetIndices = getProcAddr(lib, "PySlice_GetIndices")
+  PySlice_GetIndicesEx = getProcAddr(lib, "PySlice_GetIndicesEx")
+  PySlice_New = getProcAddr(lib, "PySlice_New")
+  PyString_Concat = getProcAddr(lib, "PyString_Concat")
+  PyString_ConcatAndDel = getProcAddr(lib, "PyString_ConcatAndDel")
+  PyString_Format = getProcAddr(lib, "PyString_Format")
+  PyString_FromStringAndSize = getProcAddr(lib, "PyString_FromStringAndSize")
+  PyString_Size = getProcAddr(lib, "PyString_Size")
+  PyString_DecodeEscape = getProcAddr(lib, "PyString_DecodeEscape")
+  PyString_Repr = getProcAddr(lib, "PyString_Repr")
+  PySys_GetObject = getProcAddr(lib, "PySys_GetObject") #PySys_Init                :=getProcAddr(lib, 'PySys_Init');
+  PySys_SetObject = getProcAddr(lib, "PySys_SetObject")
+  PySys_SetPath = getProcAddr(lib, "PySys_SetPath") #PyTraceBack_Fetch         :=getProcAddr(lib, 'PyTraceBack_Fetch');
+  PyTraceBack_Here = getProcAddr(lib, "PyTraceBack_Here")
+  PyTraceBack_Print = getProcAddr(lib, "PyTraceBack_Print") #PyTraceBack_Store         :=getProcAddr(lib, 'PyTraceBack_Store');
+  PyTuple_GetItem = getProcAddr(lib, "PyTuple_GetItem")
+  PyTuple_GetSlice = getProcAddr(lib, "PyTuple_GetSlice")
+  PyTuple_New = getProcAddr(lib, "PyTuple_New")
+  PyTuple_SetItem = getProcAddr(lib, "PyTuple_SetItem")
+  PyTuple_Size = getProcAddr(lib, "PyTuple_Size")
+  PyType_IsSubtype = getProcAddr(lib, "PyType_IsSubtype")
+  PyType_GenericAlloc = getProcAddr(lib, "PyType_GenericAlloc")
+  PyType_GenericNew = getProcAddr(lib, "PyType_GenericNew")
+  PyType_Ready = getProcAddr(lib, "PyType_Ready")
+  PyUnicode_FromWideChar = getProcAddr(lib, "PyUnicodeUCS2_FromWideChar")
+  PyUnicode_AsWideChar = getProcAddr(lib, "PyUnicodeUCS2_AsWideChar")
+  PyUnicode_FromOrdinal = getProcAddr(lib, "PyUnicodeUCS2_FromOrdinal")
+  PyWeakref_GetObject = getProcAddr(lib, "PyWeakref_GetObject")
+  PyWeakref_NewProxy = getProcAddr(lib, "PyWeakref_NewProxy")
+  PyWeakref_NewRef = getProcAddr(lib, "PyWeakref_NewRef")
+  PyWrapper_New = getProcAddr(lib, "PyWrapper_New")
+  PyBool_FromLong = getProcAddr(lib, "PyBool_FromLong")
+  Py_AtExit = getProcAddr(lib, "Py_AtExit") #Py_Cleanup                :=getProcAddr(lib, 'Py_Cleanup');
+  Py_CompileString = getProcAddr(lib, "Py_CompileString")
+  Py_FatalError = getProcAddr(lib, "Py_FatalError")
+  Py_FindMethod = getProcAddr(lib, "Py_FindMethod")
+  Py_FindMethodInChain = getProcAddr(lib, "Py_FindMethodInChain")
+  Py_FlushLine = getProcAddr(lib, "Py_FlushLine")
+  Py_Finalize = getProcAddr(lib, "Py_Finalize")
+  PyCode_Addr2Line = getProcAddr(lib, "PyCode_Addr2Line")
+  PyClass_IsSubclass = getProcAddr(lib, "PyClass_IsSubclass")
+  PyErr_ExceptionMatches = getProcAddr(lib, "PyErr_ExceptionMatches")
+  PyErr_GivenExceptionMatches = getProcAddr(lib, "PyErr_GivenExceptionMatches")
+  PyEval_EvalCode = getProcAddr(lib, "PyEval_EvalCode")
+  Py_GetVersion = getProcAddr(lib, "Py_GetVersion")
+  Py_GetCopyright = getProcAddr(lib, "Py_GetCopyright")
+  Py_GetExecPrefix = getProcAddr(lib, "Py_GetExecPrefix")
+  Py_GetPath = getProcAddr(lib, "Py_GetPath")
+  Py_GetPrefix = getProcAddr(lib, "Py_GetPrefix")
+  Py_GetProgramName = getProcAddr(lib, "Py_GetProgramName")
+  PyParser_SimpleParseString = getProcAddr(lib, "PyParser_SimpleParseString")
+  PyNode_Free = getProcAddr(lib, "PyNode_Free")
+  PyErr_NewException = getProcAddr(lib, "PyErr_NewException") #/ jah 29-sep-2000 : updated for python 2.0
+                                                              #/                   replaced Py_Malloc with PyMem_Malloc
+                                                              #/---   @Py_Malloc := Import ('Py_Malloc');
+                                                              #/+++   @Py_Malloc := Import ('PyMem_Malloc');
+  Py_Malloc = getProcAddr(lib, "PyMem_Malloc")
+  PyMem_Malloc = getProcAddr(lib, "PyMem_Malloc")
+  PyObject_CallMethod = getProcAddr(lib, "PyObject_CallMethod")
+  Py_SetProgramName = getProcAddr(lib, "Py_SetProgramName")
+  Py_IsInitialized = getProcAddr(lib, "Py_IsInitialized")
+  Py_GetProgramFullPath = getProcAddr(lib, "Py_GetProgramFullPath")
+  DLL_Py_GetBuildInfo = getProcAddr(lib, "Py_GetBuildInfo")
+  Py_NewInterpreter = getProcAddr(lib, "Py_NewInterpreter")
+  Py_EndInterpreter = getProcAddr(lib, "Py_EndInterpreter")
+  PyEval_AcquireLock = getProcAddr(lib, "PyEval_AcquireLock")
+  PyEval_ReleaseLock = getProcAddr(lib, "PyEval_ReleaseLock")
+  PyEval_AcquireThread = getProcAddr(lib, "PyEval_AcquireThread")
+  PyEval_ReleaseThread = getProcAddr(lib, "PyEval_ReleaseThread")
+  PyInterpreterState_New = getProcAddr(lib, "PyInterpreterState_New")
+  PyInterpreterState_Clear = getProcAddr(lib, "PyInterpreterState_Clear")
+  PyInterpreterState_Delete = getProcAddr(lib, "PyInterpreterState_Delete")
+  PyThreadState_New = getProcAddr(lib, "PyThreadState_New")
+  PyThreadState_Clear = getProcAddr(lib, "PyThreadState_Clear")
+  PyThreadState_Delete = getProcAddr(lib, "PyThreadState_Delete")
+  PyThreadState_Get = getProcAddr(lib, "PyThreadState_Get")
+  PyThreadState_Swap = getProcAddr(lib, "PyThreadState_Swap")
+
+var lib: TLibHandle
+
+lib = loadLibrary(dllName)
+if lib != NilLibHandle: init(lib)
diff --git a/lib/base/devel/python.pas b/lib/base/devel/python.pas
new file mode 100644
index 000000000..587ec6dc9
--- /dev/null
+++ b/lib/base/devel/python.pas
@@ -0,0 +1,2205 @@
+{

+    Light-weight binding for the Python interpreter

+       (c) 2008 Andreas Rumpf 

+    Based on 'PythonEngine' module by Dr. Dietmar Budelsky

+

+}

+

+(**************************************************************************)

+(*                                                                        *)

+(* Module:  Unit 'PythonEngine'     Copyright (c) 1997                    *)

+(*                                                                        *)

+(* Version: 3.0                     Dr. Dietmar Budelsky                  *)

+(* Sub-Version: 0.25                dbudelsky@web.de                      *)

+(*                                  Germany                               *)

+(*                                                                        *)

+(*                                  Morgan Martinet                       *)

+(*                                  4721 rue Brebeuf                      *)

+(*                                  H2J 3L2 MONTREAL (QC)                 *)

+(*                                  CANADA                                *)

+(*                                  e-mail: mmm@free.fr                   *)

+(*                                                                        *)

+(*  look our page at: http://www.multimania.com/marat                     *)

+(**************************************************************************)

+(*  Functionality:  Delphi Components that provide an interface to the    *)

+(*                  Python language (see python.txt for more infos on     *)

+(*                  Python itself).                                       *)

+(*                                                                        *)

+(**************************************************************************)

+(*  Contributors:                                                         *)

+(*      Grzegorz Makarewicz (mak@mikroplan.com.pl)                        *)

+(*      Andrew Robinson (andy@hps1.demon.co.uk)                           *)

+(*      Mark Watts(mark_watts@hotmail.com)                                *)

+(*      Olivier Deckmyn (olivier.deckmyn@mail.dotcom.fr)                  *)

+(*      Sigve Tjora (public@tjora.no)                                     *)

+(*      Mark Derricutt (mark@talios.com)                                  *)

+(*      Igor E. Poteryaev (jah@mail.ru)                                   *)

+(*      Yuri Filimonov (fil65@mail.ru)                                    *)

+(*      Stefan Hoffmeister (Stefan.Hoffmeister@Econos.de)                 *)

+(**************************************************************************)

+(* This source code is distributed with no WARRANTY, for no reason or use.*)

+(* Everyone is allowed to use and change this code free for his own tasks *)

+(* and projects, as long as this header and its copyright text is intact. *)

+(* For changed versions of this code, which are public distributed the    *)

+(* following additional conditions have to be fullfilled:                 *)

+(* 1) The header has to contain a comment on the change and the author of *)

+(*    it.                                                                 *)

+(* 2) A copy of the changed source has to be sent to the above E-Mail     *)

+(*    address or my then valid address, if this is possible to the        *)

+(*    author.                                                             *)

+(* The second condition has the target to maintain an up to date central  *)

+(* version of the component. If this condition is not acceptable for      *)

+(* confidential or legal reasons, everyone is free to derive a component  *)

+(* or to generate a diff file to my or other original sources.            *)

+(* Dr. Dietmar Budelsky, 1997-11-17                                       *)

+(**************************************************************************)

+unit python;

+

+interface

+

+uses

+  dyncalls;

+

+{$ifdef windows}

+const

+  DllName = 'python24.dll';

+{$else}

+const

+  DllName = 'libpython2.4.so'; // for UNIX systems

+{$endif}

+

+const

+  PYT_METHOD_BUFFER_INCREASE = 10;

+  PYT_MEMBER_BUFFER_INCREASE = 10;

+  PYT_GETSET_BUFFER_INCREASE = 10;

+

+  METH_VARARGS  = $0001;

+  METH_KEYWORDS = $0002;

+

+  // Masks for the co_flags field of PyCodeObject

+  CO_OPTIMIZED   = $0001;

+  CO_NEWLOCALS   = $0002;

+  CO_VARARGS     = $0004;

+  CO_VARKEYWORDS = $0008;

+

+type

+  // Rich comparison opcodes introduced in version 2.1

+  TRichComparisonOpcode = (pyLT, pyLE, pyEQ, pyNE, pyGT, pyGE);

+const

+{Type flags (tp_flags) introduced in version 2.0

+

+These flags are used to extend the type structure in a backwards-compatible

+fashion. Extensions can use the flags to indicate (and test) when a given

+type structure contains a new feature. The Python core will use these when

+introducing new functionality between major revisions (to avoid mid-version

+changes in the PYTHON_API_VERSION).

+

+Arbitration of the flag bit positions will need to be coordinated among

+all extension writers who publically release their extensions (this will

+be fewer than you might expect!)..

+

+Python 1.5.2 introduced the bf_getcharbuffer slot into PyBufferProcs.

+

+Type definitions should use Py_TPFLAGS_DEFAULT for their tp_flags value.

+

+Code can use PyType_HasFeature(type_ob, flag_value) to test whether the

+given type object has a specified feature.

+}

+

+// PyBufferProcs contains bf_getcharbuffer

+  Py_TPFLAGS_HAVE_GETCHARBUFFER = (1 shl 0);

+

+// PySequenceMethods contains sq_contains

+  Py_TPFLAGS_HAVE_SEQUENCE_IN = (1 shl 1);

+

+// Objects which participate in garbage collection (see objimp.h)

+  Py_TPFLAGS_GC = (1 shl 2);

+

+// PySequenceMethods and PyNumberMethods contain in-place operators

+  Py_TPFLAGS_HAVE_INPLACEOPS = (1 shl 3);

+

+// PyNumberMethods do their own coercion */

+  Py_TPFLAGS_CHECKTYPES = (1 shl 4);

+

+  Py_TPFLAGS_HAVE_RICHCOMPARE = (1 shl 5);

+

+// Objects which are weakly referencable if their tp_weaklistoffset is >0

+// XXX Should this have the same value as Py_TPFLAGS_HAVE_RICHCOMPARE?

+// These both indicate a feature that appeared in the same alpha release.

+

+  Py_TPFLAGS_HAVE_WEAKREFS = (1 shl 6);

+

+// tp_iter is defined

+  Py_TPFLAGS_HAVE_ITER = (1 shl 7);

+

+// New members introduced by Python 2.2 exist

+  Py_TPFLAGS_HAVE_CLASS = (1 shl 8);

+

+// Set if the type object is dynamically allocated

+  Py_TPFLAGS_HEAPTYPE = (1 shl 9);

+

+// Set if the type allows subclassing

+  Py_TPFLAGS_BASETYPE = (1 shl 10);

+

+// Set if the type is 'ready' -- fully initialized

+  Py_TPFLAGS_READY = (1 shl 12);

+

+// Set while the type is being 'readied', to prevent recursive ready calls

+  Py_TPFLAGS_READYING = (1 shl 13);

+

+// Objects support garbage collection (see objimp.h)

+  Py_TPFLAGS_HAVE_GC = (1 shl 14);

+

+  Py_TPFLAGS_DEFAULT  =      Py_TPFLAGS_HAVE_GETCHARBUFFER

+                             or Py_TPFLAGS_HAVE_SEQUENCE_IN

+                             or Py_TPFLAGS_HAVE_INPLACEOPS

+                             or Py_TPFLAGS_HAVE_RICHCOMPARE

+                             or Py_TPFLAGS_HAVE_WEAKREFS

+                             or Py_TPFLAGS_HAVE_ITER

+                             or Py_TPFLAGS_HAVE_CLASS;

+

+// See function PyType_HasFeature below for testing the flags.

+

+// Delphi equivalent used by TPythonType

+type

+  TPFlag = (tpfHaveGetCharBuffer, tpfHaveSequenceIn, tpfGC, tpfHaveInplaceOps,

+            tpfCheckTypes, tpfHaveRichCompare, tpfHaveWeakRefs,

+            tpfHaveIter, tpfHaveClass, tpfHeapType, tpfBaseType, tpfReady, 

+            tpfReadying, tpfHaveGC

+           );

+  TPFlags = set of TPFlag;

+const

+  TPFLAGS_DEFAULT = [tpfHaveGetCharBuffer, tpfHaveSequenceIn, tpfHaveInplaceOps,

+                     tpfHaveRichCompare, tpfHaveWeakRefs, tpfHaveIter, 

+                     tpfHaveClass];

+//-------  Python opcodes  ----------//

+Const

+   single_input                 = 256;

+   file_input                   = 257;

+   eval_input                   = 258;

+   funcdef                      = 259;

+   parameters                   = 260;

+   varargslist                  = 261;

+   fpdef                        = 262;

+   fplist                       = 263;

+   stmt                         = 264;

+   simple_stmt                  = 265;

+   small_stmt                   = 266;

+   expr_stmt                    = 267;

+   augassign                    = 268;

+   print_stmt                   = 269;

+   del_stmt                     = 270;

+   pass_stmt                    = 271;

+   flow_stmt                    = 272;

+   break_stmt                   = 273;

+   continue_stmt                = 274;

+   return_stmt                  = 275;

+   raise_stmt                   = 276;

+   import_stmt                  = 277;

+   import_as_name               = 278;

+   dotted_as_name               = 279;

+   dotted_name                  = 280;

+   global_stmt                  = 281;

+   exec_stmt                    = 282;

+   assert_stmt                  = 283;

+   compound_stmt                = 284;

+   if_stmt                      = 285;

+   while_stmt                   = 286;

+   for_stmt                     = 287;

+   try_stmt                     = 288;

+   except_clause                = 289;

+   suite                        = 290;

+   test                         = 291;

+   and_test                     = 291;

+   not_test                     = 293;

+   comparison                   = 294;

+   comp_op                      = 295;

+   expr                         = 296;

+   xor_expr                     = 297;

+   and_expr                     = 298;

+   shift_expr                   = 299;

+   arith_expr                   = 300;

+   term                         = 301;

+   factor                       = 302;

+   power                        = 303;

+   atom                         = 304;

+   listmaker                    = 305;

+   lambdef                      = 306;

+   trailer                      = 307;

+   subscriptlist                = 308;

+   subscript                    = 309;

+   sliceop                      = 310;

+   exprlist                     = 311;

+   testlist                     = 312;

+   dictmaker                    = 313;

+   classdef                     = 314;

+   arglist                      = 315;

+   argument                     = 316;

+   list_iter                    = 317;

+   list_for                     = 318;

+   list_if                      = 319;

+

+const

+  T_SHORT                       = 0;

+  T_INT                         = 1;

+  T_LONG                        = 2;

+  T_FLOAT                       = 3;

+  T_DOUBLE                      = 4;

+  T_STRING                      = 5;

+  T_OBJECT                      = 6;

+  T_CHAR                        = 7;	// 1-character string

+  T_BYTE                        = 8;	// 8-bit signed int

+  T_UBYTE                       = 9;

+  T_USHORT                      = 10;

+  T_UINT                        = 11;

+  T_ULONG                       = 12;

+

+// Added by Jack: strings contained in the structure

+  T_STRING_INPLACE= 13;

+

+  T_OBJECT_EX                   = 16;{ Like T_OBJECT, but raises AttributeError

+                                        when the value is NULL, instead of

+                                        converting to None. }

+

+// Flags

+  READONLY                      = 1;

+  RO                            = READONLY;		// Shorthand 

+  READ_RESTRICTED               = 2;

+  WRITE_RESTRICTED              = 4;

+  RESTRICTED                    = (READ_RESTRICTED or WRITE_RESTRICTED);

+type

+  TPyMemberType = (mtShort, mtInt, mtLong, mtFloat, mtDouble, mtString, 

+                   mtObject, mtChar, mtByte, mtUByte, mtUShort, mtUInt, 

+                   mtULong, mtStringInplace, mtObjectEx);

+  TPyMemberFlag = (mfDefault, mfReadOnly, mfReadRestricted, mfWriteRestricted, mfRestricted);

+

+//#######################################################

+//##                                                   ##

+//##    Global declarations, nothing Python specific   ##

+//##                                                   ##

+//#######################################################

+

+type

+  TPChar  = array[0..16000] of PChar;

+  PPChar  = ^TPChar;

+  PInt	   = ^Integer;

+  PDouble = ^Double;

+  PFloat  = ^Real;

+  PLong   = ^LongInt;

+  PShort  = ^ShortInt;

+  PString = ^PChar;

+

+//#######################################################

+//##                                                   ##

+//##            Python specific interface              ##

+//##                                                   ##

+//#######################################################

+

+type

+  PP_frozen	    = ^Pfrozen;

+  P_frozen	    = ^Tfrozen;

+  PPyObject	    = ^PyObject;

+  PPPyObject	    = ^PPyObject;

+  PPPPyObject	    = ^PPPyObject;

+  PPyIntObject	    = ^PyIntObject;

+  PPyTypeObject     = ^PyTypeObject;

+  PPySliceObject    = ^PySliceObject;

+

+  TPyCFunction       = function (self, args: PPyObject): PPyObject; cdecl;

+

+  Tunaryfunc         = function (ob1: PPyObject): PPyObject; cdecl;

+  Tbinaryfunc        = function (ob1,ob2: PPyObject): PPyObject; cdecl;

+  Tternaryfunc       = function (ob1,ob2,ob3: PPyObject): PPyObject; cdecl;

+  Tinquiry           = function (ob1: PPyObject): integer; cdecl;

+  Tcoercion          = function (ob1,ob2: PPPyObject): integer; cdecl;

+  Tintargfunc        = function (ob1: PPyObject; i: integer): PPyObject; cdecl;

+  Tintintargfunc     = function (ob1: PPyObject; i1, i2: integer):

+                                PPyObject; cdecl;

+  Tintobjargproc     = function (ob1: PPyObject; i: integer; ob2: PPyObject):

+                                integer; cdecl;

+  Tintintobjargproc  = function (ob1: PPyObject; i1, i2: integer;

+                                ob2: PPyObject): integer; cdecl;

+  Tobjobjargproc     = function (ob1,ob2,ob3: PPyObject): integer; cdecl;

+

+  Tpydestructor      = procedure (ob: PPyObject); cdecl;

+  Tprintfunc         = function (ob: PPyObject; var f: file; i: integer): integer; cdecl;

+  Tgetattrfunc       = function (ob1: PPyObject; name: PChar): PPyObject; cdecl;

+  Tsetattrfunc       = function (ob1: PPyObject; name: PChar; ob2: PPyObject): integer; cdecl;

+  Tcmpfunc           = function (ob1, ob2: PPyObject): integer; cdecl;

+  Treprfunc          = function (ob: PPyObject): PPyObject; cdecl;

+  Thashfunc          = function (ob: PPyObject): LongInt; cdecl;

+  Tgetattrofunc      = function (ob1, ob2: PPyObject): PPyObject; cdecl;

+  Tsetattrofunc      = function (ob1, ob2, ob3: PPyObject): integer; cdecl;

+

+/// jah 29-sep-2000: updated for python 2.0

+///                   added from object.h

+  Tgetreadbufferproc = function (ob1: PPyObject; i: integer; ptr: Pointer): integer; cdecl;

+  Tgetwritebufferproc= function (ob1: PPyObject; i: integer; ptr: Pointer): integer; cdecl;

+  Tgetsegcountproc   = function (ob1: PPyObject; i: integer): integer; cdecl;

+  Tgetcharbufferproc = function (ob1: PPyObject; i: integer; const pstr: PChar): integer; cdecl;

+  Tobjobjproc        = function (ob1, ob2: PPyObject): integer; cdecl;

+  Tvisitproc         = function (ob1: PPyObject; ptr: Pointer): integer; cdecl;

+  Ttraverseproc      = function (ob1: PPyObject; proc: visitproc; ptr: Pointer): integer; cdecl;

+

+  Trichcmpfunc       = function (ob1, ob2: PPyObject; i: Integer): PPyObject; cdecl;

+  Tgetiterfunc       = function (ob1: PPyObject): PPyObject; cdecl;

+  Titernextfunc      = function (ob1: PPyObject): PPyObject; cdecl;

+  Tdescrgetfunc      = function (ob1, ob2, ob3: PPyObject): PPyObject; cdecl;

+  Tdescrsetfunc      = function (ob1, ob2, ob3: PPyObject): Integer; cdecl;

+  Tinitproc          = function (self, args, kwds: PPyObject): Integer; cdecl;

+  Tnewfunc           = function (subtype: PPyTypeObject; args, kwds: PPyObject): PPyObject; cdecl;

+  Tallocfunc         = function (self: PPyTypeObject; nitems: integer): PPyObject; cdecl;

+

+  TPyNumberMethods = record

+     nb_add: Tbinaryfunc;

+     nb_substract: Tbinaryfunc;

+     nb_multiply: Tbinaryfunc;

+     nb_divide: Tbinaryfunc;

+     nb_remainder: Tbinaryfunc;

+     nb_divmod: Tbinaryfunc;

+     nb_power: Tternaryfunc;

+     nb_negative: Tunaryfunc;

+     nb_positive: Tunaryfunc;

+     nb_absolute: Tunaryfunc;

+     nb_nonzero: Tinquiry;

+     nb_invert: Tunaryfunc;

+     nb_lshift: Tbinaryfunc;

+     nb_rshift: Tbinaryfunc;

+     nb_and: Tbinaryfunc;

+     nb_xor: Tbinaryfunc;

+     nb_or: Tbinaryfunc;

+     nb_coerce: Tcoercion;

+     nb_int: Tunaryfunc;

+     nb_long: Tunaryfunc;

+     nb_float: Tunaryfunc;

+     nb_oct: Tunaryfunc;

+     nb_hex: Tunaryfunc;

+/// jah 29-sep-2000: updated for python 2.0

+///                   added from .h

+     nb_inplace_add: Tbinaryfunc;

+     nb_inplace_subtract: Tbinaryfunc;

+     nb_inplace_multiply: Tbinaryfunc;

+     nb_inplace_divide: Tbinaryfunc;

+     nb_inplace_remainder: Tbinaryfunc;

+     nb_inplace_power: Tternaryfunc;

+     nb_inplace_lshift: Tbinaryfunc;

+     nb_inplace_rshift: Tbinaryfunc;

+     nb_inplace_and: Tbinaryfunc;

+     nb_inplace_xor: Tbinaryfunc;

+     nb_inplace_or: Tbinaryfunc;

+     // Added in release 2.2

+     // The following require the Py_TPFLAGS_HAVE_CLASS flag

+     nb_floor_divide:         Tbinaryfunc;

+     nb_true_divide:          Tbinaryfunc;

+     nb_inplace_floor_divide: Tbinaryfunc;

+     nb_inplace_true_divide:  Tbinaryfunc;

+  end;

+  PPyNumberMethods = ^TPyNumberMethods;

+

+  TPySequenceMethods = record

+     sq_length: Tinquiry;

+     sq_concat: Tbinaryfunc;

+     sq_repeat: Tintargfunc;

+     sq_item: Tintargfunc;

+     sq_slice: Tintintargfunc;

+     sq_ass_item: Tintobjargproc;

+     sq_ass_slice: Tintintobjargproc;

+/// jah 29-sep-2000: updated for python 2.0

+///                   added from .h

+     sq_contains: Tobjobjproc;

+     sq_inplace_concat: Tbinaryfunc;

+     sq_inplace_repeat: Tintargfunc;

+  end;

+  PPySequenceMethods = ^TPySequenceMethods;

+

+  TPyMappingMethods = record

+     mp_length	: Tinquiry;

+     mp_subscript: Tbinaryfunc;

+     mp_ass_subscript: Tobjobjargproc;

+  end;

+  PPyMappingMethods = ^PyMappingMethods;

+

+/// jah 29-sep-2000: updated for python 2.0

+///                   added from .h

+  TPyBufferProcs = record

+     bf_getreadbuffer: Tgetreadbufferproc;

+     bf_getwritebuffer: Tgetwritebufferproc;

+     bf_getsegcount: Tgetsegcountproc;

+     bf_getcharbuffer: Tgetcharbufferproc;

+  end;

+  PPyBufferProcs = ^TPyBufferProcs;

+

+  TPy_complex =  record

+     real: double;

+     imag: double;

+  end;

+

+  TPyObject = record

+    ob_refcnt: Integer;

+    ob_type:   PPyTypeObject;

+  end;

+

+  TPyIntObject = object(TPyObject)

+    ob_ival: LongInt;

+  end;

+

+  PByte = ^Byte;

+  Tfrozen = packed record

+     name: PChar;

+     code: PByte;

+     size: Integer;

+  end;

+

+  TPySliceObject = object(TPyObject)

+    start, stop, step:  PPyObject;

+  end;

+

+  PPyMethodDef = ^TPyMethodDef;

+  TPyMethodDef  = record

+     ml_name:  PChar;

+     ml_meth:  TPyCFunction;

+     ml_flags: Integer;

+     ml_doc:   PChar;

+  end;

+

+  // structmember.h

+  PPyMemberDef = ^TPyMemberDef;

+  TPyMemberDef = record

+    name: PChar;

+    theType: integer;

+    offset: integer;

+    flags: integer;

+    doc: PChar;

+  end;

+

+  // descrobject.h

+

+  // Descriptors

+

+  Tgetter = function (obj: PPyObject; context: Pointer): PPyObject; cdecl;

+  Tsetter = function (obj, value: PPyObject; context: Pointer): integer; cdecl;

+

+  PPyGetSetDef = ^TPyGetSetDef;

+  TPyGetSetDef = record

+    name: PChar;

+    get: Tgetter;

+    set_: Tsetter;

+    doc: PChar;

+    closure: Pointer;

+  end;

+

+  Twrapperfunc = function (self, args: PPyObject; wrapped: Pointer): PPyObject; cdecl;

+

+  pwrapperbase = ^Twrapperbase;

+  Twrapperbase = record

+    name: PChar;

+    wrapper: Twrapperfunc;

+    doc: PChar;

+  end;

+

+  // Various kinds of descriptor objects

+

+  {#define PyDescr_COMMON \

+          PyObject_HEAD \

+          PyTypeObject *d_type; \

+          PyObject *d_name

+  }

+

+  PPyDescrObject = ^TPyDescrObject;

+  TPyDescrObject = object(TPyObject)

+    d_type: PPyTypeObject;

+    d_name: PPyObject;

+  end;

+

+  PPyMethodDescrObject = ^TPyMethodDescrObject;

+  TPyMethodDescrObject = object(TPyDescrObject)

+    d_method: PPyMethodDef;

+  end;

+

+  PPyMemberDescrObject = ^TPyMemberDescrObject;

+  TPyMemberDescrObject = object(TPyDescrObject)

+    d_member: PPyMemberDef;

+  end;

+

+  PPyGetSetDescrObject = ^TPyGetSetDescrObject;

+  TPyGetSetDescrObject = object(TPyDescrObject)

+    d_getset: PPyGetSetDef;

+  end;

+

+  PPyWrapperDescrObject = ^TPyWrapperDescrObject;

+  TPyWrapperDescrObject = object(TPyDescrObject)

+    d_base: pwrapperbase;

+    d_wrapped: Pointer; // This can be any function pointer

+  end;

+

+  // object.h

+  TPyTypeObject = object(TPyObject)

+    ob_size:        Integer; // Number of items in variable part

+    tp_name:        PChar;   // For printing

+    tp_basicsize, tp_itemsize: Integer; // For allocation

+

+    // Methods to implement standard operations

+

+    tp_dealloc:     Tpydestructor;

+    tp_print:       Tprintfunc;

+    tp_getattr:     Tgetattrfunc;

+    tp_setattr:     Tsetattrfunc;

+    tp_compare:     Tcmpfunc;

+    tp_repr:        Treprfunc;

+

+    // Method suites for standard classes

+

+    tp_as_number:   PPyNumberMethods;

+    tp_as_sequence: PPySequenceMethods;

+    tp_as_mapping:  PPyMappingMethods;

+

+    // More standard operations (here for binary compatibility)

+

+    tp_hash:        Thashfunc;

+    tp_call:        Tternaryfunc;

+    tp_str:         Treprfunc;

+    tp_getattro:    Tgetattrofunc;

+    tp_setattro:    Tsetattrofunc;

+

+/// jah 29-sep-2000: updated for python 2.0

+

+    // Functions to access object as input/output buffer

+    tp_as_buffer:   PPyBufferProcs;

+    // Flags to define presence of optional/expanded features

+    tp_flags:       LongInt;

+

+    tp_doc:         PChar; // Documentation string

+

+    // call function for all accessible objects

+    tp_traverse:    Ttraverseproc;

+

+    // delete references to contained objects

+    tp_clear:       Tinquiry;

+    // rich comparisons

+    tp_richcompare: Trichcmpfunc;

+

+    // weak reference enabler

+    tp_weaklistoffset: Longint;

+    // Iterators

+    tp_iter: Tgetiterfunc;

+    tp_iternext: Titernextfunc;

+

+    // Attribute descriptor and subclassing stuff

+    tp_methods: PPyMethodDef;

+    tp_members: PPyMemberDef;

+    tp_getset: PPyGetSetDef;

+    tp_base: PPyTypeObject;

+    tp_dict: PPyObject;

+    tp_descr_get: Tdescrgetfunc;

+    tp_descr_set: Tdescrsetfunc;

+    tp_dictoffset: longint;

+    tp_init: Tinitproc;

+    tp_alloc: Tallocfunc;

+    tp_new: Tnewfunc;

+    tp_free: Tpydestructor; // Low-level free-memory routine

+    tp_is_gc: Tinquiry; // For PyObject_IS_GC

+    tp_bases: PPyObject;

+    tp_mro: PPyObject; // method resolution order

+    tp_cache: PPyObject;

+    tp_subclasses: PPyObject;

+    tp_weaklist: PPyObject;

+    //More spares

+    tp_xxx7:        pointer;

+    tp_xxx8:        pointer;

+  end;

+

+  PPyMethodChain = ^TPyMethodChain;

+  TPyMethodChain = record

+    methods: PPyMethodDef;

+    link:    PPyMethodChain;

+  end;

+

+  PPyClassObject = ^TPyClassObject;

+  TPyClassObject = object(TPyObject)

+    cl_bases: PPyObject;      // A tuple of class objects

+    cl_dict: PPyObject;       // A dictionary

+    cl_name: PPyObject;       // A string

+    // The following three are functions or NULL

+    cl_getattr: PPyObject;

+    cl_setattr: PPyObject;

+    cl_delattr: PPyObject;

+  end;

+

+  PPyInstanceObject = ^TPyInstanceObject;

+  TPyInstanceObject = object(TPyObject)

+    in_class: PPyClassObject;      // The class object

+    in_dict: PPyObject;           // A dictionary

+  end;

+

+{ Instance method objects are used for two purposes:

+   (a) as bound instance methods (returned by instancename.methodname)

+   (b) as unbound methods (returned by ClassName.methodname)

+   In case (b), im_self is NULL

+}

+

+  PPyMethodObject = ^TPyMethodObject;

+  TPyMethodObject = object(TPyObject)

+    im_func: PPyObject;      // The function implementing the method

+    im_self: PPyObject;      // The instance it is bound to, or NULL

+    im_class: PPyObject;      // The class that defined the method

+  end;

+

+  // Bytecode object, compile.h

+  PPyCodeObject = ^TPyCodeObject;

+  TPyCodeObject = object(TPyObject)

+    co_argcount: Integer;         // #arguments, except *args

+    co_nlocals: Integer;         // #local variables

+    co_stacksize: Integer;          // #entries needed for evaluation stack

+    co_flags: Integer;         // CO_..., see below

+    co_code: PPyObject;       // instruction opcodes (it hides a PyStringObject)

+    co_consts: PPyObject;       // list (constants used)

+    co_names: PPyObject;       // list of strings (names used)

+    co_varnames: PPyObject;       // tuple of strings (local variable names)

+    co_freevars: PPyObject;	      // tuple of strings (free variable names)

+    co_cellvars: PPyObject;       // tuple of strings (cell variable names)

+    // The rest doesn't count for hash/cmp

+    co_filename: PPyObject;       // string (where it was loaded from)

+    co_name: PPyObject;       // string (name, for reference)

+    co_firstlineno: Integer;         // first source line number

+    co_lnotab: PPyObject;       // string (encoding addr<->lineno mapping)

+  end;

+

+  // from pystate.h

+  PPyInterpreterState = ^TPyInterpreterState;

+  PPyThreadState = ^TPyThreadState;

+  PPyFrameObject = ^TPyFrameObject;

+

+  // Interpreter environments

+  TPyInterpreterState = record

+    next: PPyInterpreterState;

+    tstate_head: PPyThreadState;

+

+    modules: PPyObject;

+    sysdict: PPyObject;

+    builtins: PPyObject;

+

+    checkinterval: integer;

+  end;

+

+  // Thread specific information

+  TPyThreadState = record

+    next: PPyThreadState;

+    interp: PPyInterpreterState;

+

+    frame: PPyFrameObject;

+    recursion_depth: integer;

+    ticker: integer;

+    tracing: integer;

+

+    sys_profilefunc: PPyObject;

+    sys_tracefunc: PPyObject;

+

+    curexc_type: PPyObject;

+    curexc_value: PPyObject;

+    curexc_traceback: PPyObject;

+

+    exc_type: PPyObject;

+    exc_value: PPyObject;

+    exc_traceback: PPyObject;

+

+    dict: PPyObject;

+  end;

+

+  // from frameobject.h

+

+  PPyTryBlock = ^TPyTryBlock;

+  TPyTryBlock = record

+    b_type: Integer;       // what kind of block this is

+    b_handler: Integer;       // where to jump to find handler

+    b_level: Integer;       // value stack level to pop to

+  end;

+

+  CO_MAXBLOCKS  = 0..19;

+  TPyFrameObject = object(TPyObject)

+    // start of the VAR_HEAD of an object

+    ob_size: Integer;           // Number of items in variable part

+    // End of the Head of an object

+    f_back: PPyFrameObject;    // previous frame, or NULL

+    f_code: PPyCodeObject;     // code segment

+    f_builtins: PPyObject;         // builtin symbol table (PyDictObject)

+    f_globals: PPyObject;         // global symbol table (PyDictObject)

+    f_locals: PPyObject;         // local symbol table (PyDictObject)

+    f_valuestack: PPPyObject;        // points after the last local

+    (* Next free slot in f_valuestack.  Frame creation sets to f_valuestack.

+       Frame evaluation usually NULLs it, but a frame that yields sets it

+       to the current stack top. *)

+    f_stacktop: PPPyObject;

+    f_trace: PPyObject;         // Trace function

+    f_exc_type, f_exc_value, f_exc_traceback: PPyObject;

+    f_tstate: PPyThreadState;

+    f_lasti: Integer;           // Last instruction if called

+    f_lineno: Integer;           // Current line number

+    f_restricted: Integer;           // Flag set if restricted operations

+                                      // in this scope

+    f_iblock: Integer;           // index in f_blockstack

+    f_blockstack: array[CO_MAXBLOCKS] of PyTryBlock; // for try and loop blocks

+    f_nlocals: Integer;           // number of locals

+    f_ncells: Integer;

+    f_nfreevars: Integer;

+    f_stacksize: Integer;           // size of value stack

+    f_localsplus: array[0..0] of PPyObject; // locals+stack, dynamically sized

+  end;

+

+  // From traceback.c

+  PPyTraceBackObject = ^TPyTraceBackObject;

+  TPyTraceBackObject = object(TPyObject)

+    tb_next: PPyTraceBackObject;

+    tb_frame: PPyFrameObject;

+    tb_lasti: Integer;

+    tb_lineno: Integer;

+  end;

+

+  // Parse tree node interface

+

+  PNode = ^Tnode;

+  Tnode = record

+    n_type: smallint;

+    n_str: PChar;

+    n_lineno: smallint;

+    n_nchildren: smallint;

+    n_child: PNode;

+  end;

+

+  // From weakrefobject.h

+

+  PPyWeakReference = ^TPyWeakReference;

+  TPyWeakReference = object(TPyObject)

+    wr_object: PPyObject;

+    wr_callback: PPyObject;

+    hash: longint;

+    wr_prev: PPyWeakReference;

+    wr_next: PPyWeakReference;

+  end;

+

+  // from datetime.h

+

+

+{* Fields are packed into successive bytes, each viewed as unsigned and

+ * big-endian, unless otherwise noted:

+ *

+ * byte offset

+ *  0 		year     2 bytes, 1-9999

+ *  2	  	month    1 byte,  1-12

+ *  3 		day      1 byte,  1-31

+ *  4     hour     1 byte,  0-23

+ *  5 		minute   1 byte,  0-59

+ *  6 		second   1 byte,  0-59

+ *  7 		usecond  3 bytes, 0-999999

+ * 10

+ *}

+

+const

+  { # of bytes for year, month, and day. }

+  PyDateTime_DATE_DATASIZE = 4;

+

+  { # of bytes for hour, minute, second, and usecond. }

+  PyDateTime_TIME_DATASIZE = 6;

+

+  { # of bytes for year, month, day, hour, minute, second, and usecond. }

+  PyDateTime_DATETIME_DATASIZE = 10;

+type

+  TPyDateTime_Delta = object(TPyObject)

+    hashcode: Integer;  // -1 when unknown

+    days: Integer;  // -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS

+    seconds: Integer;  // 0 <= seconds < 24*3600 is invariant

+    microseconds: Integer;  // 0 <= microseconds < 1000000 is invariant

+  end;

+  PPyDateTime_Delta = ^TPyDateTime_Delta;

+

+  TPyDateTime_TZInfo = object(TPyObject) // a pure abstract base clase

+  end;

+  PPyDateTime_TZInfo = ^TPyDateTime_TZInfo;

+

+{

+/* The datetime and time types have hashcodes, and an optional tzinfo member,

+ * present if and only if hastzinfo is true.

+ */

+#define _PyTZINFO_HEAD		\

+	PyObject_HEAD		\

+	long hashcode;		\

+	char hastzinfo;		/* boolean flag */

+}

+

+{* No _PyDateTime_BaseTZInfo is allocated; it's just to have something

+ * convenient to cast to, when getting at the hastzinfo member of objects

+ * starting with _PyTZINFO_HEAD.

+ *}

+  TPyDateTime_BaseTZInfo = object(TPyObject)

+    hashcode: Integer;

+    hastzinfo: bool;  // boolean flag

+  end;

+  PPyDateTime_BaseTZInfo = ^TPyDateTime_BaseTZInfo;

+

+{* All time objects are of PyDateTime_TimeType, but that can be allocated

+ * in two ways, with or without a tzinfo member.  Without is the same as

+ * tzinfo == None, but consumes less memory.  _PyDateTime_BaseTime is an

+ * internal struct used to allocate the right amount of space for the

+ * "without" case.

+ *}

+{#define _PyDateTime_TIMEHEAD	\

+	_PyTZINFO_HEAD		\

+	unsigned char data[_PyDateTime_TIME_DATASIZE];

+}

+

+  TPyDateTime_BaseTime = object(TPyDateTime_BaseTZInfo) 

+    data: array[0..Pred(PyDateTime_TIME_DATASIZE)] of Byte;

+  end;

+  PPyDateTime_BaseTime = ^TPyDateTime_BaseTime;

+

+  TPyDateTime_Time = object(TPyDateTime_BaseTime) // hastzinfo true

+    tzinfo: PPyObject;

+  end;

+  PPyDateTime_Time = ^PyDateTime_Time;

+

+{* All datetime objects are of PyDateTime_DateTimeType, but that can be

+ * allocated in two ways too, just like for time objects above.  In addition,

+ * the plain date type is a base class for datetime, so it must also have

+ * a hastzinfo member (although it's unused there).

+ *}

+  TPyDateTime_Date = object(TPyDateTime_BaseTZInfo) 

+    data: array [0..Pred(PyDateTime_DATE_DATASIZE)] of Byte;

+  end;

+  PPyDateTime_Date = ^TPyDateTime_Date;

+

+ {

+#define _PyDateTime_DATETIMEHEAD	\

+	_PyTZINFO_HEAD			\

+	unsigned char data[_PyDateTime_DATETIME_DATASIZE];

+}

+

+  TPyDateTime_BaseDateTime = object(TPyDateTime_BaseTZInfo) // hastzinfo false

+    data: array[0..Pred(PyDateTime_DATETIME_DATASIZE)] of Byte;

+  end;

+  PPyDateTime_BaseDateTime = ^TPyDateTime_BaseDateTime;

+

+  TPyDateTime_DateTime = object(TPyDateTime_BaseTZInfo) // hastzinfo true

+    data: array[0..Pred(PyDateTime_DATETIME_DATASIZE)] of Byte;

+    tzinfo: PPyObject;

+  end;

+  PPyDateTime_DateTime = ^TPyDateTime_DateTime;

+

+

+//#######################################################

+//##                                                   ##

+//##         New exception classes                     ##

+//##                                                   ##

+//#######################################################

+(*

+  // Python's exceptions

+  EPythonError   = object(Exception)

+      EName: String;

+      EValue: String;

+  end;

+  EPyExecError   = object(EPythonError)

+  end;

+

+  // Standard exception classes of Python

+

+/// jah 29-sep-2000: updated for python 2.0

+///                   base classes updated according python documentation

+

+{ Hierarchy of Python exceptions, Python 2.3, copied from <INSTALL>\Python\exceptions.c

+

+Exception\n\

+ |\n\

+ +-- SystemExit\n\

+ +-- StopIteration\n\

+ +-- StandardError\n\

+ |    |\n\

+ |    +-- KeyboardInterrupt\n\

+ |    +-- ImportError\n\

+ |    +-- EnvironmentError\n\

+ |    |    |\n\

+ |    |    +-- IOError\n\

+ |    |    +-- OSError\n\

+ |    |         |\n\

+ |    |         +-- WindowsError\n\

+ |    |         +-- VMSError\n\

+ |    |\n\

+ |    +-- EOFError\n\

+ |    +-- RuntimeError\n\

+ |    |    |\n\

+ |    |    +-- NotImplementedError\n\

+ |    |\n\

+ |    +-- NameError\n\

+ |    |    |\n\

+ |    |    +-- UnboundLocalError\n\

+ |    |\n\

+ |    +-- AttributeError\n\

+ |    +-- SyntaxError\n\

+ |    |    |\n\

+ |    |    +-- IndentationError\n\

+ |    |         |\n\

+ |    |         +-- TabError\n\

+ |    |\n\

+ |    +-- TypeError\n\

+ |    +-- AssertionError\n\

+ |    +-- LookupError\n\

+ |    |    |\n\

+ |    |    +-- IndexError\n\

+ |    |    +-- KeyError\n\

+ |    |\n\

+ |    +-- ArithmeticError\n\

+ |    |    |\n\

+ |    |    +-- OverflowError\n\

+ |    |    +-- ZeroDivisionError\n\

+ |    |    +-- FloatingPointError\n\

+ |    |\n\

+ |    +-- ValueError\n\

+ |    |    |\n\

+ |    |    +-- UnicodeError\n\

+ |    |        |\n\

+ |    |        +-- UnicodeEncodeError\n\

+ |    |        +-- UnicodeDecodeError\n\

+ |    |        +-- UnicodeTranslateError\n\

+ |    |\n\

+ |    +-- ReferenceError\n\

+ |    +-- SystemError\n\

+ |    +-- MemoryError\n\

+ |\n\

+ +---Warning\n\

+      |\n\

+      +-- UserWarning\n\

+      +-- DeprecationWarning\n\

+      +-- PendingDeprecationWarning\n\

+      +-- SyntaxWarning\n\

+      +-- OverflowWarning\n\

+      +-- RuntimeWarning\n\

+      +-- FutureWarning"

+}

+   EPyException = class (EPythonError);

+   EPyStandardError = class (EPyException);

+   EPyArithmeticError = class (EPyStandardError);

+   EPyLookupError = class (EPyStandardError);

+   EPyAssertionError = class (EPyStandardError);

+   EPyAttributeError = class (EPyStandardError);

+   EPyEOFError = class (EPyStandardError);

+   EPyFloatingPointError = class (EPyArithmeticError);

+   EPyEnvironmentError = class (EPyStandardError);

+   EPyIOError = class (EPyEnvironmentError);

+   EPyOSError = class (EPyEnvironmentError);

+   EPyImportError = class (EPyStandardError);

+   EPyIndexError = class (EPyLookupError);

+   EPyKeyError = class (EPyLookupError);

+   EPyKeyboardInterrupt = class (EPyStandardError);

+   EPyMemoryError = class (EPyStandardError);

+   EPyNameError = class (EPyStandardError);

+   EPyOverflowError = class (EPyArithmeticError);

+   EPyRuntimeError = class (EPyStandardError);

+   EPyNotImplementedError = class (EPyRuntimeError);

+   EPySyntaxError = class (EPyStandardError)

+   public

+      EFileName: string;

+      ELineStr: string;

+      ELineNumber: Integer;

+      EOffset: Integer;

+   end;

+   EPyIndentationError = class (EPySyntaxError);

+   EPyTabError = class (EPyIndentationError);

+   EPySystemError = class (EPyStandardError);

+   EPySystemExit = class (EPyException);

+   EPyTypeError = class (EPyStandardError);

+   EPyUnboundLocalError = class (EPyNameError);

+   EPyValueError = class (EPyStandardError);

+   EPyUnicodeError = class (EPyValueError);

+   UnicodeEncodeError = class (EPyUnicodeError);

+   UnicodeDecodeError = class (EPyUnicodeError);

+   UnicodeTranslateError = class (EPyUnicodeError);

+   EPyZeroDivisionError = class (EPyArithmeticError);

+   EPyStopIteration = class(EPyException);

+   EPyWarning = class (EPyException);

+   EPyUserWarning = class (EPyWarning);

+   EPyDeprecationWarning = class (EPyWarning);

+   PendingDeprecationWarning = class (EPyWarning);

+   FutureWarning = class (EPyWarning);

+   EPySyntaxWarning = class (EPyWarning);

+   EPyOverflowWarning = class (EPyWarning);

+   EPyRuntimeWarning = class (EPyWarning);

+   EPyReferenceError = class (EPyStandardError);

+*)

+

+var

+    PyArg_Parse: function(args: PPyObject; format: PChar):

+                     Integer; cdecl;// varargs; 

+    PyArg_ParseTuple: function(args: PPyObject; format: PChar;

+                              x1: Pointer = nil;

+                              x2: Pointer = nil;

+                              x3: Pointer = nil):

+                     Integer; cdecl;// varargs

+    Py_BuildValue: function(format: PChar): PPyObject; cdecl; // varargs

+    PyCode_Addr2Line: function (co: PPyCodeObject; addrq: Integer): Integer; cdecl;

+    DLL_Py_GetBuildInfo: function: PChar; cdecl;

+

+    // define Python flags. See file pyDebug.h

+    Py_DebugFlag: PInt;

+    Py_VerboseFlag: PInt;

+    Py_InteractiveFlag: PInt;

+    Py_OptimizeFlag: PInt;

+    Py_NoSiteFlag: PInt;

+    Py_UseClassExceptionsFlag: PInt;

+    Py_FrozenFlag: PInt;

+    Py_TabcheckFlag: PInt;

+    Py_UnicodeFlag: PInt;

+    Py_IgnoreEnvironmentFlag: PInt;

+    Py_DivisionWarningFlag: PInt;

+    //_PySys_TraceFunc:    PPPyObject;

+    //_PySys_ProfileFunc: PPPPyObject;

+

+    PyImport_FrozenModules: PP_frozen;

+

+    Py_None:            PPyObject;

+    Py_Ellipsis:        PPyObject;

+    Py_False:           PPyIntObject;

+    Py_True:            PPyIntObject;

+    Py_NotImplemented:  PPyObject;

+

+    PyExc_AttributeError: PPPyObject;

+    PyExc_EOFError: PPPyObject;

+    PyExc_IOError: PPPyObject;

+    PyExc_ImportError: PPPyObject;

+    PyExc_IndexError: PPPyObject;

+    PyExc_KeyError: PPPyObject;

+    PyExc_KeyboardInterrupt: PPPyObject;

+    PyExc_MemoryError: PPPyObject;

+    PyExc_NameError: PPPyObject;

+    PyExc_OverflowError: PPPyObject;

+    PyExc_RuntimeError: PPPyObject;

+    PyExc_SyntaxError: PPPyObject;

+    PyExc_SystemError: PPPyObject;

+    PyExc_SystemExit: PPPyObject;

+    PyExc_TypeError: PPPyObject;

+    PyExc_ValueError: PPPyObject;

+    PyExc_ZeroDivisionError: PPPyObject;

+    PyExc_ArithmeticError: PPPyObject;

+    PyExc_Exception: PPPyObject;

+    PyExc_FloatingPointError: PPPyObject;

+    PyExc_LookupError: PPPyObject;

+    PyExc_StandardError: PPPyObject;

+    PyExc_AssertionError: PPPyObject;

+    PyExc_EnvironmentError: PPPyObject;

+    PyExc_IndentationError: PPPyObject;

+    PyExc_MemoryErrorInst: PPPyObject;

+    PyExc_NotImplementedError: PPPyObject;

+    PyExc_OSError: PPPyObject;

+    PyExc_TabError: PPPyObject;

+    PyExc_UnboundLocalError: PPPyObject;

+    PyExc_UnicodeError: PPPyObject;

+

+    PyExc_Warning: PPPyObject;

+    PyExc_DeprecationWarning: PPPyObject;

+    PyExc_RuntimeWarning: PPPyObject;

+    PyExc_SyntaxWarning: PPPyObject;

+    PyExc_UserWarning: PPPyObject;

+    PyExc_OverflowWarning: PPPyObject;

+    PyExc_ReferenceError: PPPyObject;

+    PyExc_StopIteration: PPPyObject;

+    PyExc_FutureWarning: PPPyObject;

+    PyExc_PendingDeprecationWarning: PPPyObject;

+    PyExc_UnicodeDecodeError: PPPyObject;

+    PyExc_UnicodeEncodeError: PPPyObject;

+    PyExc_UnicodeTranslateError: PPPyObject;

+

+    PyType_Type: PPyTypeObject;

+    PyCFunction_Type: PPyTypeObject;

+    PyCObject_Type: PPyTypeObject;

+    PyClass_Type: PPyTypeObject;

+    PyCode_Type: PPyTypeObject;

+    PyComplex_Type: PPyTypeObject;

+    PyDict_Type: PPyTypeObject;

+    PyFile_Type: PPyTypeObject;

+    PyFloat_Type: PPyTypeObject;

+    PyFrame_Type: PPyTypeObject;

+    PyFunction_Type: PPyTypeObject;

+    PyInstance_Type: PPyTypeObject;

+    PyInt_Type: PPyTypeObject;

+    PyList_Type: PPyTypeObject;

+    PyLong_Type: PPyTypeObject;

+    PyMethod_Type: PPyTypeObject;

+    PyModule_Type: PPyTypeObject;

+    PyObject_Type: PPyTypeObject;

+    PyRange_Type: PPyTypeObject;

+    PySlice_Type: PPyTypeObject;

+    PyString_Type: PPyTypeObject;

+    PyTuple_Type: PPyTypeObject;

+

+    PyBaseObject_Type: PPyTypeObject;

+    PyBuffer_Type: PPyTypeObject;

+    PyCallIter_Type: PPyTypeObject;

+    PyCell_Type: PPyTypeObject;

+    PyClassMethod_Type: PPyTypeObject;

+    PyProperty_Type: PPyTypeObject;

+    PySeqIter_Type: PPyTypeObject;

+    PyStaticMethod_Type: PPyTypeObject;

+    PySuper_Type: PPyTypeObject;

+    PySymtableEntry_Type: PPyTypeObject;

+    PyTraceBack_Type: PPyTypeObject;

+    PyUnicode_Type: PPyTypeObject;

+    PyWrapperDescr_Type: PPyTypeObject;

+

+    PyBaseString_Type: PPyTypeObject;

+    PyBool_Type: PPyTypeObject;

+    PyEnum_Type: PPyTypeObject;

+

+    //PyArg_GetObject: function(args: PPyObject; nargs, i: integer; p_a: PPPyObject): integer; cdecl;

+    //PyArg_GetLong:   function(args: PPyObject; nargs, i: integer; p_a: PLong): integer; cdecl;

+    //PyArg_GetShort:  function(args: PPyObject; nargs, i: integer; p_a: PShort): integer; cdecl;

+    //PyArg_GetFloat:  function(args: PPyObject; nargs, i: integer; p_a: PFloat): integer; cdecl;

+    //PyArg_GetString: function(args: PPyObject; nargs, i: integer; p_a: PString): integer; cdecl;

+    //PyArgs_VaParse:  function (args: PPyObject; format: PChar; va_list: array of const): integer; cdecl;

+    // Does not work!

+    // Py_VaBuildValue: function (format: PChar; va_list: array of const): PPyObject; cdecl;

+    //PyBuiltin_Init:     procedure; cdecl;

+

+    PyComplex_FromCComplex: function(c: TPy_complex):PPyObject; cdecl;

+    PyComplex_FromDoubles: function(realv,imag: double):PPyObject; cdecl;

+    PyComplex_RealAsDouble: function(op: PPyObject): double; cdecl;

+    PyComplex_ImagAsDouble: function(op: PPyObject): double; cdecl;

+    PyComplex_AsCComplex: function(op: PPyObject): TPy_complex; cdecl;

+    PyCFunction_GetFunction: function(ob: PPyObject): Pointer; cdecl;

+    PyCFunction_GetSelf: function(ob: PPyObject): PPyObject; cdecl;

+    PyCallable_Check: function(ob	: PPyObject): integer; cdecl;

+    PyCObject_FromVoidPtr: function(cobj, destruct: Pointer): PPyObject; cdecl;

+    PyCObject_AsVoidPtr: function(ob: PPyObject): Pointer; cdecl;

+    PyClass_New: function (ob1,ob2,ob3:  PPyObject): PPyObject; cdecl;

+    PyClass_IsSubclass: function (ob1, ob2: PPyObject): integer cdecl;

+

+    Py_InitModule4: function(name: PChar; methods: PPyMethodDef; doc: PChar;

+                              passthrough: PPyObject; Api_Version: Integer):PPyObject; cdecl;

+    PyErr_BadArgument:  function: integer; cdecl;

+    PyErr_BadInternalCall: procedure; cdecl;

+    PyErr_CheckSignals: function: integer; cdecl;

+    PyErr_Clear:        procedure; cdecl;

+    PyErr_Fetch:        procedure(errtype, errvalue, errtraceback: PPPyObject); cdecl;

+    PyErr_NoMemory: function: PPyObject; cdecl;

+    PyErr_Occurred:     function: PPyObject; cdecl;

+    PyErr_Print:        procedure; cdecl;

+    PyErr_Restore:      procedure  (errtype, errvalue, errtraceback: PPyObject); cdecl;

+    PyErr_SetFromErrno: function (ob:  PPyObject):PPyObject; cdecl;

+    PyErr_SetNone:      procedure(value: PPyObject); cdecl;

+    PyErr_SetObject:    procedure  (ob1, ob2	: PPyObject); cdecl;

+    PyErr_SetString:    procedure(ErrorObject: PPyObject; text: PChar); cdecl;

+    PyImport_GetModuleDict: function: PPyObject; cdecl;

+    PyInt_FromLong:     function(x: LongInt):PPyObject; cdecl;

+    Py_Initialize:      procedure; cdecl;

+    Py_Exit:            procedure(RetVal: Integer); cdecl;

+    PyEval_GetBuiltins: function: PPyObject; cdecl;

+    PyDict_GetItem: function(mp, key: PPyObject):PPyObject; cdecl;

+    PyDict_SetItem: function(mp, key, item:PPyObject):integer; cdecl;

+    PyDict_DelItem: function(mp, key: PPyObject):integer; cdecl;

+    PyDict_Clear: procedure(mp: PPyObject); cdecl;

+    PyDict_Next: function(mp: PPyObject; pos: PInt; key, value: PPPyObject):integer; cdecl;

+    PyDict_Keys: function(mp: PPyObject):PPyObject; cdecl;

+    PyDict_Values: function(mp: PPyObject):PPyObject; cdecl;

+    PyDict_Items: function(mp: PPyObject):PPyObject; cdecl;

+    PyDict_Size: function(mp: PPyObject):integer; cdecl;

+    PyDict_DelItemString: function(dp: PPyObject;key: PChar):integer; cdecl;

+    PyDict_New: function: PPyObject; cdecl;

+    PyDict_GetItemString: function(dp: PPyObject; key: PChar): PPyObject; cdecl;

+    PyDict_SetItemString: function(dp: PPyObject; key: PChar; item: PPyObject):

+                          Integer; cdecl;

+    PyDictProxy_New: function (obj: PPyObject): PPyObject; cdecl;

+    PyModule_GetDict:     function(module:PPyObject): PPyObject; cdecl;

+    PyObject_Str:         function(v: PPyObject): PPyObject; cdecl;

+    PyRun_String:         function(str: PChar; start: Integer; globals: PPyObject;

+                                    locals: PPyObject): PPyObject; cdecl;

+    PyRun_SimpleString:   function(str: PChar): Integer; cdecl;

+    PyString_AsString:    function(ob: PPyObject): PChar; cdecl;

+    PyString_FromString:  function(str: PChar): PPyObject; cdecl;

+    PySys_SetArgv:        procedure(argc: Integer; argv: PPChar); cdecl;

+

+{+ means, Grzegorz or me has tested his non object version of this function}

+{+} PyCFunction_New: function(md:PPyMethodDef;ob:PPyObject):PPyObject; cdecl;

+{+} PyEval_CallObject: function(ob1,ob2:PPyObject):PPyObject; cdecl;

+{-} PyEval_CallObjectWithKeywords:function (ob1,ob2,ob3:PPyObject):PPyObject; cdecl;

+{-} PyEval_GetFrame:function:PPyObject; cdecl;

+{-} PyEval_GetGlobals:function:PPyObject; cdecl;

+{-} PyEval_GetLocals:function:PPyObject; cdecl;

+{-} //PyEval_GetOwner:function:PPyObject; cdecl;

+{-} PyEval_GetRestricted:function:integer; cdecl;

+

+{-} PyEval_InitThreads:procedure; cdecl;

+{-} PyEval_RestoreThread:procedure(tstate: PPyThreadState); cdecl;

+{-} PyEval_SaveThread:function:PPyThreadState; cdecl;

+

+{-} PyFile_FromString:function (pc1,pc2:PChar):PPyObject; cdecl;

+{-} PyFile_GetLine:function (ob:PPyObject;i:integer):PPyObject; cdecl;

+{-} PyFile_Name:function (ob:PPyObject):PPyObject; cdecl;

+{-} PyFile_SetBufSize:procedure(ob:PPyObject;i:integer); cdecl;

+{-} PyFile_SoftSpace:function (ob:PPyObject;i:integer):integer; cdecl;

+{-} PyFile_WriteObject:function (ob1,ob2:PPyObject;i:integer):integer; cdecl;

+{-} PyFile_WriteString:procedure(s:PChar;ob:PPyObject); cdecl;

+{+} PyFloat_AsDouble:function (ob:PPyObject):DOUBLE; cdecl;

+{+} PyFloat_FromDouble:function (db:double):PPyObject; cdecl;

+{-} PyFunction_GetCode:function (ob:PPyObject):PPyObject; cdecl;

+{-} PyFunction_GetGlobals:function (ob:PPyObject):PPyObject; cdecl;

+{-} PyFunction_New:function (ob1,ob2:PPyObject):PPyObject; cdecl;

+{-} PyImport_AddModule:function (name:PChar):PPyObject; cdecl;

+{-} PyImport_Cleanup:procedure; cdecl;

+{-} PyImport_GetMagicNumber:function:LONGINT; cdecl;

+{+} PyImport_ImportFrozenModule:function (key:PChar):integer; cdecl;

+{+} PyImport_ImportModule:function (name:PChar):PPyObject; cdecl;

+{+} PyImport_Import:function (name:PPyObject):PPyObject; cdecl;

+{-} //PyImport_Init:procedure; cdecl;

+{-} PyImport_ReloadModule:function (ob:PPyObject):PPyObject; cdecl;

+{-} PyInstance_New:function (obClass, obArg, obKW:PPyObject):PPyObject; cdecl;

+{+} PyInt_AsLong:function (ob:PPyObject):LONGINT; cdecl;

+{-} PyList_Append:function (ob1,ob2:PPyObject):integer; cdecl;

+{-} PyList_AsTuple:function (ob:PPyObject):PPyObject; cdecl;

+{+} PyList_GetItem:function (ob:PPyObject;i:integer):PPyObject; cdecl;

+{-} PyList_GetSlice:function (ob:PPyObject;i1,i2:integer):PPyObject; cdecl;

+{-} PyList_Insert:function (dp:PPyObject;idx:Integer;item:PPyObject):integer; cdecl;

+{-} PyList_New:function (size:integer):PPyObject; cdecl;

+{-} PyList_Reverse:function (ob:PPyObject):integer; cdecl;

+{-} PyList_SetItem:function (dp:PPyObject;idx:Integer;item:PPyObject):integer; cdecl;

+{-} PyList_SetSlice:function (ob:PPyObject;i1,i2:integer;ob2:PPyObject):integer; cdecl;

+{+} PyList_Size:function (ob:PPyObject):integer; cdecl;

+{-} PyList_Sort:function (ob:PPyObject):integer; cdecl;

+{-} PyLong_AsDouble:function (ob:PPyObject):DOUBLE; cdecl;

+{+} PyLong_AsLong:function (ob:PPyObject):LONGINT; cdecl;

+{+} PyLong_FromDouble:function (db:double):PPyObject; cdecl;

+{+} PyLong_FromLong:function (l:longint):PPyObject; cdecl;

+{-} PyLong_FromString:function (pc:PChar;var ppc:PChar;i:integer):PPyObject; cdecl;

+{-} PyLong_FromUnsignedLong:function(val:cardinal): PPyObject; cdecl;

+{-} PyLong_AsUnsignedLong:function(ob:PPyObject): Cardinal; cdecl;

+{-} PyLong_FromUnicode:function(ob:PPyObject; a, b: integer): PPyObject; cdecl;

+{-} PyLong_FromLongLong:function(val:Int64): PPyObject; cdecl;

+{-} PyLong_AsLongLong:function(ob:PPyObject): Int64; cdecl;

+{-} PyMapping_Check:function (ob:PPyObject):integer; cdecl;

+{-} PyMapping_GetItemString:function (ob:PPyObject;key:PChar):PPyObject; cdecl;

+{-} PyMapping_HasKey:function (ob,key:PPyObject):integer; cdecl;

+{-} PyMapping_HasKeyString:function (ob:PPyObject;key:PChar):integer; cdecl;

+{-} PyMapping_Length:function (ob:PPyObject):integer; cdecl;

+{-} PyMapping_SetItemString:function (ob:PPyObject; key:PChar; value:PPyObject):integer; cdecl;

+{-} PyMethod_Class:function (ob:PPyObject):PPyObject; cdecl;

+{-} PyMethod_Function:function (ob:PPyObject):PPyObject; cdecl;

+{-} PyMethod_New:function (ob1,ob2,ob3:PPyObject):PPyObject; cdecl;

+{-} PyMethod_Self:function (ob:PPyObject):PPyObject; cdecl;

+{-} PyModule_GetName:function (ob:PPyObject):PChar; cdecl;

+{-} PyModule_New:function (key:PChar):PPyObject; cdecl;

+{-} PyNumber_Absolute:function (ob:PPyObject):PPyObject; cdecl;

+{-} PyNumber_Add:function (ob1,ob2:PPyObject):PPyObject; cdecl;

+{-} PyNumber_And:function (ob1,ob2:PPyObject):PPyObject; cdecl;

+{-} PyNumber_Check:function (ob:PPyObject):integer; cdecl;

+{-} PyNumber_Coerce:function (var ob1,ob2:PPyObject):integer; cdecl;

+{-} PyNumber_Divide:function (ob1,ob2:PPyObject):PPyObject; cdecl;

+{-} PyNumber_FloorDivide:function (ob1,ob2:PPyObject):PPyObject; cdecl;

+{-} PyNumber_TrueDivide:function (ob1,ob2:PPyObject):PPyObject; cdecl;

+{-} PyNumber_Divmod:function (ob1,ob2:PPyObject):PPyObject; cdecl;

+{-} PyNumber_Float:function (ob:PPyObject):PPyObject; cdecl;

+{-} PyNumber_Int:function (ob:PPyObject):PPyObject; cdecl;

+{-} PyNumber_Invert:function (ob:PPyObject):PPyObject; cdecl;

+{-} PyNumber_Long:function (ob:PPyObject):PPyObject; cdecl;

+{-} PyNumber_Lshift:function (ob1,ob2:PPyObject):PPyObject; cdecl;

+{-} PyNumber_Multiply:function (ob1,ob2:PPyObject):PPyObject; cdecl;

+{-} PyNumber_Negative:function (ob:PPyObject):PPyObject; cdecl;

+{-} PyNumber_Or:function (ob1,ob2:PPyObject):PPyObject; cdecl;

+{-} PyNumber_Positive:function (ob:PPyObject):PPyObject; cdecl;

+{-} PyNumber_Power:function (ob1,ob2,ob3:PPyObject):PPyObject; cdecl;

+{-} PyNumber_Remainder:function (ob1,ob2:PPyObject):PPyObject; cdecl;

+{-} PyNumber_Rshift:function (ob1,ob2:PPyObject):PPyObject; cdecl;

+{-} PyNumber_Subtract:function (ob1,ob2:PPyObject):PPyObject; cdecl;

+{-} PyNumber_Xor:function (ob1,ob2:PPyObject):PPyObject; cdecl;

+{-} PyOS_InitInterrupts:procedure; cdecl;

+{-} PyOS_InterruptOccurred:function:integer; cdecl;

+{-} PyObject_CallObject:function (ob,args:PPyObject):PPyObject; cdecl;

+{-} PyObject_Compare:function (ob1,ob2:PPyObject):integer; cdecl;

+{-} PyObject_GetAttr:function (ob1,ob2:PPyObject):PPyObject; cdecl;

+{+} PyObject_GetAttrString:function (ob:PPyObject;c:PChar):PPyObject; cdecl;

+{-} PyObject_GetItem:function (ob,key:PPyObject):PPyObject; cdecl;

+{-} PyObject_DelItem:function (ob,key:PPyObject):PPyObject; cdecl;

+{-} PyObject_HasAttrString:function (ob:PPyObject;key:PChar):integer; cdecl;

+{-} PyObject_Hash:function (ob:PPyObject):LONGINT; cdecl;

+{-} PyObject_IsTrue:function (ob:PPyObject):integer; cdecl;

+{-} PyObject_Length:function (ob:PPyObject):integer; cdecl;

+{-} PyObject_Repr:function (ob:PPyObject):PPyObject; cdecl;

+{-} PyObject_SetAttr:function (ob1,ob2,ob3:PPyObject):integer; cdecl;

+{-} PyObject_SetAttrString:function (ob:PPyObject;key:Pchar;value:PPyObject):integer; cdecl;

+{-} PyObject_SetItem:function (ob1,ob2,ob3:PPyObject):integer; cdecl;

+{-} PyObject_Init:function (ob:PPyObject; t:PPyTypeObject):PPyObject; cdecl;

+{-} PyObject_InitVar:function (ob:PPyObject; t:PPyTypeObject; size:integer):PPyObject; cdecl;

+{-} PyObject_New:function (t:PPyTypeObject):PPyObject; cdecl;

+{-} PyObject_NewVar:function (t:PPyTypeObject; size:integer):PPyObject; cdecl;

+    PyObject_Free:procedure (ob:PPyObject); cdecl;

+{-} PyObject_IsInstance:function (inst, cls:PPyObject):integer; cdecl;

+{-} PyObject_IsSubclass:function (derived, cls:PPyObject):integer; cdecl;

+    PyObject_GenericGetAttr:function (obj, name: PPyObject): PPyObject; cdecl;

+    PyObject_GenericSetAttr:function (obj, name, value: PPyObject): Integer; cdecl;

+{-} PyObject_GC_Malloc:function (size:integer):PPyObject; cdecl;

+{-} PyObject_GC_New:function (t:PPyTypeObject):PPyObject; cdecl;

+{-} PyObject_GC_NewVar:function (t:PPyTypeObject; size:integer):PPyObject; cdecl;

+{-} PyObject_GC_Resize:function (t:PPyObject; newsize:integer):PPyObject; cdecl;

+{-} PyObject_GC_Del:procedure (ob:PPyObject); cdecl;

+{-} PyObject_GC_Track:procedure (ob:PPyObject); cdecl;

+{-} PyObject_GC_UnTrack:procedure (ob:PPyObject); cdecl;

+{-} PyRange_New:function (l1,l2,l3:longint;i:integer):PPyObject; cdecl;

+{-} PySequence_Check:function (ob:PPyObject):integer; cdecl;

+{-} PySequence_Concat:function (ob1,ob2:PPyObject):PPyObject; cdecl;

+{-} PySequence_Count:function (ob1,ob2:PPyObject):integer; cdecl;

+{-} PySequence_GetItem:function (ob:PPyObject;i:integer):PPyObject; cdecl;

+{-} PySequence_GetSlice:function (ob:PPyObject;i1,i2:integer):PPyObject; cdecl;

+{-} PySequence_In:function (ob1,ob2:PPyObject):integer; cdecl;

+{-} PySequence_Index:function (ob1,ob2:PPyObject):integer; cdecl;

+{-} PySequence_Length:function (ob:PPyObject):integer; cdecl;

+{-} PySequence_Repeat:function (ob:PPyObject;count:integer):PPyObject; cdecl;

+{-} PySequence_SetItem:function (ob:PPyObject;i:integer;value:PPyObject):integer; cdecl;

+{-} PySequence_SetSlice:function (ob:PPyObject;i1,i2:integer;value:PPyObject):integer; cdecl;

+{-} PySequence_DelSlice:function (ob:PPyObject;i1,i2:integer):integer; cdecl;

+{-} PySequence_Tuple:function (ob:PPyObject):PPyObject; cdecl;

+{-} PySequence_Contains:function (ob, value:PPyObject):integer; cdecl;

+{-} PySlice_GetIndices:function (ob:PPySliceObject;length:integer;var start,stop,step:integer):integer; cdecl;

+{-} PySlice_GetIndicesEx:function (ob:PPySliceObject;length:integer;var start,stop,step,slicelength:integer):integer; cdecl;

+{-} PySlice_New:function (start,stop,step:PPyObject):PPyObject; cdecl;

+{-} PyString_Concat:procedure(var ob1:PPyObject;ob2:PPyObject); cdecl;

+{-} PyString_ConcatAndDel:procedure(var ob1:PPyObject;ob2:PPyObject); cdecl;

+{-} PyString_Format:function (ob1,ob2:PPyObject):PPyObject; cdecl;

+{-} PyString_FromStringAndSize:function (s:PChar;i:integer):PPyObject; cdecl;

+{-} PyString_Size:function (ob:PPyObject):integer; cdecl;

+{-} PyString_DecodeEscape:function(s:PChar; len:integer; errors:PChar; unicode:integer; recode_encoding:PChar):PPyObject; cdecl;

+{-} PyString_Repr:function(ob:PPyObject; smartquotes:integer):PPyObject; cdecl;

+{+} PySys_GetObject:function (s:PChar):PPyObject; cdecl;

+{-} //PySys_Init:procedure; cdecl;

+{-} PySys_SetObject:function (s:PChar;ob:PPyObject):integer; cdecl;

+{-} PySys_SetPath:procedure(path:PChar); cdecl;

+{-} //PyTraceBack_Fetch:function:PPyObject; cdecl;

+{-} PyTraceBack_Here:function (p:pointer):integer; cdecl;

+{-} PyTraceBack_Print:function (ob1,ob2:PPyObject):integer; cdecl;

+{-} //PyTraceBack_Store:function (ob:PPyObject):integer; cdecl;

+{+} PyTuple_GetItem:function (ob:PPyObject;i:integer):PPyObject; cdecl;

+{-} PyTuple_GetSlice:function (ob:PPyObject;i1,i2:integer):PPyObject; cdecl;

+{+} PyTuple_New:function (size:Integer):PPyObject; cdecl;

+{+} PyTuple_SetItem:function (ob:PPyObject;key:integer;value:PPyObject):integer; cdecl;

+{+} PyTuple_Size:function (ob:PPyObject):integer; cdecl;

+{+} PyType_IsSubtype:function (a, b: PPyTypeObject):integer; cdecl;

+    PyType_GenericAlloc:function(atype: PPyTypeObject; nitems:Integer): PPyObject; cdecl;

+    PyType_GenericNew:function(atype: PPyTypeObject; args, kwds: PPyObject): PPyObject; cdecl;

+    PyType_Ready:function(atype: PPyTypeObject): integer; cdecl;

+{+} PyUnicode_FromWideChar:function (const w:PWideChar; size:integer):PPyObject; cdecl;

+{+} PyUnicode_AsWideChar:function (unicode: PPyObject; w:PWideChar; size:integer):integer; cdecl;

+{-} PyUnicode_FromOrdinal:function (ordinal:integer):PPyObject; cdecl;

+    PyWeakref_GetObject: function (ref: PPyObject): PPyObject; cdecl;

+    PyWeakref_NewProxy: function (ob, callback: PPyObject): PPyObject; cdecl;

+    PyWeakref_NewRef: function (ob, callback: PPyObject): PPyObject; cdecl;

+    PyWrapper_New: function (ob1, ob2: PPyObject): PPyObject; cdecl;

+    PyBool_FromLong: function (ok: Integer): PPyObject; cdecl;

+{-} Py_AtExit:function (proc: procedure):integer; cdecl;

+{-} //Py_Cleanup:procedure; cdecl;

+{-} Py_CompileString:function (s1,s2:PChar;i:integer):PPyObject; cdecl;

+{-} Py_FatalError:procedure(s:PChar); cdecl;

+{-} Py_FindMethod:function (md:PPyMethodDef;ob:PPyObject;key:PChar):PPyObject; cdecl;

+{-} Py_FindMethodInChain:function (mc:PPyMethodChain;ob:PPyObject;key:PChar):PPyObject; cdecl;

+{-} Py_FlushLine:procedure; cdecl;

+{+} Py_Finalize: procedure; cdecl;

+{-} PyErr_ExceptionMatches: function (exc: PPyObject): Integer; cdecl;

+{-} PyErr_GivenExceptionMatches: function (raised_exc, exc: PPyObject): Integer; cdecl;

+{-} PyEval_EvalCode: function (co: PPyCodeObject; globals, locals: PPyObject): PPyObject; cdecl;

+{+} Py_GetVersion: function: PChar; cdecl;

+{+} Py_GetCopyright: function: PChar; cdecl;

+{+} Py_GetExecPrefix: function: PChar; cdecl;

+{+} Py_GetPath: function: PChar; cdecl;

+{+} Py_GetPrefix: function: PChar; cdecl;

+{+} Py_GetProgramName: function: PChar; cdecl;

+

+{-} PyParser_SimpleParseString: function (str: PChar; start: Integer): PNode; cdecl;

+{-} PyNode_Free: procedure(n: PNode); cdecl;

+{-} PyErr_NewException: function (name: PChar; base, dict: PPyObject): PPyObject; cdecl;

+{-} Py_Malloc: function (size: Integer): Pointer;

+{-} PyMem_Malloc: function (size: Integer): Pointer;

+{-} PyObject_CallMethod: function (obj: PPyObject; method, format: PChar): PPyObject; cdecl;

+

+{New exported Objects in Python 1.5}

+    Py_SetProgramName: procedure(name: PChar); cdecl;

+    Py_IsInitialized: function: integer; cdecl;

+    Py_GetProgramFullPath: function: PChar; cdecl;

+    Py_NewInterpreter: function: PPyThreadState; cdecl;

+    Py_EndInterpreter: procedure(tstate: PPyThreadState); cdecl;

+    PyEval_AcquireLock: procedure; cdecl;

+    PyEval_ReleaseLock: procedure; cdecl;

+    PyEval_AcquireThread: procedure(tstate: PPyThreadState); cdecl;

+    PyEval_ReleaseThread: procedure(tstate: PPyThreadState); cdecl;

+    PyInterpreterState_New: function: PPyInterpreterState; cdecl;

+    PyInterpreterState_Clear: procedure(interp: PPyInterpreterState); cdecl;

+    PyInterpreterState_Delete: procedure(interp: PPyInterpreterState); cdecl;

+    PyThreadState_New: function (interp: PPyInterpreterState): PPyThreadState; cdecl;

+    PyThreadState_Clear: procedure(tstate: PPyThreadState); cdecl;

+    PyThreadState_Delete: procedure(tstate: PPyThreadState); cdecl;

+    PyThreadState_Get: function: PPyThreadState; cdecl;

+    PyThreadState_Swap: function (tstate: PPyThreadState): PPyThreadState; cdecl;

+

+{Further exported Objects, may be implemented later}

+{

+    PyCode_New: Pointer;

+    PyErr_SetInterrupt: Pointer;

+    PyFile_AsFile: Pointer;

+    PyFile_FromFile: Pointer;

+    PyFloat_AsString: Pointer;

+    PyFrame_BlockPop: Pointer;

+    PyFrame_BlockSetup: Pointer;

+    PyFrame_ExtendStack: Pointer;

+    PyFrame_FastToLocals: Pointer;

+    PyFrame_LocalsToFast: Pointer;

+    PyFrame_New: Pointer;

+    PyGrammar_AddAccelerators: Pointer;

+    PyGrammar_FindDFA: Pointer;

+    PyGrammar_LabelRepr: Pointer;

+    PyInstance_DoBinOp: Pointer;

+    PyInt_GetMax: Pointer;

+    PyMarshal_Init: Pointer;

+    PyMarshal_ReadLongFromFile: Pointer;

+    PyMarshal_ReadObjectFromFile: Pointer;

+    PyMarshal_ReadObjectFromString: Pointer;

+    PyMarshal_WriteLongToFile: Pointer;

+    PyMarshal_WriteObjectToFile: Pointer;

+    PyMember_Get: Pointer;

+    PyMember_Set: Pointer;

+    PyNode_AddChild: Pointer;

+    PyNode_Compile: Pointer;

+    PyNode_New: Pointer;

+    PyOS_GetLastModificationTime: Pointer;

+    PyOS_Readline: Pointer;

+    PyOS_strtol: Pointer;

+    PyOS_strtoul: Pointer;

+    PyObject_CallFunction: Pointer;

+    PyObject_CallMethod: Pointer;

+    PyObject_Print: Pointer;

+    PyParser_AddToken: Pointer;

+    PyParser_Delete: Pointer;

+    PyParser_New: Pointer;

+    PyParser_ParseFile: Pointer;

+    PyParser_ParseString: Pointer;

+    PyParser_SimpleParseFile: Pointer;

+    PyRun_AnyFile: Pointer;

+    PyRun_File: Pointer;

+    PyRun_InteractiveLoop: Pointer;

+    PyRun_InteractiveOne: Pointer;

+    PyRun_SimpleFile: Pointer;

+    PySys_GetFile: Pointer;

+    PyToken_OneChar: Pointer;

+    PyToken_TwoChars: Pointer;

+    PyTokenizer_Free: Pointer;

+    PyTokenizer_FromFile: Pointer;

+    PyTokenizer_FromString: Pointer;

+    PyTokenizer_Get: Pointer;

+    Py_Main: Pointer;

+    _PyObject_NewVar: Pointer;

+    _PyParser_Grammar: Pointer;

+    _PyParser_TokenNames: Pointer;

+    _PyThread_Started: Pointer;

+    _Py_c_diff: Pointer;

+    _Py_c_neg: Pointer;

+    _Py_c_pow: Pointer;

+    _Py_c_prod: Pointer;

+    _Py_c_quot: Pointer;

+    _Py_c_sum: Pointer;

+}

+// functions redefined in Delphi

+procedure Py_INCREF(op: PPyObject);

+procedure Py_DECREF(op: PPyObject);

+procedure Py_XINCREF(op: PPyObject);

+procedure Py_XDECREF(op: PPyObject);

+

+// This function handles all cardinals, pointer types (with no adjustment of pointers!)

+// (Extended) floats, which are handled as Python doubles and currencies, handled

+// as (normalized) Python doubles.

+function PyImport_ExecCodeModule(const name: String; codeobject: PPyObject): PPyObject;

+function PyString_Check(obj: PPyObject): Boolean;

+function PyString_CheckExact(obj: PPyObject): Boolean;

+function PyFloat_Check(obj: PPyObject): Boolean;

+function PyFloat_CheckExact(obj: PPyObject): Boolean;

+function PyInt_Check(obj: PPyObject): Boolean;

+function PyInt_CheckExact(obj: PPyObject): Boolean;

+function PyLong_Check(obj: PPyObject): Boolean;

+function PyLong_CheckExact(obj: PPyObject): Boolean;

+function PyTuple_Check(obj: PPyObject): Boolean;

+function PyTuple_CheckExact(obj: PPyObject): Boolean;

+function PyInstance_Check(obj: PPyObject): Boolean;

+function PyClass_Check(obj: PPyObject): Boolean;

+function PyMethod_Check(obj: PPyObject): Boolean;

+function PyList_Check(obj: PPyObject): Boolean;

+function PyList_CheckExact(obj: PPyObject): Boolean;

+function PyDict_Check(obj: PPyObject): Boolean;

+function PyDict_CheckExact(obj: PPyObject): Boolean;

+function PyModule_Check(obj: PPyObject): Boolean;

+function PyModule_CheckExact(obj: PPyObject): Boolean;

+function PySlice_Check(obj: PPyObject): Boolean;

+function PyFunction_Check(obj: PPyObject): Boolean;

+function PyUnicode_Check(obj: PPyObject): Boolean;

+function PyUnicode_CheckExact(obj: PPyObject): Boolean;

+function PyType_IS_GC(t: PPyTypeObject): Boolean;

+function PyObject_IS_GC(obj: PPyObject): Boolean;

+function PyWeakref_Check(obj: PPyObject): Boolean;

+function PyWeakref_CheckRef(obj: PPyObject): Boolean;

+function PyWeakref_CheckProxy(obj: PPyObject): Boolean;

+function PyBool_Check(obj: PPyObject): Boolean;

+function PyBaseString_Check(obj: PPyObject): Boolean;

+function PyEnum_Check(obj: PPyObject): Boolean;

+function PyObject_TypeCheck(obj:PPyObject; t:PPyTypeObject): Boolean;

+function Py_InitModule(const name: PChar; md: PPyMethodDef): PPyObject;

+

+function  PyType_HasFeature(AType: PPyTypeObject; AFlag: Integer): Boolean;

+

+implementation

+

+procedure Py_INCREF(op: PPyObject);

+begin

+  Inc(op.ob_refcnt);

+end;

+

+procedure Py_DECREF(op: PPyObject);

+begin

+  Dec(op.ob_refcnt);

+  if op.ob_refcnt = 0 then begin

+    op.ob_type.tp_dealloc(op);

+  end;

+end;

+

+procedure Py_XINCREF(op: PPyObject);

+begin

+  if op <> nil then Py_INCREF(op);

+end;

+

+procedure Py_XDECREF(op: PPyObject);

+begin

+  if op <> nil then Py_DECREF(op);

+end;

+

+function PyImport_ExecCodeModule(const name: String; 

+             codeobject: PPyObject): PPyObject;

+var

+  m, d, v, modules: PPyObject;

+begin

+  m:= PyImport_AddModule(PChar(name));

+  if m = nil then

+    begin

+      Result:= nil;

+      Exit;

+    end;

+  d:= PyModule_GetDict(m);

+  if PyDict_GetItemString(d, '__builtins__') = nil then

+    begin

+      if PyDict_SetItemString(d, '__builtins__', PyEval_GetBuiltins) <> 0 then

+        begin

+          Result:= nil;

+          Exit;

+        end;

+    end;

+  // Remember the fielname as the __file__ attribute

+  if PyDict_SetItemString(d, '__file__', PPyCodeObject(codeobject).co_filename) <> 0 then

+    PyErr_Clear(); // Not important enough to report

+  v:= PyEval_EvalCode(PPyCodeObject(codeobject), d, d); // XXX owner ?

+  if v = nil then

+    begin

+      Result:= nil;

+      Exit;

+    end;

+  Py_XDECREF(v);

+  modules:= PyImport_GetModuleDict();

+  if PyDict_GetItemString(modules, PChar(name)) = nil then

+    begin

+      PyErr_SetString(PyExc_ImportError^, PChar(Format('Loaded module %.200s not found in sys.modules', [name])));

+      Result:= nil;

+      Exit;

+    end;

+  Py_XINCREF(m);

+  Result:= m;

+end;

+

+function PyString_Check(obj: PPyObject): Boolean;

+begin

+  Result:= PyObject_TypeCheck(obj, PyString_Type);

+end;

+

+function PyString_CheckExact(obj: PPyObject): Boolean;

+begin

+  Result:= (obj <> nil) and (obj.ob_type = PPyTypeObject(PyString_Type));

+end;

+

+function PyFloat_Check(obj: PPyObject): Boolean;

+begin

+  Result:= PyObject_TypeCheck(obj, PyFloat_Type);

+end;

+

+function PyFloat_CheckExact(obj: PPyObject): Boolean;

+begin

+  Result:= (obj <> nil) and (obj.ob_type = PPyTypeObject(PyFloat_Type));

+end;

+

+function PyInt_Check(obj: PPyObject): Boolean;

+begin

+  Result:= PyObject_TypeCheck(obj, PyInt_Type);

+end;

+

+function PyInt_CheckExact(obj: PPyObject): Boolean;

+begin

+  Result:= (obj <> nil) and (obj.ob_type = PPyTypeObject(PyInt_Type));

+end;

+

+function PyLong_Check(obj: PPyObject): Boolean;

+begin

+  Result:= PyObject_TypeCheck(obj, PyLong_Type);

+end;

+

+function PyLong_CheckExact(obj: PPyObject): Boolean;

+begin

+  Result:= (obj <> nil) and (obj.ob_type = PPyTypeObject(PyLong_Type));

+end;

+

+function PyTuple_Check(obj: PPyObject): Boolean;

+begin

+  Result:= PyObject_TypeCheck(obj, PyTuple_Type);

+end;

+

+function PyTuple_CheckExact(obj: PPyObject): Boolean;

+begin

+  Result:= ( obj<> nil) and (obj^.ob_type = PPyTypeObject(PyTuple_Type));

+end;

+

+function PyInstance_Check(obj: PPyObject): Boolean;

+begin

+  Result:= (obj <> nil) and (obj^.ob_type = PPyTypeObject(PyInstance_Type));

+end;

+

+function PyClass_Check(obj: PPyObject): Boolean;

+begin

+  Result:= ( obj<> nil) and (obj^.ob_type = PPyTypeObject(PyClass_Type));

+end;

+

+function PyMethod_Check(obj: PPyObject): Boolean;

+begin

+  Result:= (obj <> nil) and (obj^.ob_type = PPyTypeObject(PyMethod_Type));

+end;

+

+function PyList_Check(obj: PPyObject): Boolean;

+begin

+  Result:= PyObject_TypeCheck(obj, PyList_Type);

+end;

+

+function PyList_CheckExact(obj: PPyObject): Boolean;

+begin

+  Result:= (obj<>nil) and (obj^.ob_type = PPyTypeObject(PyList_Type));

+end;

+

+function PyDict_Check(obj: PPyObject): Boolean;

+begin

+  Result:= PyObject_TypeCheck(obj, PyDict_Type);

+end;

+

+function PyDict_CheckExact(obj: PPyObject): Boolean;

+begin

+  Result:= (obj<>nil) and (obj^.ob_type = PPyTypeObject(PyDict_Type));

+end;

+

+function PyModule_Check(obj: PPyObject): Boolean;

+begin

+  Result:= PyObject_TypeCheck(obj, PyModule_Type);

+end;

+

+function PyModule_CheckExact(obj: PPyObject): Boolean;

+begin

+  Result:= (obj<>nil) and (obj^.ob_type = PPyTypeObject(PyModule_Type));

+end;

+

+function PySlice_Check(obj: PPyObject): Boolean;

+begin

+  Result:= (obj<>nil) and (obj^.ob_type = PPyTypeObject(PySlice_Type));

+end;

+

+function PyFunction_Check(obj: PPyObject): Boolean;

+begin

+  Result:= (obj<>nil) and

+    ((obj.ob_type = PPyTypeObject(PyCFunction_Type)) or

+     (obj.ob_type = PPyTypeObject(PyFunction_Type)));

+end;

+

+function PyUnicode_Check(obj: PPyObject): Boolean;

+begin

+  Result:= PyObject_TypeCheck(obj, PyUnicode_Type);

+end;

+

+function PyUnicode_CheckExact(obj: PPyObject): Boolean;

+begin

+  Result:= (obj<>nil) and (obj^.ob_type = PPyTypeObject(PyUnicode_Type));

+end;

+

+function PyType_IS_GC(t: PPyTypeObject): Boolean;

+begin

+  Result:= PyType_HasFeature(t, Py_TPFLAGS_HAVE_GC);

+end;

+

+function PyObject_IS_GC(obj: PPyObject): Boolean;

+begin

+  Result:= PyType_IS_GC(obj.ob_type) and

+            ((obj.ob_type.tp_is_gc = nil) or (obj.ob_type.tp_is_gc(obj) = 1));

+end;

+

+function PyWeakref_Check(obj: PPyObject): Boolean;

+begin

+  Result:= (obj<>nil) and (PyWeakref_CheckRef(obj) or PyWeakref_CheckProxy(obj));

+end;

+

+function PyWeakref_CheckRef(obj: PPyObject): Boolean;

+begin

+  Result:= (obj<>nil) and (obj.ob_type = PPyTypeObject(PyWeakref_RefType));

+end;

+

+function PyWeakref_CheckProxy(obj: PPyObject): Boolean;

+begin

+  Result:= (obj<>nil) and

+            ((obj.ob_type = PPyTypeObject(PyWeakref_ProxyType)) or

+              (obj.ob_type = PPyTypeObject(PyWeakref_CallableProxyType)));

+end;

+

+function PyBool_Check(obj: PPyObject): Boolean;

+begin

+  Result:= (obj<>nil) and (obj.ob_type = PPyTypeObject(PyBool_Type));

+end;

+

+function PyBaseString_Check(obj: PPyObject): Boolean;

+begin

+  Result:= PyObject_TypeCheck(obj, PyBaseString_Type);

+end;

+

+function PyEnum_Check(obj: PPyObject): Boolean;

+begin

+  Result:= (obj<>nil) and (obj.ob_type = PPyTypeObject(PyEnum_Type));

+end;

+

+function PyObject_TypeCheck(obj: PPyObject; t: PPyTypeObject): Boolean;

+begin

+  Result:= (obj<>nil) and (obj.ob_type = t);

+  if not Result and (obj<>nil) and (t<>nil) then

+    Result:= PyType_IsSubtype(obj.ob_type, t) = 1;

+end;

+

+function Py_InitModule(const name: PChar; md: PPyMethodDef): PPyObject;

+begin

+  result:= Py_InitModule4(name, md, nil, nil, 1012);

+end;

+

+function PyType_HasFeature(AType: PPyTypeObject; AFlag: Integer): Boolean;

+begin

+  //(((t)->tp_flags & (f)) != 0)

+  Result:= (AType.tp_flags and AFlag) <> 0;

+end;

+

+procedure init(lib: TLibHandle);

+begin

+  Py_DebugFlag               := getProcAddr(lib, 'Py_DebugFlag');

+  Py_VerboseFlag             := getProcAddr(lib, 'Py_VerboseFlag');

+  Py_InteractiveFlag         := getProcAddr(lib, 'Py_InteractiveFlag');

+  Py_OptimizeFlag            := getProcAddr(lib, 'Py_OptimizeFlag');

+  Py_NoSiteFlag              := getProcAddr(lib, 'Py_NoSiteFlag');

+  Py_UseClassExceptionsFlag  := getProcAddr(lib, 'Py_UseClassExceptionsFlag');

+  Py_FrozenFlag              := getProcAddr(lib, 'Py_FrozenFlag');

+  Py_TabcheckFlag            := getProcAddr(lib, 'Py_TabcheckFlag');

+  Py_UnicodeFlag             := getProcAddr(lib, 'Py_UnicodeFlag');

+

+  Py_IgnoreEnvironmentFlag   := getProcAddr(lib, 'Py_IgnoreEnvironmentFlag');

+  Py_DivisionWarningFlag     := getProcAddr(lib, 'Py_DivisionWarningFlag');

+  Py_None                    := getProcAddr(lib, '_Py_NoneStruct');

+  Py_Ellipsis                := getProcAddr(lib, '_Py_EllipsisObject');

+  Py_False                   := getProcAddr(lib, '_Py_ZeroStruct');

+  Py_True                    := getProcAddr(lib, '_Py_TrueStruct');

+  Py_NotImplemented          := getProcAddr(lib, '_Py_NotImplementedStruct');

+

+  PyImport_FrozenModules     := getProcAddr(lib, 'PyImport_FrozenModules');

+

+  PyExc_AttributeError       := getProcAddr(lib, 'PyExc_AttributeError');

+  PyExc_EOFError             := getProcAddr(lib, 'PyExc_EOFError');

+  PyExc_IOError              := getProcAddr(lib, 'PyExc_IOError');

+  PyExc_ImportError          := getProcAddr(lib, 'PyExc_ImportError');

+  PyExc_IndexError           := getProcAddr(lib, 'PyExc_IndexError');

+  PyExc_KeyError             := getProcAddr(lib, 'PyExc_KeyError');

+  PyExc_KeyboardInterrupt    := getProcAddr(lib, 'PyExc_KeyboardInterrupt');

+  PyExc_MemoryError          := getProcAddr(lib, 'PyExc_MemoryError');

+  PyExc_NameError            := getProcAddr(lib, 'PyExc_NameError');

+  PyExc_OverflowError        := getProcAddr(lib, 'PyExc_OverflowError');

+  PyExc_RuntimeError         := getProcAddr(lib, 'PyExc_RuntimeError');

+  PyExc_SyntaxError          := getProcAddr(lib, 'PyExc_SyntaxError');

+  PyExc_SystemError          := getProcAddr(lib, 'PyExc_SystemError');

+  PyExc_SystemExit           := getProcAddr(lib, 'PyExc_SystemExit');

+  PyExc_TypeError            := getProcAddr(lib, 'PyExc_TypeError');

+  PyExc_ValueError           := getProcAddr(lib, 'PyExc_ValueError');

+  PyExc_ZeroDivisionError    := getProcAddr(lib, 'PyExc_ZeroDivisionError');

+  PyExc_ArithmeticError      := getProcAddr(lib, 'PyExc_ArithmeticError');

+  PyExc_Exception            := getProcAddr(lib, 'PyExc_Exception');

+  PyExc_FloatingPointError   := getProcAddr(lib, 'PyExc_FloatingPointError');

+  PyExc_LookupError          := getProcAddr(lib, 'PyExc_LookupError');

+  PyExc_StandardError        := getProcAddr(lib, 'PyExc_StandardError');

+

+  PyExc_AssertionError       := getProcAddr(lib, 'PyExc_AssertionError');

+  PyExc_EnvironmentError     := getProcAddr(lib, 'PyExc_EnvironmentError');

+  PyExc_IndentationError     := getProcAddr(lib, 'PyExc_IndentationError');

+  PyExc_MemoryErrorInst      := getProcAddr(lib, 'PyExc_MemoryErrorInst');

+  PyExc_NotImplementedError  := getProcAddr(lib, 'PyExc_NotImplementedError');

+  PyExc_OSError              := getProcAddr(lib, 'PyExc_OSError');

+  PyExc_TabError             := getProcAddr(lib, 'PyExc_TabError');

+  PyExc_UnboundLocalError    := getProcAddr(lib, 'PyExc_UnboundLocalError');

+  PyExc_UnicodeError         := getProcAddr(lib, 'PyExc_UnicodeError');

+

+  PyExc_Warning              := getProcAddr(lib, 'PyExc_Warning');

+  PyExc_DeprecationWarning   := getProcAddr(lib, 'PyExc_DeprecationWarning');

+  PyExc_RuntimeWarning       := getProcAddr(lib, 'PyExc_RuntimeWarning');

+  PyExc_SyntaxWarning        := getProcAddr(lib, 'PyExc_SyntaxWarning');

+  PyExc_UserWarning          := getProcAddr(lib, 'PyExc_UserWarning');

+

+  PyExc_OverflowWarning      := getProcAddr(lib, 'PyExc_OverflowWarning');

+  PyExc_ReferenceError       := getProcAddr(lib, 'PyExc_ReferenceError');

+  PyExc_StopIteration        := getProcAddr(lib, 'PyExc_StopIteration');

+

+  PyExc_FutureWarning        := getProcAddr(lib, 'PyExc_FutureWarning');

+  PyExc_PendingDeprecationWarning:= getProcAddr(lib, 'PyExc_PendingDeprecationWarning');

+  PyExc_UnicodeDecodeError   := getProcAddr(lib, 'PyExc_UnicodeDecodeError');

+  PyExc_UnicodeEncodeError   := getProcAddr(lib, 'PyExc_UnicodeEncodeError');

+  PyExc_UnicodeTranslateError:= getProcAddr(lib, 'PyExc_UnicodeTranslateError');

+

+  PyType_Type                := getProcAddr(lib, 'PyType_Type');

+  PyCFunction_Type           := getProcAddr(lib, 'PyCFunction_Type');

+  PyCObject_Type             := getProcAddr(lib, 'PyCObject_Type');

+  PyClass_Type               := getProcAddr(lib, 'PyClass_Type');

+  PyCode_Type                := getProcAddr(lib, 'PyCode_Type');

+  PyComplex_Type             := getProcAddr(lib, 'PyComplex_Type');

+  PyDict_Type                := getProcAddr(lib, 'PyDict_Type');

+  PyFile_Type                := getProcAddr(lib, 'PyFile_Type');

+  PyFloat_Type               := getProcAddr(lib, 'PyFloat_Type');

+  PyFrame_Type               := getProcAddr(lib, 'PyFrame_Type');

+  PyFunction_Type            := getProcAddr(lib, 'PyFunction_Type');

+  PyInstance_Type            := getProcAddr(lib, 'PyInstance_Type');

+  PyInt_Type                 := getProcAddr(lib, 'PyInt_Type');

+  PyList_Type                := getProcAddr(lib, 'PyList_Type');

+  PyLong_Type                := getProcAddr(lib, 'PyLong_Type');

+  PyMethod_Type              := getProcAddr(lib, 'PyMethod_Type');

+  PyModule_Type              := getProcAddr(lib, 'PyModule_Type');

+  PyObject_Type              := getProcAddr(lib, 'PyObject_Type');

+  PyRange_Type               := getProcAddr(lib, 'PyRange_Type');

+  PySlice_Type               := getProcAddr(lib, 'PySlice_Type');

+  PyString_Type              := getProcAddr(lib, 'PyString_Type');

+  PyTuple_Type               := getProcAddr(lib, 'PyTuple_Type');

+

+  PyUnicode_Type             := getProcAddr(lib, 'PyUnicode_Type');

+

+  PyBaseObject_Type          := getProcAddr(lib, 'PyBaseObject_Type');

+  PyBuffer_Type              := getProcAddr(lib, 'PyBuffer_Type');

+  PyCallIter_Type            := getProcAddr(lib, 'PyCallIter_Type');

+  PyCell_Type                := getProcAddr(lib, 'PyCell_Type');

+  PyClassMethod_Type         := getProcAddr(lib, 'PyClassMethod_Type');

+  PyProperty_Type            := getProcAddr(lib, 'PyProperty_Type');

+  PySeqIter_Type             := getProcAddr(lib, 'PySeqIter_Type');

+  PyStaticMethod_Type        := getProcAddr(lib, 'PyStaticMethod_Type');

+  PySuper_Type               := getProcAddr(lib, 'PySuper_Type');

+  PySymtableEntry_Type       := getProcAddr(lib, 'PySymtableEntry_Type');

+  PyTraceBack_Type           := getProcAddr(lib, 'PyTraceBack_Type');

+  PyWrapperDescr_Type        := getProcAddr(lib, 'PyWrapperDescr_Type');

+

+  PyBaseString_Type          := getProcAddr(lib, 'PyBaseString_Type');

+  PyBool_Type                := getProcAddr(lib, 'PyBool_Type');

+  PyEnum_Type                := getProcAddr(lib, 'PyEnum_Type');

+

+

+  //PyArg_GetObject           := getProcAddr(lib, 'PyArg_GetObject');

+  //PyArg_GetLong             := getProcAddr(lib, 'PyArg_GetLong');

+  //PyArg_GetShort            := getProcAddr(lib, 'PyArg_GetShort');

+  //PyArg_GetFloat            := getProcAddr(lib, 'PyArg_GetFloat');

+  //PyArg_GetString           := getProcAddr(lib, 'PyArg_GetString');

+  //PyArgs_VaParse            := getProcAddr(lib, 'PyArgs_VaParse');

+  //Py_VaBuildValue           := getProcAddr(lib, 'Py_VaBuildValue');

+  //PyBuiltin_Init            := getProcAddr(lib, 'PyBuiltin_Init');

+  PyComplex_FromCComplex    := getProcAddr(lib, 'PyComplex_FromCComplex');

+  PyComplex_FromDoubles     := getProcAddr(lib, 'PyComplex_FromDoubles');

+  PyComplex_RealAsDouble    := getProcAddr(lib, 'PyComplex_RealAsDouble');

+  PyComplex_ImagAsDouble    := getProcAddr(lib, 'PyComplex_ImagAsDouble');

+  PyComplex_AsCComplex      := getProcAddr(lib, 'PyComplex_AsCComplex');

+  PyCFunction_GetFunction   := getProcAddr(lib, 'PyCFunction_GetFunction');

+  PyCFunction_GetSelf       := getProcAddr(lib, 'PyCFunction_GetSelf');

+  PyCallable_Check          := getProcAddr(lib, 'PyCallable_Check');

+  PyCObject_FromVoidPtr     := getProcAddr(lib, 'PyCObject_FromVoidPtr');

+  PyCObject_AsVoidPtr       := getProcAddr(lib, 'PyCObject_AsVoidPtr');

+  PyClass_New               := getProcAddr(lib, 'PyClass_New');

+  PyClass_IsSubclass        := getProcAddr(lib, 'PyClass_IsSubclass');

+  PyDict_GetItem            := getProcAddr(lib, 'PyDict_GetItem');

+  PyDict_SetItem            := getProcAddr(lib, 'PyDict_SetItem');

+  PyDict_DelItem            := getProcAddr(lib, 'PyDict_DelItem');

+  PyDict_Clear              := getProcAddr(lib, 'PyDict_Clear');

+  PyDict_Next               := getProcAddr(lib, 'PyDict_Next');

+  PyDict_Keys               := getProcAddr(lib, 'PyDict_Keys');

+  PyDict_Values             := getProcAddr(lib, 'PyDict_Values');

+  PyDict_Items              := getProcAddr(lib, 'PyDict_Items');

+  PyDict_Size               := getProcAddr(lib, 'PyDict_Size');

+  PyDict_DelItemString      := getProcAddr(lib, 'PyDict_DelItemString');

+  PyDictProxy_New           := getProcAddr(lib, 'PyDictProxy_New');

+  Py_InitModule4            := getProcAddr(lib, 'Py_InitModule4');

+  PyErr_Print               := getProcAddr(lib, 'PyErr_Print');

+  PyErr_SetNone             := getProcAddr(lib, 'PyErr_SetNone');

+  PyErr_SetObject           := getProcAddr(lib, 'PyErr_SetObject');

+  PyErr_Restore             := getProcAddr(lib, 'PyErr_Restore');

+  PyErr_BadArgument         := getProcAddr(lib, 'PyErr_BadArgument');

+  PyErr_NoMemory            := getProcAddr(lib, 'PyErr_NoMemory');

+  PyErr_SetFromErrno        := getProcAddr(lib, 'PyErr_SetFromErrno');

+  PyErr_BadInternalCall     := getProcAddr(lib, 'PyErr_BadInternalCall');

+  PyErr_CheckSignals        := getProcAddr(lib, 'PyErr_CheckSignals');

+  PyErr_Occurred            := getProcAddr(lib, 'PyErr_Occurred');

+  PyErr_Clear               := getProcAddr(lib, 'PyErr_Clear');

+  PyErr_Fetch               := getProcAddr(lib, 'PyErr_Fetch');

+  PyErr_SetString           := getProcAddr(lib, 'PyErr_SetString');

+  PyEval_GetBuiltins        := getProcAddr(lib, 'PyEval_GetBuiltins');

+  PyImport_GetModuleDict    := getProcAddr(lib, 'PyImport_GetModuleDict');

+  PyInt_FromLong            := getProcAddr(lib, 'PyInt_FromLong');

+  PyArg_ParseTuple      := getProcAddr(lib, 'PyArg_ParseTuple');

+  PyArg_Parse           := getProcAddr(lib, 'PyArg_Parse');

+  Py_BuildValue         := getProcAddr(lib, 'Py_BuildValue');

+  Py_Initialize             := getProcAddr(lib, 'Py_Initialize');

+  PyDict_New                := getProcAddr(lib, 'PyDict_New');

+  PyDict_SetItemString      := getProcAddr(lib, 'PyDict_SetItemString');

+  PyModule_GetDict          := getProcAddr(lib, 'PyModule_GetDict');

+  PyObject_Str              := getProcAddr(lib, 'PyObject_Str');

+  PyRun_String              := getProcAddr(lib, 'PyRun_String');

+  PyRun_SimpleString        := getProcAddr(lib, 'PyRun_SimpleString');

+  PyDict_GetItemString      := getProcAddr(lib, 'PyDict_GetItemString');

+  PyString_AsString         := getProcAddr(lib, 'PyString_AsString');

+  PyString_FromString       := getProcAddr(lib, 'PyString_FromString');

+  PySys_SetArgv             := getProcAddr(lib, 'PySys_SetArgv');

+  Py_Exit                   := getProcAddr(lib, 'Py_Exit');

+

+  PyCFunction_New           :=getProcAddr(lib, 'PyCFunction_New');

+  PyEval_CallObject         :=getProcAddr(lib, 'PyEval_CallObject');

+  PyEval_CallObjectWithKeywords:=getProcAddr(lib, 'PyEval_CallObjectWithKeywords');

+  PyEval_GetFrame           :=getProcAddr(lib, 'PyEval_GetFrame');

+  PyEval_GetGlobals         :=getProcAddr(lib, 'PyEval_GetGlobals');

+  PyEval_GetLocals          :=getProcAddr(lib, 'PyEval_GetLocals');

+  //PyEval_GetOwner           :=getProcAddr(lib, 'PyEval_GetOwner');

+  PyEval_GetRestricted      :=getProcAddr(lib, 'PyEval_GetRestricted');

+  PyEval_InitThreads        :=getProcAddr(lib, 'PyEval_InitThreads');

+  PyEval_RestoreThread      :=getProcAddr(lib, 'PyEval_RestoreThread');

+  PyEval_SaveThread         :=getProcAddr(lib, 'PyEval_SaveThread');

+  PyFile_FromString         :=getProcAddr(lib, 'PyFile_FromString');

+  PyFile_GetLine            :=getProcAddr(lib, 'PyFile_GetLine');

+  PyFile_Name               :=getProcAddr(lib, 'PyFile_Name');

+  PyFile_SetBufSize         :=getProcAddr(lib, 'PyFile_SetBufSize');

+  PyFile_SoftSpace          :=getProcAddr(lib, 'PyFile_SoftSpace');

+  PyFile_WriteObject        :=getProcAddr(lib, 'PyFile_WriteObject');

+  PyFile_WriteString        :=getProcAddr(lib, 'PyFile_WriteString');

+  PyFloat_AsDouble          :=getProcAddr(lib, 'PyFloat_AsDouble');

+  PyFloat_FromDouble        :=getProcAddr(lib, 'PyFloat_FromDouble');

+  PyFunction_GetCode        :=getProcAddr(lib, 'PyFunction_GetCode');

+  PyFunction_GetGlobals     :=getProcAddr(lib, 'PyFunction_GetGlobals');

+  PyFunction_New            :=getProcAddr(lib, 'PyFunction_New');

+  PyImport_AddModule        :=getProcAddr(lib, 'PyImport_AddModule');

+  PyImport_Cleanup          :=getProcAddr(lib, 'PyImport_Cleanup');

+  PyImport_GetMagicNumber   :=getProcAddr(lib, 'PyImport_GetMagicNumber');

+  PyImport_ImportFrozenModule:=getProcAddr(lib, 'PyImport_ImportFrozenModule');

+  PyImport_ImportModule     :=getProcAddr(lib, 'PyImport_ImportModule');

+  PyImport_Import           :=getProcAddr(lib, 'PyImport_Import');

+  //@PyImport_Init             :=getProcAddr(lib, 'PyImport_Init');

+  PyImport_ReloadModule     :=getProcAddr(lib, 'PyImport_ReloadModule');

+  PyInstance_New            :=getProcAddr(lib, 'PyInstance_New');

+  PyInt_AsLong              :=getProcAddr(lib, 'PyInt_AsLong');

+  PyList_Append             :=getProcAddr(lib, 'PyList_Append');

+  PyList_AsTuple            :=getProcAddr(lib, 'PyList_AsTuple');

+  PyList_GetItem            :=getProcAddr(lib, 'PyList_GetItem');

+  PyList_GetSlice           :=getProcAddr(lib, 'PyList_GetSlice');

+  PyList_Insert             :=getProcAddr(lib, 'PyList_Insert');

+  PyList_New                :=getProcAddr(lib, 'PyList_New');

+  PyList_Reverse            :=getProcAddr(lib, 'PyList_Reverse');

+  PyList_SetItem            :=getProcAddr(lib, 'PyList_SetItem');

+  PyList_SetSlice           :=getProcAddr(lib, 'PyList_SetSlice');

+  PyList_Size               :=getProcAddr(lib, 'PyList_Size');

+  PyList_Sort               :=getProcAddr(lib, 'PyList_Sort');

+  PyLong_AsDouble           :=getProcAddr(lib, 'PyLong_AsDouble');

+  PyLong_AsLong             :=getProcAddr(lib, 'PyLong_AsLong');

+  PyLong_FromDouble         :=getProcAddr(lib, 'PyLong_FromDouble');

+  PyLong_FromLong           :=getProcAddr(lib, 'PyLong_FromLong');

+  PyLong_FromString         :=getProcAddr(lib, 'PyLong_FromString');

+  PyLong_FromString         :=getProcAddr(lib, 'PyLong_FromString');

+  PyLong_FromUnsignedLong   :=getProcAddr(lib, 'PyLong_FromUnsignedLong');

+  PyLong_AsUnsignedLong     :=getProcAddr(lib, 'PyLong_AsUnsignedLong');

+  PyLong_FromUnicode        :=getProcAddr(lib, 'PyLong_FromUnicode');

+  PyLong_FromLongLong       :=getProcAddr(lib, 'PyLong_FromLongLong');

+  PyLong_AsLongLong         :=getProcAddr(lib, 'PyLong_AsLongLong');

+

+  PyMapping_Check           :=getProcAddr(lib, 'PyMapping_Check');

+  PyMapping_GetItemString   :=getProcAddr(lib, 'PyMapping_GetItemString');

+  PyMapping_HasKey          :=getProcAddr(lib, 'PyMapping_HasKey');

+  PyMapping_HasKeyString    :=getProcAddr(lib, 'PyMapping_HasKeyString');

+  PyMapping_Length          :=getProcAddr(lib, 'PyMapping_Length');

+  PyMapping_SetItemString   :=getProcAddr(lib, 'PyMapping_SetItemString');

+  PyMethod_Class            :=getProcAddr(lib, 'PyMethod_Class');

+  PyMethod_Function         :=getProcAddr(lib, 'PyMethod_Function');

+  PyMethod_New              :=getProcAddr(lib, 'PyMethod_New');

+  PyMethod_Self             :=getProcAddr(lib, 'PyMethod_Self');

+  PyModule_GetName          :=getProcAddr(lib, 'PyModule_GetName');

+  PyModule_New              :=getProcAddr(lib, 'PyModule_New');

+  PyNumber_Absolute         :=getProcAddr(lib, 'PyNumber_Absolute');

+  PyNumber_Add              :=getProcAddr(lib, 'PyNumber_Add');

+  PyNumber_And              :=getProcAddr(lib, 'PyNumber_And');

+  PyNumber_Check            :=getProcAddr(lib, 'PyNumber_Check');

+  PyNumber_Coerce           :=getProcAddr(lib, 'PyNumber_Coerce');

+  PyNumber_Divide           :=getProcAddr(lib, 'PyNumber_Divide');

+

+  PyNumber_FloorDivide      :=getProcAddr(lib, 'PyNumber_FloorDivide');

+  PyNumber_TrueDivide       :=getProcAddr(lib, 'PyNumber_TrueDivide');

+  PyNumber_Divmod           :=getProcAddr(lib, 'PyNumber_Divmod');

+  PyNumber_Float            :=getProcAddr(lib, 'PyNumber_Float');

+  PyNumber_Int              :=getProcAddr(lib, 'PyNumber_Int');

+  PyNumber_Invert           :=getProcAddr(lib, 'PyNumber_Invert');

+  PyNumber_Long             :=getProcAddr(lib, 'PyNumber_Long');

+  PyNumber_Lshift           :=getProcAddr(lib, 'PyNumber_Lshift');

+  PyNumber_Multiply         :=getProcAddr(lib, 'PyNumber_Multiply');

+  PyNumber_Negative         :=getProcAddr(lib, 'PyNumber_Negative');

+  PyNumber_Or               :=getProcAddr(lib, 'PyNumber_Or');

+  PyNumber_Positive         :=getProcAddr(lib, 'PyNumber_Positive');

+  PyNumber_Power            :=getProcAddr(lib, 'PyNumber_Power');

+  PyNumber_Remainder        :=getProcAddr(lib, 'PyNumber_Remainder');

+  PyNumber_Rshift           :=getProcAddr(lib, 'PyNumber_Rshift');

+  PyNumber_Subtract         :=getProcAddr(lib, 'PyNumber_Subtract');

+  PyNumber_Xor              :=getProcAddr(lib, 'PyNumber_Xor');

+  PyOS_InitInterrupts       :=getProcAddr(lib, 'PyOS_InitInterrupts');

+  PyOS_InterruptOccurred    :=getProcAddr(lib, 'PyOS_InterruptOccurred');

+  PyObject_CallObject       :=getProcAddr(lib, 'PyObject_CallObject');

+  PyObject_Compare          :=getProcAddr(lib, 'PyObject_Compare');

+  PyObject_GetAttr          :=getProcAddr(lib, 'PyObject_GetAttr');

+  PyObject_GetAttrString    :=getProcAddr(lib, 'PyObject_GetAttrString');

+  PyObject_GetItem          :=getProcAddr(lib, 'PyObject_GetItem');

+  PyObject_DelItem          :=getProcAddr(lib, 'PyObject_DelItem');

+  PyObject_HasAttrString    :=getProcAddr(lib, 'PyObject_HasAttrString');

+  PyObject_Hash             :=getProcAddr(lib, 'PyObject_Hash');

+  PyObject_IsTrue           :=getProcAddr(lib, 'PyObject_IsTrue');

+  PyObject_Length           :=getProcAddr(lib, 'PyObject_Length');

+  PyObject_Repr             :=getProcAddr(lib, 'PyObject_Repr');

+  PyObject_SetAttr          :=getProcAddr(lib, 'PyObject_SetAttr');

+  PyObject_SetAttrString    :=getProcAddr(lib, 'PyObject_SetAttrString');

+  PyObject_SetItem          :=getProcAddr(lib, 'PyObject_SetItem');

+

+  PyObject_Init             :=getProcAddr(lib, 'PyObject_Init');

+  PyObject_InitVar          :=getProcAddr(lib, 'PyObject_InitVar');

+  PyObject_New              :=getProcAddr(lib, '_PyObject_New');

+  PyObject_NewVar           :=getProcAddr(lib, '_PyObject_NewVar');

+  PyObject_Free             :=getProcAddr(lib, 'PyObject_Free');

+

+  PyObject_IsInstance       :=getProcAddr(lib, 'PyObject_IsInstance');

+  PyObject_IsSubclass       :=getProcAddr(lib, 'PyObject_IsSubclass');

+

+  PyObject_GenericGetAttr   :=getProcAddr(lib, 'PyObject_GenericGetAttr');

+  PyObject_GenericSetAttr   :=getProcAddr(lib, 'PyObject_GenericSetAttr');

+

+  PyObject_GC_Malloc         :=getProcAddr(lib, '_PyObject_GC_Malloc');

+  PyObject_GC_New            :=getProcAddr(lib, '_PyObject_GC_New');

+  PyObject_GC_NewVar         :=getProcAddr(lib, '_PyObject_GC_NewVar');

+  PyObject_GC_Resize         :=getProcAddr(lib, '_PyObject_GC_Resize');

+  PyObject_GC_Del            :=getProcAddr(lib, 'PyObject_GC_Del');

+  PyObject_GC_Track          :=getProcAddr(lib, 'PyObject_GC_Track');

+  PyObject_GC_UnTrack        :=getProcAddr(lib, 'PyObject_GC_UnTrack');

+

+  PyRange_New               :=getProcAddr(lib, 'PyRange_New');

+  PySequence_Check          :=getProcAddr(lib, 'PySequence_Check');

+  PySequence_Concat         :=getProcAddr(lib, 'PySequence_Concat');

+  PySequence_Count          :=getProcAddr(lib, 'PySequence_Count');

+  PySequence_GetItem        :=getProcAddr(lib, 'PySequence_GetItem');

+  PySequence_GetSlice       :=getProcAddr(lib, 'PySequence_GetSlice');

+  PySequence_In             :=getProcAddr(lib, 'PySequence_In');

+  PySequence_Index          :=getProcAddr(lib, 'PySequence_Index');

+  PySequence_Length         :=getProcAddr(lib, 'PySequence_Length');

+  PySequence_Repeat         :=getProcAddr(lib, 'PySequence_Repeat');

+  PySequence_SetItem        :=getProcAddr(lib, 'PySequence_SetItem');

+  PySequence_SetSlice       :=getProcAddr(lib, 'PySequence_SetSlice');

+  PySequence_DelSlice       :=getProcAddr(lib, 'PySequence_DelSlice');

+  PySequence_Tuple          :=getProcAddr(lib, 'PySequence_Tuple');

+  PySequence_Contains       :=getProcAddr(lib, 'PySequence_Contains');

+  PySlice_GetIndices        :=getProcAddr(lib, 'PySlice_GetIndices');

+  PySlice_GetIndicesEx      :=getProcAddr(lib, 'PySlice_GetIndicesEx');

+  PySlice_New               :=getProcAddr(lib, 'PySlice_New');

+  PyString_Concat           :=getProcAddr(lib, 'PyString_Concat');

+  PyString_ConcatAndDel     :=getProcAddr(lib, 'PyString_ConcatAndDel');

+  PyString_Format           :=getProcAddr(lib, 'PyString_Format');

+  PyString_FromStringAndSize:=getProcAddr(lib, 'PyString_FromStringAndSize');

+  PyString_Size             :=getProcAddr(lib, 'PyString_Size');

+  PyString_DecodeEscape     :=getProcAddr(lib, 'PyString_DecodeEscape');

+  PyString_Repr             :=getProcAddr(lib, 'PyString_Repr');

+  PySys_GetObject           :=getProcAddr(lib, 'PySys_GetObject');

+  //PySys_Init                :=getProcAddr(lib, 'PySys_Init');

+  PySys_SetObject           :=getProcAddr(lib, 'PySys_SetObject');

+  PySys_SetPath             :=getProcAddr(lib, 'PySys_SetPath');

+  //PyTraceBack_Fetch         :=getProcAddr(lib, 'PyTraceBack_Fetch');

+  PyTraceBack_Here          :=getProcAddr(lib, 'PyTraceBack_Here');

+  PyTraceBack_Print         :=getProcAddr(lib, 'PyTraceBack_Print');

+  //PyTraceBack_Store         :=getProcAddr(lib, 'PyTraceBack_Store');

+  PyTuple_GetItem           :=getProcAddr(lib, 'PyTuple_GetItem');

+  PyTuple_GetSlice          :=getProcAddr(lib, 'PyTuple_GetSlice');

+  PyTuple_New               :=getProcAddr(lib, 'PyTuple_New');

+  PyTuple_SetItem           :=getProcAddr(lib, 'PyTuple_SetItem');

+  PyTuple_Size              :=getProcAddr(lib, 'PyTuple_Size');

+

+  PyType_IsSubtype          :=getProcAddr(lib, 'PyType_IsSubtype');

+  PyType_GenericAlloc       :=getProcAddr(lib, 'PyType_GenericAlloc');

+  PyType_GenericNew         :=getProcAddr(lib, 'PyType_GenericNew');

+  PyType_Ready              :=getProcAddr(lib, 'PyType_Ready');

+

+  PyUnicode_FromWideChar    :=getProcAddr(lib, 'PyUnicodeUCS2_FromWideChar');

+  PyUnicode_AsWideChar      :=getProcAddr(lib, 'PyUnicodeUCS2_AsWideChar');

+  PyUnicode_FromOrdinal     :=getProcAddr(lib, 'PyUnicodeUCS2_FromOrdinal');

+

+  PyWeakref_GetObject       :=getProcAddr(lib, 'PyWeakref_GetObject');

+  PyWeakref_NewProxy        :=getProcAddr(lib, 'PyWeakref_NewProxy');

+  PyWeakref_NewRef          :=getProcAddr(lib, 'PyWeakref_NewRef');

+  PyWrapper_New             :=getProcAddr(lib, 'PyWrapper_New');

+

+  PyBool_FromLong           :=getProcAddr(lib, 'PyBool_FromLong'); 

+

+  Py_AtExit                 :=getProcAddr(lib, 'Py_AtExit');

+  //Py_Cleanup                :=getProcAddr(lib, 'Py_Cleanup');

+  Py_CompileString          :=getProcAddr(lib, 'Py_CompileString');

+  Py_FatalError             :=getProcAddr(lib, 'Py_FatalError');

+  Py_FindMethod             :=getProcAddr(lib, 'Py_FindMethod');

+  Py_FindMethodInChain      :=getProcAddr(lib, 'Py_FindMethodInChain');

+  Py_FlushLine              :=getProcAddr(lib, 'Py_FlushLine');

+  Py_Finalize                :=getProcAddr(lib, 'Py_Finalize');

+  PyCode_Addr2Line     := getProcAddr(lib, 'PyCode_Addr2Line');

+  PyClass_IsSubclass         :=getProcAddr(lib, 'PyClass_IsSubclass');

+  PyErr_ExceptionMatches     :=getProcAddr(lib, 'PyErr_ExceptionMatches');

+  PyErr_GivenExceptionMatches:=getProcAddr(lib, 'PyErr_GivenExceptionMatches');

+  PyEval_EvalCode            :=getProcAddr(lib, 'PyEval_EvalCode');

+  Py_GetVersion              :=getProcAddr(lib, 'Py_GetVersion');

+  Py_GetCopyright            :=getProcAddr(lib, 'Py_GetCopyright');

+  Py_GetExecPrefix           :=getProcAddr(lib, 'Py_GetExecPrefix');

+  Py_GetPath                 :=getProcAddr(lib, 'Py_GetPath');

+  Py_GetPrefix               :=getProcAddr(lib, 'Py_GetPrefix');

+  Py_GetProgramName          :=getProcAddr(lib, 'Py_GetProgramName');

+  PyParser_SimpleParseString :=getProcAddr(lib, 'PyParser_SimpleParseString');

+  PyNode_Free                :=getProcAddr(lib, 'PyNode_Free');

+  PyErr_NewException         :=getProcAddr(lib, 'PyErr_NewException');

+/// jah 29-sep-2000 : updated for python 2.0

+///                   replaced Py_Malloc with PyMem_Malloc

+///---   @Py_Malloc := Import ('Py_Malloc');

+///+++   @Py_Malloc := Import ('PyMem_Malloc');

+  Py_Malloc := getProcAddr(lib, 'PyMem_Malloc');

+  PyMem_Malloc := getProcAddr(lib, 'PyMem_Malloc');

+  PyObject_CallMethod        := getProcAddr(lib, 'PyObject_CallMethod');

+  Py_SetProgramName        := getProcAddr(lib, 'Py_SetProgramName');

+  Py_IsInitialized         := getProcAddr(lib, 'Py_IsInitialized');

+  Py_GetProgramFullPath    := getProcAddr(lib, 'Py_GetProgramFullPath');

+  DLL_Py_GetBuildInfo    := getProcAddr(lib, 'Py_GetBuildInfo');

+  Py_NewInterpreter        := getProcAddr(lib, 'Py_NewInterpreter');

+  Py_EndInterpreter        := getProcAddr(lib, 'Py_EndInterpreter');

+  PyEval_AcquireLock       := getProcAddr(lib, 'PyEval_AcquireLock');

+  PyEval_ReleaseLock       := getProcAddr(lib, 'PyEval_ReleaseLock');

+  PyEval_AcquireThread     := getProcAddr(lib, 'PyEval_AcquireThread');

+  PyEval_ReleaseThread     := getProcAddr(lib, 'PyEval_ReleaseThread');

+  PyInterpreterState_New   := getProcAddr(lib, 'PyInterpreterState_New');

+  PyInterpreterState_Clear := getProcAddr(lib, 'PyInterpreterState_Clear');

+  PyInterpreterState_Delete:= getProcAddr(lib, 'PyInterpreterState_Delete');

+  PyThreadState_New        := getProcAddr(lib, 'PyThreadState_New');

+  PyThreadState_Clear      := getProcAddr(lib, 'PyThreadState_Clear');

+  PyThreadState_Delete     := getProcAddr(lib, 'PyThreadState_Delete');

+  PyThreadState_Get        := getProcAddr(lib, 'PyThreadState_Get');

+  PyThreadState_Swap       := getProcAddr(lib, 'PyThreadState_Swap');

+end;

+

+var

+  lib: TLibHandle;

+initialization

+  lib := loadLibrary(dllName);

+  if lib <> NilLibHandle then init(lib);

+end.