Make a copy


git-svn-id: https://svn.apache.org/repos/asf/commons/proper/net/tags/NET_2_1_RC1@796056 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/KEYS b/KEYS
new file mode 100644
index 0000000..1f1e015
--- /dev/null
+++ b/KEYS
@@ -0,0 +1,181 @@
+This file contains the PGP keys of various developers.
+Please don't use them for email unless you have to. Their main
+purpose is code signing.
+
+Users: pgp < KEYS
+       gpg --import KEYS
+Developers: 
+        pgp -kxa <your name> and append it to this file.
+        (pgpk -ll <your name> && pgpk -xa <your name>) >> this file.
+        (gpg --list-sigs <your name>
+             && gpg --armor --export <your name>) >> this file.
+
+pub  1024D/B1313DE2 2003-01-15 Robert Burrell Donkin (CODE SIGNING KEY) <rdonkin@apache.org>
+sig 3       B1313DE2 2003-01-15   Robert Burrell Donkin (CODE SIGNING KEY) <rdonkin@apache.org>
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.0.7 (GNU/Linux)
+
+mQGiBD4lztcRBAClmlgorzoHH7IVYYerQY0e7QU0X3+4PRGGZVcbkZA3qMZV8rG3
+FSB4qp3cLX7rnco26oQbP4jSqXe1piEzYloyzYvgW9t0uFOFF7N8h9XtgA3E836v
+DE/dbrteJ6wZZvS0BR1J0u2/+3nSf4bdmzjd8JPMCIp4q4ztTMTNsWKUswCg3vRA
+NpL1bO0lTi5M013YhY+8wHcD/0Swc47PQuruwL+54ZMFFEHu+24UukU/7T6X2hos
+ERgq9HkUyqK5mOEqp4Y4AfhwPfzp/qOFbg+Jn0IIVg3XGZhTLyeBiwHpXBhJw2TT
+FXhLxm9G2PoYgkhMSgOo4wrHLCMszfvOABzCEZ4TAw3k4s3X4PSfNjHjOHUNYWhb
+1BNLA/wIVDCdOyHoUvw6R0rCTKFcHSXu7XQxjYIBKGAQkcNlCZElqNVlqa+eQTPW
+3AHXor/TUDzzd4afjkvmWaayGDZwOSWlsfqfPItvzTNzmE44wqfICa0/aMgkU6aZ
+m/k+UMFegH1YVBaAl0aj8Gx+T5B7JqA9i7+lmw3nwB1Ge0miBbQ9Um9iZXJ0IEJ1
+cnJlbGwgRG9ua2luIChDT0RFIFNJR05JTkcgS0VZKSA8cmRvbmtpbkBhcGFjaGUu
+b3JnPohZBBMRAgAZBQI+Jc7XBAsHAwIDFQIDAxYCAQIeAQIXgAAKCRDVM051sTE9
+4qflAJ9B2L8SOnFRnoJktHImJU9JO72IdwCgpM08Fi8O0dI5WuOFdz5sLobqioY=
+=nk3Z
+-----END PGP PUBLIC KEY BLOCK-----
+pub  1024D/57452E64 2001-09-20 Jeffrey D. Brekke <brekke@apache.org>
+sig 3       57452E64 2003-10-23   Jeffrey D. Brekke <brekke@apache.org>
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.2.3 (GNU/Linux)
+
+mQGiBDupN50RBADJVVB7IvDqVXArvsxWt0BBOC74Qn91G3w5/kEzuv6cjv4Wc4Ll
+s2o229+FxjASQ8G3k1RXLdkn/sGaU7A/D0YD0AJgE7Xz4pe6qusu/ABjUsmWCOBc
+6pzZ22xSF5NjYsPEKvWbc/oZFAepa/juAufjK6Ubhdsdaje/o42mALZoKwCg5xwF
+HW+yyf5Ws6Nr36OI2DxmlA0EAKdQM4c71KJlqtF9Ck2NcchJ/xr7DBg+leBhoHFP
+j3tFijdXJz96glptZak0ssupZ8v24y3QhqLzkkwfYsOeS3+y+AEpa2LvyeECu/KJ
+rtfvX8PiViN1A+6D8D43S+UlKK10NgF60eo0AcxP/XVei5Obz54HvM45wW4CYeIJ
+ZcgCA/46e5LivzuoFyMTqP+5o4CwC402uhR7Wba1VQVSki5IP+vl5vatUC/iIfVo
+CMtiHSEZ1mo6eThgd9on+Ju62Q4PNYEYkyLpJfew1VzdoJUCrho96iiJPy6NVZo9
+tUXhdOfSrUiqOT9i8+zjLiRsGV3fd3eSxtuKJX4dxzpCaXuzBLQlSmVmZnJleSBE
+LiBCcmVra2UgPGJyZWtrZUBhcGFjaGUub3JnPohdBBMRAgAdBQsHCgMEAxUDAgMW
+AgECF4AFAj+XPmgFCQty1MsACgkQ7ub3MVdFLmRTfwCdHBz+mooBeV57oj2g3JY4
+Q2Jd0uAAn1u1J/GbkPbQJ6i/gBozQPm6iamnuQENBDupN7cQBACzGaBHk7LAPmCV
+iNZRunUVqaLvykJ7BS5R6s8fJ/m3//rB/ooirXsEDnm++FjiSXKpeYRk9yawi2/U
+BmCVK9xX2zDV08fB/3FDoCLQ3o6zcJTOLaY8SsCDbr4SUauycGEoue5Umy9sOxOa
+1cT4TtPNHZ3eWnzDB3+9iZ5TCucb8wADBQP+MZ4ZYtwNxiytYS3jHcjlvGTARhvP
+nTNqtcq9OZPLsGorQ5WlJVnwaOXUk13f8SxasuLPorbORIME9I38FuF+xavO2sMk
+fVxGgXE78gDCUAyqyvvnb2lWvlDwBVLdq2+UiumLFSNhAWu6fFef+dF9xDpNQhDK
+KF2mlhdfLc/osseITAQYEQIADAUCO6k3twUJAsfqAAAKCRDu5vcxV0UuZJZlAJ9w
+ety/S7kFtg13ekvoPBiL+/nwNACgyWxd+g+B6Jhxm2KTardZb5nKa3w=
+=cOP8
+-----END PGP PUBLIC KEY BLOCK-----
+pub  1024D/47717B4B 2004-05-01 Steven M. Cohen (no comment needed) <scohen@javactivity.org>
+sig 3       47717B4B 2004-05-01   Steven M. Cohen (no comment needed) <scohen@javactivity.org>
+sub  1024g/32E08DCC 2004-05-01
+sig         47717B4B 2004-05-01   Steven M. Cohen (no comment needed) <scohen@javactivity.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.2.1 (GNU/Linux)
+
+mQGiBECS+kARBADIjMbaWVyh1AkcoipkjVTW4X8jp2RJrh3NDNhq5GE5xV+j0+Rb
+HCiZRoSbzZ8XAdIfF6y3Z0DjDee69KuGxmrpMbwooB+XsKVYMMOxO8YDgKxjxeWl
+65boEOeeGjCQNzniQirY4qy/V0+2hUjjmJOA8o7BxZwblZsLvFZPNyMwxwCg7ifb
+5otvBRZbmDyb4ecQ3SfSlFcD/R32IH2Z5xIn72inCSM2iNHkujgL0oV23vsBUZ/O
+GjPmRSc1YgtXp9oeOcFXbGFppot6C9GvE3LQbvEqQPDGbfG+Us9Qs7pxxVGIczlS
+fHM+iCOuQE8IouwdoNmIsSygKpQHB982WGVwmy6AgTaMYAHvHP/CjjXczJv+MT4w
+nGr1A/9qE1aampCiWLPvUg4TM5oKa+XvADGyMdE/9rVs6Rz6jAJSp1OlDRRaAC4X
+WafaSqhs5cx1ReFAelbQvuZjw/XBAC0u2UM9uMy9Wa11faGfrTc+UTudx8IHO74u
+oQiYWa3atbBPLdzHTL7Kyu0GsfkwQhRFSxR6KPhFKm0yokgk8bQ8U3RldmVuIE0u
+IENvaGVuIChubyBjb21tZW50IG5lZWRlZCkgPHNjb2hlbkBqYXZhY3Rpdml0eS5v
+cmc+iFkEExECABkFAkCS+kAECwcDAgMVAgMDFgIBAh4BAheAAAoJEIadKLpHcXtL
+aOkAoN6wav5+gv3WnnZRnVYhxUJDdt64AKCzhTBFuhCxWUgYtYlXBm90f2yP37kB
+DQRAkvpDEAQA4N2GYczt1u0OKaVh7ScNPcNfDs+g4Eh9/62TU2NIwsLunMVxxcLS
+y5rHWOnlgv8CrBiVtrLUQ+6pg+g7OOj6CLjf/CkWSyDdbNgeuGrnYg/tx1Dhj9sw
+TgxYbXkxbjuN3SGdSaHtdOaXGxQP18RS5P3i0h4fULpEOyr01yQQ3lsAAwUEAJDK
+JzxWAqn4JOmajQ40NFwJF9h3MBZhnxB7ir5yV0FhqRnRsX60C5f2HcNWNH47u8kZ
+9W7RMqQYujBvYAAc7S1bn3gmLGDljZ1IPKuVOmzoUqlWBlJiy3O/XQYzKRimjXi/
+0dl97eHETQpv8cvXPu6snp5I59LST5JxIOOiROvdiEYEGBECAAYFAkCS+kMACgkQ
+hp0oukdxe0sppQCeJS+rSgLhHerHQmHzTQs2SOwlwoAAoLqkD1+EHjZYrpARXbR7
+hActYzM/
+=e4Xf
+-----END PGP PUBLIC KEY BLOCK-----
+pub  1024R/CDA88D2A 2004-11-24 Rory Winston (Apache signature) <rwinston@eircom.net>
+
+pub  1024D/E47D74BF 2004-11-24 Rory Winston (Apache signature) <rwinston@eircom.net>
+sub  2048g/811235D3 2004-11-24
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.2.4 (Cygwin)
+
+mIwEQaPPBwEEANUNKaJn+P87321Mipc5Q7k7P2wfL3ZCRQdj1Q8BdModjaWM4HkP
+w4CM32RXUqdRuL7qK12QGZ90zgGIicJJ5LRkrYnx+7r5D8RaUMrLTLUdZKdipfia
+ZvBSyh9g6hcHu8AJCkunH0G+qfPoIqU4b5M37+f867mVHJiznPkZzG2JAAkBAbQ1
+Um9yeSBXaW5zdG9uIChBcGFjaGUgc2lnbmF0dXJlKSA8cndpbnN0b25AZWlyY29t
+Lm5ldD6ItAQTAQIAHgUCQaPPBwIbAwYLCQgHAwIDFQIDAxYCAQIeAQIXgAAKCRBM
+wB0tzaiNKrdQA/4xKGJqDR3G3oIbus/0kSmw3zbv1G9PkVwz3sba9CqLEqWNL1Ro
+pLo21rt4Nn2T5+aGHizcqVUm/e5O7o8D7qSy1H0boRrvOIP//9ytlAlqvwylvt9N
+T/9i9vCi/VR1Im8tVYL8U2JgYj/FeJUGZLXZpFJw3PuhAKZokL30V4IZ4ZkBogRB
+o9CLEQQAys7mqztIy7VpJoSmR60VZY0eE69dnFbIj7EU2+JthaAhojjBZqFdXFmH
+3TEHK0v0cI3V39nJOqKNH0e0rcN2RqssUjUu4bDP67peqxC0VqvcktGqJYh8Rhtr
+giUtvgP3L9ZEb8l5+UiTxe9YVBytPopVvnZplWHGrtDPl1pPC5MAoI/M9HjxaA1Y
+U1wI3VVETidBtrchBACI/4R2BleGTPG6mDAvwoB7Sk24wG525wRmWnE5BwND+5L4
+KceFd5X5O/jqWz66xSNFFJKGTgo6f+M8QgYTnVqMcS1CRIEcsmA3S1Zg4bCfTnG8
+ljb683QaN7RxuSurtAwX8HE8pFG0bWQwhfm7AgpHe3wxBRbvlnWwvb90nSkkPAQA
+rrI9U8zBIYBdX3NX1oBTgOVxsV9qpk4Pw0/1VhdaxAt5z9GjioSsHU6DZILqNyzb
+efOsxuGw/Tdsodurgjw9EZHDfr4Dit5S7uBx/3hx+/jUTbsfpMquUS1GlkaBiXjf
+RXlUGCs4qvJrU7gLRsWk9PIbZvR5xFNm/s5QFUH8D6a0NVJvcnkgV2luc3RvbiAo
+QXBhY2hlIHNpZ25hdHVyZSkgPHJ3aW5zdG9uQGVpcmNvbS5uZXQ+iF4EExECAB4F
+AkGj0IsCGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQ1xaoLOR9dL8RlwCfYvkz
+36uJX4XUOFTdPd72AhdiEJUAn39OraPOHSlfJgdG67VT+ekbZbAiuQINBEGj0JcQ
+CADRexlw+MXkkF4RMIMapVSdoZxoILynC3Gd9ofdbRLHnd7PDqHc1mGM47+e1Lbj
+PWqjNQarMDZwbsGl8DGd65VpV0CeX5uPRmUJQxsHiKd1b8Hrbi6j71zjH5D4fM6m
+TBc5X9M0BCZn5fViiyydCxC99A2s3GKZWzptRoqqb3CwefP1w7eGTSYrmWi5LDLZ
+oLwxrnVmE5hdsJkmpab9QGVxoNlFZMXrDmBezJzHkB2mZzyrGRYayhsblqOyL3QB
+jIonviKANVnt3QNxfSbk9ssJj41ucWQz8ZSPXU6+5q37UdLjTAxoBafj0Ft73xCy
+eAgHZZdsRVlGLBbGE1IjV/BXAAMFCAC1XbgPqMCsPnZqZuu1YRfU5acqjEMTLNuQ
+1MrSLQ15kD7DNrDFMcueQUnoeZAvehsd4db23ueiYcFZI1YxU/WSDsEEaQrPCDVT
+ynQPkakkHMPKVTbkdIY8QorZ8hkFGWJ/zCHe5Y4eESijEib5iB0gaSSRFnPCyt5p
+7Daie9b6ZpUsCJtwOEIFOODJzThUBb6b4KNQazrlmvwG2P/SCDu3LF0HPGvPjrW4
+zD4ovUMUWArx3EvSxHyEekGjxlBISJ7k0spgzM1lEthF7FmiAZy7/K+96n8+6ylo
+wqW3M40rVY9zhrbvH0DY5PAq+OHTQ737Ne33C7u+PpDFMnM0uJZaiEkEGBECAAkF
+AkGj0JcCGwwACgkQ1xaoLOR9dL+otACeO+aD1eQ5UpvwXMk+w7yqrApI4NQAnjE+
+cVG3koNNWLuu03PLMojho4Bc
+=AOQa
+-----END PGP PUBLIC KEY BLOCK-----
+pub   1024D/B6E5C0E2 2005-08-09
+uid                  Rory Winston <rory@researchkitchen.co.uk>
+sig 3        B6E5C0E2 2005-08-09  Rory Winston <rory@researchkitchen.co.uk>
+sub   2048g/B770B4CC 2005-08-09
+sig          B6E5C0E2 2005-08-09  Rory Winston <rory@researchkitchen.co.uk>
+
+pub   1024D/11F3482A 2008-09-16 [expires: 2010-09-16]
+uid                  Rory Winston <rwinston@apache.org>
+sig 3        11F3482A 2008-09-16  Rory Winston <rwinston@apache.org>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.9 (MingW32)
+
+mQGiBEL5K9URBAC+Bczacc/jM0UzLwO0WcRJQiicJbC5U8XVcNhBoaZ5UrikGzak
+o9nNGmEA4OvDVzbDsvW5GlEMCtmr/F+BoV+6nMOFPH+dy9gT+Pybh0SzxgCHZBEA
+SBxgF5GhHNNNF7MHWCBoMa5DOax1KVDX8AOyo5RycIkoclH8mPdIwkfEawCg2Bld
+Pu1+OvWfC9NNQFP3UhvfJmcEAJpOPqBCgJWuErIWsSXIcyctRdeGq6/Z7QibHvrK
+aCXDIE2GtdD8ruerrYs5SV63YH5qmFBsbm4MuyCrCpP2MFoPUZIiCZghJ+/U8/cL
+JO1s8dNRnsg4k5zrnE9LmRqPX6Kn5gWdQ0jqFPBdXeWQS64scFmTJxY7AWBWBnyi
+aFufA/9fCQYmgdng7a6ttv0ColYTMxPySj1Vg9TURu4epFCKXf3STNSVKGgVicz7
++etAw/yKxADAfDWCCrtpSgB3gkJeBvO13fAFnuB7NabvawMG+wxlWhq7qMChaxz8
+zF5nbwrFxDcsnRsSK7gBGwUWCanl7LUZLfIGdDR/deG84rI9vrQpUm9yeSBXaW5z
+dG9uIDxyb3J5QHJlc2VhcmNoa2l0Y2hlbi5jby51az6IYAQTEQIAIAUCQvkr1QIb
+AwYLCQgHAwIEFQIIAwQWAgMBAh4BAheAAAoJEKXalD625cDiNQYAnA0Sp6/T7iXZ
+1VEzUAsHPkG7UwD1AJ4uAF6haDtAquwgZztyyBhAInyBXrkCDQRC+SvsEAgA68Tv
+xvg4a1cCTT93uK3d8LS/m4oVoxa9lDoBbQyNWpZmzMCtXdFS0mWbpkr0NlBi83hN
+iaIvzC6EfdzKKtjhzjHQNpOVRfJZvmumdwwfHw6An8Ur/2kH9JKofVs0JOEXwdZl
+FKQeTb9hM6/ei9gJvDo6+pNIWpP+wcVq/QRl35c6BRbk7GeXE/193Cayd115VFbJ
+Vu4IQA/RioyVJLApaU/unkChbiTOrxYv2Ek7Wy3/3aZCq8Ryf37vkJ8xmPMqbYDF
+/v6rEgp6jimxL2cs7JpsenSR2eMXpqPCqVlhQdTxkQihPiKzscf0/4A35thkPtUk
+meD338X7pFOLlG4UFwADBQf+Nz6b0ZQE1LzMzk4J4qYELSnJWTzPra6Nd1rJZV5E
+9rmIF+OCZ9P/bUviJmtqjQXr0I1MCwDrf7safGAyoLG3HBSni3LlIoBzzLQar04h
+wQzyTjTv8/RbdDp47fr9+4dtpwnIXPS1jFvo0IQt0uXshMwYyUT4vhl2nImH5ofZ
+dgxAbPlgXvTjTabex4RRPthnaz101ZOH79yp9rPi0pexJNrjAgW0GJexK7jKuEQ9
+wn8ag2XFkCVm2oFOqy0RpohOWJFyFJ++4yw3cbD4OPNW4hFFt6FWolWexTKihpA5
+VTycPoRQYVpbjMyfwl35BATOR+ZdUZiqMHssTCkiaYrrQohJBBgRAgAJBQJC+Svs
+AhsMAAoJEKXalD625cDi07QAn1Ol3VDfqnBFytgH9PLxVrLndeTIAJ9/RYF/rHIT
+gH0X8JsNCUPFgBWqhJkBogRI0ER3EQQAj3dAu/mO20RBpB2xBD9E0RKdMXpmHp9v
+/4AchsGCK1J6SUjBFykDB6Fnu9Z6LwbIzMMYqLNcoWeANe9bsX6RD2jDY2lSEYfh
+vXqIpZlon+70/RXi8FLYEF92ADUMjsJKRC/bpODtby/Kk1c6jkeuStrbImMMNuio
+vFkhRwCQ1nsAoMwmbKhg2HS4UgN9xwDdexFCOTOdA/4hId/38kzm7ZVfc8EzhUFG
+rN2cR/ZW/Bl73hKWKsHVfkJKltbHzXwX++P/hMUJczbpQiYqf5vSU+6Xxu0ascUF
+6gRSGMQX7E7PuxEGR4Q4Fn2rsyXFezDfueUKXRjizmmc1j5ZQoXi7WHP1e0j/wdk
+Z5XFxKzT0CALbwxSzFy5LAP/X5jKBcm3dazE6YOBKKI7AHFLivJao/SyTRGIN5DY
+/8ZD6ws83qDp3EZCQfwpuaO6N8XAiVcgt+RtWK32eQZgKF+xM5K/isI5UDIgb+zB
+HhI9JS0Y8e7gkF4RhB5+T2UycpKjppRobnvPsrCWcXmBlTWQxo/hn1WQrcXCUGDA
+tjm0IlJvcnkgV2luc3RvbiA8cndpbnN0b25AYXBhY2hlLm9yZz6IZgQTEQIAJgUC
+SNBEdwIbAwUJA8JnAAYLCQgHAwIEFQIIAwQWAgMBAh4BAheAAAoJEOtDGcER80gq
+1pQAoLjky8FNQupEEXzyen4EWM4PG468AJsHPn4heUoYhhHRuiruBG1XPMmNZA==
+=2/VL
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/NOTICE.txt b/NOTICE.txt
index 585c4ca..f006f2d 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -3,3 +3,4 @@
 
 This product includes software developed by
 The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/README b/README
index 0423573..53896ce 100644
--- a/README
+++ b/README
@@ -1,16 +1,13 @@
 
 o Building
 
-To build, you must have ant and/or maven installed.  Just type 'ant' -- the default
-target will compile the classes, run the tests and build the jar
+To build, you must have Maven 2 installed. Maven can be downloaded from 
 
-Maven can be downloaded from the main site and there is good documentation
-on the targets for building and installation instructions:
+http://maven.apache.org/.
 
-http://jakarta.apache.org/turbine/maven
 
 o Documentation
 
 You can build the documentation with:
 
-maven site
+mvn site
diff --git a/build.xml b/build.xml
deleted file mode 100644
index 95ad64c..0000000
--- a/build.xml
+++ /dev/null
@@ -1,182 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--build.xml generated by maven from project.xml version 1.3.0-dev
-  on date September 8 2004, time 2216-->
-
-<project default="jar" name="commons-net" basedir=".">
-
-  <available property="jre.dom.available" classname="java.lang.CharSequence" />
-
-  <fileset id="xmlLibs" dir="${ant.home}/lib">
-    <include name="xml-apis.jar" unless="jre.dom.available" />
-    <include name="xercesImpl.jar" unless="jre.dom.available" />
-  </fileset>
-
-  <property name="defaulttargetdir" value="target">
-  </property>
-  <property name="libdir" value="target/lib">
-  </property>
-  <property name="classesdir" value="target/classes">
-  </property>
-  <property name="testclassesdir" value="target/test-classes">
-  </property>
-  <property name="testclassesdir" value="target/test-classes">
-  </property>
-  <property name="testreportdir" value="target/test-reports">
-  </property>
-  <property name="distdir" value="dist">
-  </property>
-  <property name="javadocdir" value="dist/docs/api">
-  </property>
-  <property name="final.name" value="commons-net-1.5.0">
-  </property>
-  <path id="build.classpath">
-    <fileset dir="${libdir}">
-      <include name="**/*.jar">
-      </include>
-    </fileset>
-  </path>
-  <target name="init" description="o Initializes some properties">
-    <mkdir dir="${libdir}">
-    </mkdir>
-    <condition property="noget">
-      <equals arg2="only" arg1="${build.sysclasspath}">
-      </equals>
-    </condition>
-    <!--Test if JUNIT is present in ANT classpath-->
-
-    <available property="Junit.present" classname="junit.framework.Test">
-    </available>
-  </target>
-  <target name="compile" description="o Compile the code" depends="get-deps">
-    <mkdir dir="${classesdir}">
-    </mkdir>
-    <javac destdir="${classesdir}" deprecation="true" debug="true" optimize="false" excludes="**/package.html">
-      <src>
-        <pathelement location="src/java">
-        </pathelement>
-      </src>
-      <classpath refid="build.classpath">
-      </classpath>
-    </javac>
-    <mkdir dir="${classesdir}/META-INF">
-    </mkdir>
-    <copy todir="${classesdir}/META-INF">
-      <fileset dir=".">
-        <include name="NOTICE.txt">
-        </include>
-      </fileset>
-    </copy>
-  </target>
-  <target name="jar" description="o Create the jar" depends="compile,test">
-    <jar jarfile="${defaulttargetdir}/${final.name}.jar">
-	    <fileset dir="${classesdir}">
-		    <exclude name="**/examples/**"/>
-	    </fileset>
-    </jar>
-  </target>
-  <target name="clean" description="o Clean up the generated directories">
-    <delete dir="${defaulttargetdir}">
-    </delete>
-    <delete dir="${distdir}">
-    </delete>
-  </target>
-  <target name="dist" description="o Create a distribution" depends="jar, javadoc">
-    <mkdir dir="dist">
-    </mkdir>
-    <copy todir="dist">
-      <fileset dir="${defaulttargetdir}" includes="*.jar">
-      </fileset>
-      <fileset dir="${basedir}" includes="LICENSE*, README*">
-      </fileset>
-    </copy>
-  </target>
-  <target name="test" description="o Run the test cases" if="test.failure" depends="internal-test">
-    <fail message="There were test failures.">
-    </fail>
-  </target>
-  <target name="internal-test" if="Junit.present" depends="junit-present,compile-tests">
-    <mkdir dir="${testreportdir}">
-    </mkdir>
-    <junit dir="./" failureproperty="test.failure" printSummary="yes" fork="true" haltonerror="true">
-      <sysproperty key="basedir" value=".">
-      </sysproperty>
-      <formatter type="xml">
-      </formatter>
-      <formatter usefile="false" type="plain">
-      </formatter>
-      <classpath>
-        <path refid="build.classpath">
-        </path>
-        <pathelement path="${testclassesdir}">
-        </pathelement>
-        <pathelement path="${classesdir}">
-        </pathelement>
-        <fileset refid="xmlLibs" />
-      </classpath>
-      <batchtest todir="${testreportdir}">
-        <fileset dir="src/test">
-          <include name="**/*Test.java">
-          </include>
-          <exclude name="**/*FunctionalTest.java">
-          </exclude>
-          <exclude name="**/*POP3*.java">
-          </exclude>
-        </fileset>
-      </batchtest>
-    </junit>
-  </target>
-  <target name="junit-present" unless="Junit.present" depends="init">
-    <echo>================================= WARNING ================================</echo>
-    <echo>Junit isn't present in your ${ANT_HOME}/lib directory. Tests not executed.</echo>
-    <echo>==========================================================================</echo>
-  </target>
-  <target name="compile-tests" if="Junit.present" depends="junit-present,compile">
-    <mkdir dir="${testclassesdir}">
-    </mkdir>
-    <javac destdir="${testclassesdir}" deprecation="true" debug="true" optimize="false" excludes="**/package.html">
-      <src>
-        <pathelement location="src/test">
-        </pathelement>
-      </src>
-      <classpath>
-        <path refid="build.classpath">
-        </path>
-        <pathelement path="${classesdir}">
-        </pathelement>
-      </classpath>
-    </javac>
-  </target>
-  <target name="javadoc" description="o Generate javadoc" depends="get-deps">
-    <mkdir dir="${javadocdir}">
-    </mkdir>
-    <tstamp>
-      <format pattern="1997-yyyy" property="year">
-      </format>
-    </tstamp>
-    <property name="copyright" value="Copyright &amp;copy;  The Apache Software Foundation. All Rights Reserved.">
-    </property>
-    <property name="title" value="Apache Commons Net 1.3.0-dev API">
-    </property>
-    <javadoc use="true" private="false" destdir="${javadocdir}" author="true" version="true" sourcepath="src/java" packagenames="org.apache.commons.net.*">
-      <classpath>
-        <path refid="build.classpath">
-        </path>
-      </classpath>
-    </javadoc>
-  </target>
-  <target name="get-deps" unless="noget" depends="init">
-    <!--Proxy settings works only with a JDK 1.2 and higher.-->
-
-    <setproxy>
-    </setproxy>
-    <get dest="${libdir}/oro-2.0.8.jar" usetimestamp="true" ignoreerrors="true" src="http://www.ibiblio.org/maven/oro/jars/oro-2.0.8.jar">
-    </get>
-  </target>
-  <target name="install-maven">
-    <get dest="${user.home}/maven-install-latest.jar" usetimestamp="true" src="${repo}/maven/maven-install-latest.jar">
-    </get>
-    <unjar dest="${maven.home}" src="${user.home}/maven-install-latest.jar">
-    </unjar>
-  </target>
-</project>
diff --git a/doap_net.rdf b/doap_net.rdf
index 9e4b043..cda7a56 100644
--- a/doap_net.rdf
+++ b/doap_net.rdf
@@ -1,11 +1,11 @@
 <?xml version="1.0"?>
 <!--
    Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
 
        http://www.apache.org/licenses/LICENSE-2.0
 
@@ -17,29 +17,29 @@
 -->
 <rdf:RDF xmlns="http://usefulinc.com/ns/doap#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:asfext="http://projects.apache.org/ns/asfext#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:doap="http://usefulinc.com/ns/doap#" xml:lang="en">
   <Project rdf:about="http://commons.apache.org/net/">
-    <name>Apache Commons Net</name>
+    <name>Apache Jakarta Commons Net</name>
     <homepage rdf:resource="http://commons.apache.org/net/"/>
     <programming-language>Java</programming-language>
     <category rdf:resource="http://projects.apache.org/category/library"/>
     <license rdf:resource="http://usefulinc.com/doap/licenses/asl20"/>
-    <bug-database rdf:resource="http://issues.apache.org/jira/browse/NET"/>
-    <download-page rdf:resource="http://jakarta.apache.org/site/downloads/downloads_commons-net.cgi"/>
+    <bug-database rdf:resource="https://issues.apache.org/jira/browse/NET"/>
+    <download-page rdf:resource="http://commons.apache.org/site/downloads/downloads_commons-net.cgi"/>
     <asfext:pmc rdf:resource="http://commons.apache.org/"/>
     <shortdesc xml:lang="en">Apache Commons Net</shortdesc>
     <description xml:lang="en"/>
     <repository>
       <SVNRepository>
-        <browse rdf:resource="http://svn.apache.org/repos/asf/commons/proper/net/trunk"/>
-        <location rdf:resource="http://svn.apache.org/repos/asf/commons/proper/net"/>
+        <browse rdf:resource="http://svn.apache.org/repos/asf/jakarta/commons/proper/net/trunk"/>
+        <location rdf:resource="http://svn.apache.org/repos/asf/jakarta/commons/proper/net"/>
       </SVNRepository>
     </repository>
     <release>
       <Version>
         <name>commons-net</name>
         <created>2005-12-03</created>
-        <revision>1.4.1</revision>
+        <revision>2.0</revision>
       </Version>
     </release>
-    <mailing-list rdf:resource="http://commons.apache.org/mail-lists.html"/>
+    <mailing-list rdf:resource="http://jakarta.apache.org/site/mail2.html#Commons"/>
   </Project>
 </rdf:RDF>
diff --git a/maven.xml b/maven.xml
deleted file mode 100644
index 065d656..0000000
--- a/maven.xml
+++ /dev/null
@@ -1,90 +0,0 @@
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
--->
-<project default="jar:jar" 
-  xmlns:maven="jelly:maven"
-  xmlns:j="jelly:core" 
-  xmlns:ant="jelly:ant">
-
-  <!-- ================================================================== -->
-  <!-- T E S T : F U N C T I O N A L                                      -->
-  <!-- ================================================================== -->
-  <!-- Run any tests with FunctionalTest as the suffix.  These are for    -->
-  <!-- longer running tests or test that rely on external systems.        -->
-  <!-- ================================================================== -->
-
-  <goal name="test:functional">
-    <j:set var="testmatch" value="*FunctionalTest"/>
-    <attainGoal name="test:match"/>
-  </goal>
-
-  <!-- ================================================================== -->
-  <!-- Post goal to copy the NOTICE.txt into the source and binary        -->
-  <!-- distributions.                                                     -->
-  <!-- ================================================================== -->
-
-  <postGoal
-    name="dist:prepare-bin-filesystem">
-    <j:set 
-      var="maven.dist.bin.assembly.dir" 
-      value="${pom.getPluginContext('maven-dist-plugin').getVariable('maven.dist.bin.assembly.dir')}" />
-
-    <copy file="${basedir}/NOTICE.txt"
-          tofile="${maven.dist.bin.assembly.dir}/NOTICE.txt"
-          overwrite="yes"/>
-
-  </postGoal>
-
-  <postGoal
-    name="dist:prepare-src-filesystem">
-    <j:set 
-      var="maven.dist.src.assembly.dir" 
-      value="${pom.getPluginContext('maven-dist-plugin').getVariable('maven.dist.src.assembly.dir')}" />
-
-    <copy file="${basedir}/NOTICE.txt"
-          tofile="${maven.dist.src.assembly.dir}/NOTICE.txt"
-          overwrite="yes"/>
-
-    <copy todir="${maven.dist.src.assembly.dir}/xdocs">
-        <fileset dir="./xdocs"/>
-    </copy>
-
-    <copy todir="${maven.dist.src.assembly.dir}/proposal">
-        <fileset dir="./proposal"/>
-    </copy>
-
-  </postGoal>
-
-  <!-- ================================================================== -->
-  <!-- Post goal to create the md5 checksums for the source and binary    -->
-  <!-- distributions.                                                     -->
-  <!-- ================================================================== -->
-  
-  <postGoal name="dist:build-bin">
-    <j:set var="distDir" value="${pom.getPluginContext('maven-dist-plugin').getVariable('maven.dist.dir')}"/>
-    <j:set var="finalName" value="${pom.getPluginContext('maven-dist-plugin').getVariable('maven.final.name')}"/>
-    <ant:checksum file="${distDir}/${finalName}.tar.gz"/>
-    <ant:checksum file="${distDir}/${finalName}.zip"/>
-  </postGoal>
-  
-  <postGoal name="dist:build-src">
-    <j:set var="distDir" value="${pom.getPluginContext('maven-dist-plugin').getVariable('maven.dist.dir')}"/>
-    <j:set var="finalName" value="${pom.getPluginContext('maven-dist-plugin').getVariable('maven.final.name')}"/>
-    <ant:checksum file="${distDir}/${finalName}-src.tar.gz"/>
-    <ant:checksum file="${distDir}/${finalName}-src.zip"/>
-  </postGoal>
-
-</project>
diff --git a/pom.xml b/pom.xml
index 136a8f0..88db4cd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -27,7 +27,7 @@
 	<modelVersion>4.0.0</modelVersion>
 	<groupId>commons-net</groupId>
 	<artifactId>commons-net</artifactId>
-	<version>1.5.0</version>
+	<version>2.1-SNAPSHOT</version>
 	<name>Commons Net</name>
 	<description>
 		A collection of network utilities and protocol implementations.
@@ -39,11 +39,20 @@
 	</issueManagement>
 	<inceptionYear>1997</inceptionYear>
 	<scm>
-		<connection>scm:svn:http://svn.apache.org/repos/asf/commons/proper/net/trunk/</connection>
-		<developerConnection>scm:svn:https://svn.apache.org/repos/asf/commons/proper/net/trunk/</developerConnection>
-		<url>http://svn.apache.org/viewvc/commons/proper/net/trunk/</url>
+		<connection>scm:svn:http://svn.apache.org/repos/asf/commons/proper/net/branches/NET_2_0</connection>
+		<developerConnection>scm:svn:https://svn.apache.org/repos/asf/commons/proper/net/branches/NET_2_0</developerConnection>
+		<url>http://svn.apache.org/viewvc/commons/proper/net/branches/NET_2_0</url>
 	</scm>
 
+	<distributionManagement>
+		<site>
+			<id>staging</id>
+			<name>Apache Website</name>
+			<url>scp://people.apache.org/~rwinston/release/net/</url>
+		</site>
+	</distributionManagement>
+
+
 	<developers>
 		<developer>
 			<name>Jeffrey D. Brekke</name>
@@ -66,7 +75,7 @@
 		<developer>
 			<name>Daniel F. Savarese</name>
 			<id>dfs</id>
-			<email>dfs -> apache.org</email>
+			<email>dfs@apache.org</email>
 			<organization>
 				&lt;a href="http://www.savarese.com/"&gt;Savarese Software Research&lt;/a&gt;
 			</organization>
@@ -82,7 +91,7 @@
 	<contributors>
 		<contributor>
 			<name>Rob Hasselbaum</name>
-			<email>rhasselbaum -> alumni.ithaca.edu</email>
+			<email>rhasselbaum@alumni.ithaca.edu</email>
 		</contributor>
 		<contributor>
 			<name>Mario Ivankovits</name>
@@ -105,29 +114,24 @@
 
 	<dependencies>
 		<dependency>
-			<groupId>oro</groupId>
-			<artifactId>oro</artifactId>
-			<version>2.0.8</version>
-		</dependency>
-		<dependency>
 			<groupId>junit</groupId>
 			<artifactId>junit</artifactId>
-			<version>3.8.1</version>
+			<version>3.8.2</version>
 			<scope>test</scope>
 		</dependency>
 	</dependencies>
 
 	<properties>
+		<maven.compile.source>1.5</maven.compile.source>
+		<maven.compile.target>1.5</maven.compile.target>
 		<commons.componentid>net</commons.componentid>
-		<commons.release.version>1.4.1</commons.release.version>
+		<commons.release.version>2.0</commons.release.version>
 		<commons.binary.suffix></commons.binary.suffix>
 		<commons.jira.id>NET</commons.jira.id>
 		<commons.jira.pid>12310487</commons.jira.pid>
 	</properties> 
 
 	<build>
-		<sourceDirectory>src/java</sourceDirectory>
-		<testSourceDirectory>src/test</testSourceDirectory>
 		<plugins>
 
 			<plugin>
@@ -140,17 +144,13 @@
 				</configuration>
 			</plugin>
 
-
-
 			<plugin>
 				<groupId>org.apache.maven.plugins</groupId>
 				<artifactId>maven-surefire-plugin</artifactId>
 				<configuration>
-					<includes>
-						<include>**/*Test.java</include>
-					</includes>
 					<excludes>
 						<exclude>**/*FunctionalTest.java</exclude>
+						<exclude>**/TestSetupParameters.java</exclude>
 						<exclude>**/*POP3*.java</exclude>
 					</excludes>
 				</configuration>
@@ -166,18 +166,88 @@
 					<tarLongFileMode>gnu</tarLongFileMode>
 				</configuration>
 			</plugin>
+
+			<plugin>
+				<artifactId>maven-antrun-plugin</artifactId>
+				<executions>
+					<execution>
+						<phase>package</phase>
+						<configuration>
+							<tasks>
+								<jar destfile="target/commons-net-ftp-${version}.jar">
+									<fileset dir="target/classes" 
+										includes="org/apache/commons/net/ftp/**,org/apache/commons/net/*,org/apache/commons/net/io/*,org/apache/commons/net/util/*"/>
+
+									<metainf dir="${basedir}" includes="NOTICE.txt,LICENSE.txt"/>
+									<manifest>
+										<attribute name="Extension-Name" value="org.apache.commons.net"/>
+										<attribute name="Specification-Title" value="${project.name}"/>
+										<attribute name="Implementation-Title" value="${project.name}"/>
+										<attribute name="Implementation-Vendor" value="${project.organization.name}"/>
+										<attribute name="Implementation-Version" value="${version}"/>
+										<attribute name="Implementation-Vendor-Id" value="org.apache"/>
+										<attribute name="X-Compile-Source-JDK" value="${maven.compile.source}"/>
+										<attribute name="X-Compile-Target-JDK" value="${maven.compile.target}"/>
+
+									</manifest>
+								</jar>
+							</tasks>
+						</configuration>
+						<goals>
+							<goal>run</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+            <!--  Attaches the commons-net-ftp JAR to the Maven lifecycle
+                  to ensure that it will be signed a deployed as normal -->
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <version>1.2</version>
+                <executions>
+                    <execution>
+                        <id>attach-artifacts</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>attach-artifact</goal>
+                        </goals>
+                        <configuration>
+                            <artifacts>
+                                <artifact>
+                                    <file>target/commons-net-ftp-${version}.jar</file>
+                                    <type>jar</type>
+                                    <classifier>ftp</classifier>
+                                </artifact>
+                            </artifacts>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+
 		</plugins>
+
+		<testResources>
+			<testResource>
+				<directory>${basedir}/src/test/java</directory>
+				<includes>
+					<include>**/*Test.java</include>
+				</includes>
+			</testResource>
+		</testResources>
+
+
 	</build>
 
 	<reporting>
 		<plugins>
-
 			<plugin>
 				<groupId>org.apache.maven.plugins</groupId>
 				<artifactId>maven-changes-plugin</artifactId>
 				<version>2.0</version>
 				<configuration>
-					<xmlPath>xdocs/changes.xml</xmlPath>
+					<xmlPath>${basedir}/src/site/xdoc/changes.xml</xmlPath>
 					<issueLinkTemplate>%URL%/%ISSUE%</issueLinkTemplate>
 				</configuration>
 				<reportSets>
@@ -189,6 +259,12 @@
 					</reportSet>
 				</reportSets>
 			</plugin>
+
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>findbugs-maven-plugin</artifactId>
+			</plugin>
+
 			<plugin>
 				<groupId>org.codehaus.mojo</groupId>
 				<artifactId>clirr-maven-plugin</artifactId>
@@ -198,18 +274,6 @@
 					<minSeverity>info</minSeverity>
 				</configuration>
 			</plugin>
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-javadoc-plugin</artifactId>
-				<version>2.4</version>
-				<configuration>
-					<linksource>true</linksource>
-					<links>
-						<link>http://java.sun.com/j2se/1.5.0/docs/api/</link>
-					</links>
-				</configuration>
-			</plugin>
-
 		</plugins>
 	</reporting>
 
diff --git a/project.properties b/project.properties
deleted file mode 100644
index de1ebc4..0000000
--- a/project.properties
+++ /dev/null
@@ -1,41 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-maven.repo.remote=http://repo1.maven.org/maven
-
-maven.checkstyle.javadoc.scope = protected
-maven.checkstyle.format = turbine
-
-maven.changelog.factory=org.apache.maven.svnlib.SvnChangeLogFactory
-
-maven.jar.excludes=**/examples/**
-maven.compile.target=1.2
-maven.compile.source=1.2
-
-# Jar Manifest Additional Attributes
-maven.jar.manifest.attributes.list=Implementation-Vendor-Id,X-Compile-Source-JDK,X-Compile-Target-JDK
-maven.jar.manifest.attribute.Implementation-Vendor-Id=org.apache
-maven.jar.manifest.attribute.X-Compile-Source-JDK=${maven.compile.source}
-maven.jar.manifest.attribute.X-Compile-Target-JDK=${maven.compile.target}
-
-# Make the source distro unzip to a different directory
-maven.dist.src.assembly.dir=${maven.dist.assembly.dir}/src/${maven.final.name}-src
-
-# commons site L&F
-maven.xdoc.date=left
-maven.xdoc.version=${pom.currentVersion}
-maven.xdoc.developmentProcessUrl=http://commons.apache.org/charter.html
-maven.xdoc.poweredby.image=maven-feather.png
-maven.javadoc.links=http://java.sun.com/j2se/1.3/docs/api/
diff --git a/project.xml b/project.xml
deleted file mode 100644
index 9fdaf5c..0000000
--- a/project.xml
+++ /dev/null
@@ -1,246 +0,0 @@
-<?xml version="1.0"?>
-<!--
-Licensed to the Apache Software Foundation (ASF) under one or more
-contributor license agreements.  See the NOTICE file distributed with
-this work for additional information regarding copyright ownership.
-The ASF licenses this file to You under the Apache License, Version 2.0
-(the "License"); you may not use this file except in compliance with
-the License.  You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-<project>
-	<pomVersion>3</pomVersion>
-
-	<name>Commons Net</name>
-	<groupId>commons-net</groupId>
-    <artifactId>commons-net</artifactId>
-	<currentVersion>1.5.0-SNAPSHOT</currentVersion>
-	<inceptionYear>1997</inceptionYear>
-	<shortDescription>Commons Net</shortDescription>
-	<description/>
-
-	<logo>/images/net-logo-white.png</logo>
-
-	<url>http://commons.apache.org/${pom.artifactId.substring(8)}/</url>
-	<package>org.apache.commons.${pom.artifactId.substring(8)}</package>
-
-	<organization>
-		<name>The Apache Software Foundation</name>
-          <url>http://commons.apache.org/</url>
-          <logo>http://commons.apache.org/images/logo.png</logo>
-	</organization>
-
-	<licenses>
-		<license>
-			<name>The Apache Software License, Version 2.0</name>
-			<url>/LICENSE.txt</url>
-			<distribution>repo</distribution>
-		</license>
-	</licenses>
-
-	<gumpRepositoryId>commons</gumpRepositoryId>
-	<issueTrackingUrl>http://issues.apache.org/jira/</issueTrackingUrl>
-	<siteAddress>commons.apache.org</siteAddress>
-	<siteDirectory>/www/commons.apache.org/${pom.artifactId.substring(8)}/</siteDirectory>
-	<distributionDirectory>/www/people.apache.org/builds/commons/${pom.artifactId.substring(8)}/</distributionDirectory>
-
-	<repository>
-		<connection>scm:svn:http://svn.apache.org/repos/asf/commons/proper/${pom.artifactId.substring(8)}/trunk</connection>
-		<url>http://svn.apache.org/repos/asf/commons/proper/${pom.artifactId.substring(8)}/trunk</url>
-	</repository>
-
-	<mailingLists>
-		<mailingList>
-            <name>Commons Dev List</name>
-            <subscribe>dev-subscribe@commons.apache.org</subscribe>
-            <unsubscribe>dev-unsubscribe@commons.apache.org</unsubscribe>
-            <archive>http://mail-archives.apache.org/mod_mbox/commons-dev/</archive>
-		</mailingList>
-		<mailingList>
-            <name>Commons User List</name>
-            <subscribe>user-subscribe@commons.apache.org</subscribe>
-            <unsubscribe>user-unsubscribe@commons.apache.org</unsubscribe>
-            <archive>http://mail-archives.apache.org/mod_mbox/commons-user/</archive>
-		</mailingList>
-	</mailingLists>
-
-	<versions>
-		<version>
-			<id>1.0.0</id>
-			<name>1.0.0</name>
-			<tag>NET_1_0_0</tag>
-		</version>
-		<version>
-			<id>1.1.0</id>
-			<name>1.1.0</name>
-			<tag>NET_1_1_0</tag>
-		</version>
-		<version>
-			<id>1.2.0</id>
-			<name>1.2.0</name>
-			<tag>NET_1_2_0</tag>
-		</version>
-		<version>
-			<id>1.2.1</id>
-			<name>1.2.1</name>
-			<tag>NET_1_2_1</tag>
-		</version>
-		<version>
-			<id>1.2.2</id>
-			<name>1.2.2</name>
-			<tag>NET_1_2_2</tag>
-		</version>
-		<version>
-			<id>1.3.0</id>
-			<name>1.3.0</name>
-			<tag>NET_1_3_0</tag>
-		</version>
-		<version>
-			<id>1.4.0</id>
-			<name>1.4.0</name>
-			<tag>NET_1_4_0</tag>
-		</version>	
-	</versions>
-
-	<developers>
-		<developer>
-			<name>Jeffrey D. Brekke</name>
-			<id>brekke</id>
-			<email>Jeff.Brekke@qg.com</email>
-			<organization>Quad/Graphics, Inc.</organization>
-		</developer>
-		<developer>
-			<name>Steve Cohen</name>
-			<id>scohen</id>
-			<email>scohen@apache.org</email>
-			<organization>javactivity.org</organization>
-		</developer>
-		<developer>
-			<name>Bruno D'Avanzo</name>
-			<id>brudav</id>
-			<email>bruno.davanzo@hp.com</email>
-			<organization>Hewlett-Packard</organization>
-		</developer>
-		<developer>
-			<name>Daniel F. Savarese</name>
-			<id>dfs</id>
-			<email>dfs -> apache.org</email>
-			<organization>
-			&lt;a href="http://www.savarese.com/"&gt;Savarese Software Research&lt;/a&gt;
-			</organization>
-		</developer>
-		<developer>
-			<name>Rory Winston</name>
-			<id>rwinston</id>
-			<email>rwinston@apache.org</email>
-			<organization></organization>
-		</developer>
-	</developers>
-
-	<contributors>
-		<contributor>
-			<name>Rob Hasselbaum</name>
-			<email>rhasselbaum -> alumni.ithaca.edu</email>
-		</contributor>
-		<contributor>
-			<name>Mario Ivankovits</name>
-			<email>mario@ops.co.at</email>
-		</contributor>
-		<contributor>
-			<name>Tapan Karecha</name>
-			<email>tapan@india.hp.com</email>
-		</contributor>
-		<contributor>
-			<name>Winston Ojeda</name>
-			<email>Winston.Ojeda@qg.com</email>
-			<organization>Quad/Graphics, Inc.</organization>
-		</contributor>
-		<contributor>
-			<name>Ted Wise</name>
-			<email>ctwise@bellsouth.net</email>
-		</contributor>
-	</contributors>
-
-	<dependencies>
-	  <dependency>
-        <groupId>oro</groupId>
-        <artifactId>oro</artifactId>
-	    <version>2.0.8</version>
-      </dependency>
-
-      <dependency>
-        <groupId>maven</groupId>
-        <artifactId>maven-xdoc-plugin</artifactId>
-        <version>1.9.2</version>
-        <url>http://maven.apache.org/reference/plugins/xdoc/</url>
-        <type>plugin</type>
-        <properties>
-          <comment>
-              &lt;strong&gt;Site Only&lt;/strong&gt; - v1.9.2 (minimum)
-              required for building the Site documentation.
-          </comment>
-        </properties>
-      </dependency>
-
-	</dependencies>
-
-	<build>
-
-            <nagEmailAddress>dev@commons.apache.org</nagEmailAddress>
-
-		<sourceDirectory>src/java</sourceDirectory>
-
-		<resources>
-			<resource>
-				<directory>${basedir}</directory>
-				<targetPath>META-INF</targetPath>
-				<includes>
-					<include>NOTICE.txt</include>
-				</includes>
-			</resource>
-		</resources>
-
-		<unitTestSourceDirectory>src/test</unitTestSourceDirectory>
-
-		<unitTest>
-			<includes>
-				<include>**/*Test.java</include>
-			</includes>
-			<excludes>
-				<exclude>**/*FunctionalTest.java</exclude>
-				<exclude>**/*POP3*.java</exclude>
-			</excludes>
-		</unitTest>
-
-		<resources>
-			<resource>
-				<directory>${basedir}</directory>
-				<targetPath>META-INF</targetPath>
-				<includes>
-					<include>NOTICE.txt</include>
-				</includes>
-			</resource>
-		</resources>
-
-	</build>
-
-	<reports>
-		<report>maven-changes-plugin</report>
-		<report>maven-tasklist-plugin</report>
-		<report>maven-junit-report-plugin</report>
-		<report>maven-jdepend-plugin</report>
-		<report>maven-jcoverage-plugin</report>
-		<report>maven-simian-plugin</report>
-		<report>maven-javadoc-plugin</report>
-		<report>maven-jxr-plugin</report>
-		<report>maven-license-plugin</report>
-	</reports>
-
-</project>
diff --git a/proposal/ftp2/build.xml b/proposal/ftp2/build.xml
deleted file mode 100644
index 2b9169e..0000000
--- a/proposal/ftp2/build.xml
+++ /dev/null
@@ -1,170 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
--->
-
-<project default="jar" name="commons-net-ftp2" basedir=".">
-  <property name="defaulttargetdir" value="target">
-  </property>
-  <property name="libdir" value="target/lib">
-  </property>
-  <property name="classesdir" value="target/classes">
-  </property>
-  <property name="testclassesdir" value="target/test-classes">
-  </property>
-  <property name="testreportdir" value="target/test-reports">
-  </property>
-  <property name="distdir" value="dist">
-  </property>
-  <property name="javadocdir" value="dist/docs/api">
-  </property>
-  <property name="final.name" value="commons-net-ftp2-SNAPSHOT">
-  </property>
-  <target name="init" description="o Initializes some properties">
-    <mkdir dir="${libdir}">
-    </mkdir>
-    <condition property="noget">
-      <equals arg2="only" arg1="${build.sysclasspath}">
-      </equals>
-    </condition>
-  </target>
-  <target name="compile" description="o Compile the code" depends="get-deps">
-    <mkdir dir="${classesdir}">
-    </mkdir>
-    <javac destdir="${classesdir}" deprecation="true" debug="true" optimize="false" excludes="**/package.html">
-      <src>
-        <pathelement location="src/java">
-        </pathelement>
-      </src>
-      <classpath>
-        <fileset dir="${libdir}">
-          <include name="*.jar">
-          </include>
-        </fileset>
-      </classpath>
-    </javac>
-  </target>
-  <target name="jar" description="o Create the jar" depends="compile,test">
-    <jar jarfile="target/${final.name}.jar" excludes="**/package.html" basedir="${classesdir}">
-    </jar>
-  </target>
-  <target name="clean" description="o Clean up the generated directories">
-    <delete dir="${defaulttargetdir}">
-    </delete>
-    <delete dir="${distdir}">
-    </delete>
-  </target>
-  <target name="dist" description="o Create a distribution" depends="jar, javadoc">
-    <mkdir dir="dist">
-    </mkdir>
-    <copy todir="dist">
-      <fileset dir="${defaulttargetdir}" includes="*.jar">
-      </fileset>
-      <fileset dir="${basedir}" includes="LICENSE*, README*">
-      </fileset>
-    </copy>
-  </target>
-  <target name="test" description="o Run the test cases" if="test.failure" depends="internal-test">
-    <fail message="There were test failures.">
-    </fail>
-  </target>
-  <target name="internal-test" depends="compile-tests">
-    <mkdir dir="${testreportdir}">
-    </mkdir>
-    <junit dir="./" failureproperty="test.failure" printSummary="yes" fork="true" haltonerror="true">
-      <sysproperty key="basedir" value=".">
-      </sysproperty>
-      <formatter type="xml">
-      </formatter>
-      <formatter usefile="false" type="plain">
-      </formatter>
-      <classpath>
-        <fileset dir="${libdir}">
-          <include name="*.jar">
-          </include>
-        </fileset>
-        <pathelement path="${testclassesdir}">
-        </pathelement>
-        <pathelement path="${classesdir}">
-        </pathelement>
-      </classpath>
-      <batchtest todir="${testreportdir}">
-        <fileset dir="src/test">
-          <include name="**/*Test.java">
-          </include>
-        </fileset>
-      </batchtest>
-    </junit>
-  </target>
-  <target name="compile-tests" depends="compile">
-    <mkdir dir="${testclassesdir}">
-    </mkdir>
-    <javac destdir="${testclassesdir}" deprecation="true" debug="true" optimize="false" excludes="**/package.html">
-      <src>
-        <pathelement location="src/test">
-        </pathelement>
-      </src>
-      <classpath>
-        <fileset dir="${libdir}">
-          <include name="*.jar">
-          </include>
-        </fileset>
-        <pathelement path="${classesdir}">
-        </pathelement>
-      </classpath>
-    </javac>
-  </target>
-  <target name="javadoc" description="o Generate javadoc" depends="jar">
-    <mkdir dir="${javadocdir}">
-    </mkdir>
-    <tstamp>
-      <format pattern="-yyyy" property="year">
-      </format>
-    </tstamp>
-    <property name="copyright" value="Copyright &amp;copy;  . All Rights Reserved.">
-    </property>
-    <property name="title" value="Apache Commons/Net FTP Proposal SNAPSHOT API">
-    </property>
-    <javadoc use="true" private="true" destdir="${javadocdir}" author="true" version="true" sourcepath="src/java" packagenames="org.apache.commons.net.ftp.ftp2.*">
-      <classpath>
-        <fileset dir="${libdir}">
-          <include name="*.jar">
-          </include>
-        </fileset>
-        <pathelement location="target/${final.name}.jar">
-        </pathelement>
-      </classpath>
-    </javadoc>
-  </target>
-  <target name="get-deps" unless="noget" depends="init">
-    <get dest="${libdir}/oro-2.0.6.jar" usetimestamp="true" ignoreerrors="true" src="http://www.ibiblio.org/maven/oro/jars/oro-2.0.6.jar">
-    </get>
-    <get dest="${libdir}/commons-net-SNAPSHOT.jar" usetimestamp="true" ignoreerrors="true" src="http://www.ibiblio.org/maven/commons-net/jars/commons-net-SNAPSHOT.jar">
-    </get>
-    <get dest="${libdir}/junit-3.8.1.jar" usetimestamp="true" ignoreerrors="true" src="http://www.ibiblio.org/maven/junit/jars/junit-3.8.1.jar">
-    </get>
-    <get dest="${libdir}/ant-1.5.jar" usetimestamp="true" ignoreerrors="true" src="http://www.ibiblio.org/maven/ant/jars/ant-1.5.jar">
-    </get>
-    <get dest="${libdir}/ant-optional-1.5.jar" usetimestamp="true" ignoreerrors="true" src="http://www.ibiblio.org/maven/ant/jars/ant-optional-1.5.jar">
-    </get>
-  </target>
-  <target name="install-maven">
-    <get dest="${user.home}/maven-install-latest.jar" usetimestamp="true" src="${maven.repo.remote}/maven/maven-install-latest.jar">
-    </get>
-    <unjar dest="${maven.home}" src="${user.home}/maven-install-latest.jar">
-    </unjar>
-  </target>
-</project>
\ No newline at end of file
diff --git a/proposal/ftp2/maven.xml b/proposal/ftp2/maven.xml
deleted file mode 100644
index 736e3ea..0000000
--- a/proposal/ftp2/maven.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
--->
-<project default="java:jar" xmlns:j="jelly:core">
-
-  <!-- we can customize the Maven build here -->
-  	
-</project>
diff --git a/proposal/ftp2/project.xml b/proposal/ftp2/project.xml
deleted file mode 100644
index 23c5ebc..0000000
--- a/proposal/ftp2/project.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-<?xml version="1.0"?>
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
--->
-
-<project>
-  <pomVersion>3</pomVersion>
-  <name>Apache Commons/Net FTP Proposal</name>
-  <groupId>commons-net-ftp2</groupId>
-  <artifactId>commons-net-ftp2</artifactId>
-  <currentVersion>SNAPSHOT</currentVersion>
-  <organization/>
-  <package>org.apache.commons.net.ftp.ftp2</package>
-  
-  <shortDescription>Apache Commons/Net FTP Proposal</shortDescription>
-  
-  <description/>
-  
-  <url>http://commons.apache.org/sandbox/net/</url>
-  <issueTrackingUrl/>
-  <siteAddress/>
-  <siteDirectory/>
-  <distributionDirectory/>
-
-  <repository>
-    <connection>scm:cvs:pserver:anoncvs@cvs.apache.org:/home/cvspublic:jakarta-commons-sandbox/net/proposal/ftp2</connection>
-    <url>http://cvs.apache.org/viewcvs/jakarta-commons-sandbox/net/proposal/ftp2</url>
-  </repository>
-
-  <mailingLists/>
-
-  <developers/>
-  
-  <dependencies>
-    <dependency>
-      <groupId>oro</groupId>
-      <artifactId>oro</artifactId>
-      <version>2.0.6</version>
-      <url>http://jakarta.apache.org/oro/</url>
-    </dependency>
-
-    <dependency>
-      <groupId>commons-net</groupId>
-      <artifactId>commons-net</artifactId>
-      <version>SNAPSHOT</version>
-    </dependency>
-    
-  </dependencies>
-  
-  <build>
-
-    <sourceDirectory>src/java</sourceDirectory>
-    <unitTestSourceDirectory>src/test</unitTestSourceDirectory>
-    
-    <unitTest>
-      <includes>
-        <include>**/*Test.java</include>
-      </includes>
-    </unitTest>
-    
-  </build>
-</project>
diff --git a/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/FTPClient2.java b/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/FTPClient2.java
deleted file mode 100644
index b964413..0000000
--- a/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/FTPClient2.java
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.net.ftp.ftp2;
-
-import java.io.IOException;
-import java.net.Socket;
-import org.apache.commons.net.ftp.FTPClient;
-import org.apache.commons.net.ftp.FTPCommand;
-import org.apache.commons.net.ftp.FTPFile;
-import org.apache.commons.net.ftp.ftp2.parser.UnixFTPEntryParser;
-
-/**
- * FTPClient2.java
- * This class is derived by design from Daniel Savarese's FTPClient.
- * It is designed to have all the same functionality, but add support 
- * for a new alternative design for File List Parsing.  There is no reason 
- * why this  could not have been included in FTPClient, but it is a fairly 
- * sizable chunk  of code and given that the community process for this 
- * project is still  a work in progress I thought it would be better to keep a
- * fairly  clear line between the old and the new; it's less confusing that 
- * way.
- *
- * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
- * @version $Id$
- */
-public class FTPClient2 extends FTPClient
-{
-    private FTPFileEntryParser defaultParser;
-    /**
-     * The only constructor for this class.
-     */
-    public FTPClient2()
-    {
-        super();
-        this.defaultParser = new UnixFTPEntryParser();
-    }
-    
-    /**
-     * Using a programmer specified <code> FTPFileEntryParser </code>, obtain a 
-     * list of file information for a directory or information for
-     * just a single file.  This information is obtained through the LIST
-     * command.  The contents of the returned array is determined by the
-     * <code> FTPFileEntryParser </code> used.
-     * The server may or may not expand glob expressions.  You should avoid
-     * using glob expressions because the return format for glob listings
-     * differs from server to server and will likely cause this method to fail.
-     * <p>
-     * @param parser The <code> FTPFileEntryParser </code> that should be
-     *         used to parse the server file listing.   
-     * @param pathname  The file or directory to list.
-     * @return The list of file information contained in the given path in
-     *         the format determined by the <code> parser </code> parameter.
-     * @exception FTPConnectionClosedException
-     *      If the FTP server prematurely closes the connection as a result
-     *      of the client being idle or some other reason causing the server
-     *      to send FTP reply code 421.  This exception may be caught either
-     *      as an IOException or independently as itself.
-     * @exception IOException  If an I/O error occurs while either sending a
-     *      command to the server or receiving a reply from the server.
-     */
-    public FTPFile[] listFiles(FTPFileEntryParser parser, String pathname)
-    throws IOException
-    {
-        FTPFileList lister = createFileList(pathname, parser);
-        FTPFile[] list = lister.getFiles();
-        return list;
-    }
-
-    /**
-     * Using the <code> DefaultFTPFileListEntryParser </code>, obtain a list of
-     * file information
-     * for a directory or information for just a single file.  This information
-     * is obtained through the LIST command.  If the given
-     * pathname is a directory and contains no files, <code> null </code> is
-     * returned, otherwise an array of <code> FTPFile </code> instances
-     * representing the files in the directory is returned.
-     * If the pathname corresponds to a file, only the information for that
-     * file will be contained in the array (which will be of length 1).  The
-     * server may or may not expand glob expressions.  You should avoid using
-     * glob expressions because the return format for glob listings differs
-     * from server to server and will likely cause this method to fail.
-     * <p>
-     * @param pathname  The file or directory to list.
-     * @return The list of file information contained in the given path.  null
-     *     if the list could not be obtained or if there are no files in
-     *     the directory.
-     * @exception FTPConnectionClosedException
-     *      If the FTP server prematurely closes the connection as a result
-     *      of the client being idle or some other reason causing the server
-     *      to send FTP reply code 421.  This exception may be caught either
-     *      as an IOException or independently as itself.
-     * @exception IOException  If an I/O error occurs while either sending a
-     *      command to the server or receiving a reply from the server.
-     */
-    public FTPFile[] listFiles(String pathname) throws IOException
-    {
-        return listFiles(this.defaultParser, pathname);
-    }
-    
-    /**
-     * Using the <code> DefaultFTPFileEntryParser </code>, obtain a list of 
-     * file information for the current working directory.  This information
-     * is obtained through the LIST command.  If the given
-     * current directory contains no files null is returned, otherwise an 
-     * array of <code> FTPFile </code> instances representing the files in the
-     * directory is returned.
-     * <p>
-     * @return The list of file information contained in the current working
-     *     directory.  null if the list could not be obtained or if there are
-     *     no files in the directory.
-     * @exception FTPConnectionClosedException
-     *      If the FTP server prematurely closes the connection as a result
-     *      of the client being idle or some other reason causing the server
-     *      to send FTP reply code 421.  This exception may be caught either
-     *      as an IOException or independently as itself.
-     * @exception IOException  If an I/O error occurs while either sending a
-     *      command to the server or receiving a reply from the server.
-     */
-    public FTPFile[] listFiles() throws IOException
-    {
-        return listFiles(this.defaultParser, null);
-    }
-
-    /**
-     * Using the default <code> FTPFileEntryParser </code>,  initialize an 
-     * object containing a raw file information for the current working 
-     * directory.  This information is obtained through  the LIST command.  
-     * This object is then capable of being iterated to return a sequence 
-     * of FTPFile objects with information filled in by the
-     * <code> FTPFileEntryParser </code> used.
-     * The server may or may not expand glob expressions.  You should avoid
-     * using glob expressions because the return format for glob listings
-     * differs from server to server and will likely cause this method to fail.
-     * <p>
-     * @return An iteratable object that holds the raw information and is 
-     * capable of providing parsed FTPFile objects, one for each file containing
-     * information contained in the given path in the format determined by the 
-     * <code> parser </code> parameter.   Null will be returned if a 
-     * data connection cannot be opened.  If the current working directory
-     * contains no files, an empty array will be the return.
-     * @exception FTPConnectionClosedException
-     *      If the FTP server prematurely closes the connection as a result
-     *      of the client being idle or some other reason causing the server
-     *      to send FTP reply code 421.  This exception may be caught either
-     *      as an IOException or independently as itself.
-     * @exception IOException  If an I/O error occurs while either sending a
-     *      command to the server or receiving a reply from the server.
-     * @see FTPFileList
-     */
-    public FTPFileList createFileList() throws IOException
-    {
-        return createFileList(null, this.defaultParser);
-    }
-
-    /**
-     * Using the default <code> FTPFileEntryParser </code>, 
-     * initialize an object containing a raw file information for a directory 
-     * or information for a single file.  This information is obtained through 
-     * the LIST command.  This object is then capable of being iterated to 
-     * return a sequence of FTPFile objects with information filled in by the
-     * <code> FTPFileEntryParser </code> used.
-     * The server may or may not expand glob expressions.  You should avoid
-     * using glob expressions because the return format for glob listings
-     * differs from server to server and will likely cause this method to fail.
-     * <p>
-     * @param basedir The file or directory to list.
-     * @return An iteratable object that holds the raw information and is 
-     * capable of providing parsed FTPFile objects, one for each file containing
-     * information contained in the given path in the format determined by the 
-     * <code> parser </code> parameter.   Null will be returned if a 
-     * data connection cannot be opened.  If the supplied path contains
-     * no files, an empty array will be the return.
-     * @exception FTPConnectionClosedException
-     *      If the FTP server prematurely closes the connection as a result
-     *      of the client being idle or some other reason causing the server
-     *      to send FTP reply code 421.  This exception may be caught either
-     *      as an IOException or independently as itself.
-     * @exception IOException  If an I/O error occurs while either sending a
-     *      command to the server or receiving a reply from the server.
-     * @see FTPFileList
-     */
-    public FTPFileList createFileList(String basedir) throws IOException
-    {
-        return createFileList(basedir, this.defaultParser);
-    }
-
-    /**
-     * Using a programmer specified <code> FTPFileEntryParser </code>, 
-     * initialize an object containing a raw file information for the 
-     * current working directory.  This information is obtained through 
-     * the LIST command.  This object is then capable of being iterated to 
-     * return a sequence of FTPFile objects with information filled in by the
-     * <code> FTPFileEntryParser </code> used.
-     * The server may or may not expand glob expressions.  You should avoid
-     * using glob expressions because the return format for glob listings
-     * differs from server to server and will likely cause this method to fail.
-     * <p>
-     * @param parser The <code> FTPFileEntryParser </code> that should be
-     *         used to parse each server file listing.   
-     * @return An iteratable object that holds the raw information and is 
-     * capable of providing parsed FTPFile objects, one for each file containing
-     * information contained in the given path in the format determined by the 
-     * <code> parser </code> parameter.   Null will be returned if a 
-     * data connection cannot be opened.  If the current working directory 
-     * contains no files, an empty array will be the return.
-     * @exception FTPConnectionClosedException
-     *      If the FTP server prematurely closes the connection as a result
-     *      of the client being idle or some other reason causing the server
-     *      to send FTP reply code 421.  This exception may be caught either
-     *      as an IOException or independently as itself.
-     * @exception IOException  If an I/O error occurs while either sending a
-     *      command to the server or receiving a reply from the server.
-     * @see FTPFileList
-     */
-    public FTPFileList createFileList(FTPFileEntryParser parser)
-    throws IOException
-    {
-        return createFileList(null, parser);
-    }
-
-    /**
-     * Using a programmer specified <code> FTPFileEntryParser </code>, 
-     * initialize an object containing a raw file information for a directory 
-     * or information for a single file.  This information is obtained through 
-     * the LIST command.  This object is then capable of being iterated to 
-     * return a sequence of FTPFile objects with information filled in by the
-     * <code> FTPFileEntryParser </code> used.
-     * The server may or may not expand glob expressions.  You should avoid
-     * using glob expressions because the return format for glob listings
-     * differs from server to server and will likely cause this method to fail.
-     * <p>
-     * @param parser The <code> FTPFileEntryParser </code> that should be
-     *         used to parse each server file listing.   
-     * @param pathname  The file or directory to list.
-     * @return An iteratable object that holds the raw information and is 
-     * capable of providing parsed FTPFile objects, one for each file containing
-     * information contained in the given path in the format determined by the 
-     * <code> parser </code> parameter.  Null will be returned if a 
-     * data connection cannot be opened.  If the supplied path contains
-     * no files, an empty array will be the return.
-     * @exception FTPConnectionClosedException
-     *      If the FTP server prematurely closes the connection as a result
-     *      of the client being idle or some other reason causing the server
-     *      to send FTP reply code 421.  This exception may be caught either
-     *      as an IOException or independently as itself.
-     * @exception IOException  If an I/O error occurs while either sending a
-     *      command to the server or receiving a reply from the server.
-     * @see FTPFileList
-     */
-    public FTPFileList createFileList(String pathname,
-                                      FTPFileEntryParser parser)
-    throws IOException
-    {
-        Socket socket;
-        FTPFile[] results;
-
-        if ((socket = __openDataConnection(FTPCommand.LIST, pathname)) == null)
-        {
-            return null;
-        }
-
-        FTPFileList list =
-            FTPFileList.create(socket.getInputStream(), parser);
-
-        socket.close();
-
-        completePendingCommand();
-
-        return list;
-    }
-}
diff --git a/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/FTPFileEntryParser.java b/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/FTPFileEntryParser.java
deleted file mode 100644
index ab8e73d..0000000
--- a/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/FTPFileEntryParser.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.net.ftp.ftp2;
-
-import org.apache.commons.net.ftp.FTPFile;
-
-/**
- * FTPFileEntryParser defines the interface for parsing a single FTP file
- * listing and converting that information into an 
- * {@link org.apache.commons.net.ftp.FTPFile} instance.
- * Sometimes you will want to parse unusual listing formats, in which
- * case you would create your own implementation of FTPFileEntryParser and
- * if necessary, subclass FTPFile.
- *
- * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
- * @version $Id$
- * @see org.apache.commons.net.ftp.FTPFile
- * @see FTPClient2#listFiles
- */
-public interface FTPFileEntryParser
-{
-    /**
-     * Parses a line of an FTP server file listing and converts it into a usable
-     * format in the form of an <code> FTPFile </code> instance.  If the
-     * file listing line doesn't describe a file, <code> null </code> should be
-     * returned, otherwise a <code> FTPFile </code> instance representing the
-     * files in the directory is returned.
-     * <p>
-     * @param listEntry A line of text from the file listing
-     * @return An FTPFile instance corresponding to the supplied entry
-     */
-    public FTPFile parseFTPEntry(String listEntry);
-}
diff --git a/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/FTPFileIterator.java b/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/FTPFileIterator.java
deleted file mode 100644
index 1d442b6..0000000
--- a/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/FTPFileIterator.java
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.net.ftp.ftp2;
-
-import org.apache.commons.net.ftp.FTPFile;
-import java.util.Vector;
-
-/**
- * FTPFileIterator.java
- * This class implements a bidirectional iterator over an FTPFileList.
- * Elements may be retrieved one at at time using the hasNext() - next()
- * syntax familiar from Java 2 collections.  Alternatively, entries may
- * be receieved as an array of any requested number of entries or all of them.
- *
- * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
- * @version $Id$
- * @see org.apache.commons.net.ftp.ftp2.FTPFileList
- */
-public class FTPFileIterator
-{
-    private Vector rawlines;
-    private FTPFileEntryParser parser;
-
-    private static final int UNINIT = -1;
-    private static final int DIREMPTY = -2;
-    private int itemptr = 0;
-    private int firstGoodEntry = UNINIT;
-
-    /**
-     * "Package-private" constructor.  Only the FTPFileList can
-     * create an iterator, using it's iterator() method.  The list
-     * will be iterated with the list's default parser.
-     *
-     * @param rawlist the FTPFileList to be iterated
-     */
-    FTPFileIterator ( FTPFileList rawlist )
-    {
-        this(rawlist, rawlist.getParser());
-    }
-
-    /**
-     * "Package-private" constructor.  Only the FTPFileList can
-     * create an iterator, using it's iterator() method.  The list will be
-     * iterated with a supplied parser
-     *
-     * @param rawlist the FTPFileList to be iterated
-     * @param parser the system specific parser for raw FTP entries.
-     */
-    FTPFileIterator ( FTPFileList rawlist, FTPFileEntryParser parser )
-    {
-        this.rawlines = rawlist.getLines();
-        this.parser = parser;
-    }
-
-    private FTPFile parseFTPEntry(String entry)
-    {
-        return this.parser.parseFTPEntry(entry);
-    }
-
-    private int getFirstGoodEntry()
-    {
-        FTPFile entry = null;
-        for (int iter = 0; iter < this.rawlines.size(); iter++)
-        {
-            String line = (String) this.rawlines.elementAt(iter);
-            entry = parseFTPEntry(line);
-            if (null != entry)
-            {
-                return iter;
-            }
-        }
-        return DIREMPTY;
-    }
-
-    private void init()
-    {
-        this.itemptr = 0;
-        this.firstGoodEntry = UNINIT;
-    }
-
-    private static final FTPFile[] EMPTY = new FTPFile[0];
-
-    /**
-     * Returns a list of FTPFile objects for ALL files listed in the server's
-     * LIST output.
-     *
-     * @return a list of FTPFile objects for ALL files listed in the server's
-     * LIST output.
-     */
-    public FTPFile[] getFiles()
-    {
-        if (this.itemptr != DIREMPTY)
-        {
-            init();
-        }
-        return getNext(0);
-    }
-
-    /**
-     * Returns an array of at most <code>quantityRequested</code> FTPFile 
-     * objects starting at this iterator's current position  within its 
-     * associated list. If fewer than <code>quantityRequested</code> such 
-     * elements are available, the returned array will have a length equal 
-     * to the number of entries at and after after the current position.  
-     * If no such entries are found, this array will have a length of 0.
-     * 
-     * After this method is called the current position is advanced by 
-     * either <code>quantityRequested</code> or the number of entries 
-     * available after the iterator, whichever is fewer.
-     * 
-     * @param quantityRequested
-     * the maximum number of entries we want to get.  A 0
-     * passed here is a signal to get ALL the entries.
-     * 
-     * @return an array of at most <code>quantityRequested</code> FTPFile 
-     * objects starting at the current position of this iterator within its 
-     * list and at least the number of elements which  exist in the list at 
-     * and after its current position.
-     */
-    public FTPFile[] getNext(int quantityRequested)
-    {
-
-        // if we haven't gotten past the initial junk do so.
-        if (this.firstGoodEntry == UNINIT)
-        {
-            this.firstGoodEntry = getFirstGoodEntry();
-        }
-        if (this.firstGoodEntry == DIREMPTY)
-        {
-            return EMPTY;
-        }
-
-        int max = this.rawlines.size() - this.firstGoodEntry;
-
-        // now that we know the maximum we can possibly get,
-        // resolve a 0 request to ask for that many.
-
-        int howMany = (quantityRequested == 0) ? max : quantityRequested;
-        howMany = (howMany + this.itemptr < this.rawlines.size())
-                   ? howMany
-                   : this.rawlines.size() - this.itemptr;
-
-        FTPFile[] output = new FTPFile[howMany];
-
-        for (int i = 0, e = this.firstGoodEntry + this.itemptr ;
-                i < howMany; i++, e++)
-        {
-            output[i] = parseFTPEntry((String) this.rawlines.elementAt(e));
-            this.itemptr++;
-
-        }
-        return output;
-    }
-
-    /**
-     * Method for determining whether getNext() will successfully return a
-     * non-null value.
-     *
-     * @return true if there exist any files after the one currently pointed
-     * to by the internal iterator, false otherwise.
-     */
-    public boolean hasNext()
-    {
-        int fge = this.firstGoodEntry;
-        if (fge == DIREMPTY)
-        {
-            //directory previously found empty - return false
-            return false;
-        }
-        else if (fge < 0)
-        {
-            // we haven't scanned the list yet so do it first
-            fge = getFirstGoodEntry();
-        }
-        return fge + this.itemptr < this.rawlines.size();
-    }
-
-    /**
-     * Returns a single parsed FTPFile object corresponding to the raw input
-     * line at this iterator's current position.
-     *
-     * After this method is called the internal iterator is advanced by one
-     * element (unless already at end of list).
-     *
-     * @return a single FTPFile object corresponding to the raw input line
-     * at the position of the internal iterator over the list of raw input
-     * lines maintained by this object or null if no such object exists.
-     */
-    public FTPFile next()
-    {
-        FTPFile[] file = getNext(1);
-        if (file.length > 0)
-        {
-            return file[0];
-        }
-        else
-        {
-            return null;
-        }
-    }
-
-    /**
-     * Returns an array of at most <code>quantityRequested</code> FTPFile 
-     * objects starting at the position preceding this iterator's current 
-     * position within its associated list. If fewer than 
-     * <code>quantityRequested</code> such elements are available, the 
-     * returned array will have a length equal to the number of entries after
-     * the iterator.  If no such entries are found, this array will have a 
-     * length of 0.  The entries will be ordered in the same order as the 
-     * list, not reversed.
-     *
-     * After this method is called the current position is moved back by 
-     * either <code>quantityRequested</code> or the number of entries 
-     * available before the current position, whichever is fewer.
-     * @param quantityRequested the maximum number of entries we want to get.  
-     * A 0 passed here is a signal to get ALL the entries.
-     * @return  an array of at most <code>quantityRequested</code> FTPFile 
-     * objects starting at the position preceding the current position of 
-     * this iterator within its list and at least the number of elements which
-     * exist in the list prior to its current position.
-     */
-    public FTPFile[] getPrevious(int quantityRequested)
-    {
-        int howMany = quantityRequested;
-        // can't retreat further than we've previously advanced
-        if (howMany > this.itemptr)
-        {
-            howMany = this.itemptr;
-        }
-        FTPFile[] output = new FTPFile[howMany];
-        for (int i = howMany, e = this.firstGoodEntry + this.itemptr; i > 0; )
-        {
-            output[--i] = parseFTPEntry((String) this.rawlines.elementAt(--e));
-            this.itemptr--;
-        }
-        return output;
-    }
-
-    /**
-     * Method for determining whether getPrevious() will successfully return a
-     * non-null value.
-     *
-     * @return true if there exist any files before the one currently pointed
-     * to by the internal iterator, false otherwise.
-     */
-    public boolean hasPrevious()
-    {
-        int fge = this.firstGoodEntry;
-        if (fge == DIREMPTY)
-        {
-            //directory previously found empty - return false
-            return false;
-        }
-        else if (fge < 0)
-        {
-            // we haven't scanned the list yet so do it first
-            fge = getFirstGoodEntry();
-        }
-
-        return this.itemptr > fge;
-    }
-
-    /**
-     * Returns a single parsed FTPFile object corresponding to the raw input
-     * line at the position preceding that of the internal iterator over
-     * the list of raw lines maintained by this object
-     *
-     * After this method is called the internal iterator is retreated by one
-     * element (unless it is already at beginning of list).
-     * @return a single FTPFile object corresponding to the raw input line
-     * at the position immediately preceding that of the internal iterator
-     * over the list of raw input lines maintained by this object.
-     */
-    public FTPFile previous()
-    {
-        FTPFile[] file = getPrevious(1);
-        if (file.length > 0)
-        {
-            return file[0];
-        }
-        else
-        {
-            return null;
-        }
-    }
-}
diff --git a/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/FTPFileList.java b/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/FTPFileList.java
deleted file mode 100644
index c336ad8..0000000
--- a/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/FTPFileList.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.net.ftp.ftp2;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.Vector;
-import org.apache.commons.net.ftp.FTPFile;
-
-/**
- * FTPFileList.java
- * This class encapsulates a listing of files from an FTP server.  It is 
- * initialized with an input stream which is read and the input split into
- * lines, each of which (after some possible initial verbiage) represents
- * a file on the FTP server.  A parser is also supplied, which is used to
- * iterate through the internal list of lines parsing each into an FTPFile
- * object which is returned to the caller of the iteration methods.  This 
- * parser may be replaced with another, allowing the same list to be parsed
- * with different parsers. 
- * Parsing takes place on an as-needed basis, basically, the first time a 
- * position is iterated over.  This happens at the time of iteration, not 
- * prior to it as the older <code>(FTPClient.listFiles()</code> methods did, 
- * which required a bigger memory hit.
- *
- * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
- * @version $Id$
- * @see FTPClient2#listFiles
- * @see FTPClient2#createFileList
- */
-public class FTPFileList
-{
-    /**
-     * storage for the raw lines of input read from the FTP server
-     */
-    private Vector lines = null;
-    /**
-     * the FTPFileEntryParser assigned to be used with this lister
-     */
-    private FTPFileEntryParser parser;
-    /**
-     * private status code for an empty directory
-     */
-    private static final int EMPTY_DIR = -2;
-
-    /**
-     * The only constructor for FTPFileList, private because
-     * construction only invoked at createFTPFileList()
-     *
-     * @param parser a <code>FTPFileEntryParser</code> value that knows
-     * how to parse the entries returned by a particular FTP site.
-     */
-    private FTPFileList (FTPFileEntryParser parser)
-    {
-        this.parser = parser;
-        this.lines = new Vector();
-    }
-
-    /**
-     * The only way to create an <code>FTPFileList</code> object.  Invokes
-     * the private constructor and then reads the stream  supplied stream to
-     * build the intermediate array of "lines" which will later be parsed
-     * into <code>FTPFile</code> object.
-     *
-     * @param stream The input stream created by reading the socket on which 
-     * the output of the LIST command was returned
-     * @param parser the default <code>FTPFileEntryParser</code> to be used
-     * by this object.  This may later be changed using the init() method.
-     * 
-     * @return the <code>FTPFileList</code> created, with an initialized
-     * of unparsed lines of output.  Will be null if the listing cannot
-     * be read from the stream.
-     * @exception IOException
-     *                   Thrown on any failure to read from the socket.
-     */
-    public static FTPFileList create( InputStream stream,
-                                      FTPFileEntryParser parser)
-            throws IOException
-    {
-        FTPFileList list = new FTPFileList(parser);
-        list.readStream(stream);
-        return list;
-    } 
-
-    /**
-     * internal method for reading the input into the <code>lines</code> vector.
-     * 
-     * @param stream The socket stream on which the input will be read.
-     * 
-     * @exception IOException
-     */
-    private void readStream(InputStream stream) throws IOException
-    {
-        BufferedReader reader =
-            new BufferedReader(new InputStreamReader(stream));
-
-        String line = reader.readLine();
-
-        while (line != null)
-        {
-            this.lines.addElement(line);
-            line = reader.readLine();
-        }
-        reader.close();
-    }
-
-    /**
-     * Accessor for this object's default parser.
-     * 
-     * @return this object's default parser.
-     */
-    FTPFileEntryParser getParser()
-    {
-        return this.parser;
-    }
-
-    /**
-     * Package private accessor for the collection of raw input lines.
-     * 
-     * @return vector containing all the raw input lines returned from the FTP 
-     * server
-     */
-    Vector getLines()
-    {
-        return this.lines;
-    }
-
-    /**
-     * create an iterator over this list using the parser with which this list 
-     * was initally created
-     * 
-     * @return an iterator over this list using the list's default parser.
-     */
-    public FTPFileIterator iterator()
-    {
-        return new FTPFileIterator(this);
-    }
-    /**
-     * create an iterator over this list using the supplied parser
-     * 
-     * @param parser The user-supplied parser with which the list is to be 
-     * iterated, may be different from this list's default parser.
-     * 
-     * @return an iterator over this list using the supplied parser.
-     */
-    public FTPFileIterator iterator(FTPFileEntryParser parser)
-    {
-        return new FTPFileIterator(this, parser);
-    }
-
-
-    /**
-     * returns an array of FTPFile objects for all the files in the directory 
-     * listing
-     *
-     * @return  an array of FTPFile objects for all the files in the directory 
-     * listinge
-     */
-    public FTPFile[] getFiles()
-    {
-        return iterator().getNext(0);
-    }
-}
diff --git a/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/parser/AIXFTPEntryParser.java b/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/parser/AIXFTPEntryParser.java
deleted file mode 100644
index 00ca05f..0000000
--- a/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/parser/AIXFTPEntryParser.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.net.ftp.ftp2.parser;
-
-import java.util.Calendar;
-import org.apache.commons.net.ftp.FTPFile;
-import org.apache.commons.net.ftp.ftp2.FTPFileEntryParser;
-
-/**
- * This class is based on UnixFTPEntryParser with some small changes, namely
- * the day and month fields being the transposed.
- * 
- * @author <a href="mailto:bretts@bml.uk.com">Brett Smith</a>
- * @version $Id$
- */
-public class AIXFTPEntryParser
-  extends MatchApparatus implements FTPFileEntryParser
-{
-  private static final String MONTHS =
-    "(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)";
-  private static final String REGEX =
-    "([bcdlf-])"
-    + "(((r|-)(w|-)(x|-))((r|-)(w|-)(x|-))((r|-)(w|-)(x|-)))\\s+" // permissions
-    + "(\\d+)\\s+" // ln
-    + "(\\S+)\\s+" // user
-    + "(\\S+)\\s+" // group
-    + "(\\d+)\\s+" // size
-    + "((?:[0-9])|(?:[0-2][0-9])|(?:3[0-1]))\\s+" // day
-    + MONTHS + "\\s+" // month
-    + "((\\d\\d\\d\\d)|((?:[01]\\d)|(?:2[0123])):([012345]\\d))\\s" // year
-    + "(\\S+)(\\s*.*)"; // file
-
-    
-  /**
-   * The sole constructor for a AIXFTPEntryParser object.
-   * 
-   * @exception IllegalArgumentException
-   * Thrown if the regular expression is unparseable.  Should not be seen 
-   * under normal conditions.  It it is seen, this is a sign that 
-   * <code>REGEX</code> is  not a valid regular expression.
-   */
-  public AIXFTPEntryParser() 
-  {
-    super(REGEX);
-  }
-
-  /**
-   * Parses a line of a unix (standard) FTP server file listing and converts 
-   * it into a usable format in the form of an <code> FTPFile </code> 
-   * instance.  If the file listing line doesn't describe a file, 
-   * <code> null </code> is returned, otherwise a <code> FTPFile </code> 
-   * instance representing the files in the directory is returned.
-   * <p>
-   * @param entry A line of text from the file listing
-   * @return An FTPFile instance corresponding to the supplied entry
-   */
-  public FTPFile parseFTPEntry(String entry)
-  {
-
-    FTPFile file = new FTPFile();
-    file.setRawListing(entry);
-    int type;
-    boolean isDevice = false;
-
-    if (matches(entry))
-      {
-        String typeStr = group(1);
-        String hardLinkCount = group(15);
-        String usr = group(16);
-        String grp = group(17);
-        String filesize = group(18);
-        String da = group(19);
-        String mo = group(20);
-        String yr = group(22);
-        String hr = group(23);
-        String min = group(24);
-        String name = group(25);
-        String endtoken = group(26);
-
-        switch (typeStr.charAt(0))
-          {
-          case 'd':
-            type = FTPFile.DIRECTORY_TYPE;
-            break;
-          case 'l':
-            type = FTPFile.SYMBOLIC_LINK_TYPE;
-            break;
-          case 'b':
-          case 'c':
-            isDevice = true;
-            // break; - fall through
-          default:
-            type = FTPFile.FILE_TYPE;
-          }
-
-        file.setType(type);
-           
-        int g = 4;
-        for (int access = 0; access < 3; access++, g += 4)
-          {
-            // Use != '-' to avoid having to check for suid and sticky bits
-            file.setPermission(access, FTPFile.READ_PERMISSION,
-                               (!group(g).equals("-")));
-            file.setPermission(access, FTPFile.WRITE_PERMISSION,
-                               (!group(g + 1).equals("-")));
-            file.setPermission(access, FTPFile.EXECUTE_PERMISSION,
-                               (!group(g + 2).equals("-")));
-          }
-
-        if (!isDevice)
-          {
-            try
-              {
-                file.setHardLinkCount(Integer.parseInt(hardLinkCount));
-              }
-            catch (NumberFormatException e)
-              {
-                // intentionally do nothing
-              }
-          }
-
-        file.setUser(usr);
-        file.setGroup(grp);
-
-        try
-          {
-            file.setSize(Integer.parseInt(filesize));
-          }
-        catch (NumberFormatException e)
-          {
-            // intentionally do nothing
-          }
-
-        Calendar cal = Calendar.getInstance();
-        cal.set(Calendar.SECOND, 0);
-        cal.set(Calendar.MINUTE, 0);
-        cal.set(Calendar.HOUR_OF_DAY, 0);
-
-        try
-          {
-            int pos = MONTHS.indexOf(mo);
-            int month = pos / 4;
-
-            if (null != yr)
-              {
-                // it's a year
-                cal.set(Calendar.YEAR, Integer.parseInt(yr));
-              }
-            else
-              {
-                // it must be  hour/minute or we wouldn't have matched
-                int year = cal.get(Calendar.YEAR);
-                // if the month we're reading is greater than now, it must
-                // be last year
-                if (cal.get(Calendar.MONTH) < month)
-                  {
-                    year--;
-                  }
-                cal.set(Calendar.YEAR, year);
-                cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hr));
-                cal.set(Calendar.MINUTE, Integer.parseInt(min));
-              }
-            cal.set(Calendar.MONTH, month);
-
-            cal.set(Calendar.DATE, Integer.parseInt(da));
-            file.setTimestamp(cal);
-          }
-        catch (NumberFormatException e)
-          {
-            // do nothing, date will be uninitialized
-          }
-        if (null == endtoken)
-          {
-            file.setName(name);
-          }
-        else
-          {
-            // oddball cases like symbolic links, file names
-            // with spaces in them.
-            name += endtoken;
-            if (type == FTPFile.SYMBOLIC_LINK_TYPE)
-              {
-
-                int end = name.indexOf(" -> ");
-                // Give up if no link indicator is present
-                if (end == -1)
-                  {
-                    file.setName(name);
-                  }
-                else
-                  {
-                    file.setName(name.substring(0, end));
-                    file.setLink(name.substring(end + 4));
-                  }
-
-              }
-            else
-              {
-                file.setName(name);
-              }
-          }
-        return file;
-      }
-    return null;
-  }
-}
diff --git a/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/parser/EnterpriseUnixFTPEntryParser.java b/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/parser/EnterpriseUnixFTPEntryParser.java
deleted file mode 100644
index e5f3ca3..0000000
--- a/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/parser/EnterpriseUnixFTPEntryParser.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.net.ftp.ftp2.parser;
-
-import java.util.Calendar;
-
-import org.apache.commons.net.ftp.FTPFile;
-import org.apache.commons.net.ftp.ftp2.FTPFileEntryParser;
-
-/**
- * Parser for the Connect Enterprise Unix FTP Server From Sterling Commerce.  
- * @version $Id$
- * @author <a href="Winston.Ojeda@qg.com">Winston Ojeda</a>
- */
-public class EnterpriseUnixFTPEntryParser extends MatchApparatus
-    implements FTPFileEntryParser
-{
-
-    // sample output line
-    //"-C--E-----FTP B QUA1I1      18128       41 Aug 12 13:56 QUADTEST"
-    private static final String MONTHS = "(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)";
-    private static final String REGEX = 
-        "(([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z])([\\-]|[A-Z]))" + 
-         "(\\S*)\\s*" + "(\\S+)\\s*" + "(\\S*)\\s*" + "(\\d*)\\s*" + 
-         "(\\d*)\\s*" + MONTHS + "\\s*" + "((?:[012]\\d*)|(?:3[01]))\\s*" + 
-         "((\\d\\d\\d\\d)|((?:[01]\\d)|(?:2[0123])):([012345]\\d))\\s" + 
-         "(\\S*)(\\s*.*)";
-
-    /**
-     * The sole constructor for a EnterpriseUnixFTPEntryParser object.
-     * 
-     */
-    public EnterpriseUnixFTPEntryParser()
-    {
-        super(REGEX);
-    }
-
-    /**
-     * Parses a line of a unix FTP server file listing and converts  it into a
-     * usable format in the form of an <code> FTPFile </code>  instance.  If
-     * the file listing line doesn't describe a file,  <code> null </code> is
-     * returned, otherwise a <code> FTPFile </code>  instance representing the
-     * files in the directory is returned.
-     * 
-     * @param entry A line of text from the file listing
-     * @return An FTPFile instance corresponding to the supplied entry
-     */
-    public FTPFile parseFTPEntry(String entry)
-    {
-
-        FTPFile file = new FTPFile();
-        file.setRawListing(entry);
-
-        int type;
-        boolean isDevice = false;
-        if (matches(entry))
-        {
-            String usr = group(14);
-            String grp = group(15);
-            String filesize = group(16);
-            String mo = group(17);
-            String da = group(18);
-            String yr = group(20);
-            String hr = group(21);
-            String min = group(22);
-            String name = group(23);
-
-            file.setType(FTPFile.FILE_TYPE);
-            file.setUser(usr);
-            file.setGroup(grp);
-            try
-            {
-                file.setSize(Integer.parseInt(filesize));
-            }
-            catch (NumberFormatException e)
-            {
-                // intentionally do nothing
-            }
-
-            Calendar cal = Calendar.getInstance();
-            cal.set(Calendar.SECOND, 
-                    0);
-            cal.set(Calendar.MINUTE, 
-                    0);
-            cal.set(Calendar.HOUR_OF_DAY, 
-                    0);
-            try
-            {
-
-                int pos = MONTHS.indexOf(mo);
-                int month = pos / 4;
-                if (yr != null)
-                {
-                    // it's a year
-                    cal.set(Calendar.YEAR, 
-                            Integer.parseInt(yr));
-                }
-                else
-                {
-                    // it must be  hour/minute or we wouldn't have matched
-                    int year = cal.get(Calendar.YEAR);
-
-                    // if the month we're reading is greater than now, it must
-                    // be last year
-                    if (cal.get(Calendar.MONTH) < month)
-                    {
-                        year--;
-                    }
-                    cal.set(Calendar.YEAR, 
-                            year);
-                    cal.set(Calendar.HOUR_OF_DAY, 
-                            Integer.parseInt(hr));
-                    cal.set(Calendar.MINUTE, 
-                            Integer.parseInt(min));
-                }
-                cal.set(Calendar.MONTH, 
-                        month);
-                cal.set(Calendar.DATE, 
-                        Integer.parseInt(da));
-                file.setTimestamp(cal);
-            }
-            catch (NumberFormatException e)
-            {
-                // do nothing, date will be uninitialized
-            }
-            file.setName(name);
-
-            return file;
-        }
-        return null;
-    }
-}
diff --git a/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/parser/MatchApparatus.java b/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/parser/MatchApparatus.java
deleted file mode 100644
index aace62f..0000000
--- a/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/parser/MatchApparatus.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.net.ftp.ftp2.parser;
-
-import org.apache.oro.text.regex.Pattern;
-import org.apache.oro.text.regex.MalformedPatternException;
-import org.apache.oro.text.regex.PatternMatcher;
-import org.apache.oro.text.regex.Perl5Matcher;
-import org.apache.oro.text.regex.Perl5Compiler;
-import org.apache.oro.text.regex.MatchResult;
-
-/**
- * This class is based on the logic of Winston Ojeda's ListParser.  It uses
- * a similar approach to Regular Expressions but is designed to fit within
- * FTPFileEntryParser design rather than the FTPFileListParser design.
- * It is also designed to encapsulate access to the oro.text.regex
- * classes in one place.
- * @author <a href="mailto:scohen@ignitesports.com">Steve Cohen</a>
- * @version $Id$
- */
-abstract class MatchApparatus
-{
-    private String prefix;
-    private Pattern pattern = null;
-    private PatternMatcher matcher = null;
-    private MatchResult result = null;
-    
-    /**
-     * The constructor for a MatchApparatus object.
-     * 
-     * @param regex  The regular expression with which this object is 
-     * initialized.
-     * 
-     * @exception IllegalArgumentException
-     * Thrown if the regular expression is unparseable.  Should not be seen in 
-     * normal conditions.  It it is seen, this is a sign that a subclass has 
-     * been created with a bad regular expression.   Since the parser must be 
-     * created before use, this means that any bad parser subclasses created 
-     * from this will bomb very quickly,  leading to easy detection.  
-     */
-    MatchApparatus(String regex) 
-    {
-        try 
-        {
-            this.prefix = "[" + getClass().getName() + "] ";
-            this.matcher = new Perl5Matcher();
-            this.pattern = new Perl5Compiler().compile(regex);
-        } 
-        catch (MalformedPatternException e) 
-        {
-            throw new IllegalArgumentException (
-                "Unparseable regex supplied:  " + regex);
-        }
-    }
-
-
-    /**
-     * Convenience method delegates to the internal MatchResult's matches()
-     * method.
-     *
-     * @param s the String to be matched
-     * @return true if s matches this object's regular expression.
-     */
-    public boolean matches(String s)
-    {
-        result = null;
-        if (matcher.matches(s.trim(), this.pattern))
-        {
-            this.result = matcher.getMatch();
-        }
-        return null != this.result;
-    }
-
-    /**
-     * Convenience method delegates to the internal MatchResult's groups()
-     * method.
-     *
-     * @return the number of groups() in the internal MatchResult.
-     */
-    public int getGroupCnt()
-    {
-        if (this.result == null)
-        {
-            return 0;
-        }
-        return this.result.groups();
-    }
-
-    /**
-     * Convenience method delegates to the internal MatchResult's group()
-     * method.  
-     *
-     * @return the content of the <code>matchnum'th<code> group of the internal
-     * match or null if this method is called without a match having been made.
-     */
-    public String group(int matchnum)
-    {
-        if (this.result == null)
-        {
-            return null;
-        }
-        return this.result.group(matchnum);
-    }
-
-    /**
-     * For debugging purposes - returns a string shows each match group by 
-     * number.
-     * 
-     * @return a string shows each match group by number.
-     */
-    public String getGroupsAsString()
-    {
-        StringBuffer b = new StringBuffer();
-        for (int i = 1; i <= this.result.groups(); i++)
-        {
-            b.append(i).append(") ").append(this.result.group(i))
-                .append(System.getProperty("line.separator"));
-        }
-        return b.toString() ;
-
-    }
-}
diff --git a/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/parser/NTFTPEntryParser.java b/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/parser/NTFTPEntryParser.java
deleted file mode 100644
index 50058ec..0000000
--- a/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/parser/NTFTPEntryParser.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.net.ftp.ftp2.parser;
-
-import java.util.Calendar;
-import org.apache.commons.net.ftp.FTPFile;
-import org.apache.commons.net.ftp.ftp2.FTPFileEntryParser;
-
-/**
- * This Class uses the ListParser class to validate the input string.
- * It also requires the NetComponents library version 1.3.7 or later
- * and the OROMatcher library for the regualar expressions stuff.
- *
- *
- * <P><B>USAGE:</B></P>
- * <LI>Create an instance of NTListParser</LI>
- *   <dd>NTListParser parser = new NTListParser();
- * <LI>Create an instance of FTPClient</LI>
- *   <dd>FTPClient FTPClientObj = new FTPClient();
- * <LI>Connect to the NODE </LI>
- *   <dd>FTPClientObj.connect();
- * <LI>Login to the NODE </LI>
- *   <dd>FTPClientObj.login(username,password);
- * <LI>Switch directories if you have to</LI>
- *   <dd>FTPClientObj.changeWorkingDirectory(thePath);
- * <LI>You might want to check if you are truly in a NT System</LI>
- *   <dd><B>String am_I_NT =  FTPClientObj.getSystemName()</B>
- *    <dd>parse am_I_NT to find out
- * <LI>Call listFiles passing the newly created parser and a filename or a 
- * mask to look for </LI>
- *   <dd>FTPClientObj.listFiles(parser,filename);
- * <LI>You'll get back the list as an array of FTPFiles like this
- *   <dd>FTPFile[] myNTFiles = FTPClientObj.listFiles(parser,filename);  (or)
- *    <dd>FTPFile[] myNTFiles = FTPClientObj.listFiles(parser);
- * <P>
- * That's all there is to it.
- * <P>
- * Each FTPFile object is populated just like any other FTPFile
- * object. The only thing not implemented at this time is the file
- * permissions, but I can do it if there is a real need for it.
- * <P>
- * !NOTE/WARNING!:Before you pass the parser to listFiles, make sure you are in 
- * the directory that you need to be. This parser will return the filtered
- * files from the directory it is in. This becomes crucial specialy if your
- * goal is to delete the output of the parser.
- * <P>
- *
- * @author  <a href="Winston.Ojeda@qg.com">Winston Ojeda</a>
- * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
- * @version $Id$
- * @see org.apache.commons.net.ftp.FTPFileListParser
- */
-public class NTFTPEntryParser
-            extends MatchApparatus implements FTPFileEntryParser
-{
-    private static final String REGEX =
-        "((?:0[1-9])|(?:1[0-2]))-" +
-        "((?:0[1-9])|(?:[1-2]\\d)|(?:3[0-1]))-" +
-        "(\\d\\d)\\s*" +
-        "((?:0[1-9])|(?:1[012])):" +
-        "([0-5]\\d)\\s*" +
-        "([AP])M\\s*" +
-        "(<DIR>)?\\s*" +
-        "([0-9]+)?\\s*" +
-        "(\\S.*)";
-
-    /**
-     * The sole constructor for an NTFTPEntryParser object.
-     * 
-     * @exception IllegalArgumentException
-     * Thrown if the regular expression is unparseable.  Should not be seen 
-     * under normal conditions.  It it is seen, this is a sign that 
-     * <code>REGEX</code> is  not a valid regular expression.
-     */
-    public NTFTPEntryParser() 
-    {
-        super(REGEX);
-    }
-
-
-    /**
-     * Parses a line of an NT FTP server file listing and converts it into a
-     * usable format in the form of an <code> FTPFile </code> instance.  If the
-     * file listing line doesn't describe a file, <code> null </code> is
-     * returned, otherwise a <code> FTPFile </code> instance representing the
-     * files in the directory is returned.
-     * <p>
-     * @param entry A line of text from the file listing
-     * @return An FTPFile instance corresponding to the supplied entry
-     */
-    public FTPFile parseFTPEntry(String entry)
-    {
-        FTPFile f = new FTPFile();
-        f.setRawListing(entry);
-        int type;
-        boolean isDevice = false;
-
-        if (matches(entry))
-        {
-            String mo = group(1);
-            String da = group(2);
-            String yr = group(3);
-            String hr = group(4);
-            String min = group(5);
-            String ampm = group(6);
-            String dirString = group(7);
-            String size = group(8);
-            String name = group(9);
-            if (null == name || name.equals(".") || name.equals(".."))
-            {
-                return (null);
-            }
-            f.setName(name);
-            //convert all the calendar stuff to ints
-            int month = new Integer(mo).intValue() - 1;
-            int day = new Integer(da).intValue();
-            int year = new Integer(yr).intValue() + 2000;
-            int hour = new Integer(hr).intValue();
-            int minutes = new Integer(min).intValue();
-
-            // Y2K stuff? this will break again in 2080 but I will
-            // be sooooo dead anyways who cares.
-            // SMC - IS NT's directory date REALLY still not Y2K-compliant?
-            if (year > 2080)
-            {
-                year -= 100;
-            }
-
-            Calendar cal = Calendar.getInstance();
-            //set the calendar
-            cal.set(Calendar.SECOND, 0);
-            cal.set(Calendar.MINUTE, minutes);
-            cal.set(Calendar.HOUR, hour);
-            cal.set(Calendar.YEAR, year);
-            cal.set(Calendar.DATE, day);
-            cal.set(Calendar.MONTH, month);
-            int ap = Calendar.AM;
-            if ("P".equals(ampm))
-            {
-                ap = Calendar.PM;
-            }
-            cal.set(Calendar.AM_PM, ap);
-            f.setTimestamp(cal);
-
-            if ("<DIR>".equals(dirString))
-            {
-                f.setType(FTPFile.DIRECTORY_TYPE);
-                f.setSize(0);
-            }
-            else
-            {
-                f.setType(FTPFile.FILE_TYPE);
-                if (null != size)
-                {
-                    f.setSize(new Integer(size).intValue());
-                }
-            }
-            return (f);
-        }
-        return null;
-    }
-}
diff --git a/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/parser/OS2FTPEntryParser.java b/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/parser/OS2FTPEntryParser.java
deleted file mode 100644
index 4caa994..0000000
--- a/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/parser/OS2FTPEntryParser.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.net.ftp.ftp2.parser;
-
-import java.util.Calendar;
-import org.apache.commons.net.ftp.FTPFile;
-import org.apache.commons.net.ftp.ftp2.FTPFileEntryParser;
-
-/**
- * This Class uses the ListParser class to validate the input string.
- * It also requires the NetComponents library version 1.3.7 or later
- * and the OROMatcher library for the regualar expressions stuff.
- *
- *
- * <P><B>USAGE:</B></P>
- * <LI>Create an instance of OS2FTPEntryParser</LI>
- *   <dd>OS2FTPEntryParser parser = new OS2FTPEntryParser();
- * <LI>Create an instance of FTPClient</LI>
- *   <dd>FTPClient FTPClientObj = new FTPClient();
- * <LI>Connect to the NODE </LI>
- *   <dd>FTPClientObj.connect();
- * <LI>Login to the NODE </LI>
- *   <dd>FTPClientObj.login(username,password);
- * <LI>Switch directories if you have to</LI>
- *   <dd>FTPClientObj.changeWorkingDirectory(thePath);
- * <LI>You might want to check if you are truly in a OS2 System</LI>
- *   <dd><B>String am_I_OS2 =  FTPClientObj.getSystemName()</B>
- *    <dd>parse am_I_OS2 to find out
- * <LI>Call listFiles passing the newly created parser and a filename or a mask 
- * to look for </LI>
- *   <dd>FTPClientObj.listFiles(parser,filename);
- * <LI>You'll get back the list as an array of FTPFiles like this
- *   <dd>FTPFile[] myOS2Files = FTPClientObj.listFiles(parser,filename);  (or)
- *    <dd>FTPFile[] myOS2Files = FTPClientObj.listFiles(parser);
- * <P>
- * That's all there is to it.
- * <P>
- * Each FTPFile object is populated just like any other FTPFile
- * object. The only thing not implemented at this time is the file
- * permissions, but I can do it if there is a real need for it.
- * <P>
- * !NOTE/WARNING!:Before you pass the parser to listFiles, make sure you are 
- * in the directory that you need to be. This parser will return the filtered
- * files from the directory it is in. This becomes specially crucial if your
- * goal is to delete the output of the parser.
- * <P>
- * @author  <a href="Winston.Ojeda@qg.com">Winston Ojeda</a>
- * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
- * @version $Id$
- * @see org.apache.commons.net.ftp.FTPFileListParser
- */
-public class OS2FTPEntryParser
-            extends MatchApparatus implements FTPFileEntryParser
-
-{
-    private static final String REGEX =
-        "(\\s+|[0-9]+)\\s*" +
-        "(\\s+|[A-Z]+)\\s*" +
-        "(DIR|\\s+)\\s*" +
-        "((?:0[1-9])|(?:1[0-2]))-" +
-        "((?:0[1-9])|(?:[1-2]\\d)|(?:3[0-1]))-" +
-        "(\\d\\d)\\s*" +
-        "(?:([0-1]\\d)|(?:2[0-3])):" +
-        "([0-5]\\d)\\s*" +
-        "(\\S.*)";
-    
-    /**
-     * The sole constructor for a OS2FTPEntryParser object.
-     * 
-     * @exception IllegalArgumentException
-     * Thrown if the regular expression is unparseable.  Should not be seen 
-     * under normal conditions.  It it is seen, this is a sign that 
-     * <code>REGEX</code> is  not a valid regular expression.
-     */
-    public OS2FTPEntryParser() 
-    {
-        super(REGEX);
-    }
-
-
-    /**
-     * Parses a line of an OS2 FTP server file listing and converts it into a
-     * usable format in the form of an <code> FTPFile </code> instance.  If the
-     * file listing line doesn't describe a file, <code> null </code> is
-     * returned, otherwise a <code> FTPFile </code> instance representing the
-     * files in the directory is returned.
-     * <p>
-     * @param entry A line of text from the file listing
-     * @return An FTPFile instance corresponding to the supplied entry
-     */
-    public FTPFile parseFTPEntry(String entry)
-    {
-
-        FTPFile f = new FTPFile();
-        if (matches(entry))
-        {
-            String size = group(1);
-            String attrib = group(2);
-            String dirString = group(3);
-            String mo = group(4);
-            String da = group(5);
-            String yr = group(6);
-            String hr = group(7);
-            String min = group(8);
-            String name = group(9);
-
-            //is it a DIR or a file
-            if (dirString.trim().equals("DIR") || attrib.trim().equals("DIR"))
-            {
-                f.setType(FTPFile.DIRECTORY_TYPE);
-            }
-            else
-            {
-                f.setType(FTPFile.FILE_TYPE);
-            }
-
-            Calendar cal = Calendar.getInstance();
-
-
-            //convert all the calendar stuff to ints
-            int month = new Integer(mo).intValue() - 1;
-            int day = new Integer(da).intValue();
-            int year = new Integer(yr).intValue() + 2000;
-            int hour = new Integer(hr).intValue();
-            int minutes = new Integer(min).intValue();
-
-            // Y2K stuff? this will break again in 2080 but I will
-            // be sooooo dead anyways who cares.
-            // SMC - IS OS2's directory date REALLY still not Y2K-compliant?
-            if (year > 2080) 
-            {
-                year -= 100;
-            }
-
-            //set the calendar
-            cal.set(Calendar.SECOND, 0);
-            cal.set(Calendar.MINUTE, minutes);
-            cal.set(Calendar.HOUR_OF_DAY, hour);
-            cal.set(Calendar.YEAR, year);
-            cal.set(Calendar.DATE, day);
-            cal.set(Calendar.MONTH, month);
-            f.setTimestamp(cal);
-
-            //set the name
-            f.setName(name.trim());
-
-            //set the size
-            Long theSize = new Long(size.trim());
-            theSize = new Long(String.valueOf(theSize.intValue()));
-            f.setSize(theSize.longValue());
-
-            return (f);
-        }
-        return null;
-
-    }
-}
diff --git a/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/parser/UnixFTPEntryParser.java b/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/parser/UnixFTPEntryParser.java
deleted file mode 100644
index 6354701..0000000
--- a/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/parser/UnixFTPEntryParser.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.net.ftp.ftp2.parser;
-
-import java.util.Calendar;
-import org.apache.commons.net.ftp.FTPFile;
-import org.apache.commons.net.ftp.ftp2.FTPFileEntryParser;
-
-/**
- * This class is based on the logic of Daniel Savarese's
- * DefaultFTPListParser, but adapted to use regular expressions and to fit the
- * new FTPFileEntryParser interface.
- * @author <a href="mailto:scohen@ignitesports.com">Steve Cohen</a>
- * @version $Id$
- */
-public class UnixFTPEntryParser
-            extends MatchApparatus implements FTPFileEntryParser
-{
-    private static final String MONTHS =
-        "(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)";
-    private static final String REGEX =
-        "([bcdlf-])"
-        + "(((r|-)(w|-)(x|-))((r|-)(w|-)(x|-))((r|-)(w|-)(x|-)))\\s+"
-        + "(\\d+)\\s+"
-        + "(\\S+)\\s+"
-        + "(\\S+)\\s+"
-        + "(\\d+)\\s+"
-        + MONTHS + "\\s+"
-        + "((?:[0-9])|(?:[0-2][0-9])|(?:3[0-1]))\\s+"
-        + "((\\d\\d\\d\\d)|((?:[01]\\d)|(?:2[0123])):([012345]\\d))\\s"
-        + "(\\S+)(\\s*.*)";
-
-    
-    /**
-     * The sole constructor for a UnixFTPEntryParser object.
-     * 
-     * @exception IllegalArgumentException
-     * Thrown if the regular expression is unparseable.  Should not be seen 
-     * under normal conditions.  It it is seen, this is a sign that 
-     * <code>REGEX</code> is  not a valid regular expression.
-     */
-    public UnixFTPEntryParser() 
-    {
-        super(REGEX);
-    }
-
-    /**
-     * Parses a line of a unix (standard) FTP server file listing and converts 
-     * it into a usable format in the form of an <code> FTPFile </code> 
-     * instance.  If the file listing line doesn't describe a file, 
-     * <code> null </code> is returned, otherwise a <code> FTPFile </code> 
-     * instance representing the files in the directory is returned.
-     * <p>
-     * @param entry A line of text from the file listing
-     * @return An FTPFile instance corresponding to the supplied entry
-     */
-    public FTPFile parseFTPEntry(String entry)
-    {
-
-        FTPFile file = new FTPFile();
-        file.setRawListing(entry);
-        int type;
-        boolean isDevice = false;
-
-        if (matches(entry))
-        {
-            String typeStr = group(1);
-            String hardLinkCount = group(15);
-            String usr = group(16);
-            String grp = group(17);
-            String filesize = group(18);
-            String mo = group(19);
-            String da = group(20);
-            String yr = group(22);
-            String hr = group(23);
-            String min = group(24);
-            String name = group(25);
-            String endtoken = group(26);
-
-            switch (typeStr.charAt(0))
-            {
-            case 'd':
-                type = FTPFile.DIRECTORY_TYPE;
-                break;
-            case 'l':
-                type = FTPFile.SYMBOLIC_LINK_TYPE;
-                break;
-            case 'b':
-            case 'c':
-                isDevice = true;
-                // break; - fall through
-            default:
-                type = FTPFile.FILE_TYPE;
-            }
-
-            file.setType(type);
-           
-            int g = 4;
-            for (int access = 0; access < 3; access++, g += 4)
-            {
-                // Use != '-' to avoid having to check for suid and sticky bits
-                file.setPermission(access, FTPFile.READ_PERMISSION,
-                                   (!group(g).equals("-")));
-                file.setPermission(access, FTPFile.WRITE_PERMISSION,
-                                   (!group(g + 1).equals("-")));
-                file.setPermission(access, FTPFile.EXECUTE_PERMISSION,
-                                   (!group(g + 2).equals("-")));
-            }
-
-            if (!isDevice)
-            {
-                try
-                {
-                    file.setHardLinkCount(Integer.parseInt(hardLinkCount));
-                }
-                catch (NumberFormatException e)
-                {
-                    // intentionally do nothing
-                }
-            }
-
-            file.setUser(usr);
-            file.setGroup(grp);
-
-            try
-            {
-                file.setSize(Integer.parseInt(filesize));
-            }
-            catch (NumberFormatException e)
-            {
-                // intentionally do nothing
-            }
-
-            Calendar cal = Calendar.getInstance();
-            cal.set(Calendar.SECOND, 0);
-            cal.set(Calendar.MINUTE, 0);
-            cal.set(Calendar.HOUR_OF_DAY, 0);
-
-            try
-            {
-                int pos = MONTHS.indexOf(mo);
-                int month = pos / 4;
-
-                if (null != yr)
-                {
-                    // it's a year
-                    cal.set(Calendar.YEAR, Integer.parseInt(yr));
-                }
-                else
-                {
-                    // it must be  hour/minute or we wouldn't have matched
-                    int year = cal.get(Calendar.YEAR);
-                    // if the month we're reading is greater than now, it must
-                    // be last year
-                    if (cal.get(Calendar.MONTH) < month)
-                    {
-                        year--;
-                    }
-                    cal.set(Calendar.YEAR, year);
-                    cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hr));
-                    cal.set(Calendar.MINUTE, Integer.parseInt(min));
-                }
-                cal.set(Calendar.MONTH, month);
-
-                cal.set(Calendar.DATE, Integer.parseInt(da));
-                file.setTimestamp(cal);
-            }
-            catch (NumberFormatException e)
-            {
-                // do nothing, date will be uninitialized
-            }
-            if (null == endtoken)
-            {
-                file.setName(name);
-            }
-            else
-            {
-                // oddball cases like symbolic links, file names
-                // with spaces in them.
-                name += endtoken;
-                if (type == FTPFile.SYMBOLIC_LINK_TYPE)
-                {
-
-                    int end = name.indexOf(" -> ");
-                    // Give up if no link indicator is present
-                    if (end == -1)
-                    {
-                        file.setName(name);
-                    }
-                    else
-                    {
-                        file.setName(name.substring(0, end));
-                        file.setLink(name.substring(end + 4));
-                    }
-
-                }
-                else
-                {
-                    file.setName(name);
-                }
-            }
-            return file;
-        }
-        return null;
-    }
-}
diff --git a/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/parser/VMSFTPEntryParser.java b/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/parser/VMSFTPEntryParser.java
deleted file mode 100644
index f67d7f5..0000000
--- a/proposal/ftp2/src/java/org/apache/commons/net/ftp/ftp2/parser/VMSFTPEntryParser.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.net.ftp.ftp2.parser;
-
-import java.util.Calendar;
-import org.apache.commons.net.ftp.FTPFile;
-import org.apache.commons.net.ftp.ftp2.FTPFileEntryParser;
-
-/**
- * This Class uses the FTPEntryParser class to validate the input string.
- * It also requires the NetComponents library version 1.3.7 or later
- * and the OROMatcher library for the regualar expressions stuff.
- *
- *
- * <P><B>USAGE:</B></P>
- * <LI>Create an instance of VMSFTPEntryParser</LI>
- *   <dd>VMSFTPEntryParser parser = new VMSFTPEntryParser(boolean);
- *  <dd><code>True</code>  = returns all versions of a file with the respective 
- * ;#
- *  <dd><code>False</code> = only the last version will return <B>(Default)</B>
- * <LI>Create an instance of FTPClient</LI>
- *   <dd>FTPClient FTPClientObj = new FTPClient();
- * <LI>Connect to the NODE </LI>
- *   <dd>FTPClientObj.connect();
- * <LI>Login to the NODE </LI>
- *   <dd>FTPClientObj.login(username,password);
- * <LI>Switch directories if you have to</LI>
- *   <dd>FTPClientObj.changeWorkingDirectory(thePath);
- * <LI>You might want to check if you are truly in a VMS System</LI>
- *   <dd>And how do I do that you ask? easy...  VMS is such a wonderful OS 
- * that when we do   <dd><B>String am_I_VMS =  FTPClientObj.getSystemName()</B>
- *   <dd>it returns NULL, while everyone else returns the FTP servername
- * <LI>Call listFiles passing the newly created parser and a filename or a mask
- *  to look for </LI> <dd>FTPClientObj.listFiles(parser,filename);
- * <LI>You'll get back the list as an array of FTPFile objects like this
- *   <dd>FTPFile[] myVMSFiles = FTPClientObj.listFiles(parser,filename);  (or)
- *    <dd>FTPFile[] myVMSFiles = FTPClientObj.listFiles(parser);
- *    <dd>If <code>filename</code> is a filename and versioning is OFF, the 
- * version <dd>you requested will come back without the ;#
- * <P>
- * That's all there is to it.
- * <P>
- * Each FTPFile object is populated just like any other FTPFile
- * object. The only thing not implemented at this time is the file
- * permissions, but I can do it if there is a real need for it.
- * <P>
- * !NOTE/WARNING!:Before you pass the parser to listFiles, make sure you are
- * in the directory that you need to be. This parser will return the filtered
- * files from the directory it is in. This becomes crucial specialy if your
- * goal is to delete the output of the parser.
- * <P>
- * @author  <a href="Winston.Ojeda@qg.com">Winston Ojeda</a>
- * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
- * @version $Id$
- */
-public class VMSFTPEntryParser
-            extends MatchApparatus implements FTPFileEntryParser
-{
-    private String prefix = "[" + getClass().getName() + "] ";
-    private boolean versioning;
-
-    /* This is how a VMS LIST output really looks
-    
-          "1-JUN.LIS;1              9/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,RE)",
-          "1-JUN.LIS;2              9/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,RE)",
-          "DATA.DIR;1               1/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,RE)",
-    */
-    private static final String MONTHS =
-        "(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)";
-
-    private static final String REGEX =
-        "(.*;[0-9]+)\\s*" +
-        "(\\d+)/\\d+\\s*" +
-        "(\\d{1,2})-" +
-        MONTHS +
-        "-([0-9]{4})\\s*" +
-        "((?:[01]\\d)|(?:2[0-3])):([012345]\\d):([012345]\\d)\\s*" +
-        "\\[([0-9$A-Za-z_]+),([0-9$a-zA-Z_]+)\\]\\s*" +
-        "(\\([a-zA-Z]*,[a-zA-Z]*,[a-zA-Z]*,[a-zA-Z]*\\))";
-
-
-    /**
-     * Convenience Constructor for a VMSFTPEntryParser object.  Sets the 
-     * <code>versioning</code> member false
-     * 
-     * @exception IllegalArgumentException
-     * Thrown if the regular expression is unparseable.  Should not be seen 
-     * under normal conditions.  It it is seen, this is a sign that 
-     * <code>REGEX</code> is  not a valid regular expression.
-     */
-    public VMSFTPEntryParser()
-    {
-        this(false);
-    }
-    
-    /**
-     * Constructor for a VMSFTPEntryParser object.  Sets the versioning member 
-     * to the supplied value.
-     *  
-     * @param versioning Value to which versioning is to be set.
-     * 
-     * @exception IllegalArgumentException
-     * Thrown if the regular expression is unparseable.  Should not be seen 
-     * under normal conditions.  It it is seen, this is a sign that 
-     * <code>REGEX</code> is  not a valid regular expression.
-     */
-    public VMSFTPEntryParser(boolean versioning)
-    {
-        super(REGEX);
-        this.versioning = versioning;
-    }
-
-    /**
-     * Parses a line of a VMS FTP server file listing and converts it into a
-     * usable format in the form of an <code> FTPFile </code> instance.  If the
-     * file listing line doesn't describe a file, <code> null </code> is
-     * returned, otherwise a <code> FTPFile </code> instance representing the
-     * files in the directory is returned.
-     * <p>
-     * @param entry A line of text from the file listing
-     * @return An FTPFile instance corresponding to the supplied entry
-     */
-    public FTPFile parseFTPEntry(String entry)
-    {
-        //one block in VMS equals 512 bytes
-        Integer oneBlock = new Integer(512);
-        int intBlock = oneBlock.intValue();
-        long longBlock = 512;
-
-
-        if (matches(entry))
-        {
-            FTPFile f = new FTPFile();
-            f.setRawListing(entry);
-            String name = group(1);
-            String size = group(2);
-            String day = group(3);
-            String mo = group(4);
-            String yr = group(5);
-            String hr = group(6);
-            String min = group(7);
-            String sec = group(8);
-            String grp = group(9);
-            String owner = group(10);
-
-            if (name.lastIndexOf(".DIR") != -1) 
-            {
-                f.setType(FTPFile.DIRECTORY_TYPE);
-            } 
-            else 
-            {
-                f.setType(FTPFile.FILE_TYPE);
-            }
-            //set FTPFile name
-            //Check also for versions to be returned or not
-            if (versioning) 
-            {
-                f.setName(name);
-            } 
-            else 
-            {
-                name = name.substring(0, name.lastIndexOf(";"));
-                f.setName(name);
-            }
-            //size is retreived in blocks and needs to be put in bytes
-            //for us humans and added to the FTPFile array
-            Long theSize = new Long(size);
-            long sizeInBytes = theSize.longValue() * longBlock;
-            f.setSize(sizeInBytes);
-
-            //set the date
-            Calendar cal = Calendar.getInstance();
-
-            cal.clear();
-
-            cal.set(Calendar.DATE, new Integer(day).intValue());
-            cal.set(Calendar.MONTH, MONTHS.indexOf(mo) / 4);
-            cal.set(Calendar.YEAR, new Integer(yr).intValue());
-            cal.set(Calendar.HOUR_OF_DAY, new Integer(hr).intValue());
-            cal.set(Calendar.MINUTE, new Integer(min).intValue());
-            cal.set(Calendar.SECOND, new Integer(sec).intValue());
-            f.setTimestamp(cal);
-
-            f.setGroup(grp);
-            f.setUser(owner);
-            //set group and owner
-            //Since I don't need the persmissions on this file (RWED), I'll 
-            //leave that for further development. 'Cause it will be a bit 
-            //elaborate to do it right with VMSes World, Global and so forth.
-            return f;
-        }
-        return null;
-    }
-}
diff --git a/proposal/ftp2/src/test/org/apache/commons/net/ftp/ftp2/parser/EnterpriseUnixFTPEntryParserTest.java b/proposal/ftp2/src/test/org/apache/commons/net/ftp/ftp2/parser/EnterpriseUnixFTPEntryParserTest.java
deleted file mode 100644
index 751eaf8..0000000
--- a/proposal/ftp2/src/test/org/apache/commons/net/ftp/ftp2/parser/EnterpriseUnixFTPEntryParserTest.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.net.ftp.ftp2.parser;
-
-import junit.framework.TestSuite;
-
-import org.apache.commons.net.ftp.FTPFile;
-import org.apache.commons.net.ftp.ftp2.FTPFileEntryParser;
-
-/**
- * Tests the EnterpriseUnixFTPEntryParser
- * 
- * @version $Id$
- * @author <a href="mailto:Winston.Ojeda@qg.com">Winston Ojeda</a>
- */
-public class EnterpriseUnixFTPEntryParserTest extends FTPParseTestFramework
-{
-
-    private static final String[] BADSAMPLES = 
-    {
-        "zrwxr-xr-x   2 root     root         4096 Mar  2 15:13 zxbox", 
-        "dxrwr-xr-x   2 root     root         4096 Aug 24  2001 zxjdbc", 
-        "drwxr-xr-x   2 root     root         4096 Jam  4 00:03 zziplib", 
-        "drwxr-xr-x   2 root     99           4096 Feb 23 30:01 zzplayer", 
-        "drwxr-xr-x   2 root     root         4096 Aug 36  2001 zztpp", 
-        "-rw-r--r--   1 14       staff       80284 Aug 22  zxJDBC-1.2.3.tar.gz", 
-        "-rw-r--r--   1 14       staff      119:26 Aug 22  2000 zxJDBC-1.2.3.zip", 
-        "-rw-r--r--   1 ftp      no group    83853 Jan 22  2001 zxJDBC-1.2.4.tar.gz", 
-        "-rw-r--r--   1ftp       nogroup    126552 Jan 22  2001 zxJDBC-1.2.4.zip", 
-        "-rw-r--r--   1 root     root       111325 Apr -7 18:79 zxJDBC-2.0.1b1.tar.gz", 
-        "drwxr-xr-x   2 root     root         4096 Mar  2 15:13 zxbox", 
-        "drwxr-xr-x   2 root     root         4096 Aug 24  2001 zxjdbc", 
-        "drwxr-xr-x   2 root     root         4096 Jan  4 00:03 zziplib", 
-        "drwxr-xr-x   2 root     99           4096 Feb 23  2001 zzplayer", 
-        "drwxr-xr-x   2 root     root         4096 Aug  6  2001 zztpp", 
-        "-rw-r--r--   1 14       staff       80284 Aug 22  2000 zxJDBC-1.2.3.tar.gz", 
-        "-rw-r--r--   1 14       staff      119926 Aug 22  2000 zxJDBC-1.2.3.zip", 
-        "-rw-r--r--   1 ftp      nogroup     83853 Jan 22  2001 zxJDBC-1.2.4.tar.gz", 
-        "-rw-r--r--   1 ftp      nogroup    126552 Jan 22  2001 zxJDBC-1.2.4.zip", 
-        "-rw-r--r--   1 root     root       111325 Apr 27  2001 zxJDBC-2.0.1b1.tar.gz", 
-        "-rw-r--r--   1 root     root       190144 Apr 27  2001 zxJDBC-2.0.1b1.zip"
-    };
-    private static final String[] GOODSAMPLES = 
-    {
-        "-C--E-----FTP B QUA1I1      18128       41 Aug 12 13:56 QUADTEST", 
-        "-C--E-----FTP A QUA1I1      18128       41 Aug 12 13:56 QUADTEST2"
-    };
-
-    /**
-     * Creates a new EnterpriseUnixFTPEntryParserTest object.
-     * 
-     * @param name Test name.
-     */
-    public EnterpriseUnixFTPEntryParserTest(String name)
-    {
-        super(name);
-    }
-
-    /**
-     * Method suite.
-     * 
-     * @return TestSuite
-     */
-    public static TestSuite suite()
-    {
-
-        return (new TestSuite(EnterpriseUnixFTPEntryParserTest.class));
-    }
-
-    /**
-     * @see org.apache.commons.net.ftp.ftp2.parser.FTPParseTestFramework#testParseFieldsOnDirectory()
-     */
-    public void testParseFieldsOnDirectory() throws Exception
-    {
-        // Everything is a File for now.
-    }
-
-    /**
-     * @see org.apache.commons.net.ftp.ftp2.parser.FTPParseTestFramework#testParseFieldsOnFile()
-     */
-    public void testParseFieldsOnFile() throws Exception
-    {
-        FTPFile file = getParser().parseFTPEntry("-C--E-----FTP B QUA1I1      18128       41 Aug 12 13:56 QUADTEST");
-        assertTrue("Should be a file.", 
-                   file.isFile());
-        assertEquals("QUADTEST", 
-                     file.getName());
-        assertEquals(41, 
-                     file.getSize());
-        assertEquals("QUA1I1", 
-                     file.getUser());
-        assertEquals("18128", 
-                     file.getGroup());
-        assertEquals("Mon Aug 12 13:56:00 2002", 
-                     df.format(file.getTimestamp().getTime()));
-        checkPermisions(file);
-    }
-
-    /**
-     * @see org.apache.commons.net.ftp.ftp2.parser.FTPParseTestFramework#getBadListing()
-     */
-    protected String[] getBadListing()
-    {
-
-        return (BADSAMPLES);
-    }
-
-    /**
-     * @see org.apache.commons.net.ftp.ftp2.parser.FTPParseTestFramework#getGoodListing()
-     */
-    protected String[] getGoodListing()
-    {
-
-        return (GOODSAMPLES);
-    }
-
-    /**
-     * @see org.apache.commons.net.ftp.ftp2.parser.FTPParseTestFramework#getParser()
-     */
-    protected FTPFileEntryParser getParser()
-    {
-
-        return (new EnterpriseUnixFTPEntryParser());
-    }
-
-    /**
-     * Method checkPermisions. Verify that the parser does NOT  set the
-     * permissions.
-     * 
-     * @param dir
-     */
-    private void checkPermisions(FTPFile dir)
-    {
-        assertTrue("Owner should not have read permission.", 
-                   !dir.hasPermission(FTPFile.USER_ACCESS, 
-                                      FTPFile.READ_PERMISSION));
-        assertTrue("Owner should not have write permission.", 
-                   !dir.hasPermission(FTPFile.USER_ACCESS, 
-                                      FTPFile.WRITE_PERMISSION));
-        assertTrue("Owner should not have execute permission.", 
-                   !dir.hasPermission(FTPFile.USER_ACCESS, 
-                                      FTPFile.EXECUTE_PERMISSION));
-        assertTrue("Group should not have read permission.", 
-                   !dir.hasPermission(FTPFile.GROUP_ACCESS, 
-                                      FTPFile.READ_PERMISSION));
-        assertTrue("Group should not have write permission.", 
-                   !dir.hasPermission(FTPFile.GROUP_ACCESS, 
-                                      FTPFile.WRITE_PERMISSION));
-        assertTrue("Group should not have execute permission.", 
-                   !dir.hasPermission(FTPFile.GROUP_ACCESS, 
-                                      FTPFile.EXECUTE_PERMISSION));
-        assertTrue("World should not have read permission.", 
-                   !dir.hasPermission(FTPFile.WORLD_ACCESS, 
-                                      FTPFile.READ_PERMISSION));
-        assertTrue("World should not have write permission.", 
-                   !dir.hasPermission(FTPFile.WORLD_ACCESS, 
-                                      FTPFile.WRITE_PERMISSION));
-        assertTrue("World should not have execute permission.", 
-                   !dir.hasPermission(FTPFile.WORLD_ACCESS, 
-                                      FTPFile.EXECUTE_PERMISSION));
-    }
-}
diff --git a/proposal/ftp2/src/test/org/apache/commons/net/ftp/ftp2/parser/FTPParseTestFramework.java b/proposal/ftp2/src/test/org/apache/commons/net/ftp/ftp2/parser/FTPParseTestFramework.java
deleted file mode 100644
index cc50bad..0000000
--- a/proposal/ftp2/src/test/org/apache/commons/net/ftp/ftp2/parser/FTPParseTestFramework.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.net.ftp.ftp2.parser;
-
-import junit.framework.TestCase;
-
-import java.text.SimpleDateFormat;
-import java.util.Locale;
-import org.apache.commons.net.ftp.FTPFile;
-import org.apache.commons.net.ftp.ftp2.FTPFileEntryParser;
-
-/**
- * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
- * @version $Id$
- */
-public abstract class FTPParseTestFramework extends TestCase
-{
-    private FTPFileEntryParser parser = null;
-    protected SimpleDateFormat df = null;
-    
-    /**
-     * @see junit.framework.TestCase#TestCase(String)
-     */
-    public FTPParseTestFramework(String name)
-    {
-        super(name);
-    }
-
-    /**
-     * Method testBadListing.
-     * Tests that parser provided failures actually fail.
-     * @throws Exception
-     */
-    public void testBadListing() throws Exception
-    {
-
-        String[] badsamples = getBadListing();
-        for (int i = 0; i < badsamples.length; i++)
-        {
-
-            String test = badsamples[i];
-            FTPFile f = parser.parseFTPEntry(test);
-            assertNull("Should have Failed to parse " + test, 
-                       f);
-        }
-    }
-
-    /**
-     * Method testGoodListing.
-     * Test that parser provided listings pass.
-     * @throws Exception
-     */
-    public void testGoodListing() throws Exception
-    {
-
-        String[] goodsamples = getGoodListing();
-        for (int i = 0; i < goodsamples.length; i++)
-        {
-
-            String test = goodsamples[i];
-            FTPFile f = parser.parseFTPEntry(test);
-            assertNotNull("Failed to parse " + test, 
-                          f);
-        }
-    }
-
-    /**
-     * Method getBadListing.
-     * Implementors must provide a listing that contains failures.
-     * @return String[]
-     */
-    protected abstract String[] getBadListing();
-
-    /**
-     * Method getGoodListing.
-     * Implementors must provide a listing that passes.
-     * @return String[]
-     */
-    protected abstract String[] getGoodListing();
-
-    /**
-     * Method getParser.
-     * Provide the parser to use for testing.
-     * @return FTPFileEntryParser
-     */
-    protected abstract FTPFileEntryParser getParser();
-    
-    /**
-     * Method testParseFieldsOnDirectory.
-     * Provide a test to show that fields on a directory entry are parsed correctly.
-     * @throws Exception
-     */
-    public abstract void testParseFieldsOnDirectory() throws Exception;
-    
-    /**
-     * Method testParseFieldsOnFile.
-     * Provide a test to show that fields on a file entry are parsed correctly.
-     * @throws Exception
-     */
-    public abstract void testParseFieldsOnFile() throws Exception;
-
-    /**
-     * @see junit.framework.TestCase#setUp()
-     */
-    protected void setUp() throws Exception
-    {
-        super.setUp();
-        parser = getParser();
-        df = new SimpleDateFormat("EEE MMM dd kk:mm:ss yyyy", Locale.US);
-    }
-}
diff --git a/proposal/ftp2/src/test/org/apache/commons/net/ftp/ftp2/parser/NTFTPEntryParserTest.java b/proposal/ftp2/src/test/org/apache/commons/net/ftp/ftp2/parser/NTFTPEntryParserTest.java
deleted file mode 100644
index d6d89f7..0000000
--- a/proposal/ftp2/src/test/org/apache/commons/net/ftp/ftp2/parser/NTFTPEntryParserTest.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.net.ftp.ftp2.parser;
-
-import org.apache.commons.net.ftp.FTPFile;
-import org.apache.commons.net.ftp.ftp2.FTPFileEntryParser;
-
-import junit.framework.TestSuite;
-
-/**
- * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
- * @versionn $Id$
- */
-public class NTFTPEntryParserTest extends FTPParseTestFramework
-{
-
-    private static final String [] goodsamples = {
-                "05-26-95  10:57AM               143712 $LDR$",
-                "05-20-97  03:31PM                  681 .bash_history",
-                "12-05-96  05:03PM       <DIR>          absoft2",
-                "11-14-97  04:21PM                  953 AUDITOR3.INI",
-                "05-22-97  08:08AM                  828 AUTOEXEC.BAK",
-                "01-22-98  01:52PM                  795 AUTOEXEC.BAT",
-                "05-13-97  01:46PM                  828 AUTOEXEC.DOS",
-                "12-03-96  06:38AM                  403 AUTOTOOL.LOG",
-                "01-20-97  03:48PM       <DIR>          bin",
-
-            };
-
-    private static final String [] badsamples = {
-                "05-26-1995  10:57AM               143712 $LDR$",
-                "20-05-97  03:31PM                  681 .bash_history",
-                "12-05-96  17:03         <DIR>          absoft2",
-                "05-22-97  08:08                    828 AUTOEXEC.BAK",
-                "     0           DIR   05-19-97   12:56  local",
-                "     0           DIR   05-12-97   16:52  Maintenance Desktop",
-
-            };
-
-    /**
-     * @see junit.framework.TestCase#TestCase(String)
-     */
-    public NTFTPEntryParserTest (String name)
-    {
-        super(name);
-    }
-
-    /**
-     * @see org.apache.commons.net.ftp.ftp2.parser.FTPParseTestFramework#getGoodListing()
-     */
-    protected String[] getGoodListing()
-    {
-        return(goodsamples);
-    }
-    
-    /**
-     * @see org.apache.commons.net.ftp.ftp2.parser.FTPParseTestFramework#getBadListing()
-     */
-    protected String[] getBadListing()
-    {
-        return(badsamples);
-    }
-
-    /**
-     * @see org.apache.commons.net.ftp.ftp2.parser.FTPParseTestFramework#getParser()
-     */
-    protected FTPFileEntryParser getParser()
-    {
-        return(new NTFTPEntryParser());
-    }
-    
-    /**
-     * Method suite.
-     * @return TestSuite
-     */
-    public static TestSuite suite()
-    {
-        return(new TestSuite(NTFTPEntryParserTest.class));
-    }
-    
-    /**
-     * @see org.apache.commons.net.ftp.ftp2.parser.FTPParseTestFramework#testParseFieldsOnDirectory()
-     */
-    public void testParseFieldsOnDirectory() throws Exception
-    {
-        FTPFile dir = getParser().parseFTPEntry("12-05-96  05:03PM       <DIR>          absoft2");
-        assertNotNull("Could not parse entry.", dir);
-        assertEquals("Thu Dec 05 17:03:00 1996", 
-                     df.format(dir.getTimestamp().getTime()));
-        assertTrue("Should have been a directory.", 
-                   dir.isDirectory());
-        assertEquals("absoft2", dir.getName());
-        assertEquals(0, dir.getSize());       
-    }
-
-    /**
-     * @see org.apache.commons.net.ftp.ftp2.parser.FTPParseTestFramework#testParseFieldsOnFile()
-     */
-    public void testParseFieldsOnFile() throws Exception
-    {
-        FTPFile f = getParser().parseFTPEntry("05-22-97  08:08AM                  828 AUTOEXEC.BAK");
-        assertNotNull("Could not parse entry.", f);
-        assertEquals("Thu May 22 08:08:00 1997", 
-                     df.format(f.getTimestamp().getTime()));
-        assertTrue("Should have been a file.", 
-                   f.isFile());
-        assertEquals("AUTOEXEC.BAK", f.getName());
-        assertEquals(828, f.getSize());   
-    }
-}
diff --git a/proposal/ftp2/src/test/org/apache/commons/net/ftp/ftp2/parser/OS2FTPEntryParserTest.java b/proposal/ftp2/src/test/org/apache/commons/net/ftp/ftp2/parser/OS2FTPEntryParserTest.java
deleted file mode 100644
index f883fbf..0000000
--- a/proposal/ftp2/src/test/org/apache/commons/net/ftp/ftp2/parser/OS2FTPEntryParserTest.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.net.ftp.ftp2.parser;
-
-import junit.framework.TestSuite;
-
-import org.apache.commons.net.ftp.FTPFile;
-import org.apache.commons.net.ftp.ftp2.FTPFileEntryParser;
-
-/**
- * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
- * @version $Id$
- */
-public class OS2FTPEntryParserTest extends FTPParseTestFramework
-{
-
-    private static final String[] badsamples = 
-    {
-        "                 DIR   12-30-97   12:32  jbrekke", 
-        "     0    rsa    DIR   11-25-97   09:42  junk", 
-        "     0           dir   05-12-97   16:44  LANGUAGE", 
-        "     0           DIR   05-19-2000 12:56  local", 
-        "     0           DIR   13-05-97   25:49  MPTN", 
-        "587823    RSA    DIR   Jan-08-97   13:58  OS2KRNL", 
-        " 33280      A          1997-02-03  13:49  OS2LDR", 
-        "12-05-96  05:03PM       <DIR>          absoft2", 
-        "11-14-97  04:21PM                  953 AUDITOR3.INI"
-    };
-    private static final String[] goodsamples = 
-    {
-        "     0           DIR   12-30-97   12:32  jbrekke", 
-        "     0           DIR   11-25-97   09:42  junk", 
-        "     0           DIR   05-12-97   16:44  LANGUAGE", 
-        "     0           DIR   05-19-97   12:56  local", 
-        "     0           DIR   05-12-97   16:52  Maintenance Desktop", 
-        "     0           DIR   05-13-97   10:49  MPTN", 
-        "587823    RSA    DIR   01-08-97   13:58  OS2KRNL", 
-        " 33280      A          02-09-97   13:49  OS2LDR", 
-        "     0           DIR   11-28-97   09:42  PC", 
-        "149473      A          11-17-98   16:07  POPUPLOG.OS2", 
-        "     0           DIR   05-12-97   16:44  PSFONTS"
-    };
-
-    /**
-     * @see junit.framework.TestCase#TestCase(String)
-     */
-    public OS2FTPEntryParserTest(String name)
-    {
-        super(name);
-    }
-
-    /**
-     * Method suite.
-     * @return TestSuite
-     */
-    public static TestSuite suite()
-    {
-
-        return (new TestSuite(OS2FTPEntryParserTest.class));
-    }
-
-    /**
-     * @see org.apache.commons.net.ftp.ftp2.parser.FTPParseTestFramework#testParseFieldsOnDirectory()
-     */
-    public void testParseFieldsOnDirectory() throws Exception    
-    {
-        FTPFile dir = getParser().parseFTPEntry("     0           DIR   11-28-97   09:42  PC");
-        assertNotNull("Could not parse entry.", dir);
-        assertTrue("Should have been a directory.", 
-                   dir.isDirectory());
-        assertEquals(0,dir.getSize());
-        assertEquals("PC", dir.getName());
-        assertEquals("Fri Nov 28 09:42:00 1997", 
-                     df.format(dir.getTimestamp().getTime()));
-    }
-
-    /**
-     * @see org.apache.commons.net.ftp.ftp2.parser.FTPParseTestFramework#testParseFieldsOnFile()
-     */
-    public void testParseFieldsOnFile() throws Exception 
-    {
-        FTPFile file = getParser().parseFTPEntry("149473      A          11-17-98   16:07  POPUPLOG.OS2");
-        assertNotNull("Could not parse entry.", file);
-        assertTrue("Should have been a file.", 
-                   file.isFile());
-        assertEquals(149473,file.getSize());
-        assertEquals("POPUPLOG.OS2", file.getName());
-        assertEquals("Tue Nov 17 16:07:00 1998", 
-                     df.format(file.getTimestamp().getTime()));           
-    }
-
-    /**
-     * @see org.apache.commons.net.ftp.ftp2.parser.FTPParseTestFramework#getBadListing()
-     */
-    protected String[] getBadListing()
-    {
-
-        return (badsamples);
-    }
-
-    /**
-     * @see org.apache.commons.net.ftp.ftp2.parser.FTPParseTestFramework#getGoodListing()
-     */
-    protected String[] getGoodListing()
-    {
-
-        return (goodsamples);
-    }
-
-    /**
-     * @see org.apache.commons.net.ftp.ftp2.parser.FTPParseTestFramework#getParser()
-     */
-    protected FTPFileEntryParser getParser()
-    {
-
-        return (new OS2FTPEntryParser());
-    }
-}
diff --git a/proposal/ftp2/src/test/org/apache/commons/net/ftp/ftp2/parser/UnixFTPEntryParserTest.java b/proposal/ftp2/src/test/org/apache/commons/net/ftp/ftp2/parser/UnixFTPEntryParserTest.java
deleted file mode 100644
index 8d70859..0000000
--- a/proposal/ftp2/src/test/org/apache/commons/net/ftp/ftp2/parser/UnixFTPEntryParserTest.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.net.ftp.ftp2.parser;
-
-import junit.framework.TestSuite;
-
-import org.apache.commons.net.ftp.FTPFile;
-import org.apache.commons.net.ftp.ftp2.FTPFileEntryParser;
-
-/**
- * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
- * @versionn $Id$
- */
-public class UnixFTPEntryParserTest extends FTPParseTestFramework
-{
-
-    private static final String[] badsamples = 
-    {
-        "zrwxr-xr-x   2 root     root         4096 Mar  2 15:13 zxbox", 
-        "dxrwr-xr-x   2 root     root         4096 Aug 24  2001 zxjdbc", 
-        "drwxr-xr-x   2 root     root         4096 Jam  4 00:03 zziplib", 
-        "drwxr-xr-x   2 root     99           4096 Feb 23 30:01 zzplayer", 
-        "drwxr-xr-x   2 root     root         4096 Aug 36  2001 zztpp", 
-        "-rw-r--r--   1 14       staff       80284 Aug 22  zxJDBC-1.2.3.tar.gz", 
-        "-rw-r--r--   1 14       staff      119:26 Aug 22  2000 zxJDBC-1.2.3.zip", 
-        "-rw-r--r--   1 ftp      no group    83853 Jan 22  2001 zxJDBC-1.2.4.tar.gz", 
-        "-rw-r--r--   1ftp       nogroup    126552 Jan 22  2001 zxJDBC-1.2.4.zip", 
-        "-rw-r--r--   1 root     root       111325 Apr -7 18:79 zxJDBC-2.0.1b1.tar.gz"
-    };
-
-    private static final String[] goodsamples = 
-    {
-        "-rw-r--r--   1 500      500            21 Aug  8 14:14 JB3-TES1.gz",       
-        "-rwxr-xr-x   2 root     root         4096 Mar  2 15:13 zxbox", 
-        "drwxr-xr-x   2 root     root         4096 Aug 24  2001 zxjdbc", 
-        "drwxr-xr-x   2 root     root         4096 Jan  4 00:03 zziplib", 
-        "drwxr-xr-x   2 root     99           4096 Feb 23  2001 zzplayer", 
-        "drwxr-xr-x   2 root     root         4096 Aug  6  2001 zztpp", 
-        "lrw-r--r--   1 14       14          80284 Aug 22  2000 zxJDBC-1.2.3.tar.gz", 
-        "frw-r--r--   1 14       staff      119926 Aug 22  2000 zxJDBC-1.2.3.zip", 
-        "crw-r--r--   1 ftp      nogroup     83853 Jan 22  2001 zxJDBC-1.2.4.tar.gz", 
-        "brw-r--r--   1 ftp      nogroup    126552 Jan 22  2001 zxJDBC-1.2.4.zip", 
-        "-rw-r--r--   1 root     root       111325 Apr 27  2001 zxJDBC-2.0.1b1.tar.gz", 
-        "-rw-r--r--   1 root     root       190144 Apr 27  2001 zxJDBC-2.0.1b1.zip",
-        "-rwxr-xr-x   2 500      500           166 Nov  2  2001 73131-testtes1.afp",
-        "-rw-r--r--   1 500      500           166 Nov  9  2001 73131-testtes1.AFP",
-        "-rw-r--r--   1 500      500           166 Nov 12  2001 73131-testtes2.afp",
-        "-rw-r--r--   1 500      500           166 Nov 12  2001 73131-testtes2.AFP",      
-        "-rw-r--r--   1 500      500       2040000 Aug  5 07:35 testRemoteUPCopyNIX",
-        "-rw-r--r--   1 500      500       2040000 Aug  5 07:31 testRemoteUPDCopyNIX",
-        "-rw-r--r--   1 500      500       2040000 Aug  5 07:31 testRemoteUPVCopyNIX"       
-    };
-
-    /**
-     * @see junit.framework.TestCase#TestCase(String)
-     */
-    public UnixFTPEntryParserTest(String name)
-    {
-        super(name);
-    }
-
-    /**
-     * @see org.apache.commons.net.ftp.ftp2.parser.FTPParseTestFramework#getBadListing()
-     */
-    protected String[] getBadListing()
-    {
-        return(badsamples);
-    }
-    
-    /**
-     * @see org.apache.commons.net.ftp.ftp2.parser.FTPParseTestFramework#getGoodListing()
-     */
-    protected String[] getGoodListing()
-    {
-        return(goodsamples);
-    }
-    
-    /**
-     * @see org.apache.commons.net.ftp.ftp2.parser.FTPParseTestFramework#getParser()
-     */
-    protected FTPFileEntryParser getParser() 
-    {
-        return(new UnixFTPEntryParser());
-    }
-    
-    /**
-     * @see org.apache.commons.net.ftp.ftp2.parser.FTPParseTestFramework#testParseFieldsOnDirectory()
-     */
-    public void testParseFieldsOnDirectory() throws Exception
-    {
-        FTPFile f = getParser().parseFTPEntry("drwxr-xr-x   2 user     group         4096 Mar  2 15:13 zxbox");
-        assertNotNull("Could not parse entry.", 
-                      f);
-        assertTrue("Should have been a directory.", 
-                   f.isDirectory());       
-        checkPermissions(f);
-        assertEquals(2, 
-                     f.getHardLinkCount());
-        assertEquals("user", 
-                     f.getUser());
-        assertEquals("group", 
-                     f.getGroup());
-        assertEquals("zxbox", 
-                     f.getName());
-        assertEquals(4096, 
-                     f.getSize());
-        assertEquals("Sat Mar 02 15:13:00 2002", 
-                     df.format(f.getTimestamp().getTime()));
-    }
-
-    /**
-     * Method checkPermissions.
-     * Verify that the persmissions were properly set.
-     * @param f
-     */
-    private void checkPermissions(FTPFile f)
-    {
-        assertTrue("Should have user read permission.", 
-                   f.hasPermission(FTPFile.USER_ACCESS, 
-                                   FTPFile.READ_PERMISSION));
-        assertTrue("Should have user write permission.", 
-                   f.hasPermission(FTPFile.USER_ACCESS, 
-                                   FTPFile.WRITE_PERMISSION));
-        assertTrue("Should have user execute permission.", 
-                   f.hasPermission(FTPFile.USER_ACCESS, 
-                                   FTPFile.EXECUTE_PERMISSION));
-        assertTrue("Should have group read permission.", 
-                   f.hasPermission(FTPFile.GROUP_ACCESS, 
-                                   FTPFile.READ_PERMISSION));
-        assertTrue("Should NOT have group write permission.", 
-                   !f.hasPermission(FTPFile.GROUP_ACCESS, 
-                                    FTPFile.WRITE_PERMISSION));
-        assertTrue("Should have group execute permission.", 
-                   f.hasPermission(FTPFile.GROUP_ACCESS, 
-                                   FTPFile.EXECUTE_PERMISSION));
-        assertTrue("Should have world read permission.", 
-                   f.hasPermission(FTPFile.WORLD_ACCESS, 
-                                   FTPFile.READ_PERMISSION));
-        assertTrue("Should NOT have world write permission.", 
-                   !f.hasPermission(FTPFile.WORLD_ACCESS, 
-                                    FTPFile.WRITE_PERMISSION));
-        assertTrue("Should have world execute permission.", 
-                   f.hasPermission(FTPFile.WORLD_ACCESS, 
-                                   FTPFile.EXECUTE_PERMISSION));
-    }
-
-    /**
-     * @see org.apache.commons.net.ftp.ftp2.parser.FTPParseTestFramework#testParseFieldsOnFile()
-     */
-    public void testParseFieldsOnFile() throws Exception
-    {
-        FTPFile f = getParser().parseFTPEntry("-rwxr-xr-x   2 user     group         4096 Mar  2 15:13 zxbox");
-        assertNotNull("Could not parse entry.", 
-                      f);
-        assertTrue("Should have been a file.", 
-                   f.isFile());
-        checkPermissions(f);
-        assertEquals(2, 
-                     f.getHardLinkCount());
-        assertEquals("user", 
-                     f.getUser());
-        assertEquals("group", 
-                     f.getGroup());
-        assertEquals("zxbox", 
-                     f.getName());
-        assertEquals(4096, 
-                     f.getSize());
-        assertEquals("Sat Mar 02 15:13:00 2002", 
-                     df.format(f.getTimestamp().getTime()));
-    }
-    
-    /**
-     * Method suite.
-     * @return TestSuite
-     */
-    public static TestSuite suite()
-    {
-        return(new TestSuite(UnixFTPEntryParserTest.class));
-    }
-}
diff --git a/proposal/ftp2/src/test/org/apache/commons/net/ftp/ftp2/parser/VMSFTPEntryParserTest.java b/proposal/ftp2/src/test/org/apache/commons/net/ftp/ftp2/parser/VMSFTPEntryParserTest.java
deleted file mode 100644
index 9874e6e..0000000
--- a/proposal/ftp2/src/test/org/apache/commons/net/ftp/ftp2/parser/VMSFTPEntryParserTest.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.net.ftp.ftp2.parser;
-
-import junit.framework.TestSuite;
-
-import org.apache.commons.net.ftp.FTPFile;
-import org.apache.commons.net.ftp.ftp2.FTPFileEntryParser;
-
-/**
- * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
- * @version $Id$
- */
-public class VMSFTPEntryParserTest extends FTPParseTestFramework
-{
-    private static final String[] badsamples = 
-    {
-
-        "1-JUN.LIS;1              9/9           2-jun-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,RE)", 
-        "1-JUN.LIS;2              9/9           JUN-2-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,)", 
-        "1-JUN.LIS;2              a/9           2-JUN-98 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,)", 
-        "DATA.DIR; 1              1/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (,RWED,RWED,RE)", 
-        "120196.TXT;1           118/126        14-APR-1997 12:45:27 PM  [GROUP,OWNER]    (RWED,,RWED,RE)", 
-        "30CHARBAR.TXT;1         11/18          2-JUN-1998 08:38:42  [GROUP-1,OWNER]    (RWED,RWED,RWED,RE)", 
-        "A.;2                    18/18          1-JUL-1998 08:43:20  [GROUP,OWNER]    (RWED2,RWED,RWED,RE)", 
-        "AA.;2                  152/153        13-FED-1997 08:13:43  [GROUP,OWNER]    (RWED,RWED,RWED,RE)"
-    };
-    
-    private static final String[] goodsamples = 
-    {
-
-        "1-JUN.LIS;1              9/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,RE)", 
-        "1-JUN.LIS;2              9/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,)", 
-        "1-JUN.LIS;2              9/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,)", 
-        "DATA.DIR;1               1/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (,RWED,RWED,RE)", 
-        "120196.TXT;1           118/126        14-APR-1997 12:45:27  [GROUP,OWNER]    (RWED,,RWED,RE)", 
-        "30CHARBAR.TXT;1         11/18          2-JUN-1998 08:38:42  [GROUP,OWNER]    (RWED,RWED,RWED,RE)", 
-        "A.;2                    18/18          1-JUL-1998 08:43:20  [GROUP,OWNER]    (RWED,RWED,RWED,RE)", 
-        "AA.;2                  152/153        13-FEB-1997 08:13:43  [GROUP,OWNER]    (RWED,RWED,RWED,RE)"
-    };
-
-    /**
-     * @see junit.framework.TestCase#TestCase(String)
-     */
-    public VMSFTPEntryParserTest(String name)
-    {
-        super(name);
-    }
-
-    /**
-     * @see org.apache.commons.net.ftp.ftp2.parser.FTPParseTestFramework#testParseFieldsOnDirectory()
-     */
-    public void testParseFieldsOnDirectory() throws Exception
-    {
-
-        FTPFile dir = getParser().parseFTPEntry("DATA.DIR;1               1/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,RE)");
-        assertTrue("Should be a directory.", 
-                   dir.isDirectory());
-        assertEquals("DATA.DIR", 
-                     dir.getName());
-        assertEquals(512, 
-                     dir.getSize());
-        assertEquals("Tue Jun 02 07:32:04 1998", 
-                     df.format(dir.getTimestamp().getTime()));
-        assertEquals("GROUP", 
-                     dir.getGroup());
-        assertEquals("OWNER", 
-                     dir.getUser());
-        checkPermisions(dir);
-    }
-
-    /**
-     * @see org.apache.commons.net.ftp.ftp2.parser.FTPParseTestFramework#testParseFieldsOnFile()
-     */
-    public void testParseFieldsOnFile() throws Exception
-    {
-        FTPFile file = getParser().parseFTPEntry("1-JUN.LIS;1              9/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RWED,RE)");
-        assertTrue("Should be a file.", 
-                   file.isFile());
-        assertEquals("1-JUN.LIS", 
-                     file.getName());
-        assertEquals(9 * 512, 
-                     file.getSize());
-        assertEquals("Tue Jun 02 07:32:04 1998", 
-                     df.format(file.getTimestamp().getTime()));
-        assertEquals("GROUP", 
-                     file.getGroup());
-        assertEquals("OWNER", 
-                     file.getUser());
-        checkPermisions(file);
-    }
-
-    /**
-     * @see org.apache.commons.net.ftp.ftp2.parser.FTPParseTestFramework#getBadListing()
-     */
-    protected String[] getBadListing()
-    {
-
-        return (badsamples);
-    }
-
-    /**
-     * @see org.apache.commons.net.ftp.ftp2.parser.FTPParseTestFramework#getGoodListing()
-     */
-    protected String[] getGoodListing()
-    {
-
-        return (goodsamples);
-    }
-
-    /**
-     * @see org.apache.commons.net.ftp.ftp2.parser.FTPParseTestFramework#getParser()
-     */
-    protected FTPFileEntryParser getParser()
-    {
-
-        return (new VMSFTPEntryParser());
-    }
-
-    /**
-     * Method checkPermisions.
-     * Verify that the VMS parser does NOT  set the permissions.
-     * @param dir
-     */
-    private void checkPermisions(FTPFile dir)
-    {
-        assertTrue("Owner should not have read permission.", 
-                   !dir.hasPermission(FTPFile.USER_ACCESS, 
-                                      FTPFile.READ_PERMISSION));
-        assertTrue("Owner should not have write permission.", 
-                   !dir.hasPermission(FTPFile.USER_ACCESS, 
-                                      FTPFile.WRITE_PERMISSION));
-        assertTrue("Owner should not have execute permission.", 
-                   !dir.hasPermission(FTPFile.USER_ACCESS, 
-                                      FTPFile.EXECUTE_PERMISSION));
-        assertTrue("Group should not have read permission.", 
-                   !dir.hasPermission(FTPFile.GROUP_ACCESS, 
-                                      FTPFile.READ_PERMISSION));
-        assertTrue("Group should not have write permission.", 
-                   !dir.hasPermission(FTPFile.GROUP_ACCESS, 
-                                      FTPFile.WRITE_PERMISSION));
-        assertTrue("Group should not have execute permission.", 
-                   !dir.hasPermission(FTPFile.GROUP_ACCESS, 
-                                      FTPFile.EXECUTE_PERMISSION));
-        assertTrue("World should not have read permission.", 
-                   !dir.hasPermission(FTPFile.WORLD_ACCESS, 
-                                      FTPFile.READ_PERMISSION));
-        assertTrue("World should not have write permission.", 
-                   !dir.hasPermission(FTPFile.WORLD_ACCESS, 
-                                      FTPFile.WRITE_PERMISSION));
-        assertTrue("World should not have execute permission.", 
-                   !dir.hasPermission(FTPFile.WORLD_ACCESS, 
-                                      FTPFile.EXECUTE_PERMISSION));
-    }
-    
-    /**
-     * Method suite.
-     * @return TestSuite
-     */
-    public static TestSuite suite()
-    {
-        return(new TestSuite(VMSFTPEntryParserTest.class));
-    }   
-}
diff --git a/src/assembly/bin.xml b/src/assembly/bin.xml
index 2a08ac1..b896871 100644
--- a/src/assembly/bin.xml
+++ b/src/assembly/bin.xml
@@ -1,5 +1,5 @@
 <!--
- Licensed to the Apache Software Foundation (ASF) under one or more
+Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
@@ -15,29 +15,33 @@
  limitations under the License.
 -->
 <assembly>
-    <id>bin</id>
-    <formats>
-        <format>tar.gz</format>
-        <format>zip</format>
-    </formats>
-    <includeSiteDirectory>false</includeSiteDirectory>
-    <fileSets>
-        <fileSet>
-            <includes>
-                <include>LICENSE.txt</include>
-                <include>NOTICE.txt</include>
-            </includes>
-        </fileSet>
-        <fileSet>
-            <directory>target</directory>
-            <outputDirectory></outputDirectory>
-            <includes>
-                <include>*.jar</include>
-            </includes>
-        </fileSet>
-        <fileSet>
-            <directory>target/site/apidocs</directory>
-            <outputDirectory>apidocs</outputDirectory>
-        </fileSet>
-    </fileSets>
+	<id>bin</id>
+	<formats>
+		<format>tar.gz</format>
+		<format>tar.bz2</format>
+		<format>zip</format>
+	</formats>
+	<fileSets>
+		<fileSet>
+			<includes>
+				<include>README*</include>
+				<include>LICENSE*</include>
+				<include>NOTICE*</include>
+			</includes>
+		</fileSet>
+		<fileSet>
+			<directory>target</directory>
+			<outputDirectory></outputDirectory>
+			<includes>
+				<include>*.jar</include>
+			</includes>
+		</fileSet>
+		<fileSet>
+			<directory>target/site/apidocs</directory>
+			<outputDirectory>apidocs</outputDirectory>
+			<includes>
+				<include>**/*</include>
+			</includes>
+		</fileSet>
+	</fileSets>
 </assembly>
diff --git a/src/assembly/src.xml b/src/assembly/src.xml
index 1c25fbc..988f734 100644
--- a/src/assembly/src.xml
+++ b/src/assembly/src.xml
@@ -1,5 +1,5 @@
 <!--
- Licensed to the Apache Software Foundation (ASF) under one or more
+Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
@@ -15,33 +15,25 @@
  limitations under the License.
 -->
 <assembly>
-    <id>src</id>
-    <formats>
-        <format>tar.gz</format>
-        <format>zip</format>
-    </formats>
-    <baseDirectory>${project.artifactId}-${project.version}-src</baseDirectory>
-    <fileSets>
-        <fileSet>
-            <includes>
-                <include>build.xml</include>
-                <include>LICENSE.txt</include>
-                <include>maven.xml</include>
-                <include>NOTICE.txt</include>
-                <include>pom.xml</include>
-                <include>project.properties</include>
-                <include>project.xml</include>
-                <include>README</include>
-            </includes>
-        </fileSet>
-        <fileSet>
-            <directory>proposal</directory>
-        </fileSet>
-        <fileSet>
-            <directory>src</directory>
-        </fileSet>
-        <fileSet>
-            <directory>xdocs</directory>
-        </fileSet>
-    </fileSets>
+  <id>src</id>
+  <formats>
+    <format>tar.gz</format>
+    <format>tar.bz2</format>
+    <format>zip</format>
+  </formats>
+  <baseDirectory>${artifactId}-${version}-src</baseDirectory>
+  <fileSets>
+    <fileSet>
+      <includes>
+        <include>README*</include>
+        <include>LICENSE*</include>
+        <include>NOTICE*</include>
+        <include>pom.xml</include>
+      </includes>
+    </fileSet>
+    <fileSet>
+      <directory>src</directory>
+    </fileSet>
+  </fileSets>
 </assembly>
+
diff --git a/src/java/examples/nntp/NNTPUtils.java b/src/java/examples/nntp/NNTPUtils.java
deleted file mode 100644
index 60222c6..0000000
--- a/src/java/examples/nntp/NNTPUtils.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package examples.nntp;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.Reader;
-import java.util.StringTokenizer;
-
-import org.apache.commons.net.io.DotTerminatedMessageReader;
-import org.apache.commons.net.nntp.Article;
-import org.apache.commons.net.nntp.NNTPClient;
-
-/**
- * 
- * Some convenience methods for NNTP example classes.
- * 
- * @author Rory Winston <rwinston@checkfree.com>
- */
-public class NNTPUtils {
-
-    /**
-     * Given an {@link NNTPClient} instance, and an integer range of messages, return 
-     * an array of {@link Article} instances.
-     * @param client 
-     * @param lowArticleNumber
-     * @param highArticleNumber
-     * @return Article[] An array of Article
-     * @throws IOException
-     */
-    public  static Article[] getArticleInfo(NNTPClient client, int lowArticleNumber, int highArticleNumber)
-            throws IOException {
-            Reader reader = null;
-            Article[] articles = null;
-            reader =
-                (DotTerminatedMessageReader) client.retrieveArticleInfo(
-                    lowArticleNumber,
-                    highArticleNumber);
-
-            if (reader != null) {
-                String theInfo = readerToString(reader);
-                StringTokenizer st = new StringTokenizer(theInfo, "\n");
-
-                // Extract the article information
-                // Mandatory format (from NNTP RFC 2980) is :
-                // Subject\tAuthor\tDate\tID\tReference(s)\tByte Count\tLine Count
-
-                int count = st.countTokens();
-                articles = new Article[count];
-                int index = 0;
-
-                while (st.hasMoreTokens()) {
-                    StringTokenizer stt = new StringTokenizer(st.nextToken(), "\t");
-                    Article article = new Article();
-                    article.setArticleNumber(Integer.parseInt(stt.nextToken()));
-                    article.setSubject(stt.nextToken());
-                    article.setFrom(stt.nextToken());
-                    article.setDate(stt.nextToken());
-                    article.setArticleId(stt.nextToken());
-                    article.addHeaderField("References", stt.nextToken());
-                    articles[index++] = article;
-                }
-            } else {
-                return null;
-            }
-
-            return articles;
-        }
-        
-    
-    /**
-     * Convert a {@link Reader} instance to a String
-     * @param reader The Reader instance
-     * @return String
-     */
-    public static String readerToString(Reader reader) {
-        String temp = null;
-        StringBuffer sb = null;
-        BufferedReader bufReader = new BufferedReader(reader);
-
-        sb = new StringBuffer();
-        try {
-            temp = bufReader.readLine();
-            while (temp != null) {
-                sb.append(temp);
-                sb.append("\n");
-                temp = bufReader.readLine();
-            }
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-
-        return sb.toString();
-    }
-}
diff --git a/src/java/org/apache/commons/net/SocketFactory.java b/src/java/org/apache/commons/net/SocketFactory.java
deleted file mode 100644
index b3b467c..0000000
--- a/src/java/org/apache/commons/net/SocketFactory.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.net;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.UnknownHostException;
-
-/***
- * The SocketFactory interface provides a means for the programmer to
- * control the creation of sockets and provide his own Socket
- * implementations for use by all classes derived from
- * {@link org.apache.commons.net.SocketClient}.
- * This allows you to provide your own Socket implementations and
- * to perform security checks or browser capability requests before
- * creating a Socket.
- * <p>
- * <p>
- * @author Daniel F. Savarese
- * @see DefaultSocketFactory
- ***/
-
-public interface SocketFactory
-{
-
-    /***
-     * Creates a Socket connected to the given host and port.
-     * <p>
-     * @param host The hostname to connect to.
-     * @param port The port to connect to.
-     * @return A Socket connected to the given host and port.
-     * @exception UnknownHostException  If the hostname cannot be resolved.
-     * @exception IOException If an I/O error occurs while creating the Socket.
-     ***/
-    public Socket createSocket(String host, int port)
-    throws UnknownHostException, IOException;
-
-
-    /***
-     * Creates a Socket connected to the given host and port.
-     * <p>
-     * @param address The address of the host to connect to.
-     * @param port The port to connect to.
-     * @return A Socket connected to the given host and port.
-     * @exception IOException If an I/O error occurs while creating the Socket.
-     ***/
-    public Socket createSocket(InetAddress address, int port)
-    throws IOException;
-
-
-    /***
-     * Creates a Socket connected to the given host and port and
-     * originating from the specified local address and port.
-     * <p>
-     * @param host The hostname to connect to.
-     * @param port The port to connect to.
-     * @param localAddr  The local address to use.
-     * @param localPort  The local port to use.
-     * @return A Socket connected to the given host and port.
-     * @exception UnknownHostException  If the hostname cannot be resolved.
-     * @exception IOException If an I/O error occurs while creating the Socket.
-     ***/
-    public Socket createSocket(String host, int port, InetAddress localAddr,
-                               int localPort)
-    throws UnknownHostException, IOException;
-
-    /***
-     * Creates a Socket connected to the given host and port and
-     * originating from the specified local address and port.
-     * <p>
-     * @param address The address of the host to connect to.
-     * @param port The port to connect to.
-     * @param localAddr  The local address to use.
-     * @param localPort  The local port to use.
-     * @return A Socket connected to the given host and port.
-     * @exception IOException If an I/O error occurs while creating the Socket.
-     ***/
-    public Socket createSocket(InetAddress address, int port,
-                               InetAddress localAddr, int localPort)
-    throws IOException;
-
-    /***
-     * Creates a ServerSocket bound to a specified port.  A port
-     * of 0 will create the ServerSocket on a system-determined free port.
-     * <p>
-     * @param port  The port on which to listen, or 0 to use any free port.
-     * @return A ServerSocket that will listen on a specified port.
-     * @exception IOException If an I/O error occurs while creating
-     *                        the ServerSocket.
-     ***/
-    public ServerSocket createServerSocket(int port) throws IOException;
-
-    /***
-     * Creates a ServerSocket bound to a specified port with a given
-     * maximum queue length for incoming connections.  A port of 0 will
-     * create the ServerSocket on a system-determined free port.
-     * <p>
-     * @param port  The port on which to listen, or 0 to use any free port.
-     * @param backlog  The maximum length of the queue for incoming connections.
-     * @return A ServerSocket that will listen on a specified port.
-     * @exception IOException If an I/O error occurs while creating
-     *                        the ServerSocket.
-     ***/
-    public ServerSocket createServerSocket(int port, int backlog)
-    throws IOException;
-
-    /***
-     * Creates a ServerSocket bound to a specified port on a given local
-     * address with a given maximum queue length for incoming connections.
-     * A port of 0 will
-     * create the ServerSocket on a system-determined free port.
-     * <p>
-     * @param port  The port on which to listen, or 0 to use any free port.
-     * @param backlog  The maximum length of the queue for incoming connections.
-     * @param bindAddr  The local address to which the ServerSocket should bind.
-     * @return A ServerSocket that will listen on a specified port.
-     * @exception IOException If an I/O error occurs while creating
-     *                        the ServerSocket.
-     ***/
-    public ServerSocket createServerSocket(int port, int backlog,
-                                           InetAddress bindAddr)
-    throws IOException;
-}
diff --git a/src/java/org/apache/commons/net/ftp/DefaultFTPFileListParser.java b/src/java/org/apache/commons/net/ftp/DefaultFTPFileListParser.java
deleted file mode 100644
index 1eea827..0000000
--- a/src/java/org/apache/commons/net/ftp/DefaultFTPFileListParser.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.net.ftp;
-import org.apache.commons.net.ftp.parser.UnixFTPEntryParser;
-
-/**
- * DefaultFTPFileListParser is the default implementation of
- * {@link org.apache.commons.net.ftp.FTPFileListParser}
- * used by {@link org.apache.commons.net.ftp.FTPClient}
- * to parse file listings.
- * Sometimes you will want to parse unusual listing formats, in which
- * case you would create your own implementation of FTPFileListParser and
- * if necessary, subclass FTPFile.
- * <p>
- * As of version 1.2, this class merely extends UnixFTPEntryParser.
- * It will be removed in version 2.0.
- * <p>
- * @author Daniel F. Savarese
- * @see FTPFileListParser
- * @see FTPFile
- * @see FTPClient#listFiles
- * @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
- * @deprecated This class is deprecated as of version 1.2 and will be
- * removed in version 2.0 -- use the autodetect mechanism in
- * DefaultFTPFileEntryParserFactory instead.
- */
-public final class DefaultFTPFileListParser extends UnixFTPEntryParser
-{
-
-
-
-}
diff --git a/src/java/org/apache/commons/net/ftp/FTPFileEntryParserImpl.java b/src/java/org/apache/commons/net/ftp/FTPFileEntryParserImpl.java
deleted file mode 100644
index 16cede8..0000000
--- a/src/java/org/apache/commons/net/ftp/FTPFileEntryParserImpl.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.net.ftp;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * This abstract class implements both the older FTPFileListParser and
- * newer FTPFileEntryParser interfaces with default functionality.
- * All the classes in the parser subpackage inherit from this.
- *
- */
-public abstract class FTPFileEntryParserImpl
-    implements FTPFileEntryParser, FTPFileListParser
-{
-    /**
-     * The constructor for a FTPFileEntryParserImpl object.
-     */
-    public FTPFileEntryParserImpl()
-    {
-    }
-
-
-    /***
-     * Parses an FTP server file listing and converts it into a usable format
-     * in the form of an array of <code> FTPFile </code> instances.  If the
-     * file list contains no files, <code> null </code> should be
-     * returned, otherwise an array of <code> FTPFile </code> instances
-     * representing the files in the directory is returned.
-     * <p>
-     * @param listStream The InputStream from which the file list should be
-     *        read.
-     * @return The list of file information contained in the given path.  null
-     *     if the list could not be obtained or if there are no files in
-     *     the directory.
-     * @exception java.io.IOException  If an I/O error occurs reading the listStream.
-     ***/
-    public FTPFile[] parseFileList(InputStream listStream, String encoding) throws IOException
-    {
-        FTPFileList ffl = FTPFileList.create(listStream, this, encoding);
-        return ffl.getFiles();
-
-    }
-    
-    /***
-     * Parses an FTP server file listing and converts it into a usable format
-     * in the form of an array of <code> FTPFile </code> instances.  If the
-     * file list contains no files, <code> null </code> should be
-     * returned, otherwise an array of <code> FTPFile </code> instances
-     * representing the files in the directory is returned.
-     * <p>
-     * @param listStream The InputStream from which the file list should be
-     *        read.
-     * @return The list of file information contained in the given path.  null
-     *     if the list could not be obtained or if there are no files in
-     *     the directory.
-     * @exception java.io.IOException  If an I/O error occurs reading the listStream.
-     *
-     * @deprecated The version of this method which takes an encoding should be used.
-    ***/
-    public FTPFile[] parseFileList(InputStream listStream) throws IOException
-    {
-        return parseFileList(listStream, null);
-    }
-
-    /**
-     * Reads the next entry using the supplied BufferedReader object up to
-     * whatever delemits one entry from the next.  This default implementation
-     * simply calls BufferedReader.readLine().
-     *
-     * @param reader The BufferedReader object from which entries are to be
-     * read.
-     *
-     * @return A string representing the next ftp entry or null if none found.
-     * @exception java.io.IOException thrown on any IO Error reading from the reader.
-     */
-    public String readNextEntry(BufferedReader reader) throws IOException
-    {
-        return reader.readLine();
-    }
-    /**
-     * This method is a hook for those implementors (such as
-     * VMSVersioningFTPEntryParser, and possibly others) which need to
-     * perform some action upon the FTPFileList after it has been created
-     * from the server stream, but before any clients see the list.
-     *
-     * This default implementation removes entries that do not parse as files.
-     *
-     * @param original Original list after it has been created from the server stream
-     *
-     * @return <code>original</code> unmodified.
-     */
-     public List preParse(List original) {
-         Iterator it = original.iterator();
-         while (it.hasNext()){
-            String entry = (String) it.next();
-            if (null == parseFTPEntry(entry)) {
-                it.remove();
-            }
-         }
-         return original;
-     }
-}
-
-/* Emacs configuration
- * Local variables:        **
- * mode:             java  **
- * c-basic-offset:   4     **
- * indent-tabs-mode: nil   **
- * End:                    **
- */
diff --git a/src/java/org/apache/commons/net/ftp/FTPFileIterator.java b/src/java/org/apache/commons/net/ftp/FTPFileIterator.java
deleted file mode 100644
index 1fb4f7e..0000000
--- a/src/java/org/apache/commons/net/ftp/FTPFileIterator.java
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.net.ftp;
-import java.util.List;
-
-/**
- * This class implements a bidirectional iterator over an FTPFileList.
- * Elements may be retrieved one at at time using the hasNext() - next()
- * syntax familiar from Java 2 collections.  Alternatively, entries may
- * be receieved as an array of any requested number of entries or all of them.
- *
- * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
- * @version $Id$
- * @see org.apache.commons.net.ftp.FTPFileList
- * @see org.apache.commons.net.ftp.FTPFileEntryParser
- * @see org.apache.commons.net.ftp.FTPListParseEngine
- * @deprecated This class is deprecated as of version 1.2 and will be
- * removed in version 2.0 - use FTPFileParseEngine instead
- */
-public class FTPFileIterator
-{
-    /**
-     * a vector of strings, each representing a possibly valid ftp file
-     * entry
-     */
-    private List rawlines;
-
-    /**
-     * the parser to which this iterator delegates its parsing duties
-     */
-    private FTPFileEntryParser parser;
-
-    /**
-     * constant shorthand for the situation where the raw listing has not
-     * yet been scanned
-     */
-    private static final int UNINIT = -1;
-
-    /**
-     * constant shorthand for the situation where the raw listing has been
-     * scanned and found to have no valid entry.
-     */
-    private static final int DIREMPTY = -2;
-
-    /**
-     * this iterator's current position within <code>rawlines</code>.
-     */
-    private int itemptr = 0;
-
-    /**
-     * number within <code>rawlines</code> of the first valid file entry.
-     */
-    private int firstGoodEntry = UNINIT;
-
-    /**
-     * "Package-private" constructor.  Only the FTPFileList can
-     * create an iterator, using it's iterator() method.  The list
-     * will be iterated with the list's default parser.
-     *
-     * @param rawlist the FTPFileList to be iterated
-     */
-    FTPFileIterator (FTPFileList rawlist)
-    {
-        this(rawlist, rawlist.getParser());
-    }
-
-    /**
-     * "Package-private" constructor.  Only the FTPFileList can
-     * create an iterator, using it's iterator() method.  The list will be
-     * iterated with a supplied parser
-     *
-     * @param rawlist the FTPFileList to be iterated
-     * @param parser the system specific parser for raw FTP entries.
-     */
-    FTPFileIterator (FTPFileList rawlist,
-                            FTPFileEntryParser parser)
-    {
-        this.rawlines = rawlist.getLines();
-        this.parser = parser;
-    }
-
-    /**
-     * Delegates to this object's parser member the job of parsing an
-     * entry.
-     *
-     * @param entry  A string containing one entry, as determined by the
-     * parser's getNextEntry() method.
-     *
-     * @return an FTPFile object representing this entry or null if it can't be
-     *         parsed as a file
-     */
-    private FTPFile parseFTPEntry(String entry)
-    {
-        return this.parser.parseFTPEntry(entry);
-    }
-
-    /**
-     * Skips over any introductory lines and stuff in the listing that does
-     * not represent files, returning the line number of the first entry
-     * that does represent a file.
-     *
-     * @return the line number within <code>rawlines</code> of the first good
-     * entry in the array or DIREMPTY if there are no good entries.
-     */
-    private int getFirstGoodEntry()
-    {
-        FTPFile entry = null;
-        for (int iter = 0; iter < this.rawlines.size(); iter++)
-        {
-            String line = (String) this.rawlines.get(iter);
-            entry = parseFTPEntry(line);
-            if (null != entry)
-            {
-                return iter;
-            }
-        }
-        return DIREMPTY;
-    }
-
-    /**
-     * resets iterator to the beginning of the list.
-     */
-    private void init()
-    {
-        this.itemptr = 0;
-        this.firstGoodEntry = UNINIT;
-    }
-
-    /**
-     * shorthand for an empty return value.
-     */
-    private static final FTPFile[] EMPTY = new FTPFile[0];
-
-    /**
-     * Returns a list of FTPFile objects for ALL files listed in the server's
-     * LIST output.
-     *
-     * @return a list of FTPFile objects for ALL files listed in the server's
-     * LIST output.
-     */
-    public FTPFile[] getFiles()
-    {
-        if (this.itemptr != DIREMPTY)
-        {
-            init();
-        }
-        return getNext(0);
-    }
-
-    /**
-     * Returns an array of at most <code>quantityRequested</code> FTPFile
-     * objects starting at this iterator's current position  within its
-     * associated list. If fewer than <code>quantityRequested</code> such
-     * elements are available, the returned array will have a length equal
-     * to the number of entries at and after after the current position.
-     * If no such entries are found, this array will have a length of 0.
-     *
-     * After this method is called the current position is advanced by
-     * either <code>quantityRequested</code> or the number of entries
-     * available after the iterator, whichever is fewer.
-     *
-     * @param quantityRequested
-     * the maximum number of entries we want to get.  A 0
-     * passed here is a signal to get ALL the entries.
-     *
-     * @return an array of at most <code>quantityRequested</code> FTPFile
-     * objects starting at the current position of this iterator within its
-     * list and at least the number of elements which  exist in the list at
-     * and after its current position.
-     */
-    public FTPFile[] getNext(int quantityRequested)
-    {
-
-        // if we haven't gotten past the initial junk do so.
-        if (this.firstGoodEntry == UNINIT)
-        {
-            this.firstGoodEntry = getFirstGoodEntry();
-        }
-        if (this.firstGoodEntry == DIREMPTY)
-        {
-            return EMPTY;
-        }
-
-        int max = this.rawlines.size() - this.firstGoodEntry;
-
-        // now that we know the maximum we can possibly get,
-        // resolve a 0 request to ask for that many.
-
-        int howMany = (quantityRequested == 0) ? max : quantityRequested;
-        howMany = (howMany + this.itemptr < this.rawlines.size())
-                   ? howMany
-                   : this.rawlines.size() - this.itemptr;
-
-        FTPFile[] output = new FTPFile[howMany];
-
-        for (int i = 0, e = this.firstGoodEntry + this.itemptr ;
-                i < howMany; i++, e++)
-        {
-            output[i] = parseFTPEntry((String) this.rawlines.get(e));
-            this.itemptr++;
-        }
-        return output;
-    }
-
-    /**
-     * Method for determining whether getNext() will successfully return a
-     * non-null value.
-     *
-     * @return true if there exist any files after the one currently pointed
-     * to by the internal iterator, false otherwise.
-     */
-    public boolean hasNext()
-    {
-        int fge = this.firstGoodEntry;
-        if (fge == DIREMPTY)
-        {
-            //directory previously found empty - return false
-            return false;
-        }
-        else if (fge < 0)
-        {
-            // we haven't scanned the list yet so do it first
-            fge = getFirstGoodEntry();
-        }
-        return fge + this.itemptr < this.rawlines.size();
-    }
-
-    /**
-     * Returns a single parsed FTPFile object corresponding to the raw input
-     * line at this iterator's current position.
-     *
-     * After this method is called the internal iterator is advanced by one
-     * element (unless already at end of list).
-     *
-     * @return a single FTPFile object corresponding to the raw input line
-     * at the position of the internal iterator over the list of raw input
-     * lines maintained by this object or null if no such object exists.
-     */
-    public FTPFile next()
-    {
-        FTPFile[] file = getNext(1);
-        if (file.length > 0)
-        {
-            return file[0];
-        }
-        else
-        {
-            return null;
-        }
-    }
-
-    /**
-     * Returns an array of at most <code>quantityRequested</code> FTPFile
-     * objects starting at the position preceding this iterator's current
-     * position within its associated list. If fewer than
-     * <code>quantityRequested</code> such elements are available, the
-     * returned array will have a length equal to the number of entries after
-     * the iterator.  If no such entries are found, this array will have a
-     * length of 0.  The entries will be ordered in the same order as the
-     * list, not reversed.
-     *
-     * After this method is called the current position is moved back by
-     * either <code>quantityRequested</code> or the number of entries
-     * available before the current position, whichever is fewer.
-     * @param quantityRequested the maximum number of entries we want to get.
-     * A 0 passed here is a signal to get ALL the entries.
-     * @return  an array of at most <code>quantityRequested</code> FTPFile
-     * objects starting at the position preceding the current position of
-     * this iterator within its list and at least the number of elements which
-     * exist in the list prior to its current position.
-     */
-    public FTPFile[] getPrevious(int quantityRequested)
-    {
-        int howMany = quantityRequested;
-        // can't retreat further than we've previously advanced
-        if (howMany > this.itemptr)
-        {
-            howMany = this.itemptr;
-        }
-        FTPFile[] output = new FTPFile[howMany];
-        for (int i = howMany, e = this.firstGoodEntry + this.itemptr; i > 0;)
-        {
-            output[--i] = parseFTPEntry((String) this.rawlines.get(--e));
-            this.itemptr--;
-        }
-        return output;
-    }
-
-    /**
-     * Method for determining whether getPrevious() will successfully return a
-     * non-null value.
-     *
-     * @return true if there exist any files before the one currently pointed
-     * to by the internal iterator, false otherwise.
-     */
-    public boolean hasPrevious()
-    {
-        int fge = this.firstGoodEntry;
-        if (fge == DIREMPTY)
-        {
-            //directory previously found empty - return false
-            return false;
-        }
-        else if (fge < 0)
-        {
-            // we haven't scanned the list yet so do it first
-            fge = getFirstGoodEntry();
-        }
-
-        return this.itemptr > fge;
-    }
-
-    /**
-     * Returns a single parsed FTPFile object corresponding to the raw input
-     * line at the position preceding that of the internal iterator over
-     * the list of raw lines maintained by this object
-     *
-     * After this method is called the internal iterator is retreated by one
-     * element (unless it is already at beginning of list).
-     * @return a single FTPFile object corresponding to the raw input line
-     * at the position immediately preceding that of the internal iterator
-     * over the list of raw input lines maintained by this object.
-     */
-    public FTPFile previous()
-    {
-        FTPFile[] file = getPrevious(1);
-        if (file.length > 0)
-        {
-            return file[0];
-        }
-        else
-        {
-            return null;
-        }
-    }
-}
-
-/* Emacs configuration
- * Local variables:        **
- * mode:             java  **
- * c-basic-offset:   4     **
- * indent-tabs-mode: nil   **
- * End:                    **
- */
diff --git a/src/java/org/apache/commons/net/ftp/FTPFileList.java b/src/java/org/apache/commons/net/ftp/FTPFileList.java
deleted file mode 100644
index c507529..0000000
--- a/src/java/org/apache/commons/net/ftp/FTPFileList.java
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.net.ftp;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * This class encapsulates a listing of files from an FTP server.  It is
- * initialized with an input stream which is read and the input split into
- * lines, each of which (after some possible initial verbiage) represents
- * a file on the FTP server.  A parser is also supplied, which is used to
- * iterate through the internal list of lines parsing each into an FTPFile
- * object which is returned to the caller of the iteration methods.  This
- * parser may be replaced with another, allowing the same list to be parsed
- * with different parsers.
- * Parsing takes place on an as-needed basis, basically, the first time a
- * position is iterated over.  This happens at the time of iteration, not
- * prior to it as the older <code>(FTPClient.listFiles()</code> methods did,
- * which required a bigger memory hit.
- *
- * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
- * @version $Id$
- * @see org.apache.commons.net.ftp.FTPClient#createFileList
- * @see org.apache.commons.net.ftp.FTPFileIterator
- * @see org.apache.commons.net.ftp.FTPFileEntryParser
- * @see org.apache.commons.net.ftp.FTPListParseEngine
- * @deprecated This class is deprecated as of version 1.2 and will be
- * removed in version 2.0 -- use FTPFileParseEngine instead.
- */
-public class FTPFileList
-{
-    /**
-     * storage for the raw lines of input read from the FTP server
-     */
-    private LinkedList lines = null;
-    /**
-     * the FTPFileEntryParser assigned to be used with this lister
-     */
-    private FTPFileEntryParser parser;
-    /**
-     * private status code for an empty directory
-     */
-    private static final int EMPTY_DIR = -2;
-
-    /**
-     * The only constructor for FTPFileList, private because
-     * construction only invoked at create()
-     *
-     * @param parser a <code>FTPFileEntryParser</code> value that knows
-     * how to parse the entries returned by a particular FTP site.
-     * @param encoding The encoding to use.
-     */
-    private FTPFileList (FTPFileEntryParser parser, String encoding)
-    {
-        this.parser = parser;
-        this.lines = new LinkedList();
-    }
-
-    /**
-     * The only way to create an <code>FTPFileList</code> object.  Invokes
-     * the private constructor and then reads the stream  supplied stream to
-     * build the intermediate array of "lines" which will later be parsed
-     * into <code>FTPFile</code> object.
-     *
-     * @param stream The input stream created by reading the socket on which
-     * the output of the LIST command was returned
-     * @param parser the default <code>FTPFileEntryParser</code> to be used
-     * by this object.  This may later be changed using the init() method.
-     * @param encoding The encoding to use
-     *
-     * @return the <code>FTPFileList</code> created, with an initialized
-     * of unparsed lines of output.  Will be null if the listing cannot
-     * be read from the stream.
-     * @exception IOException
-     *                   Thrown on any failure to read from the socket.
-     */
-    public static FTPFileList create(InputStream stream,
-                                      FTPFileEntryParser parser,
-                                      String encoding)
-            throws IOException
-    {
-        FTPFileList list = new FTPFileList(parser, encoding);
-        list.readStream(stream, encoding);
-        parser.preParse(list.lines);
-        return list;
-    }
-    
-    /**
-     * The only way to create an <code>FTPFileList</code> object.  Invokes
-     * the private constructor and then reads the stream  supplied stream to
-     * build the intermediate array of "lines" which will later be parsed
-     * into <code>FTPFile</code> object.
-     *
-     * @param stream The input stream created by reading the socket on which
-     * the output of the LIST command was returned
-     * @param parser the default <code>FTPFileEntryParser</code> to be used
-     * by this object.  This may later be changed using the init() method.
-     *
-     * @return the <code>FTPFileList</code> created, with an initialized
-     * of unparsed lines of output.  Will be null if the listing cannot
-     * be read from the stream.
-     * @exception IOException
-     *                   Thrown on any failure to read from the socket.
-     *
-     * @deprecated The version of this method which takes an encoding should be used.
-    */
-    public static FTPFileList create(InputStream stream, FTPFileEntryParser parser)
-        throws IOException
-    {
-        return create(stream, parser, null);
-    }
-    
-    
-
-    /**
-     * internal method for reading the input into the <code>lines</code> vector.
-     *
-     * @param stream The socket stream on which the input will be read.
-     * @param encoding The encoding to use.
-     *
-     * @exception IOException thrown on any failure to read the stream
-     */
-    public void readStream(InputStream stream, String encoding) throws IOException
-    {
-        BufferedReader reader = new BufferedReader(new InputStreamReader(stream, encoding));
-
-        String line = this.parser.readNextEntry(reader);
-
-        while (line != null)
-        {
-            this.lines.add(line);
-            line = this.parser.readNextEntry(reader);
-        }
-        reader.close();
-    }
-    
-    /**
-     * internal method for reading the input into the <code>lines</code> vector.
-     *
-     * @param stream The socket stream on which the input will be read.
-     *
-     * @exception IOException thrown on any failure to read the stream
-     *
-     * @deprecated The version of this method which takes an encoding should be used.
-    */
-    public void readStream(InputStream stream) throws IOException
-    {
-     readStream(stream, null);
-    }
-     
-
-    /**
-     * Accessor for this object's default parser.
-     *
-     * @return this object's default parser.
-     */
-    FTPFileEntryParser getParser()
-    {
-        return this.parser;
-    }
-
-    /**
-     * Package private accessor for the collection of raw input lines.
-     *
-     * @return vector containing all the raw input lines returned from the FTP
-     * server
-     */
-    List getLines()
-    {
-        return this.lines;
-    }
-
-    /**
-     * create an iterator over this list using the parser with which this list
-     * was initally created
-     *
-     * @return an iterator over this list using the list's default parser.
-     */
-    public FTPFileIterator iterator()
-    {
-        return new FTPFileIterator(this);
-    }
-    /**
-     * create an iterator over this list using the supplied parser
-     *
-     * @param parser The user-supplied parser with which the list is to be
-     * iterated, may be different from this list's default parser.
-     *
-     * @return an iterator over this list using the supplied parser.
-     */
-    public FTPFileIterator iterator(FTPFileEntryParser parser)
-    {
-        return new FTPFileIterator(this, parser);
-    }
-
-
-    /**
-     * returns an array of FTPFile objects for all the files in the directory
-     * listing
-     *
-     * @return  an array of FTPFile objects for all the files in the directory
-     * listinge
-     */
-    public FTPFile[] getFiles()
-    {
-        return iterator().getFiles();
-    }
-    
-
-
-}
-
-/* Emacs configuration
- * Local variables:        **
- * mode:             java  **
- * c-basic-offset:   4     **
- * indent-tabs-mode: nil   **
- * End:                    **
- */
diff --git a/src/java/org/apache/commons/net/ftp/FTPFileListParser.java b/src/java/org/apache/commons/net/ftp/FTPFileListParser.java
deleted file mode 100644
index f586b9e..0000000
--- a/src/java/org/apache/commons/net/ftp/FTPFileListParser.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.net.ftp;
-import java.io.IOException;
-import java.io.InputStream;
-
-/***
- * FTPFileListParser defines the interface for parsing FTP file listings
- * and converting that information into an array of
- * {@link org.apache.commons.net.ftp.FTPFile} instances.
- * Sometimes you will want to parse unusual listing formats, in which
- * case you would create your own implementation of FTPFileListParser and
- * if necessary, subclass FTPFile.
- * <p>
- * <p>
- * @author Daniel F. Savarese
- * @see FTPFile
- * @see FTPClient#listFiles
- * @deprecated This interface is deprecated as of version 1.2 and will be
- * removed in version 2.0 -- use FTPFileEntryParser instead.
- ***/
-
-public interface FTPFileListParser
-{
-
-    /***
-     * Parses an FTP server file listing and converts it into a usable format
-     * in the form of an array of <code> FTPFile </code> instances.  If the
-     * file list contains no files, <code> null </code> should be
-     * returned, otherwise an array of <code> FTPFile </code> instances
-     * representing the files in the directory is returned.
-     * <p>
-     * @param listStream The InputStream from which the file list should be
-     *        read.
-     * @param encoding The encoding to use.
-     * @return The list of file information contained in the given path.  null
-     *     if the list could not be obtained or if there are no files in
-     *     the directory.
-     * @exception IOException  If an I/O error occurs reading the listStream.
-     ***/
-    FTPFile[] parseFileList(InputStream listStream, String encoding) throws IOException;
-    
-    /***
-     * Parses an FTP server file listing and converts it into a usable format
-     * in the form of an array of <code> FTPFile </code> instances.  If the
-     * file list contains no files, <code> null </code> should be
-     * returned, otherwise an array of <code> FTPFile </code> instances
-     * representing the files in the directory is returned.
-     * <p>
-     * @param listStream The InputStream from which the file list should be
-     *        read.
-     * @return The list of file information contained in the given path.  null
-     *     if the list could not be obtained or if there are no files in
-     *     the directory.
-     * @exception IOException  If an I/O error occurs reading the listStream.
-     ***/
-    FTPFile[] parseFileList(InputStream listStream) throws IOException;
-
-}
diff --git a/src/java/org/apache/commons/net/ftp/FTPFileListParserImpl.java b/src/java/org/apache/commons/net/ftp/FTPFileListParserImpl.java
deleted file mode 100644
index 0812cf9..0000000
--- a/src/java/org/apache/commons/net/ftp/FTPFileListParserImpl.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.net.ftp;
-
-import org.apache.commons.net.ftp.parser.RegexFTPFileEntryParserImpl;
-
-/**
- * This abstract class implements both the older FTPFileListParser and
- * newer FTPFileEntryParser interfaces with default functionality.
- * All the classes in the parser subpackage inherit from this.
- *
- * @author Steve Cohen <scohen@apache.org>
- * @see org.apache.commons.net.ftp.parser.RegexFTPFileEntryParserImpl
- * @deprecated This class is deprecated as of version 1.2 and will be
- *             removed in version 2.0 --
- *             org.apache.commons.net.ftp.RegexFTPFileEntryParserImpl is its
- *             designated replacement.  Class has been renamed, entire
- *             implemenation is in RegexFTPFileEntryParserImpl.
- *
- */
-public abstract class FTPFileListParserImpl
-    extends RegexFTPFileEntryParserImpl
-{
-    /**
-     * The constructor for a FTPFileListParserImpl object.
-     *
-     * @param regex  The regular expression with which this object is
-     * initialized.
-     *
-     * @exception IllegalArgumentException
-     * Thrown if the regular expression is unparseable.  Should not be seen in
-     * normal conditions.  It it is seen, this is a sign that a subclass has
-     * been created with a bad regular expression.   Since the parser must be
-     * created before use, this means that any bad parser subclasses created
-     * from this will bomb very quickly,  leading to easy detection.
-     */
-
-    public FTPFileListParserImpl(String regex) {
-        super(regex);
-    }
-
-
-}
-
-/* Emacs configuration
- * Local variables:        **
- * mode:             java  **
- * c-basic-offset:   4     **
- * indent-tabs-mode: nil   **
- * End:                    **
- */
diff --git a/src/java/org/apache/commons/net/ftp/parser/MVSFTPEntryParser.java b/src/java/org/apache/commons/net/ftp/parser/MVSFTPEntryParser.java
deleted file mode 100644
index a43715d..0000000
--- a/src/java/org/apache/commons/net/ftp/parser/MVSFTPEntryParser.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.net.ftp.parser;
-
-import org.apache.commons.net.ftp.FTPClientConfig;
-import org.apache.commons.net.ftp.FTPFile;
-
-/**
- * Implementation of FTPFileEntryParser and FTPFileListParser for IBM MVS Systems.
- *
- * @author <a href="jnadler@srcginc.com">Jeff Nadler</a>
- * @author <a href="wnoto@openfinance.com">William Noto</a>
- * @version $Id$
- * @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for usage instructions)
- */
-public class MVSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
-{  
-    /**
-     * This is the regular expression used by this parser.
-     */
-    private static final String REGEX = "(.*)\\s+([^\\s]+)\\s*";
-    
-    /**
-     * Although this parser is now ignoring dates, someone may someday
-     * figure out a way to accomodate this and this appears to be the 
-     * format used.  For now, it won't be used.
-     * SMC 2005/04/08
-     */
-    static final String DEFAULT_DATE_FORMAT 
-        = "yyyy/MM/dd"; // 2001/11/09
-
-        
-    // This is not at all the tightest possible regexp for MVS LIST
-    // output, but I'm not a mainframe guru so I have little idea what the
-    // range of valid values are.  I just needed to get the filename (Dsname);
-    // note that no other FTPFile fields can be filled in with the results of
-    // a LIST on MVS.  The 'Referred' date seems to be 'last accessed date'
-    // and not 'last modified date' so I didn't bother parsing it.
-    //
-    // Of course it works perfectly as-is and it distinguishes header lines from
-    // file results so that's the important thing.  
-    //
-    // This parser should be used when SYST returns:
-    // 'MVS is the operating system of this server. FTP Server is running on z/OS.'
-    //
-    // Also note that there is no concept of directories in MVS, just datasets,
-    // which have names composed of four dot separated names of up to 8 chars.
-    // As a result, FTPFile.FILE_TYPE is always used. -JN 6/2004 jnadler<at>srcginc<dotcom>
-
-    // Sample LIST results from MVS:
-    //
-    //Volume Unit    Referred Ext Used Recfm Lrecl BlkSz Dsorg Dsname
-    //FPFS42 3390   2004/06/23  1    1  FB     128  6144  PS  INCOMING.RPTBM023.D061704
-    //FPFS41 3390   2004/06/23  1    1  FB     128  6144  PS  INCOMING.RPTBM056.D061704
-    //FPFS25 3390   2004/06/23  1    1  FB     128  6144  PS  INCOMING.WTM204.D061704
-
-    /**
-     * The sole constructor for a MVSFTPEntryParser object.
-     *
-     * @exception IllegalArgumentException
-     * Thrown if the regular expression is unparseable.  Should not be seen
-     * under normal conditions.  It it is seen, this is a sign that
-     * <code>REGEX</code> is  not a valid regular expression.
-     */
-    public MVSFTPEntryParser()
-    {
-        super(REGEX);
-    }
-
-    /**
-     * Parses a line of an MVS FTP server file listing and converts it into a
-     * usable format in the form of an <code> FTPFile </code> instance.  If the
-     * file listing line doesn't describe a file, <code> null </code> is
-     * returned, otherwise a <code> FTPFile </code> instance representing the
-     * files in the directory is returned.
-     * <p>
-     * @param entry A line of text from the file listing
-     * @return An FTPFile instance corresponding to the supplied entry
-     */
-    public FTPFile parseFTPEntry(String entry)
-    {       
-        FTPFile f = null;
-        if (matches(entry))          
-        {
-            f = new FTPFile();
-            String dataSetName = group(2);
-            f.setType(FTPFile.FILE_TYPE);
-            f.setName(dataSetName);
-
-            return (f);
-        }
-        return null;
-    }
-
-    /* 
-     * @return
-     */
-    protected FTPClientConfig getDefaultConfiguration() {
-        return new FTPClientConfig(
-                FTPClientConfig.SYST_MVS,
-                DEFAULT_DATE_FORMAT,
-                null, null, null, null);
-    }
-}
diff --git a/src/java/org/apache/commons/net/util/ListenerList.java b/src/java/org/apache/commons/net/util/ListenerList.java
deleted file mode 100644
index e091a8e..0000000
--- a/src/java/org/apache/commons/net/util/ListenerList.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.net.util;
-
-import java.io.Serializable;
-import java.util.Enumeration;
-import java.util.EventListener;
-import java.util.Vector;
-
-/**
- * @author Daniel F. Savarese
- */
-
-public class ListenerList implements Serializable
-{
-    private Vector __listeners;
-
-    public ListenerList()
-    {
-        __listeners = new Vector();
-    }
-
-    public synchronized void addListener(EventListener listener)
-    {
-        __listeners.addElement(listener);
-    }
-
-    public synchronized void removeListener(EventListener listener)
-    {
-        __listeners.removeElement(listener);
-    }
-
-    public synchronized Enumeration getListeners()
-    {
-        return ((Vector)__listeners.clone()).elements();
-    }
-
-    public int getListenerCount()
-    {
-        return __listeners.size();
-    }
-
-}
diff --git a/src/main/java/examples/cidr/SubnetUtilsExample.java b/src/main/java/examples/cidr/SubnetUtilsExample.java
new file mode 100644
index 0000000..532e46b
--- /dev/null
+++ b/src/main/java/examples/cidr/SubnetUtilsExample.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package examples.cidr;
+
+import java.util.Arrays;
+import java.util.Scanner;
+
+import org.apache.commons.net.util.SubnetUtils;
+import org.apache.commons.net.util.SubnetUtils.SubnetInfo;
+
+/**
+ * Example class that shows how to use the {@link SubnetUtils} class. 
+ * @author Rory Winston <rwinston@apache.org>
+ *
+ */
+public class SubnetUtilsExample {
+    
+    public static void main(String[] args) {
+        String subnet = "192.168.0.3/31";
+        SubnetUtils utils = new SubnetUtils(subnet);
+        SubnetInfo info = utils.getInfo();
+        
+        System.out.printf("Subnet Information for %s:\n", subnet);
+        System.out.println("--------------------------------------");
+        System.out.printf("IP Address:\t\t\t%s\t[%s]\n", info.getAddress(), 
+                Integer.toBinaryString(info.asInteger(info.getAddress())));
+        System.out.printf("Netmask:\t\t\t%s\t[%s]\n", info.getNetmask(), 
+                Integer.toBinaryString(info.asInteger(info.getNetmask())));
+        System.out.printf("CIDR Representation:\t\t%s\n\n", info.getCidrSignature());
+        
+        System.out.printf("Supplied IP Address:\t\t%s\n\n", info.getAddress());
+        
+        System.out.printf("Network Address:\t\t%s\t[%s]\n", info.getNetworkAddress(), 
+                Integer.toBinaryString(info.asInteger(info.getNetworkAddress())));
+        System.out.printf("Broadcast Address:\t\t%s\t[%s]\n", info.getBroadcastAddress(), 
+                Integer.toBinaryString(info.asInteger(info.getBroadcastAddress())));
+        System.out.printf("Low Address:\t\t\t%s\t[%s]\n", info.getLowAddress(), 
+                Integer.toBinaryString(info.asInteger(info.getLowAddress())));
+        System.out.printf("High Address:\t\t\t%s\t[%s]\n", info.getHighAddress(), 
+                Integer.toBinaryString(info.asInteger(info.getHighAddress())));
+        
+        System.out.printf("Total usable addresses: \t%d\n", info.getAddressCount());
+        System.out.printf("Address List: %s\n\n", Arrays.toString(info.getAllAddresses()));
+        
+        final String prompt ="Enter an IP address (e.g. 192.168.0.10):"; 
+        System.out.println(prompt);
+        Scanner scanner = new Scanner(System.in);
+        while (scanner.hasNextLine()) {
+            String address = scanner.nextLine();
+            System.out.println("The IP address [" + address + "] is " 
+                    + (info.isInRange(address) ? "" : "not ") 
+                    + "within the subnet [" + subnet + "]");
+            System.out.println(prompt);
+        }
+        
+    }
+
+}
diff --git a/src/java/examples/ftp.java b/src/main/java/examples/ftp/FTPExample.java
similarity index 96%
rename from src/java/examples/ftp.java
rename to src/main/java/examples/ftp/FTPExample.java
index 2c58405..38b5678 100644
--- a/src/java/examples/ftp.java
+++ b/src/main/java/examples/ftp/FTPExample.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +14,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package examples;
+
+package examples.ftp;
 
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -22,6 +23,8 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.PrintWriter;
+
+import org.apache.commons.net.PrintCommandListener;
 import org.apache.commons.net.ftp.FTP;
 import org.apache.commons.net.ftp.FTPClient;
 import org.apache.commons.net.ftp.FTPConnectionClosedException;
@@ -37,7 +40,7 @@
  * Usage: ftp [-s] [-b] <hostname> <username> <password> <remote file> <local file>
  * <p>
  ***/
-public final class ftp
+public final class FTPExample
 {
 
     public static final String USAGE =
diff --git a/src/java/examples/ftp.java b/src/main/java/examples/ftp/FTPSExample.java
similarity index 76%
copy from src/java/examples/ftp.java
copy to src/main/java/examples/ftp/FTPSExample.java
index 2c58405..7c82e44 100644
--- a/src/java/examples/ftp.java
+++ b/src/main/java/examples/ftp/FTPSExample.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +14,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package examples;
+
+package examples.ftp;
 
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -22,13 +23,16 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.PrintWriter;
+import java.security.NoSuchAlgorithmException;
+
+import org.apache.commons.net.PrintCommandListener;
 import org.apache.commons.net.ftp.FTP;
-import org.apache.commons.net.ftp.FTPClient;
 import org.apache.commons.net.ftp.FTPConnectionClosedException;
 import org.apache.commons.net.ftp.FTPReply;
+import org.apache.commons.net.ftp.FTPSClient;
 
 /***
- * This is an example program demonstrating how to use the FTPClient class.
+ * This is an example program demonstrating how to use the FTPSClient class.
  * This program connects to an FTP server and retrieves the specified
  * file.  If the -s flag is used, it stores the local file at the FTP server.
  * Just so you can see what's happening, all reply strings are printed.
@@ -37,7 +41,7 @@
  * Usage: ftp [-s] [-b] <hostname> <username> <password> <remote file> <local file>
  * <p>
  ***/
-public final class ftp
+public final class FTPSExample
 {
 
     public static final String USAGE =
@@ -46,13 +50,14 @@
         "\t-s store file on server (upload)\n" +
         "\t-b use binary transfer mode\n";
 
-    public static final void main(String[] args)
+    public static final void main(String[] args) throws NoSuchAlgorithmException
     {
         int base = 0;
         boolean storeFile = false, binaryTransfer = false, error = false;
         String server, username, password, remote, local;
-        FTPClient ftp;
-
+        String protocol = "SSL";    // SSL/TLS
+        FTPSClient ftps;
+        
         for (base = 0; base < args.length; base++)
         {
             if (args[base].startsWith("-s"))
@@ -75,34 +80,35 @@
         remote = args[base++];
         local = args[base];
 
-        ftp = new FTPClient();
-        ftp.addProtocolCommandListener(new PrintCommandListener(
-                                           new PrintWriter(System.out)));
+        ftps = new FTPSClient(protocol);
+       
+        ftps.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
 
         try
         {
             int reply;
-            ftp.connect(server);
+
+            ftps.connect(server);
             System.out.println("Connected to " + server + ".");
 
             // After connection attempt, you should check the reply code to verify
             // success.
-            reply = ftp.getReplyCode();
+            reply = ftps.getReplyCode();
 
             if (!FTPReply.isPositiveCompletion(reply))
             {
-                ftp.disconnect();
+                ftps.disconnect();
                 System.err.println("FTP server refused connection.");
                 System.exit(1);
             }
         }
         catch (IOException e)
         {
-            if (ftp.isConnected())
+            if (ftps.isConnected())
             {
                 try
                 {
-                    ftp.disconnect();
+                    ftps.disconnect();
                 }
                 catch (IOException f)
                 {
@@ -117,21 +123,23 @@
 __main:
         try
         {
-            if (!ftp.login(username, password))
+            ftps.setBufferSize(1000);
+
+            if (!ftps.login(username, password))
             {
-                ftp.logout();
+                ftps.logout();
                 error = true;
                 break __main;
             }
 
-            System.out.println("Remote system is " + ftp.getSystemName());
+            
+            System.out.println("Remote system is " + ftps.getSystemName());
 
-            if (binaryTransfer)
-                ftp.setFileType(FTP.BINARY_FILE_TYPE);
+            if (binaryTransfer) ftps.setFileType(FTP.BINARY_FILE_TYPE);
 
             // Use passive mode as default because most of us are
             // behind firewalls these days.
-            ftp.enterLocalPassiveMode();
+            ftps.enterLocalPassiveMode();
 
             if (storeFile)
             {
@@ -139,7 +147,7 @@
 
                 input = new FileInputStream(local);
 
-                ftp.storeFile(remote, input);
+                ftps.storeFile(remote, input);
 
                 input.close();
             }
@@ -149,12 +157,12 @@
 
                 output = new FileOutputStream(local);
 
-                ftp.retrieveFile(remote, output);
+                ftps.retrieveFile(remote, output);
 
                 output.close();
             }
 
-            ftp.logout();
+            ftps.logout();
         }
         catch (FTPConnectionClosedException e)
         {
@@ -169,11 +177,11 @@
         }
         finally
         {
-            if (ftp.isConnected())
+            if (ftps.isConnected())
             {
                 try
                 {
-                    ftp.disconnect();
+                    ftps.disconnect();
                 }
                 catch (IOException f)
                 {
@@ -186,4 +194,3 @@
     } // end main
 
 }
-
diff --git a/src/java/examples/server2serverFTP.java b/src/main/java/examples/ftp/ServerToServerFTP.java
similarity index 96%
rename from src/java/examples/server2serverFTP.java
rename to src/main/java/examples/ftp/ServerToServerFTP.java
index 04f69ac..72f100f 100644
--- a/src/java/examples/server2serverFTP.java
+++ b/src/main/java/examples/ftp/ServerToServerFTP.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,11 +14,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package examples;
+
+package examples.ftp;
 
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.net.InetAddress;
+
+import org.apache.commons.net.PrintCommandListener;
 import org.apache.commons.net.ProtocolCommandListener;
 import org.apache.commons.net.ftp.FTPClient;
 import org.apache.commons.net.ftp.FTPReply;
@@ -34,7 +37,7 @@
  * Usage: ftp <host1> <user1> <pass1> <file1> <host2> <user2> <pass2> <file2>
  * <p>
  ***/
-public final class server2serverFTP
+public final class ServerToServerFTP
 {
 
     public static final void main(String[] args)
diff --git a/src/java/examples/tftp.java b/src/main/java/examples/ftp/TFTPExample.java
similarity index 97%
rename from src/java/examples/tftp.java
rename to src/main/java/examples/ftp/TFTPExample.java
index ef73ab9..2ea353e 100644
--- a/src/java/examples/tftp.java
+++ b/src/main/java/examples/ftp/TFTPExample.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +14,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package examples;
+
+package examples.ftp;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -43,7 +44,7 @@
  *        -b Use binary transfer mode
  * <p>
  ***/
-public final class tftp
+public final class TFTPExample
 {
     static final String USAGE =
         "Usage: tftp [options] hostname localfile remotefile\n\n" +
diff --git a/src/java/examples/messages.java b/src/main/java/examples/mail/POP3Mail.java
similarity index 96%
rename from src/java/examples/messages.java
rename to src/main/java/examples/mail/POP3Mail.java
index 7306b72..2991f0d 100644
--- a/src/java/examples/messages.java
+++ b/src/main/java/examples/mail/POP3Mail.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +14,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package examples;
+
+package examples.mail;
 
 import java.io.BufferedReader;
 import java.io.IOException;
@@ -31,7 +32,7 @@
  * Usage: messages <pop3 server hostname> <username> <password>
  * <p>
  ***/
-public final class messages
+public final class POP3Mail
 {
 
     public static final void printMessageInfo(BufferedReader reader, int id)
diff --git a/src/java/examples/mail.java b/src/main/java/examples/mail/SMTPMail.java
similarity index 90%
rename from src/java/examples/mail.java
rename to src/main/java/examples/mail/SMTPMail.java
index 2c93f75..faa0cfe 100644
--- a/src/java/examples/mail.java
+++ b/src/main/java/examples/mail/SMTPMail.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +14,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package examples;
+
+package examples.mail;
 
 import java.io.BufferedReader;
 import java.io.FileNotFoundException;
@@ -23,8 +24,11 @@
 import java.io.InputStreamReader;
 import java.io.PrintWriter;
 import java.io.Writer;
+import java.util.ArrayList;
 import java.util.Enumeration;
-import java.util.Vector;
+import java.util.List;
+
+import org.apache.commons.net.PrintCommandListener;
 import org.apache.commons.net.io.Util;
 import org.apache.commons.net.smtp.SMTPClient;
 import org.apache.commons.net.smtp.SMTPReply;
@@ -37,13 +41,13 @@
  * <p>
  ***/
 
-public final class mail
+public final class SMTPMail
 {
 
     public final static void main(String[] args)
     {
         String sender, recipient, subject, filename, server, cc;
-        Vector ccList = new Vector();
+        List<String> ccList = new ArrayList<String>();
         BufferedReader stdin;
         FileReader fileReader = null;
         Writer writer;
@@ -93,7 +97,7 @@
                     break;
 
                 header.addCC(cc);
-                ccList.addElement(cc);
+                ccList.add(cc);
             }
 
             System.out.print("Filename: ");
@@ -128,10 +132,10 @@
             client.setSender(sender);
             client.addRecipient(recipient);
 
-            en = ccList.elements();
+           
 
-            while (en.hasMoreElements())
-                client.addRecipient((String)en.nextElement());
+            for (String recpt : ccList)
+                client.addRecipient(recpt);
 
             writer = client.sendMessageData();
 
diff --git a/src/java/examples/nntp/ExtendedNNTPOps.java b/src/main/java/examples/nntp/ExtendedNNTPOps.java
similarity index 84%
rename from src/java/examples/nntp/ExtendedNNTPOps.java
rename to src/main/java/examples/nntp/ExtendedNNTPOps.java
index 4fe311d..4f4035b 100644
--- a/src/java/examples/nntp/ExtendedNNTPOps.java
+++ b/src/main/java/examples/nntp/ExtendedNNTPOps.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,21 +14,23 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package examples.nntp;
 
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.util.List;
 
+import org.apache.commons.net.PrintCommandListener;
 import org.apache.commons.net.nntp.Article;
 import org.apache.commons.net.nntp.NNTPClient;
 import org.apache.commons.net.nntp.NewsgroupInfo;
 
-import examples.PrintCommandListener;
 
 /**
  * Simple class showing some of the extended commands (AUTH, XOVER, LIST ACTIVE)
  * 
- * @author Rory Winston <rwinston@checkfree.com>
+ * @author Rory Winston <rwinston@apache.org>
  */
 public class ExtendedNNTPOps {
 
@@ -56,12 +58,12 @@
             // XOVER
             NewsgroupInfo testGroup = new NewsgroupInfo();
             client.selectNewsgroup("alt.test", testGroup);
-            int lowArticleNumber = testGroup.getFirstArticle();
-            int highArticleNumber = lowArticleNumber + 100;
-            Article[] articles = NNTPUtils.getArticleInfo(client, lowArticleNumber, highArticleNumber);
+            long lowArticleNumber = testGroup.getFirstArticle();
+            long  highArticleNumber = lowArticleNumber + 100;
+            List<Article> articles = NNTPUtils.getArticleInfo(client, lowArticleNumber, highArticleNumber);
 
-            for (int i = 0; i < articles.length; ++i) {
-                System.out.println(articles[i].getSubject());
+            for (Article article : articles) {
+                System.out.println(article.getSubject());
             }
 
             // LIST ACTIVE
diff --git a/src/java/examples/nntp/newsgroups.java b/src/main/java/examples/nntp/ListNewsgroups.java
similarity index 96%
rename from src/java/examples/nntp/newsgroups.java
rename to src/main/java/examples/nntp/ListNewsgroups.java
index 8a65bc1..13a453a 100644
--- a/src/java/examples/nntp/newsgroups.java
+++ b/src/main/java/examples/nntp/ListNewsgroups.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package examples.nntp;
 
 import java.io.IOException;
@@ -29,7 +30,7 @@
  * <p>
  ***/
 
-public final class newsgroups
+public final class ListNewsgroups
 {
 
     public final static void main(String[] args)
diff --git a/src/java/examples/nntp/MessageThreading.java b/src/main/java/examples/nntp/MessageThreading.java
similarity index 77%
rename from src/java/examples/nntp/MessageThreading.java
rename to src/main/java/examples/nntp/MessageThreading.java
index 5c04c09..286a17c 100644
--- a/src/java/examples/nntp/MessageThreading.java
+++ b/src/main/java/examples/nntp/MessageThreading.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -15,18 +15,20 @@
  * limitations under the License.
  */
 
+
 package examples.nntp;
 
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.net.SocketException;
+import java.util.List;
 
+import org.apache.commons.net.PrintCommandListener;
 import org.apache.commons.net.nntp.Article;
 import org.apache.commons.net.nntp.NNTPClient;
 import org.apache.commons.net.nntp.NewsgroupInfo;
 import org.apache.commons.net.nntp.Threader;
 
-import examples.PrintCommandListener;
 
 public class MessageThreading {
     public MessageThreading() {
@@ -44,27 +46,27 @@
         NNTPClient client = new NNTPClient();
         client.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
         client.connect(hostname);
-        
-        if(!client.authenticate(user, password)) {
-            System.out.println("Authentication failed for user " + user + "!");
-            System.exit(1);
-        }
-        
+//      optional authentication
+//        
+//        if(!client.authenticate(user, password)) {
+//            System.out.println("Authentication failed for user " + user + "!");
+//          //  System.exit(1);
+//        }
+//        
         NewsgroupInfo group = new NewsgroupInfo();
-        client.selectNewsgroup("comp.lang.lisp", group);
+        client.selectNewsgroup("alt.test", group);
         
-        int lowArticleNumber = group.getFirstArticle();
-        int highArticleNumber = lowArticleNumber + 100;
+        long lowArticleNumber = group.getFirstArticle();
+        long highArticleNumber = lowArticleNumber + 5000;
         
         System.out.println("Retrieving articles between [" + lowArticleNumber + "] and [" + highArticleNumber + "]");
-        Article[] articles = NNTPUtils.getArticleInfo(client, lowArticleNumber, highArticleNumber);
+        List<Article> articles = NNTPUtils.getArticleInfo(client, lowArticleNumber, highArticleNumber);
         
         System.out.println("Building message thread tree...");
         Threader threader = new Threader();
         Article root = (Article)threader.thread(articles);
         
         Article.printThread(root, 0);
-        
     }
     
     
diff --git a/src/main/java/examples/nntp/NNTPUtils.java b/src/main/java/examples/nntp/NNTPUtils.java
new file mode 100644
index 0000000..efc0715
--- /dev/null
+++ b/src/main/java/examples/nntp/NNTPUtils.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package examples.nntp;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+import org.apache.commons.net.io.DotTerminatedMessageReader;
+import org.apache.commons.net.nntp.Article;
+import org.apache.commons.net.nntp.NNTPClient;
+
+/**
+ * 
+ * Some convenience methods for NNTP example classes.
+ * 
+ * @author Rory Winston <rwinston@checkfree.com>
+ */
+public class NNTPUtils {
+
+	/**
+	 * Given an {@link NNTPClient} instance, and an integer range of messages, return 
+	 * an array of {@link Article} instances.
+	 * @param client 
+	 * @param lowArticleNumber
+	 * @param highArticleNumber
+	 * @return Article[] An array of Article
+	 * @throws IOException
+	 */
+	public  static List<Article> getArticleInfo(NNTPClient client, long lowArticleNumber, long highArticleNumber)
+	throws IOException {
+		Reader reader = null;
+		List<Article> articles = new ArrayList<Article>();
+		reader =
+			(DotTerminatedMessageReader) client.retrieveArticleInfo(
+					lowArticleNumber,
+					highArticleNumber);
+
+		if (reader != null) {
+			String theInfo = readerToString(reader);
+			StringTokenizer st = new StringTokenizer(theInfo, "\n");
+
+			// Extract the article information
+			// Mandatory format (from NNTP RFC 2980) is :
+			// Subject\tAuthor\tDate\tID\tReference(s)\tByte Count\tLine Count
+
+			int count = st.countTokens();
+			int index = 0;
+
+			while (st.hasMoreTokens()) {
+				String msg = st.nextToken();
+				System.out.println("Message:" + msg);
+				StringTokenizer stt = new StringTokenizer(msg, "\t");
+
+				try {
+					Article article = new Article();
+					article.setArticleNumber(Integer.parseInt(stt.nextToken()));
+					article.setSubject(stt.nextToken());
+					article.setFrom(stt.nextToken());
+					article.setDate(stt.nextToken());
+					article.setArticleId(stt.nextToken());
+					article.addHeaderField("References", stt.nextToken());
+					articles.add(article); 
+				}
+				catch (NoSuchElementException nse) {
+					// ignore this message
+				}
+			}
+		} else {
+			return null;
+		}
+
+		return articles;
+	}
+
+
+	/**
+	 * Convert a {@link Reader} instance to a String
+	 * @param reader The Reader instance
+	 * @return String
+	 */
+	public static String readerToString(Reader reader) {
+		String temp = null;
+		StringBuffer sb = null;
+		BufferedReader bufReader = new BufferedReader(reader);
+
+		sb = new StringBuffer();
+		try {
+			temp = bufReader.readLine();
+			while (temp != null) {
+				sb.append(temp);
+				sb.append("\n");
+				temp = bufReader.readLine();
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+
+		return sb.toString();
+	}
+}
diff --git a/src/java/examples/nntp/post.java b/src/main/java/examples/nntp/PostMessage.java
similarity index 96%
rename from src/java/examples/nntp/post.java
rename to src/main/java/examples/nntp/PostMessage.java
index 45bc052..6e0a561 100644
--- a/src/java/examples/nntp/post.java
+++ b/src/main/java/examples/nntp/PostMessage.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package examples.nntp;
 
 import java.io.BufferedReader;
@@ -23,12 +24,13 @@
 import java.io.InputStreamReader;
 import java.io.PrintWriter;
 import java.io.Writer;
+
+import org.apache.commons.net.PrintCommandListener;
 import org.apache.commons.net.io.Util;
 import org.apache.commons.net.nntp.NNTPClient;
 import org.apache.commons.net.nntp.NNTPReply;
 import org.apache.commons.net.nntp.SimpleNNTPHeader;
 
-import examples.PrintCommandListener;
 
 /***
  * This is an example program using the NNTP package to post an article
@@ -37,7 +39,7 @@
  * <p>
  ***/
 
-public final class post
+public final class PostMessage
 {
 
     public final static void main(String[] args)
diff --git a/src/java/examples/ntp/NTPClient.java b/src/main/java/examples/ntp/NTPClient.java
similarity index 98%
rename from src/java/examples/ntp/NTPClient.java
rename to src/main/java/examples/ntp/NTPClient.java
index 80f95b5..2b55e1e 100644
--- a/src/java/examples/ntp/NTPClient.java
+++ b/src/main/java/examples/ntp/NTPClient.java
@@ -7,7 +7,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -16,6 +16,7 @@
  * limitations under the License.
  */
 
+
 import java.io.IOException;
 import java.net.InetAddress;
 import java.net.SocketException;
@@ -150,7 +151,7 @@
         // We want to timeout if a response takes longer than 10 seconds
         client.setDefaultTimeout(10000);
         try {
-            client.open(NtpV3Packet.NTP_PORT);
+            client.open();
             for (int i = 0; i < args.length; i++)
             {
                 System.out.println();
@@ -170,4 +171,4 @@
         client.close();
     }
 
-}
\ No newline at end of file
+}
diff --git a/src/java/examples/ntp/TimeClient.java b/src/main/java/examples/ntp/TimeClient.java
similarity index 94%
rename from src/java/examples/ntp/TimeClient.java
rename to src/main/java/examples/ntp/TimeClient.java
index a4cda26..34cc2dd 100644
--- a/src/java/examples/ntp/TimeClient.java
+++ b/src/main/java/examples/ntp/TimeClient.java
@@ -8,7 +8,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -16,11 +16,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
  
 import java.io.IOException;
 import java.net.InetAddress;
-import org.apache.commons.net.TimeTCPClient;
-import org.apache.commons.net.TimeUDPClient;
+
+import org.apache.commons.net.time.TimeTCPClient;
+import org.apache.commons.net.time.TimeUDPClient;
 
 /***
  * This is an example program demonstrating how to use the TimeTCPClient
diff --git a/src/java/examples/TelnetClientExample.java b/src/main/java/examples/telnet/TelnetClientExample.java
similarity index 98%
rename from src/java/examples/TelnetClientExample.java
rename to src/main/java/examples/telnet/TelnetClientExample.java
index 11b70e3..56d43fc 100644
--- a/src/java/examples/TelnetClientExample.java
+++ b/src/main/java/examples/telnet/TelnetClientExample.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +14,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package examples;
+
+package examples.telnet;
 
 import java.io.InputStream;
 import java.io.OutputStream;
diff --git a/src/java/examples/weatherTelnet.java b/src/main/java/examples/telnet/WeatherTelnet.java
similarity index 93%
rename from src/java/examples/weatherTelnet.java
rename to src/main/java/examples/telnet/WeatherTelnet.java
index 18371d3..750ad37 100644
--- a/src/java/examples/weatherTelnet.java
+++ b/src/main/java/examples/telnet/WeatherTelnet.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,11 +14,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package examples;
+
+package examples.telnet;
 
 import java.io.IOException;
 import org.apache.commons.net.telnet.TelnetClient;
 
+import examples.util.IOUtil;
+
 /***
  * This is an example of a trivial use of the TelnetClient class.
  * It connects to the weather server at the University of Michigan,
@@ -33,7 +36,7 @@
  ***/
 
 // This class requires the IOUtil support class!
-public final class weatherTelnet
+public final class WeatherTelnet
 {
 
     public final static void main(String[] args)
diff --git a/src/java/examples/chargen.java b/src/main/java/examples/unix/chargen.java
similarity index 95%
rename from src/java/examples/chargen.java
rename to src/main/java/examples/unix/chargen.java
index 72f3f84..5d683af 100644
--- a/src/java/examples/chargen.java
+++ b/src/main/java/examples/unix/chargen.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +14,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package examples;
+
+package examples.unix;
 
 import java.io.BufferedReader;
 import java.io.IOException;
@@ -22,8 +23,9 @@
 import java.io.InterruptedIOException;
 import java.net.InetAddress;
 import java.net.SocketException;
-import org.apache.commons.net.CharGenTCPClient;
-import org.apache.commons.net.CharGenUDPClient;
+
+import org.apache.commons.net.chargen.CharGenTCPClient;
+import org.apache.commons.net.chargen.CharGenUDPClient;
 
 /***
  * This is an example program demonstrating how to use the CharGenTCPClient
diff --git a/src/java/examples/daytime.java b/src/main/java/examples/unix/daytime.java
similarity index 93%
rename from src/java/examples/daytime.java
rename to src/main/java/examples/unix/daytime.java
index 99841de..32fdd59 100644
--- a/src/java/examples/daytime.java
+++ b/src/main/java/examples/unix/daytime.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,12 +14,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package examples;
+
+package examples.unix;
 
 import java.io.IOException;
 import java.net.InetAddress;
-import org.apache.commons.net.DaytimeTCPClient;
-import org.apache.commons.net.DaytimeUDPClient;
+
+import org.apache.commons.net.daytime.DaytimeTCPClient;
+import org.apache.commons.net.daytime.DaytimeUDPClient;
 
 /***
  * This is an example program demonstrating how to use the DaytimeTCP
diff --git a/src/java/examples/echo.java b/src/main/java/examples/unix/echo.java
similarity index 96%
rename from src/java/examples/echo.java
rename to src/main/java/examples/unix/echo.java
index feeddf0..677d2d2 100644
--- a/src/java/examples/echo.java
+++ b/src/main/java/examples/unix/echo.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +14,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package examples;
+
+package examples.unix;
 
 import java.io.BufferedReader;
 import java.io.IOException;
@@ -24,8 +25,9 @@
 import java.io.PrintWriter;
 import java.net.InetAddress;
 import java.net.SocketException;
-import org.apache.commons.net.EchoTCPClient;
-import org.apache.commons.net.EchoUDPClient;
+
+import org.apache.commons.net.echo.EchoTCPClient;
+import org.apache.commons.net.echo.EchoUDPClient;
 
 /***
  * This is an example program demonstrating how to use the EchoTCPClient
diff --git a/src/java/examples/finger.java b/src/main/java/examples/unix/finger.java
similarity index 96%
rename from src/java/examples/finger.java
rename to src/main/java/examples/unix/finger.java
index 269eeb3..3985f58 100644
--- a/src/java/examples/finger.java
+++ b/src/main/java/examples/unix/finger.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,12 +14,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package examples;
+
+package examples.unix;
 
 import java.io.IOException;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
-import org.apache.commons.net.FingerClient;
+
+import org.apache.commons.net.finger.FingerClient;
 
 /***
  * This is an example of how you would implement the finger command
diff --git a/src/java/examples/fwhois.java b/src/main/java/examples/unix/fwhois.java
similarity index 94%
rename from src/java/examples/fwhois.java
rename to src/main/java/examples/unix/fwhois.java
index b2f3d91..741f8c2 100644
--- a/src/java/examples/fwhois.java
+++ b/src/main/java/examples/unix/fwhois.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,12 +14,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package examples;
+
+package examples.unix;
 
 import java.io.IOException;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
-import org.apache.commons.net.WhoisClient;
+
+import org.apache.commons.net.whois.WhoisClient;
 
 /***
  * This is an example of how you would implement the Linux fwhois command
diff --git a/src/java/examples/rdate.java b/src/main/java/examples/unix/rdate.java
similarity index 93%
rename from src/java/examples/rdate.java
rename to src/main/java/examples/unix/rdate.java
index da33b23..c1e4a88 100644
--- a/src/java/examples/rdate.java
+++ b/src/main/java/examples/unix/rdate.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,12 +14,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package examples;
+
+package examples.unix;
 
 import java.io.IOException;
 import java.net.InetAddress;
-import org.apache.commons.net.TimeTCPClient;
-import org.apache.commons.net.TimeUDPClient;
+
+import org.apache.commons.net.time.TimeTCPClient;
+import org.apache.commons.net.time.TimeUDPClient;
 
 /***
  * This is an example program demonstrating how to use the TimeTCPClient
diff --git a/src/java/examples/rexec.java b/src/main/java/examples/unix/rexec.java
similarity index 96%
rename from src/java/examples/rexec.java
rename to src/main/java/examples/unix/rexec.java
index 3778630..3d34838 100644
--- a/src/java/examples/rexec.java
+++ b/src/main/java/examples/unix/rexec.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,11 +14,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package examples;
+
+package examples.unix;
 
 import java.io.IOException;
 import org.apache.commons.net.bsd.RExecClient;
 
+import examples.util.IOUtil;
+
 /***
  * This is an example program demonstrating how to use the RExecClient class.
  * This program connects to an rexec server and requests that the
diff --git a/src/java/examples/rlogin.java b/src/main/java/examples/unix/rlogin.java
similarity index 96%
rename from src/java/examples/rlogin.java
rename to src/main/java/examples/unix/rlogin.java
index 7ca6f9c..9315dbd 100644
--- a/src/java/examples/rlogin.java
+++ b/src/main/java/examples/unix/rlogin.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,11 +14,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package examples;
+
+package examples.unix;
 
 import java.io.IOException;
 import org.apache.commons.net.bsd.RLoginClient;
 
+import examples.util.IOUtil;
+
 /***
  * This is an example program demonstrating how to use the RLoginClient
  * class. This program connects to an rlogin daemon and begins to
diff --git a/src/java/examples/rshell.java b/src/main/java/examples/unix/rshell.java
similarity index 96%
rename from src/java/examples/rshell.java
rename to src/main/java/examples/unix/rshell.java
index 2781a8a..c625f4b 100644
--- a/src/java/examples/rshell.java
+++ b/src/main/java/examples/unix/rshell.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,11 +14,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package examples;
+
+package examples.unix;
 
 import java.io.IOException;
 import org.apache.commons.net.bsd.RCommandClient;
 
+import examples.util.IOUtil;
+
 /***
  * This is an example program demonstrating how to use the RCommandClient
  * class. This program connects to an rshell daemon and requests that the
diff --git a/src/java/examples/IOUtil.java b/src/main/java/examples/util/IOUtil.java
similarity index 97%
rename from src/java/examples/IOUtil.java
rename to src/main/java/examples/util/IOUtil.java
index 9dfd480..64e7a69 100644
--- a/src/java/examples/IOUtil.java
+++ b/src/main/java/examples/util/IOUtil.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +14,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package examples;
+
+package examples.util;
 
 import java.io.IOException;
 import java.io.InputStream;
diff --git a/src/java/org/apache/commons/net/DatagramSocketClient.java b/src/main/java/org/apache/commons/net/DatagramSocketClient.java
similarity index 99%
rename from src/java/org/apache/commons/net/DatagramSocketClient.java
rename to src/main/java/org/apache/commons/net/DatagramSocketClient.java
index 9c3c647..33e6109 100644
--- a/src/java/org/apache/commons/net/DatagramSocketClient.java
+++ b/src/main/java/org/apache/commons/net/DatagramSocketClient.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net;
 
 import java.net.DatagramSocket;
diff --git a/src/java/org/apache/commons/net/DatagramSocketFactory.java b/src/main/java/org/apache/commons/net/DatagramSocketFactory.java
similarity index 97%
rename from src/java/org/apache/commons/net/DatagramSocketFactory.java
rename to src/main/java/org/apache/commons/net/DatagramSocketFactory.java
index 89d6e61..49b63d9 100644
--- a/src/java/org/apache/commons/net/DatagramSocketFactory.java
+++ b/src/main/java/org/apache/commons/net/DatagramSocketFactory.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net;
 
 import java.net.DatagramSocket;
diff --git a/src/java/org/apache/commons/net/DefaultDatagramSocketFactory.java b/src/main/java/org/apache/commons/net/DefaultDatagramSocketFactory.java
similarity index 97%
rename from src/java/org/apache/commons/net/DefaultDatagramSocketFactory.java
rename to src/main/java/org/apache/commons/net/DefaultDatagramSocketFactory.java
index 6706f4e..4a1079a 100644
--- a/src/java/org/apache/commons/net/DefaultDatagramSocketFactory.java
+++ b/src/main/java/org/apache/commons/net/DefaultDatagramSocketFactory.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net;
 
 import java.net.DatagramSocket;
diff --git a/src/java/org/apache/commons/net/DefaultSocketFactory.java b/src/main/java/org/apache/commons/net/DefaultSocketFactory.java
similarity index 96%
rename from src/java/org/apache/commons/net/DefaultSocketFactory.java
rename to src/main/java/org/apache/commons/net/DefaultSocketFactory.java
index 5d3f10d..076ef27 100644
--- a/src/java/org/apache/commons/net/DefaultSocketFactory.java
+++ b/src/main/java/org/apache/commons/net/DefaultSocketFactory.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net;
 
 import java.io.IOException;
@@ -22,6 +23,8 @@
 import java.net.Socket;
 import java.net.UnknownHostException;
 
+import javax.net.SocketFactory;
+
 /***
  * DefaultSocketFactory implements the SocketFactory interface by
  * simply wrapping the java.net.Socket and java.net.ServerSocket
@@ -36,7 +39,7 @@
  * @see SocketClient#setSocketFactory
  ***/
 
-public class DefaultSocketFactory implements SocketFactory
+public class DefaultSocketFactory extends SocketFactory
 {
 
     /***
@@ -48,6 +51,7 @@
      * @exception UnknownHostException  If the hostname cannot be resolved.
      * @exception IOException If an I/O error occurs while creating the Socket.
      ***/
+    @Override
     public Socket createSocket(String host, int port)
     throws UnknownHostException, IOException
     {
@@ -62,6 +66,7 @@
      * @return A Socket connected to the given host and port.
      * @exception IOException If an I/O error occurs while creating the Socket.
      ***/
+    @Override
     public Socket createSocket(InetAddress address, int port)
     throws IOException
     {
@@ -80,6 +85,7 @@
      * @exception UnknownHostException  If the hostname cannot be resolved.
      * @exception IOException If an I/O error occurs while creating the Socket.
      ***/
+    @Override
     public Socket createSocket(String host, int port,
                                InetAddress localAddr, int localPort)
     throws UnknownHostException, IOException
@@ -98,6 +104,7 @@
      * @return A Socket connected to the given host and port.
      * @exception IOException If an I/O error occurs while creating the Socket.
      ***/
+    @Override
     public Socket createSocket(InetAddress address, int port,
                                InetAddress localAddr, int localPort)
     throws IOException
diff --git a/src/java/org/apache/commons/net/MalformedServerReplyException.java b/src/main/java/org/apache/commons/net/MalformedServerReplyException.java
similarity index 97%
rename from src/java/org/apache/commons/net/MalformedServerReplyException.java
rename to src/main/java/org/apache/commons/net/MalformedServerReplyException.java
index c284552..651d2b2 100644
--- a/src/java/org/apache/commons/net/MalformedServerReplyException.java
+++ b/src/main/java/org/apache/commons/net/MalformedServerReplyException.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net;
 
 import java.io.IOException;
diff --git a/src/java/examples/PrintCommandListener.java b/src/main/java/org/apache/commons/net/PrintCommandListener.java
similarity index 93%
rename from src/java/examples/PrintCommandListener.java
rename to src/main/java/org/apache/commons/net/PrintCommandListener.java
index 0d32363..e1978db 100644
--- a/src/java/examples/PrintCommandListener.java
+++ b/src/main/java/org/apache/commons/net/PrintCommandListener.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +14,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package examples;
+
+package org.apache.commons.net;
 
 import java.io.PrintWriter;
 import org.apache.commons.net.ProtocolCommandEvent;
@@ -25,6 +26,8 @@
  * a sample implementation of the ProtocolCommandListener interface
  * which just prints out to a specified stream all command/reply traffic.
  * <p>
+ *
+ * @since 2.0
  ***/
 
 public class PrintCommandListener implements ProtocolCommandListener
@@ -48,3 +51,4 @@
         __writer.flush();
     }
 }
+
diff --git a/src/java/org/apache/commons/net/ProtocolCommandEvent.java b/src/main/java/org/apache/commons/net/ProtocolCommandEvent.java
similarity index 98%
rename from src/java/org/apache/commons/net/ProtocolCommandEvent.java
rename to src/main/java/org/apache/commons/net/ProtocolCommandEvent.java
index c61142a..285b5fd 100644
--- a/src/java/org/apache/commons/net/ProtocolCommandEvent.java
+++ b/src/main/java/org/apache/commons/net/ProtocolCommandEvent.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net;
 import java.util.EventObject;
 
diff --git a/src/java/org/apache/commons/net/ProtocolCommandListener.java b/src/main/java/org/apache/commons/net/ProtocolCommandListener.java
similarity index 97%
rename from src/java/org/apache/commons/net/ProtocolCommandListener.java
rename to src/main/java/org/apache/commons/net/ProtocolCommandListener.java
index 7335e8a..46c6c10 100644
--- a/src/java/org/apache/commons/net/ProtocolCommandListener.java
+++ b/src/main/java/org/apache/commons/net/ProtocolCommandListener.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net;
 import java.util.EventListener;
 
diff --git a/src/java/org/apache/commons/net/ProtocolCommandSupport.java b/src/main/java/org/apache/commons/net/ProtocolCommandSupport.java
similarity index 87%
rename from src/java/org/apache/commons/net/ProtocolCommandSupport.java
rename to src/main/java/org/apache/commons/net/ProtocolCommandSupport.java
index 082665e..c0ec9cc 100644
--- a/src/java/org/apache/commons/net/ProtocolCommandSupport.java
+++ b/src/main/java/org/apache/commons/net/ProtocolCommandSupport.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,10 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net;
 
 import java.io.Serializable;
-import java.util.Enumeration;
+import java.util.EventListener;
+
 import org.apache.commons.net.util.ListenerList;
 
 /***
@@ -63,18 +65,13 @@
      ***/
     public void fireCommandSent(String command, String message)
     {
-        Enumeration en;
         ProtocolCommandEvent event;
-        ProtocolCommandListener listener;
-
-        en = __listeners.getListeners();
 
         event = new ProtocolCommandEvent(__source, command, message);
 
-        while (en.hasMoreElements())
+        for (EventListener listener : __listeners)
         {
-            listener = (ProtocolCommandListener)en.nextElement();
-            listener.protocolCommandSent(event);
+           ((ProtocolCommandListener)listener).protocolCommandSent(event);
         }
     }
 
@@ -93,18 +90,12 @@
      ***/
     public void fireReplyReceived(int replyCode, String message)
     {
-        Enumeration en;
         ProtocolCommandEvent event;
-        ProtocolCommandListener listener;
-
-        en = __listeners.getListeners();
-
         event = new ProtocolCommandEvent(__source, replyCode, message);
 
-        while (en.hasMoreElements())
+        for (EventListener listener : __listeners)
         {
-            listener = (ProtocolCommandListener)en.nextElement();
-            listener.protocolReplyReceived(event);
+            ((ProtocolCommandListener)listener).protocolReplyReceived(event);
         }
     }
 
diff --git a/src/java/org/apache/commons/net/SocketClient.java b/src/main/java/org/apache/commons/net/SocketClient.java
similarity index 77%
rename from src/java/org/apache/commons/net/SocketClient.java
rename to src/main/java/org/apache/commons/net/SocketClient.java
index fa68894..f085293 100644
--- a/src/java/org/apache/commons/net/SocketClient.java
+++ b/src/main/java/org/apache/commons/net/SocketClient.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,16 +14,22 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net;
 
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.InetAddress;
+import java.net.InetSocketAddress;
 import java.net.Socket;
 import java.net.SocketException;
 import java.net.UnknownHostException;
 
+import javax.net.ServerSocketFactory;
+import javax.net.SocketFactory;
+
+
 /**
  * The SocketClient provides the basic operations that are required of
  * client objects accessing sockets.  It is meant to be
@@ -55,7 +61,11 @@
 
     /** The default SocketFactory shared by all SocketClient instances. */
     private static final SocketFactory __DEFAULT_SOCKET_FACTORY =
-        new DefaultSocketFactory();
+            SocketFactory.getDefault();
+    
+    /** The default {@link ServerSocketFactory} */
+    private static final ServerSocketFactory __DEFAULT_SERVER_SOCKET_FACTORY = 
+            ServerSocketFactory.getDefault();
 
     /** The timeout to use after opening a socket. */
     protected int _timeout_;
@@ -63,11 +73,6 @@
     /** The socket used for the connection. */
     protected Socket _socket_;
 
-    /**
-     * A status variable indicating if the client's socket is currently open.
-     */
-    protected boolean _isConnected_;
-
     /** The default port the client should connect to. */
     protected int _defaultPort_;
 
@@ -79,8 +84,20 @@
 
     /** The socket's SocketFactory. */
     protected SocketFactory _socketFactory_;
-
-
+    
+    /** The socket's ServerSocket Factory. */
+    protected ServerSocketFactory _serverSocketFactory_;
+    
+    /** The socket's connect timeout (0 = infinite timeout) */
+    private static final int DEFAULT_CONNECT_TIMEOUT = 0;
+    protected int connectTimeout = DEFAULT_CONNECT_TIMEOUT;
+    
+    /** Hint for SO_RCVBUF size */
+    int receiveBufferSize = -1;
+    
+    /** Hint for SO_SNDBUF size */
+    int sendBufferSize = -1;
+    
     /**
      * Default constructor for SocketClient.  Initializes
      * _socket_ to null, _timeout_ to 0, _defaultPort to 0,
@@ -94,8 +111,8 @@
         _output_ = null;
         _timeout_ = 0;
         _defaultPort_ = 0;
-        _isConnected_ = false;
         _socketFactory_ = __DEFAULT_SOCKET_FACTORY;
+        _serverSocketFactory_ = __DEFAULT_SERVER_SOCKET_FACTORY;
     }
 
 
@@ -120,7 +137,6 @@
         _socket_.setSoTimeout(_timeout_);
         _input_ = _socket_.getInputStream();
         _output_ = _socket_.getOutputStream();
-        _isConnected_ = true;
     }
 
 
@@ -140,7 +156,10 @@
     public void connect(InetAddress host, int port)
     throws SocketException, IOException
     {
-        _socket_ = _socketFactory_.createSocket(host, port);
+        _socket_ = _socketFactory_.createSocket();
+        if (receiveBufferSize != -1) _socket_.setReceiveBufferSize(receiveBufferSize);
+        if (sendBufferSize != -1) _socket_.setSendBufferSize(sendBufferSize);
+        _socket_.connect(new InetSocketAddress(host, port), connectTimeout);
         _connectAction_();
     }
 
@@ -159,10 +178,9 @@
      * @exception UnknownHostException If the hostname cannot be resolved.
      */
     public void connect(String hostname, int port)
-    throws SocketException, IOException, UnknownHostException
+    throws SocketException, IOException
     {
-        _socket_ = _socketFactory_.createSocket(hostname, port);
-        _connectAction_();
+        connect(InetAddress.getByName(hostname), port);
     }
 
 
@@ -185,7 +203,11 @@
                         InetAddress localAddr, int localPort)
     throws SocketException, IOException
     {
-        _socket_ = _socketFactory_.createSocket(host, port, localAddr, localPort);
+        _socket_ = _socketFactory_.createSocket();     
+        if (receiveBufferSize != -1) _socket_.setReceiveBufferSize(receiveBufferSize);
+        if (sendBufferSize != -1) _socket_.setSendBufferSize(sendBufferSize);
+        _socket_.bind(new InetSocketAddress(localAddr, localPort));
+        _socket_.connect(new InetSocketAddress(host, port), connectTimeout);
         _connectAction_();
     }
 
@@ -210,9 +232,7 @@
                         InetAddress localAddr, int localPort)
     throws SocketException, IOException
     {
-        _socket_ =
-            _socketFactory_.createSocket(hostname, port, localAddr, localPort);
-        _connectAction_();
+       connect(InetAddress.getByName(hostname), port, localAddr, localPort);
     }
 
 
@@ -265,13 +285,12 @@
      */
     public void disconnect() throws IOException
     {
-        if(_socket_ != null) _socket_.close();
-        if(_input_ != null) _input_.close();
-        if(_output_ != null) _output_.close();
-        _socket_ = null;
+        if (_socket_ != null) _socket_.close();
+        if (_input_ != null) _input_.close();
+        if (_output_ != null) _output_.close();
+        if (_socket_ != null) _socket_ = null;
         _input_ = null;
         _output_ = null;
-        _isConnected_ = false;
     }
 
 
@@ -283,7 +302,10 @@
      */
     public boolean isConnected()
     {
-        return _isConnected_;
+        if (_socket_ == null)
+            return false;
+        
+        return _socket_.isConnected();
     }
 
 
@@ -355,6 +377,30 @@
     {
         _socket_.setSoTimeout(timeout);
     }
+    
+    
+    /**
+     * Set the underlying socket send buffer size.
+     * <p>
+     * @param size The size of the buffer in bytes.
+     * @throws SocketException 
+     * @since 2.0
+     */
+    public void setSendBufferSize(int size) throws SocketException {
+        sendBufferSize = size;
+    }
+    
+    
+    /**
+     * Sets the underlying socket receive buffer size.
+     * <p>
+     * @param size The size of the buffer in bytes.
+     * @throws SocketException 
+     * @since 2.0
+     */
+    public void setReceiveBufferSize(int size) throws SocketException  {
+        receiveBufferSize = size;
+    }
 
 
     /**
@@ -393,8 +439,31 @@
     {
         return _socket_.getTcpNoDelay();
     }
-
-
+    
+    /**
+     * Sets the SO_KEEPALIVE flag on the currently opened socket.
+     * 
+     * From the Javadocs, the default keepalive time is 2 hours (although this is 
+     * implementation  dependent). It looks as though the Windows WSA sockets implementation
+     * allows a specific keepalive value to be set, although this seems not to be the case on 
+     * other systems.
+     * @param  keepAlive If true, keepAlive is turned on
+     * @throws SocketException
+     */
+    public void setKeepAlive(boolean keepAlive) throws SocketException {
+    	_socket_.setKeepAlive(keepAlive);
+    }
+    
+    /**
+     * Returns the current value of the SO_KEEPALIVE flag on the currently opened socket.
+     * 
+     * @return True if SO_KEEPALIVE is enabled.
+     * @throws SocketException
+     */
+    public boolean getKeepAlive() throws SocketException {
+    	return _socket_.getKeepAlive();
+    }
+    
     /**
      * Sets the SO_LINGER timeout on the currently opened socket.
      * <p>
@@ -501,6 +570,51 @@
         else
             _socketFactory_ = factory;
     }
+    
+    /**
+     * Sets the ServerSocketFactory used by the SocketClient to open ServerSocket
+     * connections.  If the factory value is null, then a default
+     * factory is used (only do this to reset the factory after having
+     * previously altered it).
+     * <p>
+     * @param factory  The new ServerSocketFactory the SocketClient should use.
+     * @since 2.0
+     */
+    public void setServerSocketFactory(ServerSocketFactory factory) {
+        if (factory == null)
+            _serverSocketFactory_ = __DEFAULT_SERVER_SOCKET_FACTORY;
+        else
+            _serverSocketFactory_ = factory;
+    }
+    
+    /**
+     * Sets the connection timeout in milliseconds, which will be passed to the {@link Socket} object's
+     * connect() method. 
+     * @param connectTimeout The connection timeout to use (in ms)
+     * @since 2.0
+     */
+    public void setConnectTimeout(int connectTimeout) {
+        this.connectTimeout = connectTimeout;
+    }
+    
+    /**
+     * Get the underlying socket connection timeout.
+     * @return timeout (in ms)
+     * @since 2.0
+     */
+    public int getConnectTimeout() {
+        return connectTimeout;
+    }
+
+    /**
+     * Get the underlying {@link ServerSocketFactory}
+     * @return The server socket factory
+     * @since 2.1
+     */
+	public ServerSocketFactory getServerSocketFactory() {
+		return _serverSocketFactory_;
+	}
+	
 }
 
 
diff --git a/src/java/org/apache/commons/net/bsd/RCommandClient.java b/src/main/java/org/apache/commons/net/bsd/RCommandClient.java
similarity index 97%
rename from src/java/org/apache/commons/net/bsd/RCommandClient.java
rename to src/main/java/org/apache/commons/net/bsd/RCommandClient.java
index c42e621..0aaf739 100644
--- a/src/java/org/apache/commons/net/bsd/RCommandClient.java
+++ b/src/main/java/org/apache/commons/net/bsd/RCommandClient.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.bsd;
 
 import java.io.IOException;
@@ -107,6 +108,7 @@
 
     // Overrides method in RExecClient in order to implement proper
     // port number limitations.
+    @Override
     InputStream _createErrorStream() throws IOException
     {
         int localPort;
@@ -120,7 +122,7 @@
         {
             try
             {
-                server = _socketFactory_.createServerSocket(localPort, 1,
+                server = _serverSocketFactory_.createServerSocket(localPort, 1,
                          getLocalAddress());
             }
             catch (SocketException e)
@@ -191,6 +193,9 @@
                 _socket_ =
                     _socketFactory_.createSocket(host, port, localAddr, localPort);
             }
+            catch (BindException be) {
+                continue;
+            }
             catch (SocketException e)
             {
                 continue;
@@ -221,6 +226,7 @@
      *  cases you will only want to catch IOException since SocketException is
      *  derived from it.
      ***/
+    @Override
     public void connect(InetAddress host, int port)
     throws SocketException, IOException
     {
@@ -244,8 +250,9 @@
      *  derived from it.
      * @exception UnknownHostException If the hostname cannot be resolved.
      ***/
+    @Override
     public void connect(String hostname, int port)
-    throws SocketException, IOException, UnknownHostException, BindException
+    throws SocketException, IOException, UnknownHostException
     {
         connect(InetAddress.getByName(hostname), port, InetAddress.getLocalHost());
     }
@@ -294,6 +301,7 @@
      * @exception IllegalArgumentException If an invalid local port number
      *            is specified.
      ***/
+    @Override
     public void connect(InetAddress host, int port,
                         InetAddress localAddr, int localPort)
     throws SocketException, IOException, IllegalArgumentException
@@ -325,9 +333,10 @@
      * @exception IllegalArgumentException If an invalid local port number
      *            is specified.
      ***/
+    @Override
     public void connect(String hostname, int port,
                         InetAddress localAddr, int localPort)
-    throws SocketException, IOException, IllegalArgumentException
+    throws SocketException, IOException, IllegalArgumentException, UnknownHostException
     {
         if (localPort < MIN_CLIENT_PORT || localPort > MAX_CLIENT_PORT)
             throw new IllegalArgumentException("Invalid port number " + localPort);
diff --git a/src/java/org/apache/commons/net/bsd/RExecClient.java b/src/main/java/org/apache/commons/net/bsd/RExecClient.java
similarity index 98%
rename from src/java/org/apache/commons/net/bsd/RExecClient.java
rename to src/main/java/org/apache/commons/net/bsd/RExecClient.java
index b89dd50..f61b659 100644
--- a/src/java/org/apache/commons/net/bsd/RExecClient.java
+++ b/src/main/java/org/apache/commons/net/bsd/RExecClient.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,15 +14,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.bsd;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.net.ServerSocket;
 import java.net.Socket;
-import org.apache.commons.net.io.SocketInputStream;
+
 import org.apache.commons.net.SocketClient;
-import java.io.OutputStream;
+import org.apache.commons.net.io.SocketInputStream;
 
 /***
  * RExecClient implements the rexec() facility that first appeared in
@@ -86,7 +88,7 @@
         ServerSocket server;
         Socket socket;
 
-        server = _socketFactory_.createServerSocket(0, 1, getLocalAddress());
+        server = _serverSocketFactory_.createServerSocket(0, 1, getLocalAddress());
 
         _output_.write(Integer.toString(server.getLocalPort()).getBytes());
         _output_.write('\0');
@@ -250,6 +252,7 @@
      * <p>
      * @exception IOException If there an error occurs while disconnecting.
      ***/
+    @Override
     public void disconnect() throws IOException
     {
         if (_errorStream_ != null)
diff --git a/src/java/org/apache/commons/net/bsd/RLoginClient.java b/src/main/java/org/apache/commons/net/bsd/RLoginClient.java
similarity index 98%
rename from src/java/org/apache/commons/net/bsd/RLoginClient.java
rename to src/main/java/org/apache/commons/net/bsd/RLoginClient.java
index e128b24..7ef1a27 100644
--- a/src/java/org/apache/commons/net/bsd/RLoginClient.java
+++ b/src/main/java/org/apache/commons/net/bsd/RLoginClient.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.bsd;
 
 import java.io.IOException;
diff --git a/src/java/org/apache/commons/net/CharGenTCPClient.java b/src/main/java/org/apache/commons/net/chargen/CharGenTCPClient.java
similarity index 95%
rename from src/java/org/apache/commons/net/CharGenTCPClient.java
rename to src/main/java/org/apache/commons/net/chargen/CharGenTCPClient.java
index 677e6ec..51c4b4d 100644
--- a/src/java/org/apache/commons/net/CharGenTCPClient.java
+++ b/src/main/java/org/apache/commons/net/chargen/CharGenTCPClient.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,10 +14,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.commons.net;
+
+package org.apache.commons.net.chargen;
 
 import java.io.InputStream;
 
+import org.apache.commons.net.SocketClient;
+
 /***
  * The CharGenTCPClient class is a TCP implementation of a client for the
  * character generator protocol described in RFC 864.  It can also be
diff --git a/src/java/org/apache/commons/net/CharGenUDPClient.java b/src/main/java/org/apache/commons/net/chargen/CharGenUDPClient.java
similarity index 96%
rename from src/java/org/apache/commons/net/CharGenUDPClient.java
rename to src/main/java/org/apache/commons/net/chargen/CharGenUDPClient.java
index f455fa3..d273788 100644
--- a/src/java/org/apache/commons/net/CharGenUDPClient.java
+++ b/src/main/java/org/apache/commons/net/chargen/CharGenUDPClient.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,12 +14,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.commons.net;
+
+package org.apache.commons.net.chargen;
 
 import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.InetAddress;
 
+import org.apache.commons.net.DatagramSocketClient;
+
 /***
  * The CharGenUDPClient class is a UDP implementation of a client for the
  * character generator protocol described in RFC 864.  It can also be
diff --git a/src/java/org/apache/commons/net/DaytimeTCPClient.java b/src/main/java/org/apache/commons/net/daytime/DaytimeTCPClient.java
similarity index 95%
rename from src/java/org/apache/commons/net/DaytimeTCPClient.java
rename to src/main/java/org/apache/commons/net/daytime/DaytimeTCPClient.java
index 7df9887..6509ab7 100644
--- a/src/java/org/apache/commons/net/DaytimeTCPClient.java
+++ b/src/main/java/org/apache/commons/net/daytime/DaytimeTCPClient.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,12 +14,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.commons.net;
+
+package org.apache.commons.net.daytime;
 
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
 
+import org.apache.commons.net.SocketClient;
+
 /***
  * The DaytimeTCPClient class is a TCP implementation of a client for the
  * Daytime protocol described in RFC 867.  To use the class, merely
diff --git a/src/java/org/apache/commons/net/DaytimeUDPClient.java b/src/main/java/org/apache/commons/net/daytime/DaytimeUDPClient.java
similarity index 92%
rename from src/java/org/apache/commons/net/DaytimeUDPClient.java
rename to src/main/java/org/apache/commons/net/daytime/DaytimeUDPClient.java
index b676d9f..7c48316 100644
--- a/src/java/org/apache/commons/net/DaytimeUDPClient.java
+++ b/src/main/java/org/apache/commons/net/daytime/DaytimeUDPClient.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,12 +14,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.commons.net;
+
+package org.apache.commons.net.daytime;
 
 import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.InetAddress;
 
+import org.apache.commons.net.DatagramSocketClient;
+
 /***
  * The DaytimeUDPClient class is a UDP implementation of a client for the
  * Daytime protocol described in RFC 867.  To use the class, merely
@@ -29,7 +32,7 @@
  * string, then
  * call {@link org.apache.commons.net.DatagramSocketClient#close  close }
  * to close the connection properly.  Unlike
- * {@link org.apache.commons.net.DaytimeTCPClient},
+ * {@link org.apache.commons.net.daytime.DaytimeTCPClient},
  * successive calls to {@link #getTime  getTime } are permitted
  * without re-establishing a connection.  That is because UDP is a
  * connectionless protocol and the Daytime protocol is stateless.
diff --git a/src/java/org/apache/commons/net/DiscardTCPClient.java b/src/main/java/org/apache/commons/net/discard/DiscardTCPClient.java
similarity index 93%
rename from src/java/org/apache/commons/net/DiscardTCPClient.java
rename to src/main/java/org/apache/commons/net/discard/DiscardTCPClient.java
index cf75982..d9c25ca 100644
--- a/src/java/org/apache/commons/net/DiscardTCPClient.java
+++ b/src/main/java/org/apache/commons/net/discard/DiscardTCPClient.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,10 +14,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.commons.net;
+
+package org.apache.commons.net.discard;
 
 import java.io.OutputStream;
 
+import org.apache.commons.net.SocketClient;
+
 /***
  * The DiscardTCPClient class is a TCP implementation of a client for the
  * Discard protocol described in RFC 863.  To use the class, merely
diff --git a/src/java/org/apache/commons/net/DiscardUDPClient.java b/src/main/java/org/apache/commons/net/discard/DiscardUDPClient.java
similarity index 94%
rename from src/java/org/apache/commons/net/DiscardUDPClient.java
rename to src/main/java/org/apache/commons/net/discard/DiscardUDPClient.java
index 09608a1..4882aaf 100644
--- a/src/java/org/apache/commons/net/DiscardUDPClient.java
+++ b/src/main/java/org/apache/commons/net/discard/DiscardUDPClient.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,12 +14,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.commons.net;
+
+package org.apache.commons.net.discard;
 
 import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.InetAddress;
 
+import org.apache.commons.net.DatagramSocketClient;
+
 /***
  * The DiscardUDPClient class is a UDP implementation of a client for the
  * Discard protocol described in RFC 863.  To use the class,
diff --git a/src/java/org/apache/commons/net/EchoTCPClient.java b/src/main/java/org/apache/commons/net/echo/EchoTCPClient.java
similarity index 93%
rename from src/java/org/apache/commons/net/EchoTCPClient.java
rename to src/main/java/org/apache/commons/net/echo/EchoTCPClient.java
index 8bd940e..b174b50 100644
--- a/src/java/org/apache/commons/net/EchoTCPClient.java
+++ b/src/main/java/org/apache/commons/net/echo/EchoTCPClient.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,10 +14,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.commons.net;
+
+package org.apache.commons.net.echo;
 
 import java.io.InputStream;
 
+import org.apache.commons.net.discard.DiscardTCPClient;
+
 /***
  * The EchoTCPClient class is a TCP implementation of a client for the
  * Echo protocol described in RFC 862.  To use the class, merely
diff --git a/src/java/org/apache/commons/net/EchoUDPClient.java b/src/main/java/org/apache/commons/net/echo/EchoUDPClient.java
similarity index 94%
rename from src/java/org/apache/commons/net/EchoUDPClient.java
rename to src/main/java/org/apache/commons/net/echo/EchoUDPClient.java
index 893d2b7..453939e 100644
--- a/src/java/org/apache/commons/net/EchoUDPClient.java
+++ b/src/main/java/org/apache/commons/net/echo/EchoUDPClient.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,12 +14,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.commons.net;
+
+package org.apache.commons.net.echo;
 
 import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.InetAddress;
 
+import org.apache.commons.net.discard.DiscardUDPClient;
+
 /***
  * The EchoUDPClient class is a UDP implementation of a client for the
  * Echo protocol described in RFC 862.  To use the class,
@@ -55,6 +58,7 @@
      * @exception IOException If an error occurs during the datagram send
      *     operation.
      ***/
+    @Override
     public void send(byte[] data, int length, InetAddress host)
     throws IOException
     {
@@ -63,6 +67,7 @@
 
 
     /*** Same as <code> send(data, data.length, host) </code> ***/
+    @Override
     public void send(byte[] data, InetAddress host) throws IOException
     {
         send(data, data.length, host, DEFAULT_PORT);
diff --git a/src/java/org/apache/commons/net/FingerClient.java b/src/main/java/org/apache/commons/net/finger/FingerClient.java
similarity index 80%
rename from src/java/org/apache/commons/net/FingerClient.java
rename to src/main/java/org/apache/commons/net/finger/FingerClient.java
index 79efe73..633ba8f 100644
--- a/src/java/org/apache/commons/net/FingerClient.java
+++ b/src/main/java/org/apache/commons/net/finger/FingerClient.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.commons.net;
+package org.apache.commons.net.finger;
 
 import java.io.BufferedReader;
 import java.io.IOException;
@@ -23,6 +23,8 @@
 import java.io.BufferedOutputStream;
 import java.io.DataOutputStream;
 
+import org.apache.commons.net.SocketClient;
+
 /***
  * The FingerClient class implements the client side of the Internet Finger
  * Protocol defined in RFC 1288.  To finger a host you create a
@@ -136,6 +138,26 @@
     public InputStream getInputStream(boolean longOutput, String username)
     throws IOException
     {
+        return getInputStream(longOutput, username, null);
+    }
+    
+    /***
+     * Fingers a user and returns the input stream from the network connection
+     * of the finger query.  You must first connect to a finger server before
+     * calling this method, and you should disconnect after finishing reading
+     * the stream.
+     * <p>
+     * @param longOutput Set to true if long output is requested, false if not.
+     * @param username  The name of the user to finger.
+     * @param encoding the character encoding that should be used for the query,
+     *        null for the platform's default encoding
+     * @return The InputStream of the network connection of the finger query.
+     *         Can be read to obtain finger results.
+     * @exception IOException If an I/O error during the operation.
+     ***/
+    public InputStream getInputStream(boolean longOutput, String username, String encoding)
+    throws IOException
+    {
         DataOutputStream output;
 
         __query.setLength(0);
@@ -143,10 +165,12 @@
             __query.append(__LONG_FLAG);
         __query.append(username);
         __query.append(SocketClient.NETASCII_EOL);
+        
+        byte[] encodedQuery = 
+                (encoding == null ? __query.toString().getBytes() : __query.toString().getBytes(encoding));
 
-        output =
-          new DataOutputStream(new BufferedOutputStream(_output_, 1024));
-        output.writeBytes(__query.toString());
+        output = new DataOutputStream(new BufferedOutputStream(_output_, 1024));
+        output.write(encodedQuery, 0, encodedQuery.length);
         output.flush();
 
         return _input_;
diff --git a/src/java/org/apache/commons/net/ftp/Configurable.java b/src/main/java/org/apache/commons/net/ftp/Configurable.java
similarity index 91%
rename from src/java/org/apache/commons/net/ftp/Configurable.java
rename to src/main/java/org/apache/commons/net/ftp/Configurable.java
index 0442d36..7bf66ed 100644
--- a/src/java/org/apache/commons/net/ftp/Configurable.java
+++ b/src/main/java/org/apache/commons/net/ftp/Configurable.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.ftp;
 
 
@@ -30,6 +31,5 @@
      * <code>config</code> are somehow inadequate to configure the
      * Configurable object.
      */
-    public void configure(
-            FTPClientConfig config);
-}
\ No newline at end of file
+    public void configure(FTPClientConfig config);
+}
diff --git a/src/java/org/apache/commons/net/ftp/FTP.java b/src/main/java/org/apache/commons/net/ftp/FTP.java
similarity index 92%
rename from src/java/org/apache/commons/net/ftp/FTP.java
rename to src/main/java/org/apache/commons/net/ftp/FTP.java
index 864f629..ed72f04 100644
--- a/src/java/org/apache/commons/net/ftp/FTP.java
+++ b/src/main/java/org/apache/commons/net/ftp/FTP.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,34 +14,28 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.ftp;
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
 import java.net.InetAddress;
 import java.net.Socket;
 import java.net.SocketException;
-import java.util.Enumeration;
-import java.util.Vector;
+import java.util.ArrayList;
 
 import org.apache.commons.net.MalformedServerReplyException;
 import org.apache.commons.net.ProtocolCommandListener;
 import org.apache.commons.net.ProtocolCommandSupport;
 import org.apache.commons.net.SocketClient;
-import org.apache.commons.net.telnet.TelnetClient;
 
 /***
  * FTP provides the basic the functionality necessary to implement your
- * own FTP client.  It extends org.apache.commons.net.TelnetClient
- * simply because it saves the writing of extra code to handle the FTP
- * control connection which always remains open during an FTP session and
- * uses the Telnet protocol.  Aggregation would require writing new
- * wrapper methods and wouldn't leverage the functionality already
- * present in org.apache.commons.net.SocketClient.
+ * own FTP client.  It extends org.apache.commons.net.SocketClient since
+ * extending TelnetClient was causing unwanted behavior (like connections
+ * that did not time out properly).
  * <p>
  * To derive the full benefits of the FTP class requires some knowledge
  * of the FTP protocol defined in RFC 959.  However, there is no reason
@@ -91,12 +85,15 @@
  * <p>
  * <p>
  * @author Daniel F. Savarese
+ * @author Rory Winston 
+ * @author Joseph Hindsley
  * @see FTPClient
  * @see FTPConnectionClosedException
  * @see org.apache.commons.net.MalformedServerReplyException
+ * @version $Id$
  ***/
 
-public class FTP extends TelnetClient
+public class FTP extends SocketClient
 {
     /*** The default FTP data port (20). ***/
     public static final int DEFAULT_DATA_PORT = 20;
@@ -118,14 +115,7 @@
      ***/
     public static final int EBCDIC_FILE_TYPE = 1;
 
-    /***
-     * A constant used to indicate the file(s) being transfered should
-     * be treated as a binary image, i.e., no translations should be
-     * performed.  All constants ending in <code>FILE_TYPE</code> are used to
-     * indicate file types.
-     ***/
-    public static final int IMAGE_FILE_TYPE = 2;
-
+   
     /***
      * A constant used to indicate the file(s) being transfered should
      * be treated as a binary image, i.e., no translations should be
@@ -223,13 +213,20 @@
     public static final String DEFAULT_CONTROL_ENCODING = "ISO-8859-1";
     private static final String __modes = "AEILNTCFRPSBC";
 
-    private StringBuffer __commandBuffer;
+    private StringBuilder __commandBuffer = new StringBuilder();
 
-    int _replyCode;
-    Vector _replyLines;
-    boolean _newReplyString;
-    String _replyString;
-    String _controlEncoding;
+    protected int _replyCode;
+    protected ArrayList<String> _replyLines;
+    protected boolean _newReplyString;
+    protected String _replyString;
+    protected String _controlEncoding;
+    
+    /**
+     * This is used to signal whether a block of multiline responses beginning
+     * with xxx must be terminated by the same numeric code xxx
+     * See section 4.2 of RFC 959 for details. 
+     */
+    protected boolean strictMultilineParsing = false;
 
     /**
      * Wraps SocketClient._input_ to facilitate the writing of text
@@ -262,21 +259,36 @@
      ***/
     public FTP()
     {
+        super();
         setDefaultPort(DEFAULT_PORT);
-        __commandBuffer = new StringBuffer();
-        _replyLines = new Vector();
+        _replyLines = new ArrayList<String>();
         _newReplyString = false;
         _replyString = null;
         _commandSupport_ = new ProtocolCommandSupport(this);
         _controlEncoding = DEFAULT_CONTROL_ENCODING;
     }
 
+    // The RFC-compliant multiline termination check
+    private boolean __strictCheck(String line, String code) {
+        return (!(line.startsWith(code) && line.charAt(3) == ' '));
+    }
+    
+    // The strict check is too strong a condition because of non-conforming ftp
+    // servers like ftp.funet.fi which sent 226 as the last line of a
+    // 426 multi-line reply in response to ls /.  We relax the condition to
+    // test that the line starts with a digit rather than starting with
+    // the code.
+    private boolean __lenientCheck(String line) {
+        return (!(line.length() >= 4 && line.charAt(3) != '-' &&
+                Character.isDigit(line.charAt(0))));
+    }
+    
     private void __getReply() throws IOException
     {
         int length;
 
         _newReplyString = true;
-        _replyLines.setSize(0);
+        _replyLines.clear();
 
         String line = _controlInput_.readLine();
 
@@ -290,10 +302,11 @@
         if (length < 3)
             throw new MalformedServerReplyException(
                 "Truncated server reply: " + line);
-
+        
+        String code = null;
         try
         {
-            String code = line.substring(0, 3);
+            code = line.substring(0, 3);
             _replyCode = Integer.parseInt(code);
         }
         catch (NumberFormatException e)
@@ -302,7 +315,7 @@
                 "Could not parse response code.\nServer Reply: " + line);
         }
 
-        _replyLines.addElement(line);
+        _replyLines.add(line);
 
         // Get extra lines if message continues.
         if (length > 3 && line.charAt(3) == '-')
@@ -315,42 +328,37 @@
                     throw new FTPConnectionClosedException(
                         "Connection closed without indication.");
 
-                _replyLines.addElement(line);
+                _replyLines.add(line);
 
                 // The length() check handles problems that could arise from readLine()
                 // returning too soon after encountering a naked CR or some other
                 // anomaly.
             }
-            while (!(line.length() >= 4 && line.charAt(3) != '-' &&
-                     Character.isDigit(line.charAt(0))));
-            // This is too strong a condition because of non-conforming ftp
-            // servers like ftp.funet.fi which sent 226 as the last line of a
-            // 426 multi-line reply in response to ls /.  We relax the condition to
-            // test that the line starts with a digit rather than starting with
-            // the code.
-            // line.startsWith(code)));
+            while ( isStrictMultilineParsing() ? __strictCheck(line, code) : __lenientCheck(line));
         }
 
-        if (_commandSupport_.getListenerCount() > 0)
+        if (_commandSupport_.getListenerCount() > 0) {
             _commandSupport_.fireReplyReceived(_replyCode, getReplyString());
+        }
 
-        if (_replyCode == FTPReply.SERVICE_NOT_AVAILABLE)
-            throw new FTPConnectionClosedException(
-                "FTP response 421 received.  Server closed connection.");
+        if (_replyCode == FTPReply.SERVICE_NOT_AVAILABLE) {
+            throw new FTPConnectionClosedException("FTP response 421 received.  Server closed connection.");
+        }
     }
 
     /**
      * Initiates control connections and gets initial reply.
      * Initializes {@link #_controlInput_} and {@link #_controlOutput_}.
      */
+    @Override
     protected void _connectAction_() throws IOException
     {
         super._connectAction_();
         _controlInput_ =
-            new BufferedReader(new InputStreamReader(getInputStream(),
+            new BufferedReader(new InputStreamReader(_socket_.getInputStream(),
                                                      getControlEncoding()));
         _controlOutput_ =
-            new BufferedWriter(new OutputStreamWriter(getOutputStream(),
+            new BufferedWriter(new OutputStreamWriter(_socket_.getOutputStream(),
                                                       getControlEncoding()));
         __getReply();
         // If we received code 120, we have to fetch completion reply.
@@ -413,12 +421,12 @@
      * <p>
      * @exception IOException If an error occurs while disconnecting.
      ***/
+    @Override
     public void disconnect() throws IOException
     {
         super.disconnect();
         _controlInput_ = null;
         _controlOutput_ = null;
-        _replyLines.setSize(0);
         _newReplyString = false;
         _replyString = null;
     }
@@ -483,11 +491,10 @@
     }
 
     /**
-     * Checks if the socket is connected using reflection to be backward compatible.
-     * The return value of this method is only meaningful in an java 1.4 environment.
+     * Checks if the socket is connected 
      *
      * @param socket
-     * @return true if connected or pre java 1.4
+     * @return true if connected
      */
     private boolean socketIsConnected(Socket socket)
     {
@@ -495,24 +502,7 @@
         {
             return false;
         }
-
-        try
-        {
-            Method isConnected = socket.getClass().getMethod("isConnected", null);
-            return ((Boolean) isConnected.invoke(socket, null)).booleanValue();
-        }
-        catch (NoSuchMethodException e)
-        {
-            return true;
-        }
-        catch (IllegalAccessException e)
-        {
-            return true;
-        }
-        catch (InvocationTargetException e)
-        {
-            return true;
-        }
+        return socket.isConnected();
     }
 
     /***
@@ -637,10 +627,7 @@
      ***/
     public String[] getReplyStrings()
     {
-        String[] lines;
-        lines = new String[_replyLines.size()];
-        _replyLines.copyInto(lines);
-        return lines;
+        return _replyLines.toArray(new String[0]);
     }
 
     /***
@@ -652,21 +639,20 @@
      ***/
     public String getReplyString()
     {
-        Enumeration en;
-        StringBuffer buffer;
+        StringBuilder buffer;
 
-        if (!_newReplyString)
+        if (!_newReplyString) {
             return _replyString;
-
-        buffer = new StringBuffer(256);
-        en = _replyLines.elements();
-        while (en.hasMoreElements())
-        {
-            buffer.append((String)en.nextElement());
-            buffer.append(SocketClient.NETASCII_EOL);
         }
 
-        _newReplyString = false;
+        buffer = new StringBuilder(256);
+        
+        for (String line : _replyLines) {
+                buffer.append(line);
+                buffer.append(SocketClient.NETASCII_EOL);
+        }
+        
+         _newReplyString = false;
 
         return (_replyString = buffer.toString());
     }
@@ -1115,6 +1101,18 @@
     {
         return sendCommand(FTPCommand.ALLO, Integer.toString(bytes));
     }
+    
+    /**
+     * A convenience method to send the FTP FEAT command to the server, receive the reply,
+     * and return the reply code.
+     * @return The reply code received by the server
+     * @throws IOException  If an I/O error occurs while either sending the
+     *      command or receiving the server reply.
+     */
+    public int feat() throws IOException
+    {
+    	return sendCommand(FTPCommand.FEAT);
+    }
 
     /***
      * A convenience method to send the FTP ALLO command to the server,
@@ -1155,7 +1153,39 @@
     {
         return sendCommand(FTPCommand.REST, marker);
     }
-
+    
+    
+    /**
+     * @since 2.0
+     **/
+    public int mdtm(String file) throws IOException 
+    {
+        return sendCommand(FTPCommand.MDTM, file);
+    }
+    
+    
+    /**
+     * A convenience method to send the FTP MFMT command to the server,
+     * receive the reply, and return the reply code.
+     * <p>
+     * @param pathname The pathname for which mtime is to be changed
+     * @param timeval Timestamp in <code>YYYYMMDDhhmmss</code> format
+     * @return The reply code received from the server.
+     * @exception FTPConnectionClosedException
+     *      If the FTP server prematurely closes the connection as a result
+     *      of the client being idle or some other reason causing the server
+     *      to send FTP reply code 421.  This exception may be caught either
+     *      as an IOException or independently as itself.
+     * @exception IOException  If an I/O error occurs while either sending the
+     *      command or receiving the server reply.
+     * @see <a href="http://tools.ietf.org/html/draft-somers-ftp-mfxx-04">http://tools.ietf.org/html/draft-somers-ftp-mfxx-04</a>
+     **/
+    public int mfmt(String pathname, String timeval) throws IOException 
+    {
+    	return sendCommand(FTPCommand.MFMT, timeval + " " + pathname);
+    }
+    
+    
     /***
      * A convenience method to send the FTP RNFR command to the server,
      * receive the reply, and return the reply code.
@@ -1484,6 +1514,23 @@
         return sendCommand(FTPCommand.NOOP);
     }
 
+    /**
+     * Return whether strict multiline parsing is enabled, as per RFC 959, section 4.2.
+     * @return True if strict, false if lenient
+     * @since 2.0
+     */
+    public boolean isStrictMultilineParsing() {
+        return strictMultilineParsing;
+    }
+
+    /**
+     * Set strict multiline parsing.
+     * @param strictMultilineParsing
+     * @since 2.0
+     */
+    public void setStrictMultilineParsing(boolean strictMultilineParsing) {
+        this.strictMultilineParsing = strictMultilineParsing;
+    }
 }
 
 /* Emacs configuration
diff --git a/src/java/org/apache/commons/net/ftp/FTPClient.java b/src/main/java/org/apache/commons/net/ftp/FTPClient.java
similarity index 86%
rename from src/java/org/apache/commons/net/ftp/FTPClient.java
rename to src/main/java/org/apache/commons/net/ftp/FTPClient.java
index 2d41573..f095d3d 100644
--- a/src/java/org/apache/commons/net/ftp/FTPClient.java
+++ b/src/main/java/org/apache/commons/net/ftp/FTPClient.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.ftp;
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
@@ -25,7 +26,7 @@
 import java.net.InetAddress;
 import java.net.ServerSocket;
 import java.net.Socket;
-import java.util.Vector;
+import java.util.ArrayList;
 
 import org.apache.commons.net.MalformedServerReplyException;
 import org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory;
@@ -103,8 +104,7 @@
  * <code> FTP.STREAM_TRANSFER_MODE </code>, and
  * <code> FTP.FILE_STRUCTURE </code>.  The only file types directly supported
  * are <code> FTP.ASCII_FILE_TYPE </code> and
- * <code> FTP.IMAGE_FILE_TYPE </code> (which is the same as
- * <code> FTP.BINARY_FILE_TYPE </code>).  Because there are at lest 4
+ * <code> FTP.BINARY_FILE_TYPE </code>.  Because there are at least 4
  * different EBCDIC encodings, we have opted not to provide direct support
  * for EBCDIC.  To transfer EBCDIC and other unsupported file types you
  * must create your own filter InputStreams and OutputStreams and wrap
@@ -157,7 +157,7 @@
  * and
  * {@link org.apache.commons.net.ftp.FTP#getReplyStrings  getReplyStrings}.
  * You may avoid server disconnections while the client is idle by
- * periodicaly sending NOOP commands to the server.
+ * periodically sending NOOP commands to the server.
  * <p>
  * Rather than list it separately for each method, we mention here that
  * every method communicating with the server and throwing an IOException
@@ -175,7 +175,7 @@
  * <p>
  * Unpaged (whole list) access, using a parser accessible by auto-detect:
  * <pre>
- *    FTPClient f=FTPClient();
+ *    FTPClient f = new FTPClient();
  *    f.connect(server);
  *    f.login(username, password);
  *    FTPFile[] files = listFiles(directory);
@@ -185,7 +185,7 @@
  * defined in the first parameter of initateListParsing should be derived
  * from org.apache.commons.net.FTPFileEntryParser:
  * <pre>
- *    FTPClient f=FTPClient();
+ *    FTPClient f = new FTPClient();
  *    f.connect(server);
  *    f.login(username, password);
  *    FTPListParseEngine engine =
@@ -200,7 +200,7 @@
  * <p>
  * Paged access, using a parser accessible by auto-detect:
  * <pre>
- *    FTPClient f=FTPClient();
+ *    FTPClient f = new FTPClient();
  *    f.connect(server);
  *    f.login(username, password);
  *    FTPListParseEngine engine = f.initiateListParsing(directory);
@@ -219,19 +219,16 @@
  * <li>are in different timezones and you need accurate timestamps for dependency checking 
  *     as in Ant</li>
  * </ul>see {@link  FTPClientConfig  FTPClientConfig}.
- * <p>
- * NOTE: If you experience problems with unwanted firing of <pre>setSoTimeout()</pre> 
- * during periods of client inactivity, this can be alleviated by calling <pre>setReaderThread(false)</pre>.
- * For more details, see <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=31122">this thread</a>. 
- * </p>
  * <p> 
  * @author Daniel F. Savarese
+ * @author Rory Winston
  * @see FTP
  * @see FTPConnectionClosedException
  * @see FTPFileEntryParser
  * @see FTPFileEntryParserFactory
  * @see DefaultFTPFileEntryParserFactory
  * @see FTPClientConfig
+ * 
  * @see org.apache.commons.net.MalformedServerReplyException
  **/
 public class FTPClient extends FTP
@@ -276,6 +273,7 @@
     private long __restartOffset;
     private FTPFileEntryParserFactory __parserFactory;
     private int __bufferSize;
+    private boolean __listHiddenFiles;
 
     // __systemName is a cached value that should not be referenced directly
     // except when assigned in getSystemName and __initDefaults.
@@ -287,6 +285,13 @@
     
     private FTPClientConfig __configuration;
 
+    /** Pattern for PASV mode responses */ 
+    private static String __parms = "\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3}";
+    private static java.util.regex.Pattern __parms_pat;
+    static {
+       __parms_pat = java.util.regex.Pattern.compile(__parms);
+    }
+
     /***
      * Default FTPClient constructor.  Creates a new FTPClient instance
      * with the data connection mode set to
@@ -303,6 +308,7 @@
         __remoteVerificationEnabled = true;
         __parserFactory = new DefaultFTPFileEntryParserFactory();
         __configuration      = null;
+        __listHiddenFiles = false;
     }
 
 
@@ -335,37 +341,21 @@
     private void __parsePassiveModeReply(String reply)
     throws MalformedServerReplyException
     {
-        int i, index, lastIndex;
-        String octet1, octet2;
-        StringBuffer host;
-
-        reply = reply.substring(reply.indexOf('(') + 1,
-                                reply.indexOf(')')).trim();
-
-        host = new StringBuffer(24);
-        lastIndex = 0;
-        index = reply.indexOf(',');
-        host.append(reply.substring(lastIndex, index));
-
-        for (i = 0; i < 3; i++)
-        {
-            host.append('.');
-            lastIndex = index + 1;
-            index = reply.indexOf(',', lastIndex);
-            host.append(reply.substring(lastIndex, index));
+        java.util.regex.Matcher m = __parms_pat.matcher(reply);
+        if (!m.find()) {
+            throw new MalformedServerReplyException(
+                "Could not parse passive host information.\nServer Reply: " + reply);
         }
+        reply = m.group();
+        String parts[] = m.group().split(",");
+        
+        __passiveHost = parts[0] + '.' + parts[1] + '.' + parts[2] + '.' + parts[3];
 
-        lastIndex = index + 1;
-        index = reply.indexOf(',', lastIndex);
-
-        octet1 = reply.substring(lastIndex, index);
-        octet2 = reply.substring(index + 1);
-
-        // index and lastIndex now used as temporaries
         try
         {
-            index = Integer.parseInt(octet1);
-            lastIndex = Integer.parseInt(octet2);
+            int oct1 = Integer.parseInt(parts[4]);
+            int oct2 = Integer.parseInt(parts[5]);
+            __passivePort = (oct1 << 8) | oct2;
         }
         catch (NumberFormatException e)
         {
@@ -373,11 +363,6 @@
                 "Could not parse passive host information.\nServer Reply: " + reply);
         }
 
-        index <<= 8;
-        index |= lastIndex;
-
-        __passiveHost = host.toString();
-        __passivePort = index;
     }
 
     private boolean __storeFile(int command, String remote, InputStream local)
@@ -473,7 +458,7 @@
         if (__dataConnectionMode == ACTIVE_LOCAL_DATA_CONNECTION_MODE)
         {
             ServerSocket server;
-            server = _socketFactory_.createServerSocket(0, 1, getLocalAddress());
+            server = _serverSocketFactory_.createServerSocket(0, 1, getLocalAddress());
 
             if (!FTPReply.isPositiveCompletion(port(getLocalAddress(),
                                                     server.getLocalPort())))
@@ -512,7 +497,7 @@
             if (pasv() != FTPReply.ENTERING_PASSIVE_MODE)
                 return null;
 
-            __parsePassiveModeReply((String)_replyLines.elementAt(0));
+            __parsePassiveModeReply(_replyLines.get(_replyLines.size() - 1));
 
             socket = _socketFactory_.createSocket(__passiveHost, __passivePort);
             if ((__restartOffset > 0) && !restart(__restartOffset))
@@ -549,6 +534,7 @@
     }
 
 
+    @Override
     protected void _connectAction_() throws IOException
     {
         super._connectAction_();
@@ -589,6 +575,7 @@
      * <p>
      * @exception IOException If an error occurs while disconnecting.
      ***/
+    @Override
     public void disconnect() throws IOException
     {
         super.disconnect();
@@ -638,6 +625,7 @@
      ***/
     public boolean login(String username, String password) throws IOException
     {
+    	
         user(username);
 
         if (FTPReply.isPositiveCompletion(_replyCode))
@@ -901,7 +889,7 @@
             return false;
 
         __dataConnectionMode = PASSIVE_REMOTE_DATA_CONNECTION_MODE;
-        __parsePassiveModeReply((String)_replyLines.elementAt(0));
+        __parsePassiveModeReply(_replyLines.get(0));
 
         return true;
     }
@@ -956,7 +944,7 @@
 
     /***
      * Sets the file type to be transferred.  This should be one of
-     * <code> FTP.ASCII_FILE_TYPE </code>, <code> FTP.IMAGE_FILE_TYPE </code>,
+     * <code> FTP.ASCII_FILE_TYPE </code>, <code> FTP.BINARY_FILE_TYPE</code>,
      * etc.  The file type only needs to be set when you want to change the
      * type.  After changing it, the new type stays in effect until you change
      * it again.  The default file type is <code> FTP.ASCII_FILE_TYPE </code>
@@ -988,7 +976,7 @@
     /***
      * Sets the file type to be transferred and the format.  The type should be
      * one of  <code> FTP.ASCII_FILE_TYPE </code>,
-     * <code> FTP.IMAGE_FILE_TYPE </code>, etc.  The file type only needs to
+     * <code> FTP.BINARY_FILE_TYPE </code>, etc.  The file type only needs to
      * be set when you want to change the type.  After changing it, the new
      * type stays in effect until you change it again.  The default file type
      * is <code> FTP.ASCII_FILE_TYPE </code> if this method is never called.
@@ -1622,6 +1610,26 @@
     {
         return FTPReply.isPositiveCompletion(allo(bytes));
     }
+    
+    /**
+     * Query the server for supported features. The server may reply with a list of server-supported exensions.
+     * For example, a typical client-server interaction might be (from RFC 	2289):
+     * <pre>
+        C> feat
+        S> 211-Extensions supported:
+        S>  MLST size*;create;modify*;perm;media-type
+        S>  SIZE
+        S>  COMPRESSION
+        S>  MDTM
+        S> 211 END
+     * </pre>
+     * @see <a href="http://www.faqs.org/rfcs/rfc2389.html">http://www.faqs.org/rfcs/rfc2389.html</a>
+     * @return True if successfully completed, false if not.
+     * @throws IOException
+     */
+    public boolean features() throws IOException {
+    	return FTPReply.isPositiveCompletion(feat());
+    }
 
 
     /**
@@ -1813,7 +1821,7 @@
         if (pwd() != FTPReply.PATHNAME_CREATED)
             return null;
 
-        return __parsePathname((String)_replyLines.elementAt(0));
+        return __parsePathname(_replyLines.get( _replyLines.size() - 1));
     }
 
 
@@ -1860,7 +1868,7 @@
       // in practice FTP servers deviate, so we soften the condition to
       // a positive completion.
         if (__systemName == null && FTPReply.isPositiveCompletion(syst()))
-            __systemName = ((String)_replyLines.elementAt(0)).substring(4);
+            __systemName = _replyLines.get(_replyLines.size() - 1).substring(4);
 
         return __systemName;
     }
@@ -1927,7 +1935,7 @@
     {
         return FTPReply.isPositiveCompletion(noop());
     }
-
+    
 
     /***
      * Obtain a list of filenames in a directory (or just the name of a given
@@ -1958,7 +1966,7 @@
         String line;
         Socket socket;
         BufferedReader reader;
-        Vector results;
+        ArrayList<String> results;
 
         if ((socket = _openDataConnection_(FTPCommand.NLST, pathname)) == null)
             return null;
@@ -1966,18 +1974,17 @@
         reader =
             new BufferedReader(new InputStreamReader(socket.getInputStream(), getControlEncoding()));
 
-        results = new Vector();
+        results = new ArrayList<String>();
         while ((line = reader.readLine()) != null)
-            results.addElement(line);
+            results.add(line);
+        
         reader.close();
         socket.close();
 
         if (completePendingCommand())
         {
-            String[] result;
-            result = new String[results.size()];
-            results.copyInto(result);
-            return result;
+            String[] names = new String[ results.size() ];
+            return results.toArray(names);
         }
 
         return null;
@@ -2011,91 +2018,6 @@
     }
 
 
-    /**
-     * Using the supplied <code>parserKey</code>, obtain a list
-     * of file information for the current working directory or for just a
-     * single file.
-     * <p>
-     * If <code>key</code> is null, this object will try to autodetect
-     * the system-type/parser-type by calling the SYST command.
-     * <p>
-     * Under the DefaultFTPFileEntryParserFactory, which is used unless a
-     * different factory has been specified, the key
-     * can be either a recognized System type for which a parser has been
-     * defined, or the fully qualified class name of a class that implements
-     * org.apache.commons.net.ftp.FTPFileEntryParser.
-     * <p>
-     * This information is obtained through the LIST command.  The contents of
-     * the returned array is determined by the<code> FTPFileEntryParser </code>
-     * used.
-     * <p>
-     * @param parserKey This is a "handle" which the parser factory used
-     *                  must be able to resolve into a class implementing
-     *                  FTPFileEntryParser.
-     *                  <p>
-     *                  In the DefaultFTPFileEntryParserFactory, this
-     *                  may either be a specific key identifying a server type,
-     *                  which is used to identify a parser type,
-     *                  or the fully qualified class name of the parser.  See
-     *                  DefaultFTPFileEntryParserFactory.createFileEntryParser
-     *                  for full details.
-     *                  <p>
-     *                  If this parameter is null, will attempt to generate a key
-     *                  by running the SYST command.  This should cause no problem
-     *                  with the functionality implemented in the
-     *                  DefaultFTPFileEntryParserFactory, but may not map so well
-     *                  to an alternative user-created factory.  If that is the
-     *                  case, calling this routine with a null parameter and a
-     *                  custom parser factory may not be advisable.
-     *                  <p>
-     * @param pathname  The file or directory to list.  Since the server may
-     *                  or may not expand glob expressions, using them here
-     *                  is not recommended and may well cause this method to
-     *                  fail.
-     *
-     * @return The list of file information contained in the given path in
-     *         the format determined by the parser represented by the
-     *         <code> parserKey </code> parameter.
-     *         <p><b> 
-     *         NOTE:</b> This array may contain null members if any of the 
-     *         individual file listings failed to parse.  The caller should 
-     *         check each entry for null before referencing it.
-     * @exception FTPConnectionClosedException
-     *                   If the FTP server prematurely closes the connection
-     *                   as a result of the client being idle or some other
-     *                   reason causing the server to send FTP reply code 421.
-     *                   This exception may be caught either as an IOException
-     *                   or independently as itself.
-     * @exception IOException
-     *                   If an I/O error occurs while either sending a
-     *                   command to the server or receiving a reply
-     *                   from the server.
-     * @exception ParserInitializationException
-     *                   Thrown if the parserKey parameter cannot be
-     *                   resolved by the selected parser factory.
-     *                   In the DefaultFTPEntryParserFactory, this will
-     *                   happen when parserKey is neither
-     *                   the fully qualified class name of a class
-     *                   implementing the interface
-     *                   org.apache.commons.net.ftp.FTPFileEntryParser
-     *                   nor a string containing one of the recognized keys
-     *                   mapping to such a parser or if class loader
-     *                   security issues prevent its being loaded.
-     * @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
-     * @see org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory
-     * @see org.apache.commons.net.ftp.FTPFileEntryParser
-     * @deprecated use {@link  #listFiles()  listFiles()} or 
-     * {@link  #listFiles(String)  listFiles(String)} instead and specify the
-     * parser Key in an {@link  FTPClientConfig} object instead.
-     */
-    public FTPFile[] listFiles(String parserKey, String pathname)
-    throws IOException
-    {
-        FTPListParseEngine engine =
-            initiateListParsing(parserKey, pathname);
-        return engine.getFiles();
-    }
-
 
     /**
      * Using the default system autodetect mechanism, obtain a
@@ -2391,12 +2313,11 @@
         Socket socket;
 
         FTPListParseEngine engine = new FTPListParseEngine(parser);
-        if ((socket = _openDataConnection_(FTPCommand.LIST, pathname)) == null)
+        if ((socket = _openDataConnection_(FTPCommand.LIST, getListArguments(pathname))) == null)
         {
             return engine;
         }
 
-
         try {
             engine.readServerList(socket.getInputStream(), getControlEncoding());
         }
@@ -2408,6 +2329,22 @@
         return engine;
     }
 
+    /**
+     * @since 2.0
+     */
+    protected String getListArguments(String pathname) {
+        if (getListHiddenFiles())
+        {
+            StringBuffer sb = new StringBuffer(pathname.length() + 3);
+            sb.append("-a ");
+            sb.append(pathname);
+            return sb.toString();
+        }
+        
+        return pathname;
+    }
+
+
     /***
      * Issue the FTP STAT command to the server.
      * <p>
@@ -2447,196 +2384,46 @@
             return getReplyString();
         return null;
     }
-
+    
+    
     /**
-     * Using a programmer specified <code> FTPFileListParser </code>, obtain a
-     * list of file information for a directory or information for
-     * just a single file.  This information is obtained through the LIST
-     * command.  The contents of the returned array is determined by the
-     * <code> FTPFileListParser </code> used.
-     * The server may or may not expand glob expressions.  You should avoid
-     * using glob expressions because the return format for glob listings
-     * differs from server to server and will likely cause this method to fail.
-     * <p>
-     * @param parser The <code> FTPFileListParser </code> that should be
-     *         used to parse the server file listing.
-     * @param pathname  The file or directory to list.
-     * @return The list of file information contained in the given path in
-     *         the format determined by the <code> parser </code> parameter.
-     *         <p><b> 
-     *         NOTE:</b> This array may contain null members if any of the 
-     *         individual file listings failed to parse.  The caller should 
-     *         check each entry for null before referencing it.
-     * @exception FTPConnectionClosedException
-     *      If the FTP server prematurely closes the connection as a result
-     *      of the client being idle or some other reason causing the server
-     *      to send FTP reply code 421.  This exception may be caught either
-     *      as an IOException or independently as itself.
-     * @exception IOException  If an I/O error occurs while either sending a
-     *      command to the server or receiving a reply from the server.
-     *
-     * @exception IOException
-     * @since 5 Jan 2004
-     * @deprecated use listFiles(String parserKey, String pathname) instead
+     * Issue the FTP MDTM command (not supported by all servers to retrieve the last
+     * modification time of a file. The modification string should be in the 
+     * ISO 3077 form "YYYYMMDDhhmmss(.xxx)?". The timestamp represented should also be in 
+     * GMT, but not all FTP servers honour this.
+     * 
+     * @param pathname The file path to query.
+     * @return A string representing the last file modification time in <code>YYYYMMDDhhmmss</code> format.
+     * @throws IOException if an I/O error occurs.
+     * @since 2.0
      */
-    public FTPFile[] listFiles(FTPFileListParser parser, String pathname)
-    throws IOException
-    {
-        Socket socket;
-        FTPFile[] results;
-
-        if ((socket = _openDataConnection_(FTPCommand.LIST, pathname)) == null)
-            return new FTPFile[0];
-
-        results = parser.parseFileList(socket.getInputStream(), getControlEncoding());
-
-        socket.close();
-
-        completePendingCommand();
-
-        return results;
+    public String getModificationTime(String pathname) throws IOException {
+        if (FTPReply.isPositiveCompletion(mdtm(pathname)))
+            return getReplyString();
+        return null;
     }
 
-
+    
     /**
-     * Using a programmer specified <code> FTPFileListParser </code>,
-     * obtain a list of file information for the current working directory.
-     * This information is obtained through the LIST command.
-     * The contents of the array returned is determined by the
-     * <code> FTPFileListParser </code> used.
-     * <p>
-     *
-     * @param parser The <code> FTPFileListParser </code> that should be
-     *               used to parse the server file listing.
-     *
-     * @return The list of file information contained in the given path in
-     *         the format determined by the <code> parser </code> parameter.
-     *         <p><b> 
-     *         NOTE:</b> This array may contain null members if any of the 
-     *         individual file listings failed to parse.  The caller should 
-     *         check each entry for null before referencing it.
-     * @exception FTPConnectionClosedException
-     *                   If the FTP server prematurely closes the connection as a result
-     *                   of the client being idle or some other reason causing the server
-     *                   to send FTP reply code 421.  This exception may be caught either
-     *                   as an IOException or independently as itself.
-     * @exception IOException
-     *                   If an I/O error occurs while either sending a
-     *                   command to the server or receiving a reply from the server.
-     * @exception IOException
-     * @since 5 Jan 2004
-     * @deprecated use listFiles(String parserKey) instead.
+     * Issue the FTP MFMT command (not supported by all servers) which sets the last
+     * modified time of a file.
+     * 
+     * The timestamp should be in the form <code>YYYYMMDDhhmmss</code>. It should also
+     * be in GMT, but not all servers honour this.
+     * 
+     * An FTP server would indicate its support of this feature by including "MFMT"
+     * in its response to the FEAT command, which may be retrieved by FTPClient.features()
+     * 
+     * @param pathname The file path for which last modified time is to be changed.
+     * @param timeval The timestamp to set to, in <code>YYYYMMDDhhmmss</code> format. 
+     * @return true if successfully set, false if not
+     * @throws IOException if an I/O error occurs.
+     * @see <a href="http://tools.ietf.org/html/draft-somers-ftp-mfxx-04">http://tools.ietf.org/html/draft-somers-ftp-mfxx-04</a>
      */
-    public FTPFile[] listFiles(FTPFileListParser parser) throws IOException
-    {
-        return listFiles(parser, null);
+    public boolean setModificationTime(String pathname, String timeval) throws IOException {
+        return (FTPReply.isPositiveCompletion(mfmt(pathname, timeval)));
     }
-
-
-    /**
-     * Using a programmer specified <code> FTPFileEntryParser </code>,
-     * initialize an object containing a raw file information for the
-     * current working directory.  This information is obtained through
-     * the LIST command.  This object is then capable of being iterated to
-     * return a sequence of FTPFile objects with information filled in by the
-     * <code> FTPFileEntryParser </code> used.
-     * <p>
-     * The server may or may not expand glob expressions.  You should avoid
-     * using glob expressions because the return format for glob listings
-     * differs from server to server and will likely cause this method to fail.
-     * <p>
-     * This method differs from using the listFiles() methods in that
-     * expensive FTPFile objects are not created until needed which may be
-     * an advantage on large lists.
-     *
-     * @param parser The <code> FTPFileEntryParser </code> that should be
-     *               used to parse each server file listing.
-     *
-     * @return An iteratable object that holds the raw information and is
-     *         capable of providing parsed FTPFile objects, one for each file containing
-     *         information contained in the given path in the format determined by the
-     *         <code> parser </code> parameter.   Null will be returned if a
-     *         data connection cannot be opened.  If the current working directory
-     *         contains no files, an empty array will be the return.
-     * <pre>
-     *    FTPClient f=FTPClient();
-     *    f.connect(server);
-     *    f.login(username, password);
-     *    FTPFileList list = f.createFileList(directory, parser);
-     *    FTPFileIterator iter = list.iterator();
-     *
-     *    while (iter.hasNext()) {
-     *       FTPFile[] files = iter.getNext(25);  // "page size" you want
-     *       //do whatever you want with these files, display them, etc.
-     *       //expensive FTPFile objects not created until needed.
-     *    }
-     * </pre>
-     *
-     * @exception FTPConnectionClosedException
-     *                   If the FTP server prematurely closes the connection as a result
-     *                   of the client being idle or some other reason causing the server
-     *                   to send FTP reply code 421.  This exception may be caught either
-     *                   as an IOException or independently as itself.
-     * @exception IOException
-     *                   If an I/O error occurs while either sending a
-     *                   command to the server or receiving a reply from the server.
-     * @deprecated - use initiateListParsing(FTPFileEntryParser) method instead.
-     * @see FTPFileList
-     */
-    public FTPFileList createFileList(FTPFileEntryParser parser) throws IOException
-    {
-        return createFileList(null, parser);
-    }
-
-    /**
-     * Using a programmer specified <code> FTPFileEntryParser </code>,
-     * initialize an object containing a raw file information for a directory
-     * or information for a single file.  This information is obtained through
-     * the LIST command.  This object is then capable of being iterated to
-     * return a sequence of FTPFile objects with information filled in by the
-     * <code> FTPFileEntryParser </code> used.
-     * The server may or may not expand glob expressions.  You should avoid
-     * using glob expressions because the return format for glob listings
-     * differs from server to server and will likely cause this method to fail.
-     * <p>
-     * @param parser The <code> FTPFileEntryParser </code> that should be
-     *         used to parse each server file listing.
-     * @param pathname  The file or directory to list.
-     * @return An iteratable object that holds the raw information and is
-     * capable of providing parsed FTPFile objects, one for each file containing
-     * information contained in the given path in the format determined by the
-     * <code> parser </code> parameter.  Null will be returned if a
-     * data connection cannot be opened.  If the supplied path contains
-     * no files, an empty array will be the return.
-     * @exception FTPConnectionClosedException
-     *      If the FTP server prematurely closes the connection as a result
-     *      of the client being idle or some other reason causing the server
-     *      to send FTP reply code 421.  This exception may be caught either
-     *      as an IOException or independently as itself.
-     * @exception IOException  If an I/O error occurs while either sending a
-     *      command to the server or receiving a reply from the server.
-     * @deprecated - use initiateListParsing(String, FTPFileEntryParser)
-     * method instead.
-     * @see FTPFileList
-     */
-    public FTPFileList createFileList(String pathname,
-            FTPFileEntryParser parser)
-    throws IOException
-    {
-        Socket socket;
-
-        if ((socket = _openDataConnection_(FTPCommand.LIST, pathname)) == null)
-        {
-            return null;
-        }
-
-        FTPFileList list = FTPFileList.create(socket.getInputStream(), parser);
-
-        socket.close();
-
-        completePendingCommand();
-        return list;
-    }
+    
     
     /**
      * Set the internal buffer size.
@@ -2667,7 +2454,28 @@
     public void configure(FTPClientConfig config) {
         this.__configuration = config;
     }
-    
+
+    /**
+     * You can set this to true if you would like to get hidden files when {@link #listFiles} too.
+     * A <code>LIST -a</code> will be issued to the ftp server.
+     * It depends on your ftp server if you need to call this method, also dont expect to get rid
+     * of hidden files if you call this method with "false".
+     * 
+     * @param listHiddenFiles true if hidden files should be listed 
+     * @since 2.0
+     */
+    public void setListHiddenFiles(boolean listHiddenFiles) {
+        this.__listHiddenFiles = listHiddenFiles;
+    }
+
+    /**
+     * @see #setListHiddenFiles(boolean)
+     * @return the current state
+     * @since 2.0
+     */
+    public boolean getListHiddenFiles() {
+        return this.__listHiddenFiles;
+    }
 }
 
 /* Emacs configuration
diff --git a/src/java/org/apache/commons/net/ftp/FTPClientConfig.java b/src/main/java/org/apache/commons/net/ftp/FTPClientConfig.java
similarity index 97%
rename from src/java/org/apache/commons/net/ftp/FTPClientConfig.java
rename to src/main/java/org/apache/commons/net/ftp/FTPClientConfig.java
index 1239bcb..eb8f6ca 100644
--- a/src/java/org/apache/commons/net/ftp/FTPClientConfig.java
+++ b/src/main/java/org/apache/commons/net/ftp/FTPClientConfig.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.ftp;
 
 import java.text.DateFormatSymbols;
@@ -171,12 +172,12 @@
      */
     public static final String SYST_OS400 = "OS/400";
     
-
     /**
-     * Alternate SYST value for an AS/400 system.
+     * Identifier by which an AS/400-based ftp server is known throughout
+     * the commons-net ftp system.
      */
     public static final String SYST_AS400 = "AS/400";
-
+    
     /**
      * Identifier by which an MVS-based ftp server is known throughout
      * the commons-net ftp system.
@@ -189,10 +190,13 @@
      * This may happen if the ftpd in question was compiled without system
      * information.
      *
+     * NET-230 - Updated to be UPPERCASE so that the check done in
+     * createFileEntryParser will succeed.
+     *
      * @since 1.5
      */
     public static final String SYST_L8 = "TYPE: L8";
-
+    
     /**
      * Identifier by which an Netware-based ftp server is known throughout
      * the commons-net ftp system.
@@ -258,7 +262,7 @@
         this.serverTimeZoneId = serverTimeZoneId;
     }
     
-    private static Map LANGUAGE_CODE_MAP = new TreeMap();
+    private static Map<String, Object> LANGUAGE_CODE_MAP = new TreeMap<String, Object>();
     static {
         
         // if there are other commonly used month name encodings which
@@ -568,7 +572,7 @@
      * @return a Collection of all the language codes currently supported
      * by this class
      */
-    public static Collection getSupportedLanguageCodes() {
+    public static Collection<String> getSupportedLanguageCodes() {
         return LANGUAGE_CODE_MAP.keySet();
     }
     
diff --git a/src/java/org/apache/commons/net/ftp/FTPCommand.java b/src/main/java/org/apache/commons/net/ftp/FTPCommand.java
similarity index 90%
rename from src/java/org/apache/commons/net/ftp/FTPCommand.java
rename to src/main/java/org/apache/commons/net/ftp/FTPCommand.java
index e19ff88..f8badf5 100644
--- a/src/java/org/apache/commons/net/ftp/FTPCommand.java
+++ b/src/main/java/org/apache/commons/net/ftp/FTPCommand.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.ftp;
 
 /***
@@ -27,11 +28,10 @@
  * <p>
  * @author Daniel F. Savarese
  ***/
-
+/** TODO replace this with an enum */
 public final class FTPCommand
 {
 
-
     public static final int USER = 0;
     public static final int PASS = 1;
     public static final int ACCT = 2;
@@ -65,7 +65,12 @@
     public static final int STAT = 30;
     public static final int HELP = 31;
     public static final int NOOP = 32;
-
+    /** @since 2.0 */
+    public static final int MDTM = 33;
+    /** @since 2.1 */
+    public static final int FEAT = 34;
+    public static final int MFMT = 35;
+    
     public static final int USERNAME = USER;
     public static final int PASSWORD = PASS;
     public static final int ACCOUNT = ACCT;
@@ -99,7 +104,12 @@
     public static final int STATUS = STAT;
     //public static final int HELP = HELP;
     //public static final int NOOP = NOOP;
-
+    /** @since 2.0 */
+    public static final int GET_MOD_TIME = MDTM;
+    /** @since 2.1 */
+    public static final int FEATURES = FEAT;
+    public static final int SET_MOD_TIME = MFMT;
+    
     // Cannot be instantiated
     private FTPCommand()
     {}
@@ -108,7 +118,7 @@
                                           "USER", "PASS", "ACCT", "CWD", "CDUP", "SMNT", "REIN", "QUIT", "PORT",
                                           "PASV", "TYPE", "STRU", "MODE", "RETR", "STOR", "STOU", "APPE", "ALLO",
                                           "REST", "RNFR", "RNTO", "ABOR", "DELE", "RMD", "MKD", "PWD", "LIST",
-                                          "NLST", "SITE", "SYST", "STAT", "HELP", "NOOP"
+                                          "NLST", "SITE", "SYST", "STAT", "HELP", "NOOP", "MDTM", "FEAT", "MFMT"
                                       };
 
     /**
diff --git a/src/java/org/apache/commons/net/ftp/FTPConnectionClosedException.java b/src/main/java/org/apache/commons/net/ftp/FTPConnectionClosedException.java
similarity index 96%
rename from src/java/org/apache/commons/net/ftp/FTPConnectionClosedException.java
rename to src/main/java/org/apache/commons/net/ftp/FTPConnectionClosedException.java
index ea5cb66..477d885 100644
--- a/src/java/org/apache/commons/net/ftp/FTPConnectionClosedException.java
+++ b/src/main/java/org/apache/commons/net/ftp/FTPConnectionClosedException.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.ftp;
 import java.io.IOException;
 
diff --git a/src/java/org/apache/commons/net/ftp/FTPFile.java b/src/main/java/org/apache/commons/net/ftp/FTPFile.java
similarity index 99%
rename from src/java/org/apache/commons/net/ftp/FTPFile.java
rename to src/main/java/org/apache/commons/net/ftp/FTPFile.java
index 596850d..01edb2a 100644
--- a/src/java/org/apache/commons/net/ftp/FTPFile.java
+++ b/src/main/java/org/apache/commons/net/ftp/FTPFile.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.ftp;
 import java.io.Serializable;
 import java.util.Calendar;
@@ -382,6 +383,7 @@
      * <p>
      * @return A string representation of the FTPFile information.
      ***/
+    @Override
     public String toString()
     {
         return _rawListing;
diff --git a/src/java/org/apache/commons/net/ftp/FTPFileEntryParser.java b/src/main/java/org/apache/commons/net/ftp/FTPFileEntryParser.java
similarity index 97%
rename from src/java/org/apache/commons/net/ftp/FTPFileEntryParser.java
rename to src/main/java/org/apache/commons/net/ftp/FTPFileEntryParser.java
index a3e304f..b8ad0f7 100644
--- a/src/java/org/apache/commons/net/ftp/FTPFileEntryParser.java
+++ b/src/main/java/org/apache/commons/net/ftp/FTPFileEntryParser.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.ftp;
 import java.io.BufferedReader;
 import java.io.IOException;
@@ -93,7 +94,7 @@
  * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
  * @version $Id$
  * @see org.apache.commons.net.ftp.FTPFile
- * @see org.apache.commons.net.ftp.FTPClient#createFileList
+ * @see org.apache.commons.net.ftp.FTPClient#listFiles()
  */
 public interface FTPFileEntryParser
 {
@@ -136,7 +137,7 @@
      *
      * @return Original list as processed by this method.
      */
-    List preParse(List original);
+    List<String> preParse(List<String> original);
 
 
 }
diff --git a/src/main/java/org/apache/commons/net/ftp/FTPFileEntryParserImpl.java b/src/main/java/org/apache/commons/net/ftp/FTPFileEntryParserImpl.java
new file mode 100644
index 0000000..36fa6c3
--- /dev/null
+++ b/src/main/java/org/apache/commons/net/ftp/FTPFileEntryParserImpl.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.net.ftp;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * This abstract class implements both the older FTPFileListParser and
+ * newer FTPFileEntryParser interfaces with default functionality.
+ * All the classes in the parser subpackage inherit from this.
+ *
+ */
+public abstract class FTPFileEntryParserImpl
+    implements FTPFileEntryParser
+{
+    /**
+     * The constructor for a FTPFileEntryParserImpl object.
+     */
+    public FTPFileEntryParserImpl()
+    {
+    }
+
+    /**
+     * Reads the next entry using the supplied BufferedReader object up to
+     * whatever delemits one entry from the next.  This default implementation
+     * simply calls BufferedReader.readLine().
+     *
+     * @param reader The BufferedReader object from which entries are to be
+     * read.
+     *
+     * @return A string representing the next ftp entry or null if none found.
+     * @exception java.io.IOException thrown on any IO Error reading from the reader.
+     */
+    public String readNextEntry(BufferedReader reader) throws IOException
+    {
+        return reader.readLine();
+    }
+    /**
+     * This method is a hook for those implementors (such as
+     * VMSVersioningFTPEntryParser, and possibly others) which need to
+     * perform some action upon the FTPFileList after it has been created
+     * from the server stream, but before any clients see the list.
+     *
+     * This default implementation removes entries that do not parse as files.
+     *
+     * @param original Original list after it has been created from the server stream
+     *
+     * @return <code>original</code> unmodified.
+     */
+     public List<String> preParse(List<String> original) {
+         Iterator<String> it = original.iterator();
+         while (it.hasNext()){
+            String entry = it.next();
+            if (null == parseFTPEntry(entry)) {
+                it.remove();
+            }
+         }
+         return original;
+     }
+}
+
+/* Emacs configuration
+ * Local variables:        **
+ * mode:             java  **
+ * c-basic-offset:   4     **
+ * indent-tabs-mode: nil   **
+ * End:                    **
+ */
diff --git a/src/java/org/apache/commons/net/ftp/FTPListParseEngine.java b/src/main/java/org/apache/commons/net/ftp/FTPListParseEngine.java
similarity index 86%
rename from src/java/org/apache/commons/net/ftp/FTPListParseEngine.java
rename to src/main/java/org/apache/commons/net/ftp/FTPListParseEngine.java
index 4f7f05c..25f2a81 100644
--- a/src/java/org/apache/commons/net/ftp/FTPListParseEngine.java
+++ b/src/main/java/org/apache/commons/net/ftp/FTPListParseEngine.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.ftp;
 
 import java.io.BufferedReader;
@@ -72,8 +73,8 @@
  * @version $Id$
  */
 public class FTPListParseEngine {
-    private List entries = new LinkedList();
-    private ListIterator _internalIterator = entries.listIterator();
+    private List<String> entries = new LinkedList<String>();
+    private ListIterator<String> _internalIterator = entries.listIterator();
 
     FTPFileEntryParser parser = null;
 
@@ -82,7 +83,7 @@
     }
 
     /**
-     * handle the iniitial reading and preparsing of the list returned by
+     * handle the initial reading and preparsing of the list returned by
      * the server.  After this method has completed, this object will contain
      * a list of unparsed entries (Strings) each referring to a unique file
      * on the server.
@@ -95,33 +96,13 @@
     public void readServerList(InputStream stream, String encoding)
     throws IOException
     {
-        this.entries = new LinkedList();
+        this.entries = new LinkedList<String>();
         readStream(stream, encoding);
         this.parser.preParse(this.entries);
         resetIterator();
     }
     
-    /**
-     * handle the iniitial reading and preparsing of the list returned by
-     * the server.  After this method has completed, this object will contain
-     * a list of unparsed entries (Strings) each referring to a unique file
-     * on the server.
-     *
-     * @param stream input stream provided by the server socket.
-     *
-     * @exception IOException
-     *                   thrown on any failure to read from the sever.
-     *
-     * @deprecated The version of this method which takes an encoding should be used.
-    */
-    public void readServerList(InputStream stream)
-    throws IOException
-    {
-        readServerList(stream, null);
-    }
-    
-
-
+  
     /**
      * Internal method for reading the input into the <code>entries</code> list.
      * After this method has completed, <code>entries</code> will contain a
@@ -147,7 +128,7 @@
         {
             reader = new BufferedReader(new InputStreamReader(stream, encoding));
         }
-
+        
         String line = this.parser.readNextEntry(reader);
 
         while (line != null)
@@ -182,15 +163,15 @@
      * check each entry for null before referencing it.
      */
     public FTPFile[] getNext(int quantityRequested) {
-        List tmpResults = new LinkedList();
+        List<FTPFile> tmpResults = new LinkedList<FTPFile>();
         int count = quantityRequested;
         while (count > 0 && this._internalIterator.hasNext()) {
-            String entry = (String) this._internalIterator.next();
+            String entry = this._internalIterator.next();
             FTPFile temp = this.parser.parseFTPEntry(entry);
             tmpResults.add(temp);
             count--;
         }
-        return (FTPFile[]) tmpResults.toArray(new FTPFile[0]);
+        return tmpResults.toArray(new FTPFile[0]);
 
     }
 
@@ -221,15 +202,15 @@
      * check each entry for null before referencing it.
      */
     public FTPFile[] getPrevious(int quantityRequested) {
-        List tmpResults = new LinkedList();
+        List<FTPFile> tmpResults = new LinkedList<FTPFile>();
         int count = quantityRequested;
         while (count > 0 && this._internalIterator.hasPrevious()) {
-            String entry = (String) this._internalIterator.previous();
+            String entry = this._internalIterator.previous();
             FTPFile temp = this.parser.parseFTPEntry(entry);
             tmpResults.add(0,temp);
             count--;
         }
-        return (FTPFile[]) tmpResults.toArray(new FTPFile[0]);
+        return tmpResults.toArray(new FTPFile[0]);
     }
 
     /**
@@ -247,14 +228,14 @@
     public FTPFile[] getFiles()
     throws IOException
     {
-        List tmpResults = new LinkedList();
-        Iterator iter = this.entries.iterator();
+        List<FTPFile> tmpResults = new LinkedList<FTPFile>();
+        Iterator<String> iter = this.entries.iterator();
         while (iter.hasNext()) {
-            String entry = (String) iter.next();
+            String entry = iter.next();
             FTPFile temp = this.parser.parseFTPEntry(entry);
             tmpResults.add(temp);
         }
-        return (FTPFile[]) tmpResults.toArray(new FTPFile[0]);
+        return tmpResults.toArray(new FTPFile[0]);
 
     }
 
diff --git a/src/java/org/apache/commons/net/ftp/FTPReply.java b/src/main/java/org/apache/commons/net/ftp/FTPReply.java
similarity index 83%
rename from src/java/org/apache/commons/net/ftp/FTPReply.java
rename to src/main/java/org/apache/commons/net/ftp/FTPReply.java
index fbdf037..d99a21e 100644
--- a/src/java/org/apache/commons/net/ftp/FTPReply.java
+++ b/src/main/java/org/apache/commons/net/ftp/FTPReply.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.ftp;
 
 /***
@@ -26,6 +27,7 @@
  * <p>
  * <p>
  * @author Daniel F. Savarese
+ * TODO replace with an enum
  ***/
 
 public final class FTPReply
@@ -111,6 +113,50 @@
     public static final int PAGE_TYPE_UNKNOWN = CODE_551;
     public static final int STORAGE_ALLOCATION_EXCEEDED = CODE_552;
     public static final int FILE_NAME_NOT_ALLOWED = CODE_553;
+    
+    // FTPS Reply Codes
+    /** @since 2.0 */
+    public static final int CODE_234 = 234;
+    /** @since 2.0 */
+    public static final int CODE_235 = 235;
+    /** @since 2.0 */
+    public static final int CODE_334 = 334;
+    /** @since 2.0 */
+    public static final int CODE_335 = 335;
+    /** @since 2.0 */
+    public static final int CODE_431 = 431;
+    /** @since 2.1 */
+    public static final int CODE_522 = 522;
+    /** @since 2.0 */
+    public static final int CODE_533 = 533;
+    /** @since 2.0 */
+    public static final int CODE_534 = 534;
+    /** @since 2.0 */
+    public static final int CODE_535 = 535;
+    /** @since 2.0 */
+    public static final int CODE_536 = 536;
+    
+    /** @since 2.0 */
+    public static final int SECURITY_DATA_EXCHANGE_COMPLETE = CODE_234;
+    /** @since 2.0 */
+    public static final int SECURITY_DATA_EXCHANGE_SUCCESSFULLY = CODE_235;
+    /** @since 2.0 */
+    public static final int SECURITY_MECHANISM_IS_OK = CODE_334;
+    /** @since 2.0 */
+    public static final int SECURITY_DATA_IS_ACCEPTABLE = CODE_335;
+    /** @since 2.0 */
+    public static final int UNAVAILABLE_RESOURCE = CODE_431;
+    /** @since 2.1 */
+    public static final int BAD_TLS_NEGOTIATION_OR_DATA_ENCRYPTION_REQUIRED = CODE_522;
+    /** @since 2.0 */
+    public static final int DENIED_FOR_POLICY_REASONS = CODE_533;
+    /** @since 2.0 */
+    public static final int REQUEST_DENIED = CODE_534;
+    /** @since 2.0 */
+    public static final int FAILED_SECURITY_CHECK = CODE_535;
+    /** @since 2.0 */
+    public static final int REQUESTED_PROT_LEVEL_NOT_SUPPORTED = CODE_536;
+    
 
     // Cannot be instantiated
     private FTPReply()
diff --git a/src/main/java/org/apache/commons/net/ftp/FTPSClient.java b/src/main/java/org/apache/commons/net/ftp/FTPSClient.java
new file mode 100644
index 0000000..03b72b4
--- /dev/null
+++ b/src/main/java/org/apache/commons/net/ftp/FTPSClient.java
@@ -0,0 +1,551 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.net.ftp;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.Socket;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+
+/**
+ * FTP over SSL processing. If desired, the JVM property -Djavax.net.debug=all can be used to 
+ * see wire-level SSL details.
+ * 
+ * @version $Id$
+ * @since 2.0
+ */
+public class FTPSClient extends FTPClient {
+
+    /** keystore algorithm name. */
+    public static String KEYSTORE_ALGORITHM;
+    /** truststore algorithm name. */
+    public static String TRUSTSTORE_ALGORITHM;
+    /** provider name. */
+    public static String PROVIDER;
+    /** truststore type. */
+    public static String STORE_TYPE;
+
+    /** The value that I can set in PROT command  (C = Clear, P = Protected) */
+    private static final String[] PROT_COMMAND_VALUE = {"C","E","S","P"}; 
+    /** Default PROT Command */
+    private static final String DEFAULT_PROT = "C";
+    /** Default protocol name */
+    private static final String DEFAULT_PROTOCOL = "TLS";
+
+    /** The security mode. (True - Implicit Mode / False - Explicit Mode) */
+    private boolean isImplicit;
+    /** The use SSL/TLS protocol. */
+    private String protocol = DEFAULT_PROTOCOL;
+    /** The AUTH Command value */
+    private String auth = DEFAULT_PROTOCOL;
+    /** The context object. */
+    private SSLContext context;
+    /** The socket object. */
+    private Socket plainSocket;
+    /** The established socket flag. */
+    private boolean isCreation = true;
+    /** The use client mode flag. */
+    private boolean isClientMode = true;
+    /** The need client auth flag. */
+    private boolean isNeedClientAuth = false;
+    /** The want client auth flag. */
+    private boolean isWantClientAuth = false;
+    /** The cipher suites */
+    private String[] suites = null;
+    /** The protocol versions */
+    private String[] protocols = null;
+    
+    /** The FTPS {@link TrustManager} implementation. */
+    private TrustManager trustManager = new FTPSTrustManager();
+    
+    /** The {@link KeyManager} */
+    private KeyManager keyManager;
+
+    /**
+     * Constructor for FTPSClient.
+     * @throws NoSuchAlgorithmException A requested cryptographic algorithm 
+     * is not available in the environment.
+     */
+    public FTPSClient() throws NoSuchAlgorithmException {
+        this.protocol = DEFAULT_PROTOCOL;
+        this.isImplicit = false;
+    }
+
+    /**
+     * Constructor for FTPSClient.
+     * @param isImplicit The secutiry mode(Implicit/Explicit).
+     * @throws NoSuchAlgorithmException A requested cryptographic algorithm 
+     * is not available in the environment.
+     */
+    public FTPSClient(boolean isImplicit) throws NoSuchAlgorithmException {
+        this.protocol = DEFAULT_PROTOCOL;
+        this.isImplicit = isImplicit;
+    }
+
+    /**
+     * Constructor for FTPSClient.
+     * @param protocol the protocol
+     * @throws NoSuchAlgorithmException A requested cryptographic algorithm 
+     * is not available in the environment.
+     */
+    public FTPSClient(String protocol) throws NoSuchAlgorithmException {
+        this.protocol = protocol;
+        this.isImplicit = false;
+    }
+
+    /**
+     * Constructor for FTPSClient.
+     * @param protocol the protocol
+     * @param isImplicit The secutiry mode(Implicit/Explicit).
+     * @throws NoSuchAlgorithmException A requested cryptographic algorithm 
+     * is not available in the environment.
+     */
+    public FTPSClient(String protocol, boolean isImplicit) 
+            throws NoSuchAlgorithmException {
+        this.protocol = protocol;
+        this.isImplicit = isImplicit;
+    }
+    
+    /**
+     * Constructor for FTPSClient.
+     * @param isImplicit The secutiry mode(Implicit/Explicit).
+     * @param context A pre-configured SSL Context
+     */
+    public FTPSClient(boolean isImplicit, SSLContext context) {
+        this.isImplicit = isImplicit;
+        this.context = context;
+    }
+    
+    /**
+     * Constructor for FTPSClient.
+     * @param context A pre-configured SSL Context
+     */
+    public FTPSClient(SSLContext context) {
+        this(false, context);
+    }
+
+
+    /**
+     * Set AUTH command use value.
+     * This processing is done before connected processing.
+     * @param auth AUTH command use value.
+     */
+    public void setAuthValue(String auth) {
+        this.auth = auth;
+    }
+
+    /**
+     * Return AUTH command use value.
+     * @return AUTH command use value.
+     */
+    public String getAuthValue() {
+        return this.auth;
+    }
+
+    
+    /**
+     * Because there are so many connect() methods, 
+     * the _connectAction_() method is provided as a means of performing 
+     * some action immediately after establishing a connection, 
+     * rather than reimplementing all of the connect() methods.
+     * @throws IOException If it throw by _connectAction_.
+     * @see org.apache.commons.net.SocketClient#_connectAction_()
+     */
+    @Override
+    protected void _connectAction_() throws IOException {
+        // Implicit mode.
+        if (isImplicit) sslNegotiation();
+        super._connectAction_();
+        // Explicit mode.
+        if (!isImplicit) {
+            execAUTH();
+            sslNegotiation();
+        }
+    }
+
+    /**
+     * AUTH command.
+     * @throws SSLException If it server reply code not equal "234" and "334".
+     * @throws IOException If an I/O error occurs while either sending 
+     * the command.
+     */
+    private void execAUTH() throws SSLException, IOException {
+        int replyCode = sendCommand(
+                FTPSCommand._commands[FTPSCommand.AUTH], auth);
+        if (FTPReply.SECURITY_MECHANISM_IS_OK == replyCode) {
+            // replyCode = 334
+            // I carry out an ADAT command.
+        } else if (FTPReply.SECURITY_DATA_EXCHANGE_COMPLETE != replyCode) {
+            throw new SSLException(getReplyString());
+        }
+    }
+
+    /**
+     * Performs a lazy init of the SSL context 
+     * @throws IOException 
+     */
+    private void initSslContext() throws IOException {
+        if(context == null) {
+            try  {
+                context = SSLContext.getInstance(protocol);
+                context.init(new KeyManager[] { getKeyManager() } , new TrustManager[] { getTrustManager() } , null);
+            } catch (KeyManagementException e) {
+                IOException ioe = new IOException("Could not initialize SSL context");
+                ioe.initCause(e);
+                throw ioe;
+            } catch (NoSuchAlgorithmException e) {
+                IOException ioe = new IOException("Could not initialize SSL context");
+                ioe.initCause(e);
+                throw ioe;
+            }
+        }
+    }
+    
+    /**
+     * SSL/TLS negotiation. Acquires an SSL socket of a control 
+     * connection and carries out handshake processing.
+     * @throws IOException If server negotiation fails
+     */
+    private void sslNegotiation() throws IOException {
+        plainSocket = _socket_;
+        initSslContext();
+
+        SSLSocketFactory ssf = context.getSocketFactory();
+        String ip = _socket_.getInetAddress().getHostAddress();
+        int port = _socket_.getPort();
+        SSLSocket socket = 
+            (SSLSocket) ssf.createSocket(_socket_, ip, port, true);
+        socket.setEnableSessionCreation(isCreation);
+        socket.setUseClientMode(isClientMode);
+        // server mode
+        if (!isClientMode) {
+            socket.setNeedClientAuth(isNeedClientAuth);
+            socket.setWantClientAuth(isWantClientAuth);
+        }
+
+        if (protocols != null) socket.setEnabledProtocols(protocols);
+        if (suites != null) socket.setEnabledCipherSuites(suites);
+        socket.startHandshake();
+
+        _socket_ = socket;
+        _controlInput_ = new BufferedReader(new InputStreamReader(
+                socket .getInputStream(), getControlEncoding()));
+        _controlOutput_ = new BufferedWriter(new OutputStreamWriter(
+                socket.getOutputStream(), getControlEncoding()));
+    }
+    
+    /**
+     * Get the {@link KeyManager} instance.
+     * @return The {@link KeyManager} instance
+     */
+    private KeyManager getKeyManager() {
+        return keyManager;
+    }
+    
+    /**
+    * Set a {@link KeyManager} to use
+    * 
+    * @param keyManager The KeyManager implementation to set.
+    */
+    public void setKeyManager(KeyManager keyManager) {
+        this.keyManager = keyManager;
+    }
+
+    /**
+     * Controls whether new a SSL session may be established by this socket.
+     * @param isCreation The established socket flag.
+     */
+    public void setEnabledSessionCreation(boolean isCreation) {
+        this.isCreation = isCreation;
+    }
+
+	/**
+     * Returns true if new SSL sessions may be established by this socket.
+     * When the underlying {@link Socket} instance is not SSL-enabled (i.e. an
+     * instance of {@link SSLSocket} with {@link SSLSocket}{@link #getEnableSessionCreation()}) enabled,
+     * this returns False.
+     * @return true - Indicates that sessions may be created;
+     * this is the default. 
+     * false - indicates that an existing session must be resumed.
+     */
+    public boolean getEnableSessionCreation() {
+        if (_socket_ instanceof SSLSocket) 
+            return ((SSLSocket)_socket_).getEnableSessionCreation();
+        return false;
+    }
+
+    /**
+     * Configures the socket to require client authentication.
+     * @param isNeedClientAuth The need client auth flag.
+     */
+    public void setNeedClientAuth(boolean isNeedClientAuth) {
+        this.isNeedClientAuth = isNeedClientAuth;
+    }
+
+    /**
+     * Returns true if the socket will require client authentication.
+     * When the underlying {@link Socket} is not an {@link SSLSocket} instance, returns false.
+     * @return true - If the server mode socket should request 
+     * that the client authenticate itself.
+     */
+    public boolean getNeedClientAuth() {
+        if (_socket_ instanceof SSLSocket) 
+            return ((SSLSocket)_socket_).getNeedClientAuth();
+        return false;
+    }
+
+    /**
+     * Configures the socket to request client authentication, 
+     * but only if such a request is appropriate to the cipher 
+     * suite negotiated.
+     * @param isWantClientAuth The want client auth flag.
+     */
+    public void setWantClientAuth(boolean isWantClientAuth) {
+        this.isWantClientAuth = isWantClientAuth;
+    }
+
+    /**
+     * Returns true if the socket will request client authentication.
+     * When the underlying {@link Socket} is not an {@link SSLSocket} instance, returns false.
+     * @return true - If the server mode socket should request 
+     * that the client authenticate itself.
+     */
+    public boolean getWantClientAuth() {
+        if (_socket_ instanceof SSLSocket) 
+            return ((SSLSocket)_socket_).getWantClientAuth();
+        return false;
+    }
+
+    /**
+     * Configures the socket to use client (or server) mode in its first 
+     * handshake.
+     * @param isClientMode The use client mode flag.
+     */
+    public void setUseClientMode(boolean isClientMode) {
+        this.isClientMode = isClientMode;
+    }
+
+    /**
+     * Returns true if the socket is set to use client mode 
+     * in its first handshake.
+     * When the underlying {@link Socket} is not an {@link SSLSocket} instance, returns false.
+     * @return true - If the socket should start its first handshake 
+     * in "client" mode.
+     */
+    public boolean getUseClientMode() {
+        if (_socket_ instanceof SSLSocket) 
+            return ((SSLSocket)_socket_).getUseClientMode();
+        return false;
+    }
+
+    /**
+     * Controls which particular cipher suites are enabled for use on this 
+     * connection. Called before server negotiation.
+     * @param cipherSuites The cipher suites.
+     */
+    public void setEnabledCipherSuites(String[] cipherSuites) {
+        suites = new String[cipherSuites.length];
+        System.arraycopy(cipherSuites, 0, suites, 0, cipherSuites.length);
+    }
+
+    /**
+     * Returns the names of the cipher suites which could be enabled 
+     * for use on this connection.
+     * When the underlying {@link Socket} is not an {@link SSLSocket} instance, returns false.
+     * @return An array of cipher suite names.
+     */
+    public String[] getEnabledCipherSuites() {
+        if (_socket_ instanceof SSLSocket) 
+            return ((SSLSocket)_socket_).getEnabledCipherSuites();
+        return null;
+    }
+
+    /**
+     * Controls which particular protocol versions are enabled for use on this
+     * connection. I perform setting before a server negotiation.
+     * @param protocolVersions The protocol versions.
+     */
+    public void setEnabledProtocols(String[] protocolVersions) {
+        protocols = new String[protocolVersions.length];
+        System.arraycopy(protocolVersions, 0, protocols, 0, protocolVersions.length);
+    }
+
+    /**
+     * Returns the names of the protocol versions which are currently 
+     * enabled for use on this connection.
+     * When the underlying {@link Socket} is not an {@link SSLSocket} instance, returns false.
+     * @return An array of protocols.
+     */
+    public String[] getEnabledProtocols() {
+        if (_socket_ instanceof SSLSocket) 
+            return ((SSLSocket)_socket_).getEnabledProtocols();
+        return null;
+    }
+
+    /**
+     * PBSZ command. pbsz value: 0 to (2^32)-1 decimal integer.
+     * @param pbsz Protection Buffer Size.
+     * @throws SSLException If the server reply code does not equal "200".
+     * @throws IOException If an I/O error occurs while sending 
+     * the command.
+     */
+    public void execPBSZ(long pbsz) throws SSLException, IOException {
+        if (pbsz < 0 || 4294967295L < pbsz) 
+            throw new IllegalArgumentException();
+        if (FTPReply.COMMAND_OK != sendCommand(
+                FTPSCommand._commands[FTPSCommand.PBSZ],String.valueOf(pbsz)))
+            throw new SSLException(getReplyString());
+    }
+
+    /**
+     * PROT command.</br>
+     * C - Clear</br>
+     * S - Safe(SSL protocol only)</br>
+     * E - Confidential(SSL protocol only)</br>
+     * P - Private
+     * @param prot Data Channel Protection Level.
+     * @throws SSLException If the server reply code does not equal "200".
+     * @throws IOException If an I/O error occurs while sending 
+     * the command.
+     */
+    public void execPROT(String prot) throws SSLException, IOException {
+        if (prot == null) prot = DEFAULT_PROT;
+        if (!checkPROTValue(prot)) throw new IllegalArgumentException();
+        if (FTPReply.COMMAND_OK != sendCommand(
+                FTPSCommand._commands[FTPSCommand.PROT], prot)) 
+            throw new SSLException(getReplyString());
+        if (DEFAULT_PROT.equals(prot)) {
+            setSocketFactory(null);
+            setServerSocketFactory(null);
+        } else {
+            setSocketFactory(new FTPSSocketFactory(context));
+            setServerSocketFactory(new FTPSServerSocketFactory(context));
+            initSslContext();
+        }
+    }
+
+    /**
+     * Check the value that can be set in PROT Command value.
+     * @param prot Data Channel Protection Level.
+     * @return True - A set point is right / False - A set point is not right
+     */
+    private boolean checkPROTValue(String prot) {
+        for (int p = 0; p < PROT_COMMAND_VALUE.length; p++) {
+            if (PROT_COMMAND_VALUE[p].equals(prot)) return true;
+        }
+        return false;
+    }
+
+    /**
+     * Send an FTP command.
+     * The CCC (Clear Command Channel) command causes the underlying {@link SSLSocket} instance  to be assigned 
+     * to a plain {@link Socket} instances
+     * @param command The FTP command.
+     * @return server reply.
+     * @throws IOException If an I/O error occurs while sending 
+     * the command.
+     * @see org.apache.commons.net.ftp.FTP#sendCommand(java.lang.String)
+     */
+    @Override
+    public int sendCommand(String command, String args) throws IOException {
+        int repCode = super.sendCommand(command, args);
+        /* If CCC is issued, restore socket i/o streams to unsecured versions */
+        if (FTPSCommand._commands[FTPSCommand.CCC].equals(command)) {
+            if (FTPReply.COMMAND_OK == repCode) {
+                _socket_ = plainSocket;
+		_controlInput_ = new BufferedReader(
+				new InputStreamReader( 
+					_socket_ .getInputStream(), getControlEncoding()));
+		_controlOutput_ = new BufferedWriter(
+				new OutputStreamWriter( 
+					_socket_.getOutputStream(), getControlEncoding()));
+                setSocketFactory(null);
+            } else {
+                throw new SSLException(getReplyString());
+            }
+        }
+        return repCode;
+    }
+
+    /**
+     * Returns a socket of the data connection. 
+     * Wrapped as an {@link SSLSocket}, which carries out handshake processing.
+     * @param command The textual representation of the FTP command to send.
+     * @param arg The arguments to the FTP command. 
+     * If this parameter is set to null, then the command is sent with 
+     * no arguments.
+     * @return corresponding to the established data connection. 
+     * Null is returned if an FTP protocol error is reported at any point 
+     * during the establishment and initialization of the connection.
+     * @throws IOException If there is any problem with the connection.
+     * @see org.apache.commons.net.ftp.FTPClient#_openDataConnection_(java.lang.String, int)
+     */
+    @Override
+    protected Socket _openDataConnection_(int command, String arg)
+            throws IOException {
+        Socket socket = super._openDataConnection_(command, arg); 
+        if (socket != null && socket instanceof SSLSocket) {
+        	SSLSocket sslSocket = (SSLSocket)socket;
+
+            sslSocket.setUseClientMode(isClientMode);
+            sslSocket.setEnableSessionCreation(isCreation);
+       
+            // server mode
+            if (!isClientMode) {     	
+                sslSocket.setNeedClientAuth(isNeedClientAuth);
+                sslSocket.setWantClientAuth(isWantClientAuth);
+            }
+            if (suites != null)
+                sslSocket.setEnabledCipherSuites(suites);
+            if (protocols != null)
+                sslSocket.setEnabledProtocols(protocols);
+            sslSocket.startHandshake();
+        }
+       
+        return socket;
+    }
+
+    /**
+     * Get the currently configured {@link TrustManager}.
+     * 
+     * @return A TrustManager instance.
+     */
+    public TrustManager getTrustManager() {
+        return trustManager;
+    }
+
+    /**
+     * Override the default {@link TrustManager} to use.
+     * 
+     * @param trustManager The TrustManager implementation to set.
+     */
+    public void setTrustManager(TrustManager trustManager) {
+        this.trustManager = trustManager;
+    }    
+}
diff --git a/src/main/java/org/apache/commons/net/ftp/FTPSCommand.java b/src/main/java/org/apache/commons/net/ftp/FTPSCommand.java
new file mode 100644
index 0000000..dacf1dc
--- /dev/null
+++ b/src/main/java/org/apache/commons/net/ftp/FTPSCommand.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.net.ftp;
+
+/**
+ * FTPS-specific command
+ * @since 2.0
+ */
+public final class FTPSCommand {
+    public static final int AUTH = 0;
+    public static final int ADAT = 1;
+    public static final int PBSZ = 2;
+    public static final int PROT = 3;
+    public static final int CCC = 4;
+
+    public static final int AUTHENTICATION_SECURITY_MECHANISM = AUTH;
+    public static final int AUTHENTICATION_SECURITY_DATA = ADAT;
+    public static final int PROTECTION_BUFFER_SIZE = PBSZ;
+    public static final int DATA_CHANNEL_PROTECTION_LEVEL = PROT;
+    public static final int CLEAR_COMMAND_CHANNEL = CCC;
+
+    static final String[] _commands = {"AUTH","ADAT","PBSZ","PROT","CCC"};
+
+    /**
+     * Retrieve the FTPS command string corresponding to a specified
+     * command code.
+     * <p>
+     * @param command The command code.
+     * @return The FTPS command string corresponding to a specified 
+     *  command code.
+     */
+    public static final String getCommand(int command) {
+        return _commands[command];
+    }
+}
diff --git a/src/main/java/org/apache/commons/net/ftp/FTPSServerSocketFactory.java b/src/main/java/org/apache/commons/net/ftp/FTPSServerSocketFactory.java
new file mode 100644
index 0000000..aef3982
--- /dev/null
+++ b/src/main/java/org/apache/commons/net/ftp/FTPSServerSocketFactory.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.net.ftp;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+
+import javax.net.ServerSocketFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocket;
+
+/**
+ * Server socket factory for FTPS connections.
+ */
+public class FTPSServerSocketFactory extends ServerSocketFactory {
+    
+	/** Factory for secure socket factories */
+    private SSLContext context;
+    
+    public FTPSServerSocketFactory(SSLContext context) {
+        this.context = context;
+    }
+    
+    @Override
+    public ServerSocket createServerSocket(int port) throws IOException {
+        return init(this.context.getServerSocketFactory().createServerSocket(port));
+    }
+
+    @Override
+    public ServerSocket createServerSocket(int port, int backlog) throws IOException {
+        return 	init(this.context.getServerSocketFactory().createServerSocket(port, backlog));
+    }
+
+    @Override
+    public ServerSocket createServerSocket(int port, int backlog, InetAddress ifAddress) throws IOException {
+    	return init(this.context.getServerSocketFactory().createServerSocket(port, backlog, ifAddress));
+    }
+        
+    public ServerSocket init(ServerSocket socket) throws IOException {
+        ((SSLServerSocket) socket).setUseClientMode(true);
+        return socket;
+    }
+}
+
diff --git a/src/main/java/org/apache/commons/net/ftp/FTPSSocketFactory.java b/src/main/java/org/apache/commons/net/ftp/FTPSSocketFactory.java
new file mode 100644
index 0000000..fd77a7b
--- /dev/null
+++ b/src/main/java/org/apache/commons/net/ftp/FTPSSocketFactory.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.net.ftp;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLContext;
+
+/**
+ * 
+ * Implementation of org.apache.commons.net.SocketFactory
+ *
+ * @since 2.0
+ */
+public class FTPSSocketFactory extends SocketFactory {
+
+    private final SSLContext context;
+    
+    public FTPSSocketFactory(SSLContext context) {
+        this.context = context;
+    }
+    
+    @Override
+    public Socket createSocket(String address, int port) throws UnknownHostException, IOException {
+        return this.context.getSocketFactory().createSocket(address, port);
+    }
+
+    @Override
+    public Socket createSocket(InetAddress address, int port) throws IOException {
+        return this.context.getSocketFactory().createSocket(address, port);
+    }
+
+    @Override
+    public Socket createSocket(String address, int port, InetAddress localAddress, int localPort) throws UnknownHostException, IOException {
+        return this.context.getSocketFactory().createSocket(address, port, localAddress, localPort);
+    }
+
+    @Override
+    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
+        return this.context.getSocketFactory().createSocket(address, port, localAddress, localPort);
+    }
+}
diff --git a/src/main/java/org/apache/commons/net/ftp/FTPSTrustManager.java b/src/main/java/org/apache/commons/net/ftp/FTPSTrustManager.java
new file mode 100644
index 0000000..890b0f5
--- /dev/null
+++ b/src/main/java/org/apache/commons/net/ftp/FTPSTrustManager.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.net.ftp;
+
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * Custom {@link TrustManager} implementation.
+ * 
+ * @version $Id$
+ * @since 2.0
+ */
+public class FTPSTrustManager implements X509TrustManager
+{
+    /**
+     * No-op
+     */
+    public void checkClientTrusted(X509Certificate[] certificates, String authType)
+    {
+        return;
+    }
+
+    public void checkServerTrusted(X509Certificate[] certificates, String authType) throws CertificateException
+    {
+        for (int i = 0; i < certificates.length; ++i)
+        {
+            certificates[i].checkValidity();
+        }
+    }
+
+    public X509Certificate[] getAcceptedIssuers()
+    {
+        return null;
+    }
+}
diff --git a/src/java/org/apache/commons/net/ftp/parser/CompositeFileEntryParser.java b/src/main/java/org/apache/commons/net/ftp/parser/CompositeFileEntryParser.java
similarity index 97%
rename from src/java/org/apache/commons/net/ftp/parser/CompositeFileEntryParser.java
rename to src/main/java/org/apache/commons/net/ftp/parser/CompositeFileEntryParser.java
index db76dc3..b2efb92 100644
--- a/src/java/org/apache/commons/net/ftp/parser/CompositeFileEntryParser.java
+++ b/src/main/java/org/apache/commons/net/ftp/parser/CompositeFileEntryParser.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.ftp.parser;
 
 import org.apache.commons.net.ftp.FTPFile;
diff --git a/src/java/org/apache/commons/net/ftp/parser/ConfigurableFTPFileEntryParserImpl.java b/src/main/java/org/apache/commons/net/ftp/parser/ConfigurableFTPFileEntryParserImpl.java
similarity index 98%
rename from src/java/org/apache/commons/net/ftp/parser/ConfigurableFTPFileEntryParserImpl.java
rename to src/main/java/org/apache/commons/net/ftp/parser/ConfigurableFTPFileEntryParserImpl.java
index b0ae19f..87fd245 100644
--- a/src/java/org/apache/commons/net/ftp/parser/ConfigurableFTPFileEntryParserImpl.java
+++ b/src/main/java/org/apache/commons/net/ftp/parser/ConfigurableFTPFileEntryParserImpl.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.ftp.parser;
 
 import java.text.ParseException;
diff --git a/src/java/org/apache/commons/net/ftp/parser/DefaultFTPFileEntryParserFactory.java b/src/main/java/org/apache/commons/net/ftp/parser/DefaultFTPFileEntryParserFactory.java
similarity index 64%
rename from src/java/org/apache/commons/net/ftp/parser/DefaultFTPFileEntryParserFactory.java
rename to src/main/java/org/apache/commons/net/ftp/parser/DefaultFTPFileEntryParserFactory.java
index 5a5ad1e..6d50f06 100644
--- a/src/java/org/apache/commons/net/ftp/parser/DefaultFTPFileEntryParserFactory.java
+++ b/src/main/java/org/apache/commons/net/ftp/parser/DefaultFTPFileEntryParserFactory.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.ftp.parser;
 
 import org.apache.commons.net.ftp.Configurable;
@@ -28,15 +29,15 @@
  * org.apache.commons.net.ftp.FTPClient.listFiles()
  * if no other implementation has been specified.
  *
- * @see org.apache.commons.net.ftp.FTPClient#listFiles()
+ * @see org.apache.commons.net.ftp.FTPClient#listFiles
  * @see org.apache.commons.net.ftp.FTPClient#setParserFactory
  */
 public class DefaultFTPFileEntryParserFactory
     implements FTPFileEntryParserFactory
 {
-    private FTPClientConfig config = null;
+	private FTPClientConfig config = null;
 
-    /**
+	/**
      * This default implementation of the FTPFileEntryParserFactory
      * interface works according to the following logic:
      * First it attempts to interpret the supplied key as a fully
@@ -68,6 +69,7 @@
      *               <li>{@link FTPClientConfig#SYST_OS400 OS/400}</li>
      *               <li>{@link FTPClientConfig#SYST_VMS VMS}</li>
      *               <li>{@link FTPClientConfig#SYST_MVS MVS}</li>
+     *               <li>{@link FTPClientConfig#SYST_NETWARE}</li>
      *               </ul>
      * @return the FTPFileEntryParser corresponding to the supplied key.
      * @throws ParserInitializationException thrown if for any reason the factory cannot resolve
@@ -76,7 +78,10 @@
      */
     public FTPFileEntryParser createFileEntryParser(String key)
     {
-        Class parserClass = null;
+    	if (key == null)
+    		throw new ParserInitializationException("Parser key cannot be null");
+    		
+        Class<?> parserClass = null;
         FTPFileEntryParser parser = null;
         try
         {
@@ -87,65 +92,55 @@
         {
             try 
             {
-                String ukey = null;
-                if (null != key)
-                {
-                    ukey = key.toUpperCase(java.util.Locale.ENGLISH);
-                }
-                if (ukey.indexOf(FTPClientConfig.SYST_UNIX) >= 0
-                        || (ukey.indexOf(FTPClientConfig.SYST_L8) >= 0))
-                {
-                    parser = createUnixFTPEntryParser();
-                }
-                else if (ukey.indexOf(FTPClientConfig.SYST_VMS) >= 0)
-                {
-                    parser = createVMSVersioningFTPEntryParser();
-                }
-                else if (ukey.indexOf(FTPClientConfig.SYST_NT) >= 0)
-                {
-                    parser = createNTFTPEntryParser();
-                }
-                else if (ukey.indexOf(FTPClientConfig.SYST_OS2) >= 0)
-                {
-                    parser = createOS2FTPEntryParser();
-                }
-                else if ((ukey.indexOf(FTPClientConfig.SYST_OS400) >= 0)
-                    || (ukey.indexOf(FTPClientConfig.SYST_AS400) >= 0))
-                {
-                    parser = createOS400FTPEntryParser();
-                }
-                else if (ukey.indexOf(FTPClientConfig.SYST_MVS) >= 0)
-                {
-                    parser = createMVSEntryParser();
-                }
-                else if (ukey.indexOf(FTPClientConfig.SYST_NETWARE) >= 0) 
-                {
-                    parser = createNetwareFTPEntryParser();
-                }
-                else
-                {
-                    throw new ParserInitializationException("Unknown parser type: " + key);
-                }
+	            String ukey = key.toUpperCase(java.util.Locale.ENGLISH);
+	            if (ukey.indexOf(FTPClientConfig.SYST_UNIX) >= 0) 
+	            {
+	                parser = createUnixFTPEntryParser();
+	            }
+	            else if (ukey.indexOf(FTPClientConfig.SYST_VMS) >= 0)
+	            {
+	                parser = createVMSVersioningFTPEntryParser();
+	            }
+	            else if (ukey.indexOf(FTPClientConfig.SYST_NT) >= 0)
+	            {
+	                parser = createNTFTPEntryParser();
+	            }
+	            else if (ukey.indexOf(FTPClientConfig.SYST_OS2) >= 0)
+	            {
+	                parser = createOS2FTPEntryParser();
+	            }
+	            else if (ukey.indexOf(FTPClientConfig.SYST_OS400) >= 0 ||
+	            		ukey.indexOf(FTPClientConfig.SYST_AS400) >= 0)
+	            {
+	                parser = createOS400FTPEntryParser();
+	            }
+	            else if (ukey.indexOf(FTPClientConfig.SYST_MVS) >= 0)
+	            {
+	                parser = createMVSEntryParser();
+	        	}
+	            else if (ukey.indexOf(FTPClientConfig.SYST_NETWARE) >= 0) 
+	            {
+	            	parser = createNetwareFTPEntryParser();
+	            }
+	            else if (ukey.indexOf(FTPClientConfig.SYST_L8) >= 0) 
+	            {
+	            	// L8 normally means Unix, but move it to the end for some L8 systems that aren't.
+	            	// This check should be last!
+	            	parser = createUnixFTPEntryParser();
+	            }
+	            else
+	            {
+	                throw new ParserInitializationException("Unknown parser type: " + key);
+	            }
             } 
-            catch (NoClassDefFoundError nf)
-            {
-                if (nf.getMessage().startsWith("org/apache/oro")) {
-                    throw new ParserInitializationException(
-                        " jakarta-oro-2.x.jar required on the runtime classpath. ", nf);
-                } else {
+            catch (NoClassDefFoundError nf) {
                     throw new ParserInitializationException("Error initializing parser", nf);
-                }
             }
 
         }
         catch (NoClassDefFoundError e)
-        {
-            if (e.getMessage().startsWith("org/apache/oro")) {
-                throw new ParserInitializationException(
-                    " jakarta-oro-2.x.jar required on the runtime classpath. ", e);
-            } else {
-                throw new ParserInitializationException("Error initializing parser", e);
-            }
+        { 	
+            throw new ParserInitializationException("Error initializing parser", e);
         }
         catch (ClassCastException e)
         {
@@ -184,13 +179,13 @@
      *                   Thrown on any exception in instantiation
      * @since 1.4
      */
-    public FTPFileEntryParser createFileEntryParser(FTPClientConfig config) 
-    throws ParserInitializationException 
-    {
-        this.config = config;
-        String key = config.getServerSystemKey();
-        return createFileEntryParser(key);
-    }
+	public FTPFileEntryParser createFileEntryParser(FTPClientConfig config) 
+	throws ParserInitializationException 
+	{
+	    this.config = config;
+		String key = config.getServerSystemKey();
+		return createFileEntryParser(key);
+	}
 
 
     public FTPFileEntryParser createUnixFTPEntryParser()
@@ -203,26 +198,23 @@
         return new VMSVersioningFTPEntryParser();
     }
     
-    /**
-     * @since 1.5
-     */
     public FTPFileEntryParser createNetwareFTPEntryParser() {
-        return new NetwareFTPEntryParser();
+    	return new NetwareFTPEntryParser();
     }
 
     public FTPFileEntryParser createNTFTPEntryParser()
     {
-        if (config != null && FTPClientConfig.SYST_NT.equals(
-                config.getServerSystemKey())) 
-        {
+    	if (config != null && FTPClientConfig.SYST_NT.equals(
+    	        config.getServerSystemKey())) 
+    	{
             return new NTFTPEntryParser();
-        } else {
+    	} else {
             return new CompositeFileEntryParser(new FTPFileEntryParser[]
-                {
-                    new NTFTPEntryParser(),
-                    new UnixFTPEntryParser()
-                });
-        }
+	   	        {
+	   	            new NTFTPEntryParser(),
+	   	            new UnixFTPEntryParser()
+	   	        });
+    	}
     }
     
      public FTPFileEntryParser createOS2FTPEntryParser()
@@ -232,17 +224,17 @@
 
     public FTPFileEntryParser createOS400FTPEntryParser()
     {
-        if (config != null && 
-                FTPClientConfig.SYST_OS400.equals(config.getServerSystemKey())) 
-        {
+    	if (config != null && 
+    	        FTPClientConfig.SYST_OS400.equals(config.getServerSystemKey())) 
+    	{
             return new OS400FTPEntryParser();
-        } else {
-            return new CompositeFileEntryParser(new FTPFileEntryParser[]
-                {
-                    new OS400FTPEntryParser(),
-                    new UnixFTPEntryParser()
-                });
-        }
+    	} else {
+	        return new CompositeFileEntryParser(new FTPFileEntryParser[]
+	            {
+	                new OS400FTPEntryParser(),
+	                new UnixFTPEntryParser()
+	            });
+    	}
     }
 
     public FTPFileEntryParser createMVSEntryParser()
@@ -251,5 +243,6 @@
     }
 
 
-    
+	
 }
+
diff --git a/src/java/org/apache/commons/net/ftp/parser/EnterpriseUnixFTPEntryParser.java b/src/main/java/org/apache/commons/net/ftp/parser/EnterpriseUnixFTPEntryParser.java
similarity index 98%
rename from src/java/org/apache/commons/net/ftp/parser/EnterpriseUnixFTPEntryParser.java
rename to src/main/java/org/apache/commons/net/ftp/parser/EnterpriseUnixFTPEntryParser.java
index 1c52ba1..64b06f2 100644
--- a/src/java/org/apache/commons/net/ftp/parser/EnterpriseUnixFTPEntryParser.java
+++ b/src/main/java/org/apache/commons/net/ftp/parser/EnterpriseUnixFTPEntryParser.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.ftp.parser;
 import java.util.Calendar;
 
diff --git a/src/java/org/apache/commons/net/ftp/parser/FTPFileEntryParserFactory.java b/src/main/java/org/apache/commons/net/ftp/parser/FTPFileEntryParserFactory.java
similarity index 97%
rename from src/java/org/apache/commons/net/ftp/parser/FTPFileEntryParserFactory.java
rename to src/main/java/org/apache/commons/net/ftp/parser/FTPFileEntryParserFactory.java
index b9f48ba..934803c 100644
--- a/src/java/org/apache/commons/net/ftp/parser/FTPFileEntryParserFactory.java
+++ b/src/main/java/org/apache/commons/net/ftp/parser/FTPFileEntryParserFactory.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.ftp.parser;
 import org.apache.commons.net.ftp.FTPClientConfig;
 import org.apache.commons.net.ftp.FTPFileEntryParser;
diff --git a/src/java/org/apache/commons/net/ftp/parser/FTPTimestampParser.java b/src/main/java/org/apache/commons/net/ftp/parser/FTPTimestampParser.java
similarity index 97%
rename from src/java/org/apache/commons/net/ftp/parser/FTPTimestampParser.java
rename to src/main/java/org/apache/commons/net/ftp/parser/FTPTimestampParser.java
index 8e6f5c3..c528ae2 100644
--- a/src/java/org/apache/commons/net/ftp/parser/FTPTimestampParser.java
+++ b/src/main/java/org/apache/commons/net/ftp/parser/FTPTimestampParser.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.ftp.parser;
 
 import java.text.ParseException;
diff --git a/src/java/org/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java b/src/main/java/org/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java
similarity index 85%
rename from src/java/org/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java
rename to src/main/java/org/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java
index fc8c564..0836332 100644
--- a/src/java/org/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java
+++ b/src/main/java/org/apache/commons/net/ftp/parser/FTPTimestampParserImpl.java
@@ -99,49 +99,58 @@
         ParsePosition pp = new ParsePosition(0);
 
         Date parsed = null;
-        String timeStampStrPlusYear="";
         if (recentDateFormat != null) {
             if (lenientFutureDates) {
                 // add a day to "now" so that "slop" doesn't cause a date 
                 // slightly in the future to roll back a full year.  (Bug 35181)
                 now.add(Calendar.DATE, 1);
             }    
-            // Temporarily add the current year to the short date time
-            // to cope with short-date leap year strings.
-            // e.g. Java's DateFormatter will assume that "Feb 29 12:00" refers to 
-            // Feb 29 1970 (an invalid date) rather than a potentially valid leap year date.
-            // This is pretty bad hack to work around the deficiencies of the JDK date/time classes.
-            int year = now.get(Calendar.YEAR);
-            timeStampStrPlusYear = timestampStr + " " + year;
-            SimpleDateFormat hackFormatter = new SimpleDateFormat(recentDateFormat.toPattern() + " yyyy", 
-                    recentDateFormat.getDateFormatSymbols());
-            hackFormatter.setLenient(false);
-            hackFormatter.setTimeZone(recentDateFormat.getTimeZone());
-            parsed = hackFormatter.parse(timeStampStrPlusYear, pp);
+            parsed = recentDateFormat.parse(timestampStr, pp);
         }
-        if (parsed != null && pp.getIndex() == timeStampStrPlusYear.length()) 
+        if (parsed != null && pp.getIndex() == timestampStr.length()) 
         {
             working.setTime(parsed);
+            working.set(Calendar.YEAR, now.get(Calendar.YEAR));
 
             if (working.after(now)) {
                 working.add(Calendar.YEAR, -1);
             }
         } else {
-            pp = new ParsePosition(0);
-            parsed = defaultDateFormat.parse(timestampStr, pp);
-            // note, length checks are mandatory for us since
-            // SimpleDateFormat methods will succeed if less than
-            // full string is matched.  They will also accept, 
-            // despite "leniency" setting, a two-digit number as
-            // a valid year (e.g. 22:04 will parse as 22 A.D.) 
-            // so could mistakenly confuse an hour with a year, 
-            // if we don't insist on full length parsing.
-            if (parsed != null && pp.getIndex() == timestampStr.length()) {
+            // Temporarily add the current year to the short date time
+            // to cope with short-date leap year strings.
+            // e.g. Java's DateFormatter will assume that "Feb 29 12:00" refers to 
+            // Feb 29 1970 (an invalid date) rather than a potentially valid leap year date.
+            // This is pretty bad hack to work around the deficiencies of the JDK date/time classes.
+            if (recentDateFormat != null) {
+                pp = new ParsePosition(0);
+                int year = now.get(Calendar.YEAR);
+                String timeStampStrPlusYear = timestampStr + " " + year;
+                SimpleDateFormat hackFormatter = new SimpleDateFormat(recentDateFormat.toPattern() + " yyyy", 
+                        recentDateFormat.getDateFormatSymbols());
+                hackFormatter.setLenient(false);
+                hackFormatter.setTimeZone(recentDateFormat.getTimeZone());
+                parsed = hackFormatter.parse(timeStampStrPlusYear, pp);
+            }
+            if (parsed != null && pp.getIndex() == timestampStr.length() + 5) {
                 working.setTime(parsed);
-            } else {
-                throw new ParseException(
-                        "Timestamp could not be parsed with older or recent DateFormat", 
-                        pp.getIndex());
+            }
+            else {
+                pp = new ParsePosition(0);
+                parsed = defaultDateFormat.parse(timestampStr, pp);
+                // note, length checks are mandatory for us since
+                // SimpleDateFormat methods will succeed if less than
+                // full string is matched.  They will also accept, 
+                // despite "leniency" setting, a two-digit number as
+                // a valid year (e.g. 22:04 will parse as 22 A.D.) 
+                // so could mistakenly confuse an hour with a year, 
+                // if we don't insist on full length parsing.
+                if (parsed != null && pp.getIndex() == timestampStr.length()) {
+                    working.setTime(parsed);
+                } else {
+                    throw new ParseException(
+                            "Timestamp could not be parsed with older or recent DateFormat", 
+                            pp.getIndex());
+                }
             }
         }
         return working;
@@ -290,4 +299,3 @@
         this.lenientFutureDates = lenientFutureDates;
     }
 }
-
diff --git a/src/main/java/org/apache/commons/net/ftp/parser/MVSFTPEntryParser.java b/src/main/java/org/apache/commons/net/ftp/parser/MVSFTPEntryParser.java
new file mode 100644
index 0000000..358469f
--- /dev/null
+++ b/src/main/java/org/apache/commons/net/ftp/parser/MVSFTPEntryParser.java
@@ -0,0 +1,495 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.net.ftp.parser;
+
+import java.text.ParseException;
+import java.util.List;
+
+import org.apache.commons.net.ftp.FTPClientConfig;
+import org.apache.commons.net.ftp.FTPFile;
+
+/**
+ * Implementation of FTPFileEntryParser and FTPFileListParser for IBM zOS/MVS
+ * Systems.
+ * 
+ * @author <a href="henrik.sorensen@balcab.ch">Henrik Sorensen</a>
+ * @author <a href="jnadler@srcginc.com">Jeff Nadler</a>
+ * @author <a href="wnoto@openfinance.com">William Noto</a>
+ * 
+ * @version $Id$
+ * @see org.apache.commons.net.ftp.FTPFileEntryParser FTPFileEntryParser (for
+ *      usage instructions)
+ */
+public class MVSFTPEntryParser extends ConfigurableFTPFileEntryParserImpl {
+
+    static final int UNKNOWN_LIST_TYPE = -1;
+    static final int FILE_LIST_TYPE = 0;
+    static final int MEMBER_LIST_TYPE = 1;
+    static final int UNIX_LIST_TYPE = 2;
+    static final int JES_LEVEL_1_LIST_TYPE = 3;
+    static final int JES_LEVEL_2_LIST_TYPE = 4;
+
+    private int isType = UNKNOWN_LIST_TYPE;
+
+    /**
+     * Fallback parser for Unix-style listings
+     */
+    private UnixFTPEntryParser unixFTPEntryParser;
+
+    /**
+     * Dates are ignored for file lists, but are used for member lists where
+     * possible
+     */
+    static final String DEFAULT_DATE_FORMAT = "yyyy/MM/dd HH:mm"; // 2001/09/18
+                                                                    // 13:52
+
+    /**
+     * Matches these entries: Volume Unit Referred Ext Used Recfm Lrecl BlkSz
+     * Dsorg Dsname B10142 3390 2006/03/20 2 31 F 80 80 PS MDI.OKL.WORK
+     * 
+     */
+    static final String FILE_LIST_REGEX = "\\S+\\s+" + // volume
+                                                                // ignored
+            "\\S+\\s+" + // unit - ignored
+            "\\S+\\s+" + // access date - ignored
+            "\\S+\\s+" + // extents -ignored
+            "\\S+\\s+" + // used - ignored
+            "[FV]\\S*\\s+" + // recfm - must start with F or V
+            "\\S+\\s+" + // logical record length -ignored
+            "\\S+\\s+" + // block size - ignored
+            "(PS|PO|PO-E)\\s+" + // Dataset organisation. Many exist
+            // but only support: PS, PO, PO-E
+            "(\\S+)\\s*"; // Dataset Name (file name)
+
+    /**
+     * Matches these entries: Name VV.MM Created Changed Size Init Mod Id
+     * TBSHELF 01.03 2002/09/12 2002/10/11 09:37 11 11 0 KIL001
+     */
+    static final String MEMBER_LIST_REGEX = "(\\S+)\\s+" + // name
+            "\\S+\\s+" + // version, modification (ignored)
+            "\\S+\\s+" + // create date (ignored)
+            "(\\S+)\\s+" + // modification date
+            "(\\S+)\\s+" + // modification time
+            "\\S+\\s+" + // size in lines (ignored)
+            "\\S+\\s+" + // size in lines at creation(ignored)
+            "\\S+\\s+" + // lines modified (ignored)
+            "\\S+\\s*"; // id of user who modified (ignored)
+
+    /**
+     * Matches these entries, note: no header: IBMUSER1 JOB01906 OUTPUT 3 Spool
+     * Files 012345678901234567890123456789012345678901234 1 2 3 4
+     */
+    static final String JES_LEVEL_1_LIST_REGEX = "(\\S+)\\s+" + // job
+                                                                        // name
+                                                                        // ignored
+            "(\\S+)\\s+" + // job number
+            "(\\S+)\\s+" + // job status (OUTPUT,INPUT,ACTIVE)
+            "(\\S+)\\s+" + // number of spool files
+            "(\\S+)\\s+" + // Text "Spool" ignored
+            "(\\S+)\\s*" // Text "Files" ignored
+    ;
+
+    /**
+     * JES INTERFACE LEVEL 2 parser Matches these entries: JOBNAME JOBID OWNER
+     * STATUS CLASS IBMUSER1 JOB01906 IBMUSER OUTPUT A RC=0000 3 spool files
+     * IBMUSER TSU01830 IBMUSER OUTPUT TSU ABEND=522 3 spool files
+     * 012345678901234567890123456789012345678901234 1 2 3 4
+     * 012345678901234567890123456789012345678901234567890
+     */
+
+    static final String JES_LEVEL_2_LIST_REGEX = "(\\S+)\\s+" + // job
+                                                                        // name
+                                                                        // ignored
+            "(\\S+)\\s+" + // job number
+            "(\\S+)\\s+" + // owner ignored
+            "(\\S+)\\s+" + // job status (OUTPUT,INPUT,ACTIVE) ignored
+            "(\\S+)\\s+" + // job class ignored
+            "(\\S+).*" // rest ignored
+    ;
+
+    /*
+     * ---------------------------------------------------------------------
+     * Very brief and incomplete description of the zOS/MVS-filesystem. (Note:
+     * "zOS" is the operating system on the mainframe, and is the new name for
+     * MVS)
+     * 
+     * The filesystem on the mainframe does not have hierarchal structure as for
+     * example the unix filesystem. For a more comprehensive description, please
+     * refer to the IBM manuals
+     * 
+     * @LINK:
+     * http://publibfp.boulder.ibm.com/cgi-bin/bookmgr/BOOKS/dgt2d440/CONTENTS
+     * 
+     * 
+     * Dataset names =============
+     * 
+     * A dataset name consist of a number of qualifiers separated by '.', each
+     * qualifier can be at most 8 characters, and the total length of a dataset
+     * can be max 44 characters including the dots.
+     * 
+     * 
+     * Dataset organisation ====================
+     * 
+     * A dataset represents a piece of storage allocated on one or more disks.
+     * The structure of the storage is described with the field dataset
+     * organinsation (DSORG). There are a number of dataset organisations, but
+     * only two are usable for FTP transfer.
+     * 
+     * DSORG: PS: sequential, or flat file PO: partitioned dataset PO-E:
+     * extended partitioned dataset
+     * 
+     * The PS file is just a flat file, as you would find it on the unix file
+     * system.
+     * 
+     * The PO and PO-E files, can be compared to a single level directory
+     * structure. A PO file consist of a number of dataset members, or files if
+     * you will. It is possible to CD into the file, and to retrieve the
+     * individual members.
+     * 
+     * 
+     * Dataset record format =====================
+     * 
+     * The physical layout of the dataset is described on the dataset itself.
+     * There are a number of record formats (RECFM), but just a few is relavant
+     * for the FTP transfer.
+     * 
+     * Any one beginning with either F or V can safely used by FTP transfer. All
+     * others should only be used with great care, so this version will just
+     * ignore the other record formats. F means a fixed number of records per
+     * allocated storage, and V means a variable number of records.
+     * 
+     * 
+     * Other notes ===========
+     * 
+     * The file system supports automatically backup and retrieval of datasets.
+     * If a file is backed up, the ftp LIST command will return: ARCIVE Not
+     * Direct Access Device KJ.IOP998.ERROR.PL.UNITTEST
+     * 
+     * 
+     * Implementation notes ====================
+     * 
+     * Only datasets that have dsorg PS, PO or PO-E and have recfm beginning
+     * with F or V, is fully parsed.
+     * 
+     * The following fields in FTPFile is used: FTPFile.Rawlisting: Always set.
+     * FTPFile.Type: DIRECTORY_TYPE or FILE_TYPE or UNKNOWN FTPFile.Name: name
+     * FTPFile.Timestamp: change time or null
+     * 
+     * 
+     * 
+     * Additional information ======================
+     * 
+     * The MVS ftp server supports a number of features via the FTP interface.
+     * The features are controlled with the FTP command quote site filetype=<SEQ|JES|DB2>
+     * SEQ is the default and used for normal file transfer JES is used to
+     * interact with the Job Entry Subsystem (JES) similar to a job scheduler
+     * DB2 is used to interact with a DB2 subsystem
+     * 
+     * This parser supports SEQ and JES.
+     * 
+     * 
+     * 
+     * 
+     * 
+     * 
+     */
+
+    /**
+     * The sole constructor for a MVSFTPEntryParser object.
+     * 
+     */
+    public MVSFTPEntryParser() {
+        super(""); // note the regex is set in preParse.
+        super.configure(null); // configure parser with default configurations
+    }
+
+    /**
+     * Parses a line of an z/OS - MVS FTP server file listing and converts it
+     * into a usable format in the form of an <code> FTPFile </code> instance.
+     * If the file listing line doesn't describe a file, then
+     * <code> null </code> is returned. Otherwise a <code> FTPFile </code>
+     * instance representing the file is returned.
+     * 
+     * @param entry
+     *            A line of text from the file listing
+     * @return An FTPFile instance corresponding to the supplied entry
+     */
+    public FTPFile parseFTPEntry(String entry) {
+        boolean isParsed = false;
+        FTPFile f = new FTPFile();
+
+        if (isType == FILE_LIST_TYPE)
+            isParsed = parseFileList(f, entry);
+        else if (isType == MEMBER_LIST_TYPE) {
+            isParsed = parseMemberList(f, entry);
+            if (!isParsed)
+                isParsed = parseSimpleEntry(f, entry);
+        } else if (isType == UNIX_LIST_TYPE) {
+            isParsed = parseUnixList(f, entry);
+        } else if (isType == JES_LEVEL_1_LIST_TYPE) {
+            isParsed = parseJeslevel1List(f, entry);
+        } else if (isType == JES_LEVEL_2_LIST_TYPE) {
+            isParsed = parseJeslevel2List(f, entry);
+        }
+
+        if (!isParsed)
+            f = null;
+        
+        return f;
+    }
+
+    /**
+     * Parse entries representing a dataset list. Only datasets with DSORG PS or
+     * PO or PO-E and with RECFM F* or V* will be parsed.
+     * 
+     * Format of ZOS/MVS file list: 1 2 3 4 5 6 7 8 9 10 Volume Unit Referred
+     * Ext Used Recfm Lrecl BlkSz Dsorg Dsname B10142 3390 2006/03/20 2 31 F 80
+     * 80 PS MDI.OKL.WORK ARCIVE Not Direct Access Device
+     * KJ.IOP998.ERROR.PL.UNITTEST B1N231 3390 2006/03/20 1 15 VB 256 27998 PO
+     * PLU B1N231 3390 2006/03/20 1 15 VB 256 27998 PO-E PLB
+     * 
+     * ----------------------------------- Group within Regex [1] Volume [2]
+     * Unit [3] Referred [4] Ext: number of extents [5] Used [6] Recfm: Record
+     * format [7] Lrecl: Logical record length [8] BlkSz: Block size [9] Dsorg:
+     * Dataset organisation. Many exists but only support: PS, PO, PO-E [10]
+     * Dsname: Dataset name
+     * 
+     * Note: When volume is ARCIVE, it means the dataset is stored somewhere in
+     * a tape archive. These entries is currently not supported by this parser.
+     * A null value is returned.
+     * 
+     * @param file
+     *            will be updated with Name, Type, Timestamp if parsed.
+     * @param entry zosDirectoryEntry
+     * @return true: entry was parsed, false: entry was not parsed.
+     */
+    private boolean parseFileList(FTPFile file, String entry) {
+        if (matches(entry)) {
+            file.setRawListing(entry);
+            String name = group(2);
+            String dsorg = group(1);
+            file.setName(name);
+
+            // DSORG
+            if ("PS".equals(dsorg)) {
+                file.setType(FTPFile.FILE_TYPE);
+            } 
+            else if ("PO".equals(dsorg) || "PO-E".equals(dsorg)) {
+                // regex already ruled out anything other than PO or PO-E
+                file.setType(FTPFile.DIRECTORY_TYPE);
+            } 
+            else {
+                return false;
+            }
+            
+            return true;
+        }
+        
+        return false;
+    }
+
+    /**
+     * Parse entries within a partitioned dataset.
+     * 
+     * Format of a memberlist within a PDS: 1 2 3 4 5 6 7 8 9 Name VV.MM Created
+     * Changed Size Init Mod Id TBSHELF 01.03 2002/09/12 2002/10/11 09:37 11 11
+     * 0 KIL001 TBTOOL 01.12 2002/09/12 2004/11/26 19:54 51 28 0 KIL001
+     * 
+     * ------------------------------------------- [1] Name [2] VV.MM: Version .
+     * modification [3] Created: yyyy / MM / dd [4,5] Changed: yyyy / MM / dd
+     * HH:mm [6] Size: number of lines [7] Init: number of lines when first
+     * created [8] Mod: number of modified lines a last save [9] Id: User id for
+     * last update
+     * 
+     * 
+     * @param file
+     *            will be updated with Name, Type and Timestamp if parsed.
+     * @param entry zosDirectoryEntry
+     * @return true: entry was parsed, false: entry was not parsed.
+     */
+    private boolean parseMemberList(FTPFile file, String entry) {
+        if (matches(entry)) {
+            file.setRawListing(entry);
+            String name = group(1);
+            String datestr = group(2) + " " + group(3);
+            file.setName(name);
+            file.setType(FTPFile.FILE_TYPE);
+            try {
+                file.setTimestamp(super.parseTimestamp(datestr));
+            } catch (ParseException e) {
+                e.printStackTrace();
+                // just ignore parsing errors.
+                // TODO check this is ok
+                return false; // this is a parsing failure too.
+            }
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Assigns the name to the first word of the entry. Only to be used from a
+     * safe context, for example from a memberlist, where the regex for some
+     * reason fails. Then just assign the name field of FTPFile.
+     * 
+     * @param file
+     * @param entry
+     * @return
+     */
+    private boolean parseSimpleEntry(FTPFile file, String entry) {
+        if (entry != null && entry.length() > 0) {
+            file.setRawListing(entry);
+            String name = entry.split(" ")[0];
+            file.setName(name);
+            file.setType(FTPFile.FILE_TYPE);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Parse the entry as a standard unix file. Using the UnixFTPEntryParser.
+     * 
+     * @param file
+     * @param entry
+     * @return true: entry is parsed, false: entry could not be parsed.
+     */
+    private boolean parseUnixList(FTPFile file, String entry) {
+        file = unixFTPEntryParser.parseFTPEntry(entry);
+        if (file == null)
+            return false;
+        return true;
+    }
+
+    /**
+     * Matches these entries, note: no header: [1] [2] [3] [4] [5] IBMUSER1
+     * JOB01906 OUTPUT 3 Spool Files
+     * 012345678901234567890123456789012345678901234 1 2 3 4
+     * ------------------------------------------- Group in regex [1] Job name
+     * [2] Job number [3] Job status (INPUT,ACTIVE,OUTPUT) [4] Number of sysout
+     * files [5] The string "Spool Files"
+     * 
+     * 
+     * @param file
+     *            will be updated with Name, Type and Timestamp if parsed.
+     * @param entry zosDirectoryEntry
+     * @return true: entry was parsed, false: entry was not parsed.
+     */
+    private boolean parseJeslevel1List(FTPFile file, String entry) {
+        if (matches(entry)) {
+            if (group(3).equalsIgnoreCase("OUTPUT")) {
+                file.setRawListing(entry);
+                String name = group(2); /* Job Number, used by GET */
+                file.setName(name);
+                file.setType(FTPFile.FILE_TYPE);
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Matches these entries, note: no header: [1] [2] [3] [4] [5] JOBNAME JOBID
+     * OWNER STATUS CLASS IBMUSER1 JOB01906 IBMUSER OUTPUT A RC=0000 3 spool
+     * files IBMUSER TSU01830 IBMUSER OUTPUT TSU ABEND=522 3 spool files
+     * 012345678901234567890123456789012345678901234 1 2 3 4
+     * ------------------------------------------- Group in regex [1] Job name
+     * [2] Job number [3] Owner [4] Job status (INPUT,ACTIVE,OUTPUT) [5] Job
+     * Class [6] The rest
+     * 
+     * 
+     * @param file
+     *            will be updated with Name, Type and Timestamp if parsed.
+     * @param entry zosDirectoryEntry
+     * @return true: entry was parsed, false: entry was not parsed.
+     */
+    private boolean parseJeslevel2List(FTPFile file, String entry) {
+        if (matches(entry)) {
+            if (group(4).equalsIgnoreCase("OUTPUT")) {
+                file.setRawListing(entry);
+                String name = group(2); /* Job Number, used by GET */
+                file.setName(name);
+                file.setType(FTPFile.FILE_TYPE);
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * preParse is called as part of the interface. Per definition is is called
+     * before the parsing takes place. Three kind of lists is recognize:
+     * z/OS-MVS File lists z/OS-MVS Member lists unix file lists
+     * @since 2.0
+     */
+    @Override
+    public List<String> preParse(List<String> orig) {
+        // simply remove the header line. Composite logic will take care of the
+        // two different types of
+        // list in short order.
+        if (orig != null && orig.size() > 0) {
+            String header = orig.get(0);
+            if (header.indexOf("Volume") >= 0 && header.indexOf("Dsname") >= 0) {
+                setType(FILE_LIST_TYPE);
+                super.setRegex(FILE_LIST_REGEX);
+            } else if (header.indexOf("Name") >= 0 && header.indexOf("Id") >= 0) {
+                setType(MEMBER_LIST_TYPE);
+                super.setRegex(MEMBER_LIST_REGEX);
+            } else if (header.indexOf("total") == 0) {
+                setType(UNIX_LIST_TYPE);
+                unixFTPEntryParser = new UnixFTPEntryParser();
+            } else if (header.indexOf("Spool Files") >= 30) {
+                setType(JES_LEVEL_1_LIST_TYPE);
+                super.setRegex(JES_LEVEL_1_LIST_REGEX);
+            } else if (header.indexOf("JOBNAME") == 0
+                    && header.indexOf("JOBID") > 8) {// header contains JOBNAME JOBID OWNER // STATUS CLASS
+                setType(JES_LEVEL_2_LIST_TYPE);
+                super.setRegex(JES_LEVEL_2_LIST_REGEX);
+            } else {
+                setType(UNKNOWN_LIST_TYPE);
+            }
+            
+            if (isType != JES_LEVEL_1_LIST_TYPE) { // remove header is necessary
+                orig.remove(0);
+            }
+        }
+        
+        return orig;
+    }
+    
+    /**
+     * Explicitly set the type of listing being processed.
+     * @param type The listing type.
+     */
+    void setType(int type) {
+        isType = type;
+    }
+
+    /* 
+     * @return
+     */
+    @Override
+    protected FTPClientConfig getDefaultConfiguration() {
+        return new FTPClientConfig(FTPClientConfig.SYST_MVS,
+                DEFAULT_DATE_FORMAT, null, null, null, null);
+    }
+
+}
diff --git a/src/java/org/apache/commons/net/ftp/parser/NTFTPEntryParser.java b/src/main/java/org/apache/commons/net/ftp/parser/NTFTPEntryParser.java
similarity index 97%
rename from src/java/org/apache/commons/net/ftp/parser/NTFTPEntryParser.java
rename to src/main/java/org/apache/commons/net/ftp/parser/NTFTPEntryParser.java
index 2b2ab5b..9ed39b8 100644
--- a/src/java/org/apache/commons/net/ftp/parser/NTFTPEntryParser.java
+++ b/src/main/java/org/apache/commons/net/ftp/parser/NTFTPEntryParser.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.ftp.parser;
 import java.text.ParseException;
 
@@ -135,7 +136,8 @@
      * parameter being specified.
      * @return the default configuration for this parser.
      */
-   public FTPClientConfig getDefaultConfiguration() {
+    @Override
+    public FTPClientConfig getDefaultConfiguration() {
         return new FTPClientConfig(
                 FTPClientConfig.SYST_NT,
                 DEFAULT_DATE_FORMAT,
diff --git a/src/java/org/apache/commons/net/ftp/parser/NetwareFTPEntryParser.java b/src/main/java/org/apache/commons/net/ftp/parser/NetwareFTPEntryParser.java
similarity index 98%
rename from src/java/org/apache/commons/net/ftp/parser/NetwareFTPEntryParser.java
rename to src/main/java/org/apache/commons/net/ftp/parser/NetwareFTPEntryParser.java
index 12f5827..360cb9f 100644
--- a/src/java/org/apache/commons/net/ftp/parser/NetwareFTPEntryParser.java
+++ b/src/main/java/org/apache/commons/net/ftp/parser/NetwareFTPEntryParser.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.ftp.parser;
 
 import java.text.ParseException;
@@ -165,6 +166,7 @@
      * parameter being specified.
      * @return the default configuration for this parser.
      */
+    @Override
     protected FTPClientConfig getDefaultConfiguration() {
         return new FTPClientConfig(FTPClientConfig.SYST_NETWARE,
                 DEFAULT_DATE_FORMAT, DEFAULT_RECENT_DATE_FORMAT, null, null,
diff --git a/src/java/org/apache/commons/net/ftp/parser/OS2FTPEntryParser.java b/src/main/java/org/apache/commons/net/ftp/parser/OS2FTPEntryParser.java
similarity index 97%
rename from src/java/org/apache/commons/net/ftp/parser/OS2FTPEntryParser.java
rename to src/main/java/org/apache/commons/net/ftp/parser/OS2FTPEntryParser.java
index 32fe70b..b5cd75c 100644
--- a/src/java/org/apache/commons/net/ftp/parser/OS2FTPEntryParser.java
+++ b/src/main/java/org/apache/commons/net/ftp/parser/OS2FTPEntryParser.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.ftp.parser;
 import java.text.ParseException;
 
@@ -38,7 +39,7 @@
      * this is the regular expression used by this parser.
      */
     private static final String REGEX =
-        "(\\s+|[0-9]+)\\s*"
+        "\\s*([0-9]+)\\s*"
         + "(\\s+|[A-Z]+)\\s*"
         + "(DIR|\\s+)\\s*"
         + "(\\S+)\\s+(\\S+)\\s+" /* date stuff */
@@ -135,6 +136,7 @@
      * parameter being specified.
      * @return the default configuration for this parser.
      */
+    @Override
     protected FTPClientConfig getDefaultConfiguration() {
         return new FTPClientConfig(
                 FTPClientConfig.SYST_OS2,
diff --git a/src/java/org/apache/commons/net/ftp/parser/OS400FTPEntryParser.java b/src/main/java/org/apache/commons/net/ftp/parser/OS400FTPEntryParser.java
similarity index 98%
rename from src/java/org/apache/commons/net/ftp/parser/OS400FTPEntryParser.java
rename to src/main/java/org/apache/commons/net/ftp/parser/OS400FTPEntryParser.java
index f9e2640..d982c18 100644
--- a/src/java/org/apache/commons/net/ftp/parser/OS400FTPEntryParser.java
+++ b/src/main/java/org/apache/commons/net/ftp/parser/OS400FTPEntryParser.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.ftp.parser;
 
 import java.text.ParseException;
@@ -146,6 +147,7 @@
      * parameter being specified.
      * @return the default configuration for this parser.
      */
+    @Override
     protected FTPClientConfig getDefaultConfiguration() {
         return new FTPClientConfig(
                 FTPClientConfig.SYST_OS400,
diff --git a/src/java/org/apache/commons/net/ftp/parser/ParserInitializationException.java b/src/main/java/org/apache/commons/net/ftp/parser/ParserInitializationException.java
similarity index 97%
rename from src/java/org/apache/commons/net/ftp/parser/ParserInitializationException.java
rename to src/main/java/org/apache/commons/net/ftp/parser/ParserInitializationException.java
index 065a20d..5efadb0 100644
--- a/src/java/org/apache/commons/net/ftp/parser/ParserInitializationException.java
+++ b/src/main/java/org/apache/commons/net/ftp/parser/ParserInitializationException.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.ftp.parser;
 
 /**
diff --git a/src/java/org/apache/commons/net/ftp/parser/RegexFTPFileEntryParserImpl.java b/src/main/java/org/apache/commons/net/ftp/parser/RegexFTPFileEntryParserImpl.java
similarity index 69%
rename from src/java/org/apache/commons/net/ftp/parser/RegexFTPFileEntryParserImpl.java
rename to src/main/java/org/apache/commons/net/ftp/parser/RegexFTPFileEntryParserImpl.java
index 242ef57..66c8ad9 100644
--- a/src/java/org/apache/commons/net/ftp/parser/RegexFTPFileEntryParserImpl.java
+++ b/src/main/java/org/apache/commons/net/ftp/parser/RegexFTPFileEntryParserImpl.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -15,16 +15,15 @@
  * limitations under the License.
  */
 
+
 package org.apache.commons.net.ftp.parser;
+
+import java.util.regex.MatchResult;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
 import org.apache.commons.net.ftp.FTPFileEntryParserImpl;
-import org.apache.oro.text.regex.MalformedPatternException;
-import org.apache.oro.text.regex.MatchResult;
-import org.apache.oro.text.regex.Pattern;
-import org.apache.oro.text.regex.PatternMatcher;
-import org.apache.oro.text.regex.Perl5Compiler;
-import org.apache.oro.text.regex.Perl5Matcher;
-
-
 
 /**
  * This abstract class implements both the older FTPFileListParser and
@@ -35,8 +34,8 @@
  *
  * @author Steve Cohen <scohen@apache.org>
  */
-public abstract class RegexFTPFileEntryParserImpl extends FTPFileEntryParserImpl
-{
+public abstract class RegexFTPFileEntryParserImpl extends
+        FTPFileEntryParserImpl {
     /**
      * internal pattern the matcher tries to match, representing a file
      * entry
@@ -52,7 +51,7 @@
      * Internal PatternMatcher object used by the parser.  It has protected
      * scope in case subclasses want to make use of it for their own purposes.
      */
-    protected PatternMatcher _matcher_ = null;
+    protected Matcher _matcher_ = null;
 
     /**
      * The constructor for a RegexFTPFileEntryParserImpl object.
@@ -68,19 +67,9 @@
      * from this will bomb very quickly,  leading to easy detection.
      */
 
-    public RegexFTPFileEntryParserImpl(String regex)
-    {
+    public RegexFTPFileEntryParserImpl(String regex) {
         super();
-        try
-        {
-            _matcher_ = new Perl5Matcher();
-            pattern   = new Perl5Compiler().compile(regex);
-        }
-        catch (MalformedPatternException e)
-        {
-            throw new IllegalArgumentException (
-               "Unparseable regex supplied:  " + regex);
-        }
+        setRegex(regex);
     }
 
     /**
@@ -91,36 +80,28 @@
      * @return true if s matches this object's regular expression.
      */
 
-    public boolean matches(String s)
-    {
+    public boolean matches(String s) {
         this.result = null;
-        if (_matcher_.matches(s.trim(), this.pattern))
-        {
-            this.result = _matcher_.getMatch();
+        _matcher_ = pattern.matcher(s);
+        if (_matcher_.matches()) {
+            this.result = _matcher_.toMatchResult();
         }
         return null != this.result;
     }
 
-
-
     /**
-     * Convenience method delegates to the internal MatchResult's groups()
-     * method.
+     * Convenience method 
      *
      * @return the number of groups() in the internal MatchResult.
      */
 
-    public int getGroupCnt()
-    {
-        if (this.result == null)
-        {
+    public int getGroupCnt() {
+        if (this.result == null) {
             return 0;
         }
-        return this.result.groups();
+        return this.result.groupCount();
     }
 
-
-
     /**
      * Convenience method delegates to the internal MatchResult's group()
      * method.
@@ -131,10 +112,8 @@
      *         match or null if this method is called without a match having
      *         been made.
      */
-    public String group(int matchnum)
-    {
-        if (this.result == null)
-        {
+    public String group(int matchnum) {
+        if (this.result == null) {
             return null;
         }
         return this.result.group(matchnum);
@@ -147,17 +126,30 @@
      * @return a string shows each match group by number.
      */
 
-    public String getGroupsAsString()
-    {
+    public String getGroupsAsString() {
         StringBuffer b = new StringBuffer();
-        for (int i = 1; i <= this.result.groups(); i++)
-        {
-            b.append(i).append(") ").append(this.result.group(i))
-                .append(System.getProperty("line.separator"));
+        for (int i = 1; i <= this.result.groupCount(); i++) {
+            b.append(i).append(") ").append(this.result.group(i)).append(
+                    System.getProperty("line.separator"));
         }
         return b.toString();
     }
-    
+
+    /**
+     * Alter the current regular expression being utilised for entry parsing 
+     * and create a new {@link Pattern} instance.
+     * @param regex The new regular expression
+     * @return  true if the compiled pattern is not null
+     * @since 2.0
+     */
+    public boolean setRegex(String regex) {
+        try {
+            pattern = Pattern.compile(regex);
+        } catch (PatternSyntaxException pse) {
+            throw new IllegalArgumentException("Unparseable regex supplied: "
+                    + regex);
+        }
+        return (pattern != null);
+    }
+
 }
-
-
diff --git a/src/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParser.java b/src/main/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParser.java
similarity index 94%
rename from src/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParser.java
rename to src/main/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParser.java
index 3ef4dc6..408d247 100644
--- a/src/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParser.java
+++ b/src/main/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParser.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.ftp.parser;
 import java.text.ParseException;
 
@@ -32,12 +33,6 @@
  */
 public class UnixFTPEntryParser extends ConfigurableFTPFileEntryParserImpl
 {
-    /**
-     * months abbreviations looked for by this parser.  Also used
-     * to determine which month is matched by the parser
-     */
-    private static final String DEFAULT_MONTHS =
-        "(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)";
     
     static final String DEFAULT_DATE_FORMAT 
         = "MMM d yyyy"; //Nov 9 2001
@@ -84,20 +79,19 @@
      *        execution is on
      *    T   the 1000 bit is turned on, and execution is off (undefined bit-
      *        state)
+     *    e   z/OS external link bit
      */
     private static final String REGEX =
-        "([bcdlfmpSs-])"
-        +"(((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-])))\\+?\\s+"
+        "([bcdelfmpSs-])"
+        +"(((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-]))((r|-)(w|-)([xsStTL-])))\\+?\\s*"
         + "(\\d+)\\s+"
-        + "(\\S+)\\s+"
-        + "(?:(\\S+(?:\\s\\S+)*)\\s+)?"
+        + "(?:(\\S+(?:\\s\\S+)*?)\\s+)?"                // owner name (optional spaces)
+        + "(?:(\\S+(?:\\s\\S+)*)\\s+)?"                 // group name (optional spaces)
         + "(\\d+(?:,\\s*\\d+)?)\\s+"
-        
         /*
           numeric or standard format date
         */
-        + "((?:\\d+[-/]\\d+[-/]\\d+)|(?:\\S+\\s+\\S+))\\s+"
-        
+        + "((?:\\d+[-/]\\d+[-/]\\d+)|(?:[a-zA-Z0-9]+\\s+\\S+))\\s+"
         /* 
            year (for non-recent standard format) 
            or time (for numeric or recent standard format  
@@ -182,6 +176,9 @@
             case 'd':
                 type = FTPFile.DIRECTORY_TYPE;
                 break;
+            case 'e':
+                type = FTPFile.SYMBOLIC_LINK_TYPE;
+                break;
             case 'l':
                 type = FTPFile.SYMBOLIC_LINK_TYPE;
                 break;
@@ -284,6 +281,7 @@
      * parameter being specified.
      * @return the default configuration for this parser.
      */
+    @Override
     protected FTPClientConfig getDefaultConfiguration() {
         return new FTPClientConfig(
                 FTPClientConfig.SYST_UNIX,
@@ -292,7 +290,4 @@
                 null, null, null);
     }
     
-    
-    
-
 }
diff --git a/src/java/org/apache/commons/net/ftp/parser/VMSFTPEntryParser.java b/src/main/java/org/apache/commons/net/ftp/parser/VMSFTPEntryParser.java
similarity index 97%
rename from src/java/org/apache/commons/net/ftp/parser/VMSFTPEntryParser.java
rename to src/main/java/org/apache/commons/net/ftp/parser/VMSFTPEntryParser.java
index 4c408a1..b97fe09 100644
--- a/src/java/org/apache/commons/net/ftp/parser/VMSFTPEntryParser.java
+++ b/src/main/java/org/apache/commons/net/ftp/parser/VMSFTPEntryParser.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.ftp.parser;
 import java.io.BufferedReader;
 import java.io.IOException;
@@ -115,7 +116,7 @@
      ***/
     public FTPFile[] parseFileList(InputStream listStream) throws IOException {
         FTPListParseEngine engine = new FTPListParseEngine(this);
-        engine.readServerList(listStream);
+        engine.readServerList(listStream, null);
         return engine.getFiles();
     }
 
@@ -235,6 +236,7 @@
      * @return A string representing the next ftp entry or null if none found.
      * @exception IOException thrown on any IO Error reading from the reader.
      */
+    @Override
     public String readNextEntry(BufferedReader reader) throws IOException
     {
         String line = reader.readLine();
@@ -266,7 +268,8 @@
      * parameter being specified.
      * @return the default configuration for this parser.
      */
-   protected FTPClientConfig getDefaultConfiguration() {
+    @Override
+    protected FTPClientConfig getDefaultConfiguration() {
         return new FTPClientConfig(
                 FTPClientConfig.SYST_VMS,
                 DEFAULT_DATE_FORMAT,
diff --git a/src/java/org/apache/commons/net/ftp/parser/VMSVersioningFTPEntryParser.java b/src/main/java/org/apache/commons/net/ftp/parser/VMSVersioningFTPEntryParser.java
similarity index 80%
rename from src/java/org/apache/commons/net/ftp/parser/VMSVersioningFTPEntryParser.java
rename to src/main/java/org/apache/commons/net/ftp/parser/VMSVersioningFTPEntryParser.java
index cc75df5..a6c6f67 100644
--- a/src/java/org/apache/commons/net/ftp/parser/VMSVersioningFTPEntryParser.java
+++ b/src/main/java/org/apache/commons/net/ftp/parser/VMSVersioningFTPEntryParser.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,18 +14,18 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.ftp.parser;
 
 import java.util.HashMap;
 import java.util.List;
 import java.util.ListIterator;
+import java.util.regex.MatchResult;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
 
 import org.apache.commons.net.ftp.FTPClientConfig;
-import org.apache.oro.text.regex.MalformedPatternException;
-import org.apache.oro.text.regex.MatchResult;
-import org.apache.oro.text.regex.Pattern;
-import org.apache.oro.text.regex.Perl5Compiler;
-import org.apache.oro.text.regex.Perl5Matcher;
 
 /**
  * Special implementation VMSFTPEntryParser with versioning turned on.
@@ -48,7 +48,7 @@
 public class VMSVersioningFTPEntryParser extends VMSFTPEntryParser
 {
 
-    private Perl5Matcher _preparse_matcher_;
+    private Matcher _preparse_matcher_;
     private Pattern _preparse_pattern_;
     private static final String PRE_PARSE_REGEX =
         "(.*);([0-9]+)\\s*.*";
@@ -85,10 +85,10 @@
         configure(config);
         try
         {
-            _preparse_matcher_ = new Perl5Matcher();
-            _preparse_pattern_ = new Perl5Compiler().compile(PRE_PARSE_REGEX);
+            //_preparse_matcher_ = new Perl5Matcher();
+            _preparse_pattern_ = Pattern.compile(PRE_PARSE_REGEX);
         }
-        catch (MalformedPatternException e)
+        catch (PatternSyntaxException pse)
         {
             throw new IllegalArgumentException (
                 "Unparseable regex supplied:  " + PRE_PARSE_REGEX);
@@ -98,7 +98,7 @@
 
 
 
-    private class NameVersion {
+    private static class NameVersion {
         String name;
         int versionNumber;
         NameVersion(String name, String vers) {
@@ -116,19 +116,21 @@
      *
      * @return Original list purged of duplicates
      */
-    public List preParse(List original) {
+    @Override
+    public List<String> preParse(List<String> original) {
         original = super.preParse(original);
-        HashMap existingEntries = new HashMap();
-        ListIterator iter = original.listIterator();
+        HashMap<String, NameVersion> existingEntries = new HashMap<String, NameVersion>();
+        ListIterator<String> iter = original.listIterator();
         while (iter.hasNext()) {
-            String entry = ((String)iter.next()).trim();
+            String entry = iter.next().trim();
             MatchResult result = null;
-            if (_preparse_matcher_.matches(entry, _preparse_pattern_)) {
-                result = _preparse_matcher_.getMatch();
+            _preparse_matcher_ = _preparse_pattern_.matcher(entry);
+            if (_preparse_matcher_.matches()) {
+                result = _preparse_matcher_.toMatchResult();
                 String name = result.group(1);
                 String version = result.group(2);
                 NameVersion nv = new NameVersion(name, version);
-                NameVersion existing = (NameVersion) existingEntries.get(name);
+                NameVersion existing = existingEntries.get(name);
                 if (null != existing) {
                     if (nv.versionNumber < existing.versionNumber) {
                         iter.remove();  // removal removes from original list.
@@ -144,14 +146,15 @@
         // we now must remove those with smaller than the largest version number
         // for each name that were found before the largest
         while (iter.hasPrevious()) {
-            String entry = ((String)iter.previous()).trim();
+            String entry = iter.previous().trim();
             MatchResult result = null;
-            if (_preparse_matcher_.matches(entry, _preparse_pattern_)) {
-                result = _preparse_matcher_.getMatch();
+            _preparse_matcher_ = _preparse_pattern_.matcher(entry);
+            if (_preparse_matcher_.matches()) {
+                result = _preparse_matcher_.toMatchResult();
                 String name = result.group(1);
                 String version = result.group(2);
                 NameVersion nv = new NameVersion(name, version);
-                NameVersion existing = (NameVersion) existingEntries.get(name);
+                NameVersion existing = existingEntries.get(name);
                 if (null != existing) {
                     if (nv.versionNumber < existing.versionNumber) {
                         iter.remove(); // removal removes from original list.
@@ -163,6 +166,8 @@
         return original;
     }
 
+
+    @Override
     protected boolean isVersioning() {
         return true;
     }
diff --git a/src/java/org/apache/commons/net/io/CopyStreamAdapter.java b/src/main/java/org/apache/commons/net/io/CopyStreamAdapter.java
similarity index 93%
rename from src/java/org/apache/commons/net/io/CopyStreamAdapter.java
rename to src/main/java/org/apache/commons/net/io/CopyStreamAdapter.java
index ed8d685..09df51c 100644
--- a/src/java/org/apache/commons/net/io/CopyStreamAdapter.java
+++ b/src/main/java/org/apache/commons/net/io/CopyStreamAdapter.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,9 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.io;
 
-import java.util.Enumeration;
+import java.util.EventListener;
+
 import org.apache.commons.net.util.ListenerList;
 
 /**
@@ -84,20 +86,16 @@
     public void bytesTransferred(long totalBytesTransferred,
                                  int bytesTransferred, long streamSize)
     {
-        Enumeration listeners;
         CopyStreamEvent event;
 
-        listeners = internalListeners.getListeners();
-
         event = new CopyStreamEvent(this,
                                     totalBytesTransferred,
                                     bytesTransferred,
                                     streamSize);
 
-        while (listeners.hasMoreElements())
+        for (EventListener listener : internalListeners)
         {
-            ((CopyStreamListener) (listeners.nextElement())).
-                bytesTransferred(event);
+            ((CopyStreamListener) (listener)).bytesTransferred(event);
         }
     }
 
diff --git a/src/java/org/apache/commons/net/io/CopyStreamEvent.java b/src/main/java/org/apache/commons/net/io/CopyStreamEvent.java
similarity index 98%
rename from src/java/org/apache/commons/net/io/CopyStreamEvent.java
rename to src/main/java/org/apache/commons/net/io/CopyStreamEvent.java
index d7a9288..1d750dd 100644
--- a/src/java/org/apache/commons/net/io/CopyStreamEvent.java
+++ b/src/main/java/org/apache/commons/net/io/CopyStreamEvent.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.io;
 
 import java.util.EventObject;
diff --git a/src/java/org/apache/commons/net/io/CopyStreamException.java b/src/main/java/org/apache/commons/net/io/CopyStreamException.java
similarity index 97%
rename from src/java/org/apache/commons/net/io/CopyStreamException.java
rename to src/main/java/org/apache/commons/net/io/CopyStreamException.java
index 9aed14f..49ef6c3 100644
--- a/src/java/org/apache/commons/net/io/CopyStreamException.java
+++ b/src/main/java/org/apache/commons/net/io/CopyStreamException.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.io;
 
 import java.io.IOException;
diff --git a/src/java/org/apache/commons/net/io/CopyStreamListener.java b/src/main/java/org/apache/commons/net/io/CopyStreamListener.java
similarity index 98%
rename from src/java/org/apache/commons/net/io/CopyStreamListener.java
rename to src/main/java/org/apache/commons/net/io/CopyStreamListener.java
index dd050f7..b2c4122 100644
--- a/src/java/org/apache/commons/net/io/CopyStreamListener.java
+++ b/src/main/java/org/apache/commons/net/io/CopyStreamListener.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.io;
 
 import java.util.EventListener;
diff --git a/src/java/org/apache/commons/net/io/DotTerminatedMessageReader.java b/src/main/java/org/apache/commons/net/io/DotTerminatedMessageReader.java
similarity index 98%
rename from src/java/org/apache/commons/net/io/DotTerminatedMessageReader.java
rename to src/main/java/org/apache/commons/net/io/DotTerminatedMessageReader.java
index 5d877fa..4d25e77 100644
--- a/src/java/org/apache/commons/net/io/DotTerminatedMessageReader.java
+++ b/src/main/java/org/apache/commons/net/io/DotTerminatedMessageReader.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.io;
 
 import java.io.IOException;
@@ -80,6 +81,7 @@
      * @exception IOException If an error occurs while reading the underlying
      *            stream.
      */
+    @Override
     public int read() throws IOException
     {
         int ch;
@@ -177,6 +179,7 @@
      * @exception IOException If an error occurs in reading the underlying
      *            stream.
      */
+    @Override
     public int read(char[] buffer) throws IOException
     {
         return read(buffer, 0, buffer.length);
@@ -196,6 +199,7 @@
      * @exception IOException If an error occurs in reading the underlying
      *            stream.
      */
+    @Override
     public int read(char[] buffer, int offset, int length) throws IOException
     {
         int ch, off;
@@ -227,6 +231,7 @@
      * @exception IOException If an error occurs while checking the underlying
      *            stream.
      */
+    @Override
     public boolean ready() throws IOException
     {
         synchronized (lock)
@@ -249,6 +254,7 @@
      * @exception IOException  If an error occurs while reading the
      *            underlying stream.
      */
+    @Override
     public void close() throws IOException
     {
         synchronized (lock)
diff --git a/src/java/org/apache/commons/net/io/DotTerminatedMessageWriter.java b/src/main/java/org/apache/commons/net/io/DotTerminatedMessageWriter.java
similarity index 97%
rename from src/java/org/apache/commons/net/io/DotTerminatedMessageWriter.java
rename to src/main/java/org/apache/commons/net/io/DotTerminatedMessageWriter.java
index 17b430c..a696443 100644
--- a/src/java/org/apache/commons/net/io/DotTerminatedMessageWriter.java
+++ b/src/main/java/org/apache/commons/net/io/DotTerminatedMessageWriter.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.io;
 
 import java.io.IOException;
@@ -71,6 +72,7 @@
      * @exception IOException  If an error occurs while writing to the
      *            underlying output.
      ***/
+    @Override
     public void write(int ch) throws IOException
     {
         synchronized (lock)
@@ -111,6 +113,7 @@
      * @exception IOException If an error occurs while writing to the underlying
      *            output.
      ***/
+    @Override
     public void write(char[] buffer, int offset, int length) throws IOException
     {
         synchronized (lock)
@@ -128,6 +131,7 @@
      * @exception IOException If an error occurs while writing to the underlying
      *            output.
      ***/
+    @Override
     public void write(char[] buffer) throws IOException
     {
         write(buffer, 0, buffer.length);
@@ -141,6 +145,7 @@
      * @exception IOException If an error occurs while writing to the underlying
      *            output.
      ***/
+    @Override
     public void write(String string) throws IOException
     {
         write(string.toCharArray());
@@ -156,6 +161,7 @@
      * @exception IOException If an error occurs while writing to the underlying
      *            output.
      ***/
+    @Override
     public void write(String string, int offset, int length) throws IOException
     {
         write(string.toCharArray(), offset, length);
@@ -168,6 +174,7 @@
      * @exception IOException If an error occurs while writing to the underlying
      *            output.
      ***/
+    @Override
     public void flush() throws IOException
     {
         synchronized (lock)
@@ -185,6 +192,7 @@
      * @exception IOException If an error occurs while writing to the underlying
      *            output or closing the Writer.
      ***/
+    @Override
     public void close() throws IOException
     {
         synchronized (lock)
diff --git a/src/java/org/apache/commons/net/io/FromNetASCIIInputStream.java b/src/main/java/org/apache/commons/net/io/FromNetASCIIInputStream.java
similarity index 98%
rename from src/java/org/apache/commons/net/io/FromNetASCIIInputStream.java
rename to src/main/java/org/apache/commons/net/io/FromNetASCIIInputStream.java
index 844735a..fd3fd0e 100644
--- a/src/java/org/apache/commons/net/io/FromNetASCIIInputStream.java
+++ b/src/main/java/org/apache/commons/net/io/FromNetASCIIInputStream.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.io;
 
 import java.io.IOException;
@@ -110,6 +111,7 @@
      * @exception IOException If an error occurs while reading the underlying
      *            stream.
      ***/
+    @Override
     public int read() throws IOException
     {
         if (_noConversionRequired)
@@ -130,6 +132,7 @@
      * @exception IOException If an error occurs in reading the underlying
      *            stream.
      ***/
+    @Override
     public int read(byte buffer[]) throws IOException
     {
         return read(buffer, 0, buffer.length);
@@ -150,6 +153,7 @@
      * @exception IOException If an error occurs while reading the underlying
      *            stream.
      ***/
+    @Override
     public int read(byte buffer[], int offset, int length) throws IOException
     {
         int ch, off;
@@ -192,6 +196,7 @@
      * rely on the value returned by this method if you are trying to avoid
      * blocking.
      ***/
+    @Override
     public int available() throws IOException
     {
         return (buf.length - pos) + in.available();
diff --git a/src/java/org/apache/commons/net/io/FromNetASCIIOutputStream.java b/src/main/java/org/apache/commons/net/io/FromNetASCIIOutputStream.java
similarity index 97%
rename from src/java/org/apache/commons/net/io/FromNetASCIIOutputStream.java
rename to src/main/java/org/apache/commons/net/io/FromNetASCIIOutputStream.java
index ecf4a50..00f0b90 100644
--- a/src/java/org/apache/commons/net/io/FromNetASCIIOutputStream.java
+++ b/src/main/java/org/apache/commons/net/io/FromNetASCIIOutputStream.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.io;
 
 import java.io.FilterOutputStream;
@@ -95,6 +96,7 @@
      * @exception IOException If an error occurs while writing to the underlying
      *            stream.
      ***/
+    @Override
     public synchronized void write(int ch)
     throws IOException
     {
@@ -115,6 +117,7 @@
      * @exception IOException If an error occurs while writing to the underlying
      *            stream.
      ***/
+    @Override
     public synchronized void write(byte buffer[])
     throws IOException
     {
@@ -132,6 +135,7 @@
      * @exception IOException If an error occurs while writing to the underlying
      *            stream.
      ***/
+    @Override
     public synchronized void write(byte buffer[], int offset, int length)
     throws IOException
     {
@@ -153,6 +157,7 @@
      * <p>
      * @exception IOException  If an error occurs while closing the stream.
      ***/
+    @Override
     public synchronized void close()
     throws IOException
     {
diff --git a/src/java/org/apache/commons/net/io/SocketInputStream.java b/src/main/java/org/apache/commons/net/io/SocketInputStream.java
similarity index 96%
rename from src/java/org/apache/commons/net/io/SocketInputStream.java
rename to src/main/java/org/apache/commons/net/io/SocketInputStream.java
index d4bb23b..42602f3 100644
--- a/src/java/org/apache/commons/net/io/SocketInputStream.java
+++ b/src/main/java/org/apache/commons/net/io/SocketInputStream.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.io;
 
 import java.io.FilterInputStream;
@@ -59,6 +60,7 @@
      * @exception IOException  If there is an error in closing the stream
      *                         or socket.
      ***/
+    @Override
     public void close() throws IOException
     {
         super.close();
diff --git a/src/java/org/apache/commons/net/io/SocketOutputStream.java b/src/main/java/org/apache/commons/net/io/SocketOutputStream.java
similarity index 97%
rename from src/java/org/apache/commons/net/io/SocketOutputStream.java
rename to src/main/java/org/apache/commons/net/io/SocketOutputStream.java
index c2b8dda..7a13811 100644
--- a/src/java/org/apache/commons/net/io/SocketOutputStream.java
+++ b/src/main/java/org/apache/commons/net/io/SocketOutputStream.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.io;
 
 import java.io.FilterOutputStream;
@@ -65,6 +66,7 @@
      * @exception IOException If an error occurs while writing to the underlying
      *            stream.
      ***/
+    @Override
     public void write(byte buffer[], int offset, int length) throws IOException
     {
         out.write(buffer, offset, length);
@@ -78,6 +80,7 @@
      * @exception IOException  If there is an error in closing the stream
      *                         or socket.
      ***/
+    @Override
     public void close() throws IOException
     {
         super.close();
diff --git a/src/java/org/apache/commons/net/io/ToNetASCIIInputStream.java b/src/main/java/org/apache/commons/net/io/ToNetASCIIInputStream.java
similarity index 97%
rename from src/java/org/apache/commons/net/io/ToNetASCIIInputStream.java
rename to src/main/java/org/apache/commons/net/io/ToNetASCIIInputStream.java
index 7181219..8552b7a 100644
--- a/src/java/org/apache/commons/net/io/ToNetASCIIInputStream.java
+++ b/src/main/java/org/apache/commons/net/io/ToNetASCIIInputStream.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.io;
 
 import java.io.FilterInputStream;
@@ -61,6 +62,7 @@
      * @exception IOException If an error occurs while reading the underlying
      *            stream.
      ***/
+    @Override
     public int read() throws IOException
     {
         int ch;
@@ -105,6 +107,7 @@
      * @exception IOException If an error occurs in reading the underlying
      *            stream.
      ***/
+    @Override
     public int read(byte buffer[]) throws IOException
     {
         return read(buffer, 0, buffer.length);
@@ -125,6 +128,7 @@
      * @exception IOException If an error occurs while reading the underlying
      *            stream.
      ***/
+    @Override
     public int read(byte buffer[], int offset, int length) throws IOException
     {
         int ch, off;
@@ -156,11 +160,13 @@
     }
 
     /*** Returns false.  Mark is not supported. ***/
+    @Override
     public boolean markSupported()
     {
         return false;
     }
 
+    @Override
     public int available() throws IOException
     {
         int result;
diff --git a/src/java/org/apache/commons/net/io/ToNetASCIIOutputStream.java b/src/main/java/org/apache/commons/net/io/ToNetASCIIOutputStream.java
similarity index 97%
rename from src/java/org/apache/commons/net/io/ToNetASCIIOutputStream.java
rename to src/main/java/org/apache/commons/net/io/ToNetASCIIOutputStream.java
index 2740c21..1337803 100644
--- a/src/java/org/apache/commons/net/io/ToNetASCIIOutputStream.java
+++ b/src/main/java/org/apache/commons/net/io/ToNetASCIIOutputStream.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.io;
 
 import java.io.FilterOutputStream;
@@ -60,6 +61,7 @@
      * @exception IOException If an error occurs while writing to the underlying
      *            stream.
      ***/
+    @Override
     public synchronized void write(int ch)
     throws IOException
     {
@@ -88,6 +90,7 @@
      * @exception IOException If an error occurs while writing to the underlying
      *            stream.
      ***/
+    @Override
     public synchronized void write(byte buffer[])
     throws IOException
     {
@@ -105,6 +108,7 @@
      * @exception IOException If an error occurs while writing to the underlying
      *            stream.
      ***/
+    @Override
     public synchronized void write(byte buffer[], int offset, int length)
     throws IOException
     {
diff --git a/src/java/org/apache/commons/net/io/Util.java b/src/main/java/org/apache/commons/net/io/Util.java
similarity index 99%
rename from src/java/org/apache/commons/net/io/Util.java
rename to src/main/java/org/apache/commons/net/io/Util.java
index 42e4098..3d14183 100644
--- a/src/java/org/apache/commons/net/io/Util.java
+++ b/src/main/java/org/apache/commons/net/io/Util.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.io;
 
 import java.io.IOException;
diff --git a/src/java/org/apache/commons/net/nntp/Article.java b/src/main/java/org/apache/commons/net/nntp/Article.java
similarity index 97%
rename from src/java/org/apache/commons/net/nntp/Article.java
rename to src/main/java/org/apache/commons/net/nntp/Article.java
index e65865a..1bf3c02 100644
--- a/src/java/org/apache/commons/net/nntp/Article.java
+++ b/src/main/java/org/apache/commons/net/nntp/Article.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
- 
+
 package org.apache.commons.net.nntp;
 
 import java.util.ArrayList;
@@ -75,14 +75,14 @@
     public String[] getReferences() {
         if (references == null)
             return new String[0];
-        ArrayList list = new ArrayList();
+        ArrayList<String> list = new ArrayList<String>();
         int terminator = references.toString().indexOf(':');
         StringTokenizer st =
             new StringTokenizer(references.substring(terminator), "\t");
         while (st.hasMoreTokens()) {
             list.add(st.nextToken());
         }
-        return (String[]) list.toArray(new String[list.size()]);
+        return list.toArray(new String[list.size()]);
     }
     
     /**
@@ -117,7 +117,7 @@
                         start < (len - 2) 
                         && 
                         (subject.charAt(start + 2) == '[' || subject.charAt(start + 2) == '(')) {
-
+                        
                         int i = start + 3;
 
                         while (i < len && subject.charAt(i) >= '0' && subject.charAt(i) <= '9')
diff --git a/src/java/org/apache/commons/net/nntp/ArticlePointer.java b/src/main/java/org/apache/commons/net/nntp/ArticlePointer.java
similarity index 94%
rename from src/java/org/apache/commons/net/nntp/ArticlePointer.java
rename to src/main/java/org/apache/commons/net/nntp/ArticlePointer.java
index b114ee8..f4b89f7 100644
--- a/src/java/org/apache/commons/net/nntp/ArticlePointer.java
+++ b/src/main/java/org/apache/commons/net/nntp/ArticlePointer.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.nntp;
 
 /**
@@ -27,7 +28,7 @@
 public final class ArticlePointer
 {
     /** The number of the referenced article. */
-    public int articleNumber;
+    public long articleNumber;
     /**
      * The unique id of the referenced article, including the enclosing
      * &lt and &gt symbols which are technically not part of the
diff --git a/src/java/org/apache/commons/net/nntp/NNTP.java b/src/main/java/org/apache/commons/net/nntp/NNTP.java
similarity index 99%
rename from src/java/org/apache/commons/net/nntp/NNTP.java
rename to src/main/java/org/apache/commons/net/nntp/NNTP.java
index 4650f07..100461a 100644
--- a/src/java/org/apache/commons/net/nntp/NNTP.java
+++ b/src/main/java/org/apache/commons/net/nntp/NNTP.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.nntp;
 
 import java.io.BufferedReader;
@@ -21,9 +22,10 @@
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
+
 import org.apache.commons.net.MalformedServerReplyException;
-import org.apache.commons.net.ProtocolCommandSupport;
 import org.apache.commons.net.ProtocolCommandListener;
+import org.apache.commons.net.ProtocolCommandSupport;
 import org.apache.commons.net.SocketClient;
 
 /***
@@ -169,6 +171,7 @@
      * {@link #_reader_} and {@link #_writer_} to wrap
      * {@link SocketClient#_input_} and {@link SocketClient#_output_}.
      ***/
+    @Override
     protected void _connectAction_() throws IOException
     {
         super._connectAction_();
@@ -213,6 +216,7 @@
      * <p>
      * @exception IOException If an error occurs while disconnecting.
      ***/
+    @Override
     public void disconnect() throws IOException
     {
         super.disconnect();
diff --git a/src/java/org/apache/commons/net/nntp/NNTPClient.java b/src/main/java/org/apache/commons/net/nntp/NNTPClient.java
similarity index 98%
rename from src/java/org/apache/commons/net/nntp/NNTPClient.java
rename to src/main/java/org/apache/commons/net/nntp/NNTPClient.java
index b1e2f21..2e7a815 100644
--- a/src/java/org/apache/commons/net/nntp/NNTPClient.java
+++ b/src/main/java/org/apache/commons/net/nntp/NNTPClient.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.nntp;
 
 import java.io.BufferedReader;
@@ -23,10 +24,11 @@
 import java.io.Writer;
 import java.util.StringTokenizer;
 import java.util.Vector;
+
+import org.apache.commons.net.MalformedServerReplyException;
 import org.apache.commons.net.io.DotTerminatedMessageReader;
 import org.apache.commons.net.io.DotTerminatedMessageWriter;
 import org.apache.commons.net.io.Util;
-import org.apache.commons.net.MalformedServerReplyException;
 
 /***
  * NNTPClient encapsulates all the functionality necessary to post and
@@ -106,7 +108,7 @@
             // Get article number
             try
             {
-                pointer.articleNumber = Integer.parseInt(tokenizer.nextToken());
+                pointer.articleNumber = Long.parseLong(tokenizer.nextToken());
             }
             catch (NumberFormatException e)
             {
@@ -151,9 +153,9 @@
 
             try
             {
-                info._setArticleCount(Integer.parseInt(count));
-                info._setFirstArticle(Integer.parseInt(first));
-                info._setLastArticle(Integer.parseInt(last));
+                info._setArticleCount(Long.parseLong(count));
+                info._setFirstArticle(Long.parseLong(first));
+                info._setLastArticle(Long.parseLong(last));
             }
             catch (NumberFormatException e)
             {
@@ -174,7 +176,7 @@
     {
         NewsgroupInfo result;
         StringTokenizer tokenizer;
-        int lastNum, firstNum;
+        long lastNum, firstNum;
         String last, first, permission;
 
         result = new NewsgroupInfo();
@@ -190,8 +192,8 @@
 
         try
         {
-            lastNum = Integer.parseInt(last);
-            firstNum = Integer.parseInt(first);
+            lastNum = Long.parseLong(last);
+            firstNum = Long.parseLong(first);
             result._setFirstArticle(firstNum);
             result._setLastArticle(lastNum);
 
@@ -235,14 +237,14 @@
     {
         int size;
         String line;
-        Vector list;
+        Vector<NewsgroupInfo> list;
         BufferedReader reader;
         NewsgroupInfo tmp, info[];
 
         reader = new BufferedReader(new DotTerminatedMessageReader(_reader_));
         // Start of with a big vector because we may be reading a very large
         // amount of groups.
-        list = new Vector(2048);
+        list = new Vector<NewsgroupInfo>(2048);
 
         while ((line = reader.readLine()) != null)
         {
@@ -1007,7 +1009,7 @@
     {
         int size;
         String line;
-        Vector list;
+        Vector<String> list;
         String[] result;
         BufferedReader reader;
 
@@ -1016,7 +1018,7 @@
                                                 query.isGMT(), query.getDistributions())))
             return null;
 
-        list = new Vector();
+        list = new Vector<String>();
         reader = new BufferedReader(new DotTerminatedMessageReader(_reader_));
 
         while ((line = reader.readLine()) != null)
@@ -1210,12 +1212,13 @@
      * @return a DotTerminatedReader if successful, null otherwise
      * @throws IOException
      */
-    public Reader retrieveArticleInfo(int lowArticleNumber,
-                                      int highArticleNumber)
+    public Reader retrieveArticleInfo(long lowArticleNumber,
+                                      long highArticleNumber)
         throws IOException
     {
         return
-            __retrieveArticleInfo(lowArticleNumber + "-" + highArticleNumber);
+            __retrieveArticleInfo(lowArticleNumber + "-" +
+                                             highArticleNumber);
     }
 
     /***
diff --git a/src/java/org/apache/commons/net/nntp/NNTPCommand.java b/src/main/java/org/apache/commons/net/nntp/NNTPCommand.java
similarity index 97%
rename from src/java/org/apache/commons/net/nntp/NNTPCommand.java
rename to src/main/java/org/apache/commons/net/nntp/NNTPCommand.java
index 1b43eef..3e08fc1 100644
--- a/src/java/org/apache/commons/net/nntp/NNTPCommand.java
+++ b/src/main/java/org/apache/commons/net/nntp/NNTPCommand.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.nntp;
 
 /***
diff --git a/src/java/org/apache/commons/net/nntp/NNTPConnectionClosedException.java b/src/main/java/org/apache/commons/net/nntp/NNTPConnectionClosedException.java
similarity index 97%
rename from src/java/org/apache/commons/net/nntp/NNTPConnectionClosedException.java
rename to src/main/java/org/apache/commons/net/nntp/NNTPConnectionClosedException.java
index aba6f9a..1c3e4fb 100644
--- a/src/java/org/apache/commons/net/nntp/NNTPConnectionClosedException.java
+++ b/src/main/java/org/apache/commons/net/nntp/NNTPConnectionClosedException.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.nntp;
 
 import java.io.IOException;
diff --git a/src/java/org/apache/commons/net/nntp/NNTPReply.java b/src/main/java/org/apache/commons/net/nntp/NNTPReply.java
similarity index 98%
rename from src/java/org/apache/commons/net/nntp/NNTPReply.java
rename to src/main/java/org/apache/commons/net/nntp/NNTPReply.java
index 16d7f2c..4d81f1a 100644
--- a/src/java/org/apache/commons/net/nntp/NNTPReply.java
+++ b/src/main/java/org/apache/commons/net/nntp/NNTPReply.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.nntp;
 
 /***
@@ -52,7 +53,6 @@
     public static final int CODE_340 = 340;
     public static final int CODE_381 = 381;
     public static final int CODE_400 = 400;
-    public static final int CODE_408 = 408;
     public static final int CODE_411 = 411;
     public static final int CODE_412 = 412;
     public static final int CODE_420 = 420;
@@ -65,6 +65,7 @@
     public static final int CODE_437 = 437;
     public static final int CODE_440 = 440;
     public static final int CODE_441 = 441;
+    public static final int CODE_480 = 480;
     public static final int CODE_482 = 482;
     public static final int CODE_500 = 500;
     public static final int CODE_501 = 501;
@@ -93,7 +94,6 @@
     public static final int MORE_AUTH_INFO_REQUIRED            = CODE_381;
     public static final int SERVICE_DISCONTINUED               = CODE_400;
     public static final int NO_SUCH_NEWSGROUP                  = CODE_411;
-    public static final int AUTHENTICATION_REQUIRED            = CODE_408;
     public static final int NO_NEWSGROUP_SELECTED              = CODE_412;
     public static final int NO_CURRENT_ARTICLE_SELECTED        = CODE_420;
     public static final int NO_NEXT_ARTICLE                    = CODE_421;
@@ -105,6 +105,7 @@
     public static final int ARTICLE_REJECTED                   = CODE_437;
     public static final int POSTING_NOT_ALLOWED                = CODE_440;
     public static final int POSTING_FAILED                     = CODE_441;
+    public static final int AUTHENTICATION_REQUIRED            = CODE_480;
     public static final int AUTHENTICATION_REJECTED            = CODE_482;
     public static final int COMMAND_NOT_RECOGNIZED             = CODE_500;
     public static final int COMMAND_SYNTAX_ERROR               = CODE_501;
diff --git a/src/java/org/apache/commons/net/nntp/NewGroupsOrNewsQuery.java b/src/main/java/org/apache/commons/net/nntp/NewGroupsOrNewsQuery.java
similarity index 99%
rename from src/java/org/apache/commons/net/nntp/NewGroupsOrNewsQuery.java
rename to src/main/java/org/apache/commons/net/nntp/NewGroupsOrNewsQuery.java
index ade387c..1784417 100644
--- a/src/java/org/apache/commons/net/nntp/NewGroupsOrNewsQuery.java
+++ b/src/main/java/org/apache/commons/net/nntp/NewGroupsOrNewsQuery.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.nntp;
 
 import java.util.Calendar;
diff --git a/src/java/org/apache/commons/net/nntp/NewsgroupInfo.java b/src/main/java/org/apache/commons/net/nntp/NewsgroupInfo.java
similarity index 91%
rename from src/java/org/apache/commons/net/nntp/NewsgroupInfo.java
rename to src/main/java/org/apache/commons/net/nntp/NewsgroupInfo.java
index b109006..d945a22 100644
--- a/src/java/org/apache/commons/net/nntp/NewsgroupInfo.java
+++ b/src/main/java/org/apache/commons/net/nntp/NewsgroupInfo.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.nntp;
 
 /***
@@ -53,8 +54,8 @@
     public static final int PROHIBITED_POSTING_PERMISSION = 3;
 
     private String __newsgroup;
-    private int __estimatedArticleCount;
-    private int __firstArticle, __lastArticle;
+    private long __estimatedArticleCount;
+    private long __firstArticle, __lastArticle;
     private int __postingPermission;
 
     void _setNewsgroup(String newsgroup)
@@ -62,17 +63,17 @@
         __newsgroup = newsgroup;
     }
 
-    void _setArticleCount(int count)
+    void _setArticleCount(long count)
     {
         __estimatedArticleCount = count;
     }
 
-    void _setFirstArticle(int first)
+    void _setFirstArticle(long first)
     {
         __firstArticle = first;
     }
 
-    void _setLastArticle(int last)
+    void _setLastArticle(long last)
     {
         __lastArticle = last;
     }
@@ -98,7 +99,7 @@
      * <p>
      * @return The estimated number of articles in the newsgroup.
      ***/
-    public int getArticleCount()
+    public long getArticleCount()
     {
         return __estimatedArticleCount;
     }
@@ -108,7 +109,7 @@
      * <p>
      * @return The number of the first article in the newsgroup.
      ***/
-    public int getFirstArticle()
+    public long getFirstArticle()
     {
         return __firstArticle;
     }
@@ -118,7 +119,7 @@
      * <p>
      * @return The number of the last article in the newsgroup.
      ***/
-    public int getLastArticle()
+    public long getLastArticle()
     {
         return __lastArticle;
     }
diff --git a/src/java/org/apache/commons/net/nntp/SimpleNNTPHeader.java b/src/main/java/org/apache/commons/net/nntp/SimpleNNTPHeader.java
similarity index 95%
rename from src/java/org/apache/commons/net/nntp/SimpleNNTPHeader.java
rename to src/main/java/org/apache/commons/net/nntp/SimpleNNTPHeader.java
index 15073f3..337e975 100644
--- a/src/java/org/apache/commons/net/nntp/SimpleNNTPHeader.java
+++ b/src/main/java/org/apache/commons/net/nntp/SimpleNNTPHeader.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.nntp;
 
 /***
@@ -48,8 +49,8 @@
 public class SimpleNNTPHeader
 {
     private String __subject, __from;
-    private StringBuffer __newsgroups;
-    private StringBuffer __headerFields;
+    private StringBuilder __newsgroups;
+    private StringBuilder __headerFields;
     private int __newsgroupCount;
 
     /***
@@ -65,8 +66,8 @@
     {
         __from = from;
         __subject = subject;
-        __newsgroups = new StringBuffer();
-        __headerFields = new StringBuffer();
+        __newsgroups = new StringBuilder();
+        __headerFields = new StringBuilder();
         __newsgroupCount = 0;
     }
 
@@ -142,6 +143,7 @@
      * <p>
      * @return The article header in the form of a String.
      ***/
+    @Override
     public String toString()
     {
         StringBuffer header = new StringBuffer();
diff --git a/src/main/java/org/apache/commons/net/nntp/ThreadContainer.java b/src/main/java/org/apache/commons/net/nntp/ThreadContainer.java
new file mode 100644
index 0000000..3bda779
--- /dev/null
+++ b/src/main/java/org/apache/commons/net/nntp/ThreadContainer.java
@@ -0,0 +1,82 @@
+package org.apache.commons.net.nntp;
+
+/**
+ * A placeholder utility class, used for constructing a tree of Threadables
+ * Original implementation by Jamie Zawinski. 
+ * See the Grendel source for more details <a href="http://lxr.mozilla.org/mozilla/source/grendel/sources/grendel/view/Threader.java#511">here</a>
+ * Threadable objects
+ * @author Rory Winston <rwinston@apache.org>
+ */
+class ThreadContainer {
+    Threadable threadable;
+    ThreadContainer parent;
+    ThreadContainer prev;
+    ThreadContainer next;
+    ThreadContainer child;
+
+    /**
+     * 
+     * @param container
+     * @return true if child is under self's tree. Detects circular references
+     */
+    boolean findChild(ThreadContainer target) {
+        if (child == null)
+            return false;
+
+        else if (child == target)
+            return true;
+        else
+            return child.findChild(target);
+    }
+
+    // Copy the ThreadContainer tree structure down into the underlying Threadable objects
+    // (Make the Threadable tree look like the ThreadContainer tree)
+    // TODO convert this to an iterative function - this can blow the stack 
+    // with very large Threadable trees
+    void flush() {
+        if (parent != null && threadable == null)
+            throw new RuntimeException("no threadable in " + this.toString());
+
+        parent = null;
+
+        if (threadable != null)
+            threadable.setChild(child == null ? null : child.threadable);
+
+        if (child != null) {
+            child.flush();
+            child = null;
+        }
+
+        if (threadable != null)
+            threadable.setNext(next == null ? null : next.threadable);
+
+        if (next != null) {
+            next.flush();
+            next = null;
+        }
+
+        threadable = null;
+    }
+
+    /**
+     * Reverse the entire set of children
+     *
+     */
+    void reverseChildren() {
+        if (child != null) {
+            ThreadContainer kid, prev, rest;
+            for (prev = null, kid = child, rest = kid.next;
+                kid != null;
+                prev = kid,
+                    kid = rest,
+                    rest = (rest == null ? null : rest.next))
+                kid.next = prev;
+
+            child = prev;
+
+            // Do it for the kids 
+            for (kid = child; kid != null; kid = kid.next)
+                kid.reverseChildren();
+        }
+    }
+}
diff --git a/src/java/org/apache/commons/net/nntp/Threadable.java b/src/main/java/org/apache/commons/net/nntp/Threadable.java
similarity index 95%
rename from src/java/org/apache/commons/net/nntp/Threadable.java
rename to src/main/java/org/apache/commons/net/nntp/Threadable.java
index b8e3b6b..fb8be3e 100644
--- a/src/java/org/apache/commons/net/nntp/Threadable.java
+++ b/src/main/java/org/apache/commons/net/nntp/Threadable.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.nntp; 
 
 /**
@@ -30,4 +31,4 @@
     public void setChild(Threadable child); 
     public void setNext(Threadable next);
     public Threadable makeDummy();
-}
\ No newline at end of file
+}
diff --git a/src/java/org/apache/commons/net/nntp/Threader.java b/src/main/java/org/apache/commons/net/nntp/Threader.java
similarity index 82%
rename from src/java/org/apache/commons/net/nntp/Threader.java
rename to src/main/java/org/apache/commons/net/nntp/Threader.java
index 0787b0e..f5076b6 100644
--- a/src/java/org/apache/commons/net/nntp/Threader.java
+++ b/src/main/java/org/apache/commons/net/nntp/Threader.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 
+
 package org.apache.commons.net.nntp;
 
 /**
@@ -28,10 +29,11 @@
 
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
 
 public class Threader {
     private ThreadContainer root;
-    private HashMap idTable;
+    private HashMap<String,ThreadContainer> idTable;
     private int bogusIdCount = 0;
 
     /**
@@ -40,16 +42,16 @@
      * @param messages
      * @return null if messages == null or root.child == null
      */
-    public Threadable thread(Threadable[] messages) {
+    public Threadable thread(List<? extends Threadable> messages) {
         if (messages == null)
             return null;
 
-        idTable = new HashMap();
+        idTable = new HashMap<String,ThreadContainer>();
 
-        // walk through each Threadable element
-        for (int i = 0; i < messages.length; ++i) {
-            if (!messages[i].isDummy())
-                buildContainer(messages[i]);
+        // walk through each Threadable element    
+        for (Threadable t : messages) {
+        	if (!t.isDummy())
+        		buildContainer(t);
         }
 
         root = findRootSet();
@@ -82,7 +84,7 @@
      */
     private void buildContainer(Threadable threadable) {
         String id = threadable.messageThreadId();
-        ThreadContainer container = (ThreadContainer) idTable.get(id);
+        ThreadContainer container = idTable.get(id);
 
         // A ThreadContainer exists for this id already. This should be a forward reference, but may 
         // be a duplicate id, in which case we will need to generate a bogus placeholder id
@@ -111,7 +113,7 @@
             String[] references = threadable.messageThreadReferences();
             for (int i = 0; i < references.length; ++i) {
                 String refString = references[i];
-                ThreadContainer ref = (ThreadContainer) idTable.get(refString);
+                ThreadContainer ref = idTable.get(refString);
 
                 // if this id doesnt have a container, create one
                 if (ref == null) {
@@ -186,11 +188,11 @@
      */
     private ThreadContainer findRootSet() {
         ThreadContainer root = new ThreadContainer();
-        Iterator iter = idTable.keySet().iterator();
+        Iterator<String> iter = idTable.keySet().iterator();
 
         while (iter.hasNext()) {
             Object key = iter.next();
-            ThreadContainer c = (ThreadContainer) idTable.get(key);
+            ThreadContainer c = idTable.get(key);
             if (c.parent == null) {
                 if (c.next != null)
                     throw new RuntimeException(
@@ -274,7 +276,7 @@
             count++;
 
         // TODO verify this will avoid rehashing
-        HashMap subjectTable = new HashMap((int) (count * 1.2), (float) 0.9);
+        HashMap<String, ThreadContainer> subjectTable = new HashMap<String, ThreadContainer>((int) (count * 1.2), (float) 0.9);
         count = 0;
 
         for (ThreadContainer c = root.child; c != null; c = c.next) {
@@ -291,7 +293,7 @@
             if (subj == null || subj == "")
                 continue;
 
-            ThreadContainer old = (ThreadContainer) subjectTable.get(subj);
+            ThreadContainer old = subjectTable.get(subj);
 
             // Add this container to the table iff:
             // - There exists no container with this subject
@@ -333,7 +335,7 @@
             if (subj == null || subj == "")
                 continue;
 
-            ThreadContainer old = (ThreadContainer) subjectTable.get(subj);
+            ThreadContainer old = subjectTable.get(subj);
 
             if (old == c) // That's us
                 continue;
@@ -399,82 +401,3 @@
 
     }
 }
-
-/**
- * A placeholder utility class, used for constructing a tree of Threadables
- * Originall implementation by Jamie Zawinski. 
- * See the Grendel source for more details <a href="http://lxr.mozilla.org/mozilla/source/grendel/sources/grendel/view/Threader.java#511">here</a>
- * Threadable objects
- * @author Rory Winston <rwinston@checkfree.com>
- */
-class ThreadContainer {
-    Threadable threadable;
-    ThreadContainer parent;
-    ThreadContainer prev;
-    ThreadContainer next;
-    ThreadContainer child;
-
-    /**
-     * 
-     * @param container
-     * @return true if child is under self's tree. Detects circular references
-     */
-    boolean findChild(ThreadContainer target) {
-        if (child == null)
-            return false;
-
-        else if (child == target)
-            return true;
-        else
-            return child.findChild(target);
-    }
-
-    // Copy the ThreadContainer tree structure down into the underlying Threadable objects
-    // (Make the Threadable tree look like the ThreadContainer tree)
-    void flush() {
-        if (parent != null && threadable == null)
-            throw new RuntimeException("no threadable in " + this.toString());
-
-        parent = null;
-
-        if (threadable != null)
-            threadable.setChild(child == null ? null : child.threadable);
-
-        if (child != null) {
-            child.flush();
-            child = null;
-        }
-
-        if (threadable != null)
-            threadable.setNext(next == null ? null : next.threadable);
-
-        if (next != null) {
-            next.flush();
-            next = null;
-        }
-
-        threadable = null;
-    }
-
-    /**
-     * Reverse the entire set of children
-     *
-     */
-    void reverseChildren() {
-        if (child != null) {
-            ThreadContainer kid, prev, rest;
-            for (prev = null, kid = child, rest = kid.next;
-                kid != null;
-                prev = kid,
-                    kid = rest,
-                    rest = (rest == null ? null : rest.next))
-                kid.next = prev;
-
-            child = prev;
-
-            // Do it for the kids 
-            for (kid = child; kid != null; kid = kid.next)
-                kid.reverseChildren();
-        }
-    }
-}
diff --git a/src/java/org/apache/commons/net/ntp/NTPUDPClient.java b/src/main/java/org/apache/commons/net/ntp/NTPUDPClient.java
similarity index 98%
rename from src/java/org/apache/commons/net/ntp/NTPUDPClient.java
rename to src/main/java/org/apache/commons/net/ntp/NTPUDPClient.java
index 8037f13..e53f167 100644
--- a/src/java/org/apache/commons/net/ntp/NTPUDPClient.java
+++ b/src/main/java/org/apache/commons/net/ntp/NTPUDPClient.java
@@ -7,7 +7,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -16,9 +16,11 @@
  * limitations under the License.
  */
 
+
 import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.InetAddress;
+
 import org.apache.commons.net.DatagramSocketClient;
 
 /***
diff --git a/src/java/org/apache/commons/net/ntp/NtpUtils.java b/src/main/java/org/apache/commons/net/ntp/NtpUtils.java
similarity index 98%
rename from src/java/org/apache/commons/net/ntp/NtpUtils.java
rename to src/main/java/org/apache/commons/net/ntp/NtpUtils.java
index 43f1bbe..743fc88 100644
--- a/src/java/org/apache/commons/net/ntp/NtpUtils.java
+++ b/src/main/java/org/apache/commons/net/ntp/NtpUtils.java
@@ -7,7 +7,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -16,6 +16,7 @@
  * limitations under the License.
  */
 
+
 /***
  * Common NtpUtils Helper class.
  *
diff --git a/src/java/org/apache/commons/net/ntp/NtpV3Impl.java b/src/main/java/org/apache/commons/net/ntp/NtpV3Impl.java
similarity index 98%
rename from src/java/org/apache/commons/net/ntp/NtpV3Impl.java
rename to src/main/java/org/apache/commons/net/ntp/NtpV3Impl.java
index b89dd6a..5cf339a 100644
--- a/src/java/org/apache/commons/net/ntp/NtpV3Impl.java
+++ b/src/main/java/org/apache/commons/net/ntp/NtpV3Impl.java
@@ -7,7 +7,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -15,6 +15,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 import java.net.DatagramPacket;
 
 /***
@@ -56,7 +57,7 @@
 
     private byte[] buf = new byte[48];
 
-    private DatagramPacket dp;
+    private volatile DatagramPacket dp;
 
     /** Creates a new instance of NtpV3Impl */
     public NtpV3Impl()
@@ -127,7 +128,7 @@
      */
     public int getPoll()
     {
-        return (int) (buf[POLL_INDEX]);
+        return buf[POLL_INDEX];
     }
 
     /***
@@ -149,7 +150,7 @@
      */
     public int getPrecision()
     {
-        return (int) buf[PRECISION_INDEX];
+        return buf[PRECISION_INDEX];
     }
 
     /***
@@ -329,13 +330,13 @@
 
     private String idAsString()
     {
-        String id = "";
+        StringBuilder id = new StringBuilder();
         for (int i = 0; i <= 3; i++) {
             char c = (char) buf[REFERENCE_ID_INDEX + i];
             if (c == 0) break; // 0-terminated string
-            id = id + c;
+            id.append(c);
         }
-        return id;
+        return id.toString();
     }
 
     private String idAsHex()
@@ -564,6 +565,7 @@
      *
      * @return details of NTP packet as a string.
      */
+    @Override
     public String toString()
     {
         return "[" +
diff --git a/src/java/org/apache/commons/net/ntp/NtpV3Packet.java b/src/main/java/org/apache/commons/net/ntp/NtpV3Packet.java
similarity index 98%
rename from src/java/org/apache/commons/net/ntp/NtpV3Packet.java
rename to src/main/java/org/apache/commons/net/ntp/NtpV3Packet.java
index 01a9d4a..15ed7fa 100644
--- a/src/java/org/apache/commons/net/ntp/NtpV3Packet.java
+++ b/src/main/java/org/apache/commons/net/ntp/NtpV3Packet.java
@@ -7,7 +7,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -16,6 +16,7 @@
  * limitations under the License.
  */
 
+
 import java.net.DatagramPacket;
 
 /**
diff --git a/src/java/org/apache/commons/net/ntp/TimeInfo.java b/src/main/java/org/apache/commons/net/ntp/TimeInfo.java
similarity index 92%
rename from src/java/org/apache/commons/net/ntp/TimeInfo.java
rename to src/main/java/org/apache/commons/net/ntp/TimeInfo.java
index fd9285f..2e16824 100644
--- a/src/java/org/apache/commons/net/ntp/TimeInfo.java
+++ b/src/main/java/org/apache/commons/net/ntp/TimeInfo.java
@@ -7,7 +7,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -16,8 +16,9 @@
  * limitations under the License.
  */
 
-import java.util.List;
+
 import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Wrapper class to network time packet messages (NTP, etc) that computes
@@ -30,7 +31,7 @@
 public class TimeInfo {
 
     private NtpV3Packet _message;
-    private List _comments;
+    private List<String> _comments;
     private Long _delay;
     private Long _offset;
 
@@ -63,7 +64,7 @@
      * @param comments List of errors/warnings identified during processing
      * @throws IllegalArgumentException if message is null
      */
-    public TimeInfo(NtpV3Packet message, long returnTime, List comments)
+    public TimeInfo(NtpV3Packet message, long returnTime, List<String> comments)
     {
             this(message, returnTime, comments, true);
     }
@@ -96,7 +97,7 @@
      * @param doComputeDetails  flag to pre-compute delay/offset values
      * @throws IllegalArgumentException if message is null
      */
-    public TimeInfo(NtpV3Packet message, long returnTime, List comments,
+    public TimeInfo(NtpV3Packet message, long returnTime, List<String> comments,
                    boolean doComputeDetails)
     {
         if (message == null)
@@ -118,7 +119,7 @@
     public void addComment(String comment)
     {
         if (_comments == null) {
-            _comments = new ArrayList();
+            _comments = new ArrayList<String>();
         }
         _comments.add(comment);
     }
@@ -134,7 +135,7 @@
         }
         _detailsComputed = true;
         if (_comments == null) {
-            _comments = new ArrayList();
+            _comments = new ArrayList<String>();
         }
 
         TimeStamp origNtpTime = _message.getOriginateTimeStamp();
@@ -170,7 +171,7 @@
             // might be via a broadcast NTP packet...
             if (xmitNtpTime.ntpValue() != 0)
             {
-                _offset = new Long(xmitTime - _returnTime);
+                _offset = Long.valueOf(xmitTime - _returnTime);
                 _comments.add("Error: zero orig time -- cannot compute delay");
             } else
                 _comments.add("Error: zero orig time -- cannot compute delay/offset");
@@ -184,7 +185,7 @@
             {
                 // without receive or xmit time cannot figure out processing time
                 // so delay is simply the network travel time
-                _delay = new Long(_returnTime - origTime);
+                _delay = Long.valueOf(_returnTime - origTime);
             }
             // TODO: is offset still valid if rcvNtpTime=0 || xmitNtpTime=0 ???
             // Could always hash origNtpTime (sendTime) but if host doesn't set it
@@ -193,11 +194,11 @@
             if (rcvNtpTime.ntpValue() != 0)
             {
                 // xmitTime is 0 just use rcv time
-                _offset = new Long(rcvTime - origTime);
+                _offset = Long.valueOf(rcvTime - origTime);
             } else if (xmitNtpTime.ntpValue() != 0)
             {
                 // rcvTime is 0 just use xmitTime time
-                _offset = new Long(xmitTime - _returnTime);
+                _offset = Long.valueOf(xmitTime - _returnTime);
             }
         } else
         {
@@ -232,11 +233,11 @@
                          _comments.add("Warning: processing time > total network time");
                  }
              }
-             _delay = new Long(delayValue);
+             _delay = Long.valueOf(delayValue);
             if (origTime > _returnTime) // assert destTime >= origTime
                 _comments.add("Error: OrigTime > DestRcvTime");
 
-            _offset = new Long(((rcvTime - origTime) + (xmitTime - _returnTime)) / 2);
+            _offset = Long.valueOf(((rcvTime - origTime) + (xmitTime - _returnTime)) / 2);
         }
     }
 
@@ -245,7 +246,7 @@
      *
      * @return List or null if not yet computed
      */
-    public List getComments()
+    public List<String> getComments()
     {
         return _comments;
     }
diff --git a/src/java/org/apache/commons/net/ntp/TimeStamp.java b/src/main/java/org/apache/commons/net/ntp/TimeStamp.java
similarity index 96%
rename from src/java/org/apache/commons/net/ntp/TimeStamp.java
rename to src/main/java/org/apache/commons/net/ntp/TimeStamp.java
index 831e0f9..7758621 100644
--- a/src/java/org/apache/commons/net/ntp/TimeStamp.java
+++ b/src/main/java/org/apache/commons/net/ntp/TimeStamp.java
@@ -7,7 +7,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,12 +17,13 @@
  */
 
 
-import java.util.TimeZone;
+
+import java.lang.ref.SoftReference;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.Locale;
-import java.lang.ref.SoftReference;
-import java.text.SimpleDateFormat;
-import java.text.DateFormat;
+import java.util.TimeZone;
 
 /***
  * TimeStamp class represents the Network Time Protocol (NTP) timestamp
@@ -42,7 +43,7 @@
  * @version $Revision$ $Date$
  * @see java.util.Date
  */
-public class TimeStamp implements java.io.Serializable, Comparable
+public class TimeStamp implements java.io.Serializable, Comparable // TODO add comparable type?
 {
 
     /**
@@ -64,8 +65,8 @@
     /*
      * Caches for the DateFormatters used by various toString methods.
      */
-    private static SoftReference simpleFormatter = null;
-    private static SoftReference utcFormatter = null;
+    private static SoftReference<DateFormat> simpleFormatter = null;
+    private static SoftReference<DateFormat> utcFormatter = null;
 
     /**
      * NTP timestamp value: 64-bit unsigned fixed-point number as defined in RFC-1305
@@ -316,6 +317,7 @@
      *
      * @return  a hash code value for this object.
      */
+    @Override
     public int hashCode()
     {
         return (int) (ntpTime ^ (ntpTime >>> 32));
@@ -331,6 +333,7 @@
      * @return  <code>true</code> if the objects are the same;
      *          <code>false</code> otherwise.
      */
+    @Override
     public boolean equals(Object obj)
     {
         if (obj instanceof TimeStamp) {
@@ -348,6 +351,7 @@
      * @return NTP timestamp 64-bit long value as hex string with seconds
      * separated by fractional seconds.
      */
+    @Override
     public String toString()
     {
         return toString(ntpTime);
@@ -402,13 +406,13 @@
     {
         DateFormat formatter = null;
         if (simpleFormatter != null) {
-            formatter = (DateFormat) simpleFormatter.get();
+            formatter = simpleFormatter.get();
         }
         if (formatter == null) {
             // No cache yet, or cached formatter GC'd
             formatter = new SimpleDateFormat(NTP_DATE_FORMAT, Locale.US);
             formatter.setTimeZone(TimeZone.getDefault());
-            simpleFormatter = new SoftReference(formatter);
+            simpleFormatter = new SoftReference<DateFormat>(formatter);
         }
         Date ntpDate = getDate();
         synchronized (formatter) {
@@ -429,13 +433,13 @@
     {
         DateFormat formatter = null;
         if (utcFormatter != null)
-            formatter = (DateFormat) utcFormatter.get();
+            formatter = utcFormatter.get();
         if (formatter == null) {
             // No cache yet, or cached formatter GC'd
             formatter = new SimpleDateFormat(NTP_DATE_FORMAT + " 'UTC'",
                     Locale.US);
             formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
-            utcFormatter = new SoftReference(formatter);
+            utcFormatter = new SoftReference<DateFormat>(formatter);
         }
         Date ntpDate = getDate();
         synchronized (formatter) {
diff --git a/src/java/org/apache/commons/net/pop3/POP3.java b/src/main/java/org/apache/commons/net/pop3/POP3.java
similarity index 97%
rename from src/java/org/apache/commons/net/pop3/POP3.java
rename to src/main/java/org/apache/commons/net/pop3/POP3.java
index efdee40..8031ec9 100644
--- a/src/java/org/apache/commons/net/pop3/POP3.java
+++ b/src/main/java/org/apache/commons/net/pop3/POP3.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.pop3;
 
 import java.io.BufferedReader;
@@ -22,9 +23,9 @@
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
-import java.lang.StringBuffer;
 import java.util.Enumeration;
 import java.util.Vector;
+
 import org.apache.commons.net.MalformedServerReplyException;
 import org.apache.commons.net.ProtocolCommandListener;
 import org.apache.commons.net.ProtocolCommandSupport;
@@ -83,7 +84,7 @@
     BufferedReader _reader;
     int _replyCode;
     String _lastReplyLine;
-    Vector _replyLines;
+    Vector<String> _replyLines;
 
     /***
      * A ProtocolCommandSupport object used to manage the registering of
@@ -102,7 +103,7 @@
         __popState = DISCONNECTED_STATE;
         _reader = null;
         __writer = null;
-        _replyLines = new Vector();
+        _replyLines = new Vector<String>();
         _commandSupport_ = new ProtocolCommandSupport(this);
     }
 
@@ -137,6 +138,7 @@
      * Performs connection initialization and sets state to
      * <code> AUTHORIZATION_STATE </code>.
      ***/
+    @Override
     protected void _connectAction_() throws IOException
     {
         super._connectAction_();
@@ -223,6 +225,7 @@
      * <p>
      * @exception IOException  If there is an error in disconnecting.
      ***/
+    @Override
     public void disconnect() throws IOException
     {
         super.disconnect();
@@ -338,13 +341,13 @@
      ***/
     public String getReplyString()
     {
-        Enumeration en;
+        Enumeration<String> en;
         StringBuffer buffer = new StringBuffer(256);
 
         en = _replyLines.elements();
         while (en.hasMoreElements())
         {
-            buffer.append((String)en.nextElement());
+            buffer.append(en.nextElement());
             buffer.append(SocketClient.NETASCII_EOL);
         }
 
diff --git a/src/java/org/apache/commons/net/pop3/POP3Client.java b/src/main/java/org/apache/commons/net/pop3/POP3Client.java
similarity index 98%
rename from src/java/org/apache/commons/net/pop3/POP3Client.java
rename to src/main/java/org/apache/commons/net/pop3/POP3Client.java
index 37a31ee..9e5bb77 100644
--- a/src/java/org/apache/commons/net/pop3/POP3Client.java
+++ b/src/main/java/org/apache/commons/net/pop3/POP3Client.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.pop3;
 
 import java.io.IOException;
@@ -22,6 +23,7 @@
 import java.security.NoSuchAlgorithmException;
 import java.util.Enumeration;
 import java.util.StringTokenizer;
+
 import org.apache.commons.net.io.DotTerminatedMessageReader;
 
 /***
@@ -367,7 +369,7 @@
     public POP3MessageInfo[] listMessages() throws IOException
     {
         POP3MessageInfo[] messages;
-        Enumeration en;
+        Enumeration<String> en;
         int line;
 
         if (getState() != TRANSACTION_STATE)
@@ -385,7 +387,7 @@
 
         // Fetch lines.
         for (line = 0; line < messages.length; line++)
-            messages[line] = __parseStatus((String)en.nextElement());
+            messages[line] = __parseStatus(en.nextElement());
 
         return messages;
     }
@@ -439,7 +441,7 @@
     public POP3MessageInfo[] listUniqueIdentifiers() throws IOException
     {
         POP3MessageInfo[] messages;
-        Enumeration en;
+        Enumeration<String> en;
         int line;
 
         if (getState() != TRANSACTION_STATE)
@@ -457,7 +459,7 @@
 
         // Fetch lines.
         for (line = 0; line < messages.length; line++)
-            messages[line] = __parseUID((String)en.nextElement());
+            messages[line] = __parseUID(en.nextElement());
 
         return messages;
     }
diff --git a/src/java/org/apache/commons/net/pop3/POP3Command.java b/src/main/java/org/apache/commons/net/pop3/POP3Command.java
similarity index 97%
rename from src/java/org/apache/commons/net/pop3/POP3Command.java
rename to src/main/java/org/apache/commons/net/pop3/POP3Command.java
index 20eb0a9..48f91de 100644
--- a/src/java/org/apache/commons/net/pop3/POP3Command.java
+++ b/src/main/java/org/apache/commons/net/pop3/POP3Command.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.pop3;
 
 /***
diff --git a/src/java/org/apache/commons/net/pop3/POP3MessageInfo.java b/src/main/java/org/apache/commons/net/pop3/POP3MessageInfo.java
similarity index 97%
rename from src/java/org/apache/commons/net/pop3/POP3MessageInfo.java
rename to src/main/java/org/apache/commons/net/pop3/POP3MessageInfo.java
index 8002e1d..ae753a5 100644
--- a/src/java/org/apache/commons/net/pop3/POP3MessageInfo.java
+++ b/src/main/java/org/apache/commons/net/pop3/POP3MessageInfo.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.pop3;
 
 /***
diff --git a/src/java/org/apache/commons/net/pop3/POP3Reply.java b/src/main/java/org/apache/commons/net/pop3/POP3Reply.java
similarity index 95%
rename from src/java/org/apache/commons/net/pop3/POP3Reply.java
rename to src/main/java/org/apache/commons/net/pop3/POP3Reply.java
index a6548ba..cc4c60a 100644
--- a/src/java/org/apache/commons/net/pop3/POP3Reply.java
+++ b/src/main/java/org/apache/commons/net/pop3/POP3Reply.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.pop3;
 
 /***
diff --git a/src/java/org/apache/commons/net/smtp/RelayPath.java b/src/main/java/org/apache/commons/net/smtp/RelayPath.java
similarity index 90%
rename from src/java/org/apache/commons/net/smtp/RelayPath.java
rename to src/main/java/org/apache/commons/net/smtp/RelayPath.java
index f44e8ce..60852f8 100644
--- a/src/java/org/apache/commons/net/smtp/RelayPath.java
+++ b/src/main/java/org/apache/commons/net/smtp/RelayPath.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.smtp;
 
 import java.util.Enumeration;
@@ -32,7 +33,7 @@
 
 public final class RelayPath
 {
-    Vector _path;
+    Vector<String> _path;
     String _emailAddress;
 
     /***
@@ -43,7 +44,7 @@
      ***/
     public RelayPath(String emailAddress)
     {
-        _path = new Vector();
+        _path = new Vector<String>();
         _emailAddress = emailAddress;
     }
 
@@ -69,10 +70,11 @@
      * <p>
      * @return The properly formatted string representation of the relay path.
      ***/
+    @Override
     public String toString()
     {
         StringBuffer buffer = new StringBuffer();
-        Enumeration hosts;
+        Enumeration<String> hosts;
 
         buffer.append('<');
 
@@ -81,12 +83,12 @@
         if (hosts.hasMoreElements())
         {
             buffer.append('@');
-            buffer.append((String)hosts.nextElement());
+            buffer.append(hosts.nextElement());
 
             while (hosts.hasMoreElements())
             {
                 buffer.append(",@");
-                buffer.append((String)hosts.nextElement());
+                buffer.append(hosts.nextElement());
             }
             buffer.append(':');
         }
diff --git a/src/java/org/apache/commons/net/smtp/SMTP.java b/src/main/java/org/apache/commons/net/smtp/SMTP.java
similarity index 96%
rename from src/java/org/apache/commons/net/smtp/SMTP.java
rename to src/main/java/org/apache/commons/net/smtp/SMTP.java
index 876e92c..10a016e 100644
--- a/src/java/org/apache/commons/net/smtp/SMTP.java
+++ b/src/main/java/org/apache/commons/net/smtp/SMTP.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.smtp;
 
 import java.io.BufferedReader;
@@ -21,8 +22,9 @@
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
-import java.util.Enumeration;
-import java.util.Vector;
+import java.util.ArrayList;
+import java.util.Arrays;
+
 import org.apache.commons.net.MalformedServerReplyException;
 import org.apache.commons.net.ProtocolCommandListener;
 import org.apache.commons.net.ProtocolCommandSupport;
@@ -91,13 +93,16 @@
     // but we use ISO-8859-1 just in case 8-bit characters cross
     // the wire.
     private static final String __DEFAULT_ENCODING = "ISO-8859-1";
+    
+    /** The encoding to use (user-settable) */
+    private String encoding = __DEFAULT_ENCODING;
 
     private StringBuffer __commandBuffer;
 
     BufferedReader _reader;
     BufferedWriter _writer;
     int _replyCode;
-    Vector _replyLines;
+    ArrayList<String> _replyLines;
     boolean _newReplyString;
     String _replyString;
 
@@ -116,11 +121,21 @@
     {
         setDefaultPort(DEFAULT_PORT);
         __commandBuffer = new StringBuffer();
-        _replyLines = new Vector();
+        _replyLines = new ArrayList<String>();
         _newReplyString = false;
         _replyString = null;
         _commandSupport_ = new ProtocolCommandSupport(this);
     }
+    
+    /**
+     * Overloaded constructor where the user may specify a default encoding.
+     * @param encoding
+     * @since 2.0
+     */
+    public SMTP(String encoding) {
+        this();
+        this.encoding = encoding;
+    }
 
     private int __sendCommand(String command, String args, boolean includeSpace)
     throws IOException
@@ -160,7 +175,7 @@
         int length;
 
         _newReplyString = true;
-        _replyLines.setSize(0);
+        _replyLines.clear();
 
         String line = _reader.readLine();
 
@@ -186,7 +201,7 @@
                 "Could not parse response code.\nServer Reply: " + line);
         }
 
-        _replyLines.addElement(line);
+        _replyLines.add(line);
 
         // Get extra lines if message continues.
         if (length > 3 && line.charAt(3) == '-')
@@ -199,7 +214,7 @@
                     throw new SMTPConnectionClosedException(
                         "Connection closed without indication.");
 
-                _replyLines.addElement(line);
+                _replyLines.add(line);
 
                 // The length() check handles problems that could arise from readLine()
                 // returning too soon after encountering a naked CR or some other
@@ -221,16 +236,18 @@
     }
 
     /*** Initiates control connections and gets initial reply. ***/
+    @Override
     protected void _connectAction_() throws IOException
     {
         super._connectAction_();
         _reader =
             new BufferedReader(new InputStreamReader(_input_,
-                                                     __DEFAULT_ENCODING));
+                                                    encoding));
         _writer =
             new BufferedWriter(new OutputStreamWriter(_output_,
-                                                      __DEFAULT_ENCODING));
+                                                      encoding));
         __getReply();
+        
     }
 
 
@@ -265,13 +282,14 @@
      * <p>
      * @exception IOException If an error occurs while disconnecting.
      ***/
+    @Override
     public void disconnect() throws IOException
     {
         super.disconnect();
         _reader = null;
         _writer = null;
         _replyString = null;
-        _replyLines.setSize(0);
+        _replyLines.clear();
         _newReplyString = false;
     }
 
@@ -424,10 +442,7 @@
      ***/
     public String[] getReplyStrings()
     {
-        String[] lines;
-        lines = new String[_replyLines.size()];
-        _replyLines.copyInto(lines);
-        return lines;
+    	  return _replyLines.toArray(new String[_replyLines.size()]);
     }
 
     /***
@@ -439,17 +454,16 @@
      ***/
     public String getReplyString()
     {
-        Enumeration en;
-        StringBuffer buffer;
+        StringBuilder buffer;
 
         if (!_newReplyString)
             return _replyString;
 
-        buffer = new StringBuffer(256);
-        en = _replyLines.elements();
-        while (en.hasMoreElements())
+        buffer = new StringBuilder();
+        
+        for (String line : _replyLines)
         {
-            buffer.append((String)en.nextElement());
+            buffer.append(line);
             buffer.append(SocketClient.NETASCII_EOL);
         }
 
diff --git a/src/java/org/apache/commons/net/smtp/SMTPClient.java b/src/main/java/org/apache/commons/net/smtp/SMTPClient.java
similarity index 98%
rename from src/java/org/apache/commons/net/smtp/SMTPClient.java
rename to src/main/java/org/apache/commons/net/smtp/SMTPClient.java
index c6dd0b1..8b0bce7 100644
--- a/src/java/org/apache/commons/net/smtp/SMTPClient.java
+++ b/src/main/java/org/apache/commons/net/smtp/SMTPClient.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,11 +14,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.smtp;
 
 import java.io.IOException;
 import java.io.Writer;
 import java.net.InetAddress;
+
 import org.apache.commons.net.io.DotTerminatedMessageWriter;
 
 /***
@@ -124,10 +126,19 @@
 public class SMTPClient extends SMTP
 {
 
-    /*
+    /**
      * Default SMTPClient constructor.  Creates a new SMTPClient instance.
      */
-    //public SMTPClient() {  }
+    public SMTPClient() {  }
+    
+    /**
+     * Overloaded constructor that takes an encoding specification
+     * @param encoding The encoding to use
+     * @since 2.0
+     */
+    public SMTPClient(String encoding) {
+        super(encoding);
+    }
 
 
     /***
diff --git a/src/java/org/apache/commons/net/smtp/SMTPCommand.java b/src/main/java/org/apache/commons/net/smtp/SMTPCommand.java
similarity index 98%
rename from src/java/org/apache/commons/net/smtp/SMTPCommand.java
rename to src/main/java/org/apache/commons/net/smtp/SMTPCommand.java
index aedca11..3dcd939 100644
--- a/src/java/org/apache/commons/net/smtp/SMTPCommand.java
+++ b/src/main/java/org/apache/commons/net/smtp/SMTPCommand.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.smtp;
 
 /***
diff --git a/src/java/org/apache/commons/net/smtp/SMTPConnectionClosedException.java b/src/main/java/org/apache/commons/net/smtp/SMTPConnectionClosedException.java
similarity index 97%
rename from src/java/org/apache/commons/net/smtp/SMTPConnectionClosedException.java
rename to src/main/java/org/apache/commons/net/smtp/SMTPConnectionClosedException.java
index 416323d..dd7f813 100644
--- a/src/java/org/apache/commons/net/smtp/SMTPConnectionClosedException.java
+++ b/src/main/java/org/apache/commons/net/smtp/SMTPConnectionClosedException.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.smtp;
 
 import java.io.IOException;
diff --git a/src/java/org/apache/commons/net/smtp/SMTPReply.java b/src/main/java/org/apache/commons/net/smtp/SMTPReply.java
similarity index 98%
rename from src/java/org/apache/commons/net/smtp/SMTPReply.java
rename to src/main/java/org/apache/commons/net/smtp/SMTPReply.java
index 066f885..db8bece 100644
--- a/src/java/org/apache/commons/net/smtp/SMTPReply.java
+++ b/src/main/java/org/apache/commons/net/smtp/SMTPReply.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.smtp;
 
 /***
diff --git a/src/java/org/apache/commons/net/smtp/SimpleSMTPHeader.java b/src/main/java/org/apache/commons/net/smtp/SimpleSMTPHeader.java
similarity index 98%
rename from src/java/org/apache/commons/net/smtp/SimpleSMTPHeader.java
rename to src/main/java/org/apache/commons/net/smtp/SimpleSMTPHeader.java
index 555357a..b6a0522 100644
--- a/src/java/org/apache/commons/net/smtp/SimpleSMTPHeader.java
+++ b/src/main/java/org/apache/commons/net/smtp/SimpleSMTPHeader.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.smtp;
 
 /***
@@ -116,6 +117,7 @@
      * <p>
      * @return The message header in the form of a String.
      ***/
+    @Override
     public String toString()
     {
         StringBuffer header = new StringBuffer();
diff --git a/src/java/org/apache/commons/net/telnet/EchoOptionHandler.java b/src/main/java/org/apache/commons/net/telnet/EchoOptionHandler.java
similarity index 96%
rename from src/java/org/apache/commons/net/telnet/EchoOptionHandler.java
rename to src/main/java/org/apache/commons/net/telnet/EchoOptionHandler.java
index 6ae20b4..7b2793e 100644
--- a/src/java/org/apache/commons/net/telnet/EchoOptionHandler.java
+++ b/src/main/java/org/apache/commons/net/telnet/EchoOptionHandler.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.telnet;
 
 /***
@@ -58,6 +59,7 @@
      * <p>
      * @return always null (no response to subnegotiation)
      ***/
+    @Override
     public int[] answerSubnegotiation(int suboptionData[],
                                         int suboptionLength)
     {
@@ -69,6 +71,7 @@
      * <p>
      * @return always null (no response to subnegotiation)
      ***/
+    @Override
     public int[] startSubnegotiationLocal()
     {
         return null;
@@ -79,6 +82,7 @@
      * <p>
      * @return always null (no response to subnegotiation)
      ***/
+    @Override
     public int[] startSubnegotiationRemote()
     {
         return null;
diff --git a/src/java/org/apache/commons/net/telnet/InvalidTelnetOptionException.java b/src/main/java/org/apache/commons/net/telnet/InvalidTelnetOptionException.java
similarity index 96%
rename from src/java/org/apache/commons/net/telnet/InvalidTelnetOptionException.java
rename to src/main/java/org/apache/commons/net/telnet/InvalidTelnetOptionException.java
index 71670df..bddea95 100644
--- a/src/java/org/apache/commons/net/telnet/InvalidTelnetOptionException.java
+++ b/src/main/java/org/apache/commons/net/telnet/InvalidTelnetOptionException.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.telnet;
 
 /***
@@ -53,6 +54,7 @@
      * <p>
      * @return the error message.
      ***/
+    @Override
     public String getMessage()
     {
         return (msg + ": " + optionCode);
diff --git a/src/java/org/apache/commons/net/telnet/SimpleOptionHandler.java b/src/main/java/org/apache/commons/net/telnet/SimpleOptionHandler.java
similarity index 96%
rename from src/java/org/apache/commons/net/telnet/SimpleOptionHandler.java
rename to src/main/java/org/apache/commons/net/telnet/SimpleOptionHandler.java
index 7ba2360..5b74ad2 100644
--- a/src/java/org/apache/commons/net/telnet/SimpleOptionHandler.java
+++ b/src/main/java/org/apache/commons/net/telnet/SimpleOptionHandler.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.telnet;
 
 /***
@@ -65,6 +66,7 @@
      * <p>
      * @return always null (no response to subnegotiation)
      ***/
+    @Override
     public int[] answerSubnegotiation(int suboptionData[], int suboptionLength)
     {
         return null;
@@ -75,6 +77,7 @@
      * <p>
      * @return always null (no response to subnegotiation)
      ***/
+    @Override
     public int[] startSubnegotiationLocal()
     {
         return null;
@@ -85,6 +88,7 @@
      * <p>
      * @return always null (no response to subnegotiation)
      ***/
+    @Override
     public int[] startSubnegotiationRemote()
     {
         return null;
diff --git a/src/java/org/apache/commons/net/telnet/SuppressGAOptionHandler.java b/src/main/java/org/apache/commons/net/telnet/SuppressGAOptionHandler.java
similarity index 96%
rename from src/java/org/apache/commons/net/telnet/SuppressGAOptionHandler.java
rename to src/main/java/org/apache/commons/net/telnet/SuppressGAOptionHandler.java
index f217330..64e78eb 100644
--- a/src/java/org/apache/commons/net/telnet/SuppressGAOptionHandler.java
+++ b/src/main/java/org/apache/commons/net/telnet/SuppressGAOptionHandler.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.telnet;
 
 /***
@@ -58,6 +59,7 @@
      * <p>
      * @return always null (no response to subnegotiation)
      ***/
+    @Override
     public int[] answerSubnegotiation(int suboptionData[], int suboptionLength)
     {
         return null;
@@ -68,6 +70,7 @@
      * <p>
      * @return always null (no response to subnegotiation)
      ***/
+    @Override
     public int[] startSubnegotiationLocal()
     {
         return null;
@@ -78,6 +81,7 @@
      * <p>
      * @return always null (no response to subnegotiation)
      ***/
+    @Override
     public int[] startSubnegotiationRemote()
     {
         return null;
diff --git a/src/java/org/apache/commons/net/telnet/Telnet.java b/src/main/java/org/apache/commons/net/telnet/Telnet.java
similarity index 99%
rename from src/java/org/apache/commons/net/telnet/Telnet.java
rename to src/main/java/org/apache/commons/net/telnet/Telnet.java
index dfa010c..064778a 100644
--- a/src/java/org/apache/commons/net/telnet/Telnet.java
+++ b/src/main/java/org/apache/commons/net/telnet/Telnet.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.telnet;
 
 import java.io.BufferedInputStream;
@@ -816,6 +817,7 @@
      * <p>
      * @throws IOException - Exception in I/O.
      ***/
+    @Override
     protected void _connectAction_() throws IOException
     {
         /* (start). BUGFIX: clean the option info for each connection*/
diff --git a/src/java/org/apache/commons/net/telnet/TelnetClient.java b/src/main/java/org/apache/commons/net/telnet/TelnetClient.java
similarity index 96%
rename from src/java/org/apache/commons/net/telnet/TelnetClient.java
rename to src/main/java/org/apache/commons/net/telnet/TelnetClient.java
index dc3a61a..a043cad 100644
--- a/src/java/org/apache/commons/net/telnet/TelnetClient.java
+++ b/src/main/java/org/apache/commons/net/telnet/TelnetClient.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,12 +14,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.telnet;
 
 import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+
 import org.apache.commons.net.io.FromNetASCIIInputStream;
 import org.apache.commons.net.io.ToNetASCIIOutputStream;
 
@@ -75,11 +77,11 @@
 
     void _flushOutputStream() throws IOException
     {
-        if(_output_ != null) _output_.flush();
+        _output_.flush();
     }
     void _closeOutputStream() throws IOException
     {
-    	if(_output_ != null) _output_.close();
+        _output_.close();
     }
 
     /***
@@ -87,6 +89,7 @@
      * <p>
      * @exception IOException  If an error occurs during connection setup.
      ***/
+    @Override
     protected void _connectAction_() throws IOException
     {
         super._connectAction_();
@@ -121,10 +124,13 @@
      * close them yourself, but rather call disconnect to properly close
      * the connection.
      ***/
+    @Override
     public void disconnect() throws IOException
     {
-        if(__input != null) __input.close();
-        if(__output != null) __output.close();
+        if (__input != null)
+            __input.close();
+        if (__output != null)
+            __output.close();
         super.disconnect();
     }
 
@@ -210,6 +216,7 @@
      * <p>
      * @throws InvalidTelnetOptionException
      ***/
+    @Override
     public void addOptionHandler(TelnetOptionHandler opthand)
     throws InvalidTelnetOptionException
     {
@@ -224,6 +231,7 @@
      * <p>
      * @throws InvalidTelnetOptionException
      ***/
+    @Override
     public void deleteOptionHandler(int optcode)
     throws InvalidTelnetOptionException
     {
@@ -259,6 +267,7 @@
      * <p>
      * @param notifhand - TelnetNotificationHandler to be registered
      ***/
+    @Override
     public void registerNotifHandler(TelnetNotificationHandler  notifhand)
     {
         super.registerNotifHandler(notifhand);
@@ -268,6 +277,7 @@
      * Unregisters the current notification handler.
      * <p>
      ***/
+    @Override
     public void unregisterNotifHandler()
     {
         super.unregisterNotifHandler();
diff --git a/src/java/org/apache/commons/net/telnet/TelnetCommand.java b/src/main/java/org/apache/commons/net/telnet/TelnetCommand.java
similarity index 98%
rename from src/java/org/apache/commons/net/telnet/TelnetCommand.java
rename to src/main/java/org/apache/commons/net/telnet/TelnetCommand.java
index e9d40e9..6a49661 100644
--- a/src/java/org/apache/commons/net/telnet/TelnetCommand.java
+++ b/src/main/java/org/apache/commons/net/telnet/TelnetCommand.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.telnet;
 
 /**
diff --git a/src/java/org/apache/commons/net/telnet/TelnetInputStream.java b/src/main/java/org/apache/commons/net/telnet/TelnetInputStream.java
similarity index 98%
rename from src/java/org/apache/commons/net/telnet/TelnetInputStream.java
rename to src/main/java/org/apache/commons/net/telnet/TelnetInputStream.java
index 562d93e..d619167 100644
--- a/src/java/org/apache/commons/net/telnet/TelnetInputStream.java
+++ b/src/main/java/org/apache/commons/net/telnet/TelnetInputStream.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.telnet;
 
 import java.io.BufferedInputStream;
@@ -87,6 +88,7 @@
 
         int priority;
         __isClosed = false;
+        // TODO remove this
         // Need to set a higher priority in case JVM does not use pre-emptive
         // threads.  This should prevent scheduler induced deadlock (rather than
         // deadlock caused by a bug in this code).
@@ -115,7 +117,7 @@
             // If there is no more data AND we were told not to block, just return -2. (More efficient than exception.)
             if(!mayBlock && super.available() == 0)
                 return -2;
-
+            
             // Otherwise, exit only when we reach end of stream.
             if ((ch = super.read()) < 0)
                 return -1;
@@ -319,6 +321,7 @@
         }
     }
 
+    @Override
     public int read() throws IOException
     {
         // Critical section because we're altering __bytesAvailable,
@@ -450,6 +453,7 @@
      * @exception IOException If an error occurs in reading the underlying
      *            stream.
      ***/
+    @Override
     public int read(byte buffer[]) throws IOException
     {
         return read(buffer, 0, buffer.length);
@@ -470,6 +474,7 @@
      * @exception IOException If an error occurs while reading the underlying
      *            stream.
      ***/
+    @Override
     public int read(byte buffer[], int offset, int length) throws IOException
     {
         int ch, off;
@@ -501,11 +506,13 @@
 
 
     /*** Returns false.  Mark is not supported. ***/
+    @Override
     public boolean markSupported()
     {
         return false;
     }
 
+    @Override
     public int available() throws IOException
     {
         // Critical section because run() may change __bytesAvailable
@@ -518,6 +525,7 @@
 
     // Cannot be synchronized.  Will cause deadlock if run() is blocked
     // in read because BufferedInputStream read() is synchronized.
+    @Override
     public void close() throws IOException
     {
         // Completely disregard the fact thread may still be running.
diff --git a/src/java/org/apache/commons/net/telnet/TelnetNotificationHandler.java b/src/main/java/org/apache/commons/net/telnet/TelnetNotificationHandler.java
similarity index 97%
rename from src/java/org/apache/commons/net/telnet/TelnetNotificationHandler.java
rename to src/main/java/org/apache/commons/net/telnet/TelnetNotificationHandler.java
index 39cafdc..eaa3d9a 100644
--- a/src/java/org/apache/commons/net/telnet/TelnetNotificationHandler.java
+++ b/src/main/java/org/apache/commons/net/telnet/TelnetNotificationHandler.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.telnet;
 
 /***
diff --git a/src/java/org/apache/commons/net/telnet/TelnetOption.java b/src/main/java/org/apache/commons/net/telnet/TelnetOption.java
similarity index 98%
rename from src/java/org/apache/commons/net/telnet/TelnetOption.java
rename to src/main/java/org/apache/commons/net/telnet/TelnetOption.java
index 2b425e8..3a51714 100644
--- a/src/java/org/apache/commons/net/telnet/TelnetOption.java
+++ b/src/main/java/org/apache/commons/net/telnet/TelnetOption.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.telnet;
 
 /***
diff --git a/src/java/org/apache/commons/net/telnet/TelnetOptionHandler.java b/src/main/java/org/apache/commons/net/telnet/TelnetOptionHandler.java
similarity index 99%
rename from src/java/org/apache/commons/net/telnet/TelnetOptionHandler.java
rename to src/main/java/org/apache/commons/net/telnet/TelnetOptionHandler.java
index 6010b8e..2f2e148 100644
--- a/src/java/org/apache/commons/net/telnet/TelnetOptionHandler.java
+++ b/src/main/java/org/apache/commons/net/telnet/TelnetOptionHandler.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.telnet;
 
 /***
diff --git a/src/java/org/apache/commons/net/telnet/TelnetOutputStream.java b/src/main/java/org/apache/commons/net/telnet/TelnetOutputStream.java
similarity index 96%
rename from src/java/org/apache/commons/net/telnet/TelnetOutputStream.java
rename to src/main/java/org/apache/commons/net/telnet/TelnetOutputStream.java
index 629992f..66000c2 100644
--- a/src/java/org/apache/commons/net/telnet/TelnetOutputStream.java
+++ b/src/main/java/org/apache/commons/net/telnet/TelnetOutputStream.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.telnet;
 
 import java.io.IOException;
@@ -48,6 +49,7 @@
      * @exception IOException If an error occurs while writing to the underlying
      *            stream.
      ***/
+    @Override
     public void write(int ch) throws IOException
     {
 
@@ -107,6 +109,7 @@
      * @exception IOException If an error occurs while writing to the underlying
      *            stream.
      ***/
+    @Override
     public void write(byte buffer[]) throws IOException
     {
         write(buffer, 0, buffer.length);
@@ -123,6 +126,7 @@
      * @exception IOException If an error occurs while writing to the underlying
      *            stream.
      ***/
+    @Override
     public void write(byte buffer[], int offset, int length) throws IOException
     {
         synchronized (__client)
@@ -133,12 +137,14 @@
     }
 
     /*** Flushes the stream. ***/
+    @Override
     public void flush() throws IOException
     {
         __client._flushOutputStream();
     }
 
     /*** Closes the stream. ***/
+    @Override
     public void close() throws IOException
     {
         __client._closeOutputStream();
diff --git a/src/java/org/apache/commons/net/telnet/TerminalTypeOptionHandler.java b/src/main/java/org/apache/commons/net/telnet/TerminalTypeOptionHandler.java
similarity index 96%
rename from src/java/org/apache/commons/net/telnet/TerminalTypeOptionHandler.java
rename to src/main/java/org/apache/commons/net/telnet/TerminalTypeOptionHandler.java
index 5792ae2..0e239a2 100644
--- a/src/java/org/apache/commons/net/telnet/TerminalTypeOptionHandler.java
+++ b/src/main/java/org/apache/commons/net/telnet/TerminalTypeOptionHandler.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.telnet;
 
 /***
@@ -86,6 +87,7 @@
      * <p>
      * @return terminal type information
      ***/
+    @Override
     public int[] answerSubnegotiation(int suboptionData[], int suboptionLength)
     {
         if ((suboptionData != null) && (suboptionLength > 1)
@@ -101,7 +103,7 @@
 
                 for (int ii = 0; ii < termType.length(); ii++)
                 {
-                    response[ii + 2] = (int) termType.charAt(ii);
+                    response[ii + 2] = termType.charAt(ii);
                 }
 
                 return response;
@@ -115,6 +117,7 @@
      * <p>
      * @return always null (no response to subnegotiation)
      ***/
+    @Override
     public int[] startSubnegotiationLocal()
     {
         return null;
@@ -125,6 +128,7 @@
      * <p>
      * @return always null (no response to subnegotiation)
      ***/
+    @Override
     public int[] startSubnegotiationRemote()
     {
         return null;
diff --git a/src/main/java/org/apache/commons/net/telnet/WindowSizeOptionHandler.java b/src/main/java/org/apache/commons/net/telnet/WindowSizeOptionHandler.java
new file mode 100644
index 0000000..bb71a4a
--- /dev/null
+++ b/src/main/java/org/apache/commons/net/telnet/WindowSizeOptionHandler.java
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.net.telnet;
+
+/***
+ * Implements the telnet window size option RFC 1073.
+ * <p>
+ * @author Yuval Kashtan
+ * @version $Id$
+ * @since 2.0
+ ***/
+public class WindowSizeOptionHandler extends TelnetOptionHandler
+{
+    /***
+     * Horizontal Size
+     ***/
+    private int m_nWidth = 80;
+
+    /***
+     * Vertical Size
+     ***/
+    private int m_nHeight = 24;
+
+    /***
+     * Window size option
+     ***/
+    protected static final int WINDOW_SIZE = 31;
+
+    /***
+     * Constructor for the WindowSizeOptionHandler. Allows defining desired
+     * initial setting for local/remote activation of this option and
+     * behaviour in case a local/remote activation request for this
+     * option is received.
+     * <p>
+     * @param nWidth - Window width.
+     * @param nHeight - Window Height
+     * @param initlocal - if set to true, a WILL is sent upon connection.
+     * @param initremote - if set to true, a DO is sent upon connection.
+     * @param acceptlocal - if set to true, any DO request is accepted.
+     * @param acceptremote - if set to true, any WILL request is accepted.
+     ***/
+    public WindowSizeOptionHandler(
+        int nWidth,
+        int nHeight,
+        boolean initlocal,
+        boolean initremote,
+        boolean acceptlocal,
+        boolean acceptremote
+    ) {
+        super (
+            TelnetOption.WINDOW_SIZE,
+            initlocal,
+            initremote,
+            acceptlocal,
+            acceptremote
+        );
+
+        m_nWidth = nWidth;
+        m_nHeight = nHeight;
+    }
+
+    /***
+     * Constructor for the WindowSizeOptionHandler. Initial and accept
+     * behaviour flags are set to false
+     * <p>
+     * @param nWidth - Window width.
+     * @param nHeight - Window Height
+     ***/
+    public WindowSizeOptionHandler(
+        int nWidth,
+        int nHeight
+    ) {
+        super (
+            TelnetOption.WINDOW_SIZE,
+            false,
+            false,
+            false,
+            false
+        );
+
+        m_nWidth = nWidth;
+        m_nHeight = nHeight;
+    }
+
+    /***
+     * Implements the abstract method of TelnetOptionHandler.
+     * <p>
+     * @param suboptionData - the sequence received, whithout IAC SB & IAC SE
+     * @param suboptionLength - the length of data in suboption_data
+     * <p>
+     * @return terminal type information
+     ***/
+    @Override
+    public int[] answerSubnegotiation(int suboptionData[], int suboptionLength)
+    {
+        return null;
+    }
+
+    /***
+     * Implements the abstract method of TelnetOptionHandler.
+     * This will send the client Height and Width to the server.
+     * <p>
+     * @return always null (no response to subnegotiation)
+     ***/
+    @Override
+    public int[] startSubnegotiationLocal()
+    {
+        int nCompoundWindowSize = m_nWidth * 0x10000 + m_nHeight;
+        int nResponseSize = 5;
+        int nIndex;
+        int nShift;
+        int nTurnedOnBits;
+
+        if ((m_nWidth % 0x100) == 0xFF) {
+            nResponseSize += 1;
+        }
+
+        if ((m_nWidth / 0x100) == 0xFF) {
+            nResponseSize += 1;
+        }
+
+        if ((m_nHeight % 0x100) == 0xFF) {
+            nResponseSize += 1;
+        }
+
+        if ((m_nHeight / 0x100) == 0xFF) {
+            nResponseSize += 1;
+        }
+
+        //
+        // allocate response array
+        //
+        int response[] = new int[nResponseSize];
+
+        //
+        // Build response array.
+        // ---------------------
+        // 1. put option name.
+        // 2. loop through Window size and fill the values,
+        // 3.    duplicate 'ff' if needed.
+        //
+
+        response[0] = WINDOW_SIZE;                          // 1 //
+
+        for (                                               // 2 //
+            nIndex=1, nShift = 24;
+            nIndex < nResponseSize;
+            nIndex++, nShift -=8
+        ) {
+            nTurnedOnBits = 0xFF;
+            nTurnedOnBits <<= nShift;
+            response[nIndex] = (nCompoundWindowSize & nTurnedOnBits) >>> nShift;
+
+            if (response[nIndex] == 0xff) {                 // 3 //
+                nIndex++;
+                response[nIndex] = 0xff;
+            }
+        }
+
+        return response;
+    }
+
+    /***
+     * Implements the abstract method of TelnetOptionHandler.
+     * <p>
+     * @return always null (no response to subnegotiation)
+     ***/
+    @Override
+    public int[] startSubnegotiationRemote()
+    {
+        return null;
+    }
+}
diff --git a/src/java/org/apache/commons/net/tftp/TFTP.java b/src/main/java/org/apache/commons/net/tftp/TFTP.java
similarity index 99%
rename from src/java/org/apache/commons/net/tftp/TFTP.java
rename to src/main/java/org/apache/commons/net/tftp/TFTP.java
index e8c6255..4782615 100644
--- a/src/java/org/apache/commons/net/tftp/TFTP.java
+++ b/src/main/java/org/apache/commons/net/tftp/TFTP.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,12 +14,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.tftp;
 
 import java.io.IOException;
 import java.io.InterruptedIOException;
 import java.net.DatagramPacket;
 import java.net.SocketException;
+
 import org.apache.commons.net.DatagramSocketClient;
 
 /***
diff --git a/src/java/org/apache/commons/net/tftp/TFTPAckPacket.java b/src/main/java/org/apache/commons/net/tftp/TFTPAckPacket.java
similarity index 98%
rename from src/java/org/apache/commons/net/tftp/TFTPAckPacket.java
rename to src/main/java/org/apache/commons/net/tftp/TFTPAckPacket.java
index 3aa5743..38385be 100644
--- a/src/java/org/apache/commons/net/tftp/TFTPAckPacket.java
+++ b/src/main/java/org/apache/commons/net/tftp/TFTPAckPacket.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.tftp;
 
 import java.net.DatagramPacket;
@@ -94,6 +95,7 @@
      * @param data The buffer to store the packet and to use in the datagram.
      * @return The datagram argument.
      ***/
+    @Override
     DatagramPacket _newDatagram(DatagramPacket datagram, byte[] data)
     {
         data[0] = 0;
@@ -121,6 +123,7 @@
      * <p>
      * @return A UDP datagram containing the TFTP acknowledgement packet.
      ***/
+    @Override
     public DatagramPacket newDatagram()
     {
         byte[] data;
diff --git a/src/java/org/apache/commons/net/tftp/TFTPClient.java b/src/main/java/org/apache/commons/net/tftp/TFTPClient.java
similarity index 99%
rename from src/java/org/apache/commons/net/tftp/TFTPClient.java
rename to src/main/java/org/apache/commons/net/tftp/TFTPClient.java
index c036805..a40e860 100644
--- a/src/java/org/apache/commons/net/tftp/TFTPClient.java
+++ b/src/main/java/org/apache/commons/net/tftp/TFTPClient.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.tftp;
 
 import java.io.IOException;
diff --git a/src/java/org/apache/commons/net/tftp/TFTPDataPacket.java b/src/main/java/org/apache/commons/net/tftp/TFTPDataPacket.java
similarity index 98%
rename from src/java/org/apache/commons/net/tftp/TFTPDataPacket.java
rename to src/main/java/org/apache/commons/net/tftp/TFTPDataPacket.java
index 4fd0f47..0eab790 100644
--- a/src/java/org/apache/commons/net/tftp/TFTPDataPacket.java
+++ b/src/main/java/org/apache/commons/net/tftp/TFTPDataPacket.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.tftp;
 
 import java.net.DatagramPacket;
@@ -136,6 +137,7 @@
      * @param data The buffer to store the packet and to use in the datagram.
      * @return The datagram argument.
      ***/
+    @Override
     DatagramPacket _newDatagram(DatagramPacket datagram, byte[] data)
     {
         data[0] = 0;
@@ -167,6 +169,7 @@
      * <p>
      * @return A UDP datagram containing the TFTP data packet.
      ***/
+    @Override
     public DatagramPacket newDatagram()
     {
         byte[] data;
diff --git a/src/java/org/apache/commons/net/tftp/TFTPErrorPacket.java b/src/main/java/org/apache/commons/net/tftp/TFTPErrorPacket.java
similarity index 98%
rename from src/java/org/apache/commons/net/tftp/TFTPErrorPacket.java
rename to src/main/java/org/apache/commons/net/tftp/TFTPErrorPacket.java
index 82ebdf0..0cfa12e 100644
--- a/src/java/org/apache/commons/net/tftp/TFTPErrorPacket.java
+++ b/src/main/java/org/apache/commons/net/tftp/TFTPErrorPacket.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.tftp;
 
 import java.net.DatagramPacket;
@@ -143,6 +144,7 @@
      * @param data The buffer to store the packet and to use in the datagram.
      * @return The datagram argument.
      ***/
+    @Override
     DatagramPacket _newDatagram(DatagramPacket datagram, byte[] data)
     {
         int length;
@@ -179,6 +181,7 @@
      * <p>
      * @return A UDP datagram containing the TFTP error packet.
      ***/
+    @Override
     public DatagramPacket newDatagram()
     {
         byte[] data;
diff --git a/src/java/org/apache/commons/net/tftp/TFTPPacket.java b/src/main/java/org/apache/commons/net/tftp/TFTPPacket.java
similarity index 99%
rename from src/java/org/apache/commons/net/tftp/TFTPPacket.java
rename to src/main/java/org/apache/commons/net/tftp/TFTPPacket.java
index 349f5a9..af42e43 100644
--- a/src/java/org/apache/commons/net/tftp/TFTPPacket.java
+++ b/src/main/java/org/apache/commons/net/tftp/TFTPPacket.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.tftp;
 
 import java.net.DatagramPacket;
diff --git a/src/java/org/apache/commons/net/tftp/TFTPPacketException.java b/src/main/java/org/apache/commons/net/tftp/TFTPPacketException.java
similarity index 96%
rename from src/java/org/apache/commons/net/tftp/TFTPPacketException.java
rename to src/main/java/org/apache/commons/net/tftp/TFTPPacketException.java
index 63c7d11..37767bf 100644
--- a/src/java/org/apache/commons/net/tftp/TFTPPacketException.java
+++ b/src/main/java/org/apache/commons/net/tftp/TFTPPacketException.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.tftp;
 
 /***
diff --git a/src/java/org/apache/commons/net/tftp/TFTPReadRequestPacket.java b/src/main/java/org/apache/commons/net/tftp/TFTPReadRequestPacket.java
similarity index 98%
rename from src/java/org/apache/commons/net/tftp/TFTPReadRequestPacket.java
rename to src/main/java/org/apache/commons/net/tftp/TFTPReadRequestPacket.java
index 8bbcd5f..a2e09fe 100644
--- a/src/java/org/apache/commons/net/tftp/TFTPReadRequestPacket.java
+++ b/src/main/java/org/apache/commons/net/tftp/TFTPReadRequestPacket.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.tftp;
 
 import java.net.DatagramPacket;
diff --git a/src/java/org/apache/commons/net/tftp/TFTPRequestPacket.java b/src/main/java/org/apache/commons/net/tftp/TFTPRequestPacket.java
similarity index 98%
rename from src/java/org/apache/commons/net/tftp/TFTPRequestPacket.java
rename to src/main/java/org/apache/commons/net/tftp/TFTPRequestPacket.java
index 551d045..2264797 100644
--- a/src/java/org/apache/commons/net/tftp/TFTPRequestPacket.java
+++ b/src/main/java/org/apache/commons/net/tftp/TFTPRequestPacket.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.tftp;
 
 import java.net.DatagramPacket;
@@ -176,6 +177,7 @@
      * @param data The buffer to store the packet and to use in the datagram.
      * @return The datagram argument.
      ***/
+    @Override
     final DatagramPacket _newDatagram(DatagramPacket datagram, byte[] data)
     {
         int fileLength, modeLength;
@@ -209,6 +211,7 @@
      * <p>
      * @return A UDP datagram containing the TFTP request packet.
      ***/
+    @Override
     public final DatagramPacket newDatagram()
     {
         int fileLength, modeLength;
diff --git a/src/java/org/apache/commons/net/tftp/TFTPWriteRequestPacket.java b/src/main/java/org/apache/commons/net/tftp/TFTPWriteRequestPacket.java
similarity index 98%
rename from src/java/org/apache/commons/net/tftp/TFTPWriteRequestPacket.java
rename to src/main/java/org/apache/commons/net/tftp/TFTPWriteRequestPacket.java
index f7980a2..99bb07d 100644
--- a/src/java/org/apache/commons/net/tftp/TFTPWriteRequestPacket.java
+++ b/src/main/java/org/apache/commons/net/tftp/TFTPWriteRequestPacket.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.tftp;
 
 import java.net.DatagramPacket;
diff --git a/src/java/org/apache/commons/net/TimeTCPClient.java b/src/main/java/org/apache/commons/net/time/TimeTCPClient.java
similarity index 95%
rename from src/java/org/apache/commons/net/TimeTCPClient.java
rename to src/main/java/org/apache/commons/net/time/TimeTCPClient.java
index a174196..6684d07 100644
--- a/src/java/org/apache/commons/net/TimeTCPClient.java
+++ b/src/main/java/org/apache/commons/net/time/TimeTCPClient.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,11 +14,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.commons.net;
 
+package org.apache.commons.net.time;
+
+import java.io.DataInputStream;
 import java.io.IOException;
 import java.util.Date;
-import java.io.DataInputStream;
+
+import org.apache.commons.net.SocketClient;
 
 /***
  * The TimeTCPClient class is a TCP implementation of a client for the
@@ -78,7 +81,7 @@
     {
         DataInputStream input;
         input = new DataInputStream(_input_);
-        return (long)(input.readInt() & 0xffffffffL);
+        return (input.readInt() & 0xffffffffL);
     }
 
     /***
diff --git a/src/java/org/apache/commons/net/TimeUDPClient.java b/src/main/java/org/apache/commons/net/time/TimeUDPClient.java
similarity index 95%
rename from src/java/org/apache/commons/net/TimeUDPClient.java
rename to src/main/java/org/apache/commons/net/time/TimeUDPClient.java
index 83ed256..1596b69 100644
--- a/src/java/org/apache/commons/net/TimeUDPClient.java
+++ b/src/main/java/org/apache/commons/net/time/TimeUDPClient.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,13 +14,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.commons.net;
+
+package org.apache.commons.net.time;
 
 import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.InetAddress;
 import java.util.Date;
 
+import org.apache.commons.net.DatagramSocketClient;
+
 /***
  * The TimeUDPClient class is a UDP implementation of a client for the
  * Time protocol described in RFC 868.  To use the class, merely
@@ -30,7 +33,7 @@
  * {@link #getTime  getDate } to retrieve the time. Then call
  * {@link org.apache.commons.net.DatagramSocketClient#close  close }
  * to close the connection properly.  Unlike
- * {@link org.apache.commons.net.TimeTCPClient},
+ * {@link org.apache.commons.net.time.TimeTCPClient},
  * successive calls to {@link #getTime  getTime } or
  * {@link #getDate  getDate } are permitted
  * without re-establishing a connection.  That is because UDP is a
diff --git a/src/main/java/org/apache/commons/net/util/ListenerList.java b/src/main/java/org/apache/commons/net/util/ListenerList.java
new file mode 100644
index 0000000..3fc5059
--- /dev/null
+++ b/src/main/java/org/apache/commons/net/util/ListenerList.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.net.util;
+
+import java.io.Serializable;
+import java.util.EventListener;
+import java.util.Iterator;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * @author Daniel F. Savarese
+ */
+
+public class ListenerList implements Serializable, Iterable<EventListener>
+{
+    private final CopyOnWriteArrayList<EventListener> __listeners;
+
+    public ListenerList()
+    {
+        __listeners = new CopyOnWriteArrayList<EventListener>();
+    }
+
+    public void addListener(EventListener listener)
+    {
+            __listeners.add(listener);
+    }
+
+    public  void removeListener(EventListener listener)
+    {
+            __listeners.remove(listener);
+    }
+
+    public int getListenerCount()
+    {
+        return __listeners.size();
+    }
+    
+    /**
+     * Return an {@link Iterator} for the {@link EventListener} instances
+     * 
+     * @since 2.0
+     * TODO Check that this is a good defensive strategy
+     */
+    public Iterator<EventListener> iterator() {
+            return __listeners.iterator();
+    }
+
+}
diff --git a/src/main/java/org/apache/commons/net/util/SubnetUtils.java b/src/main/java/org/apache/commons/net/util/SubnetUtils.java
new file mode 100644
index 0000000..78d1123
--- /dev/null
+++ b/src/main/java/org/apache/commons/net/util/SubnetUtils.java
@@ -0,0 +1,239 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.net.util;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * A class that performs some subnet calculations given a network address and a subnet mask. 
+ * @see "http://www.faqs.org/rfcs/rfc1519.html"
+ * @author <rwinston@apache.org>
+ * @since 2.0
+ */
+public class SubnetUtils {
+
+    private static final String IP_ADDRESS = "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})";
+    private static final String SLASH_FORMAT = IP_ADDRESS + "/(\\d{1,3})";
+    private static final Pattern addressPattern = Pattern.compile(IP_ADDRESS);
+    private static final Pattern cidrPattern = Pattern.compile(SLASH_FORMAT);
+    private static final int NBITS = 32;
+
+    private int netmask = 0;
+    private int address = 0;
+    private int network = 0;
+    private int broadcast = 0;
+
+    /**
+     * Constructor that takes a CIDR-notation string, e.g. "192.168.0.1/16"
+     * @param cidrNotation A CIDR-notation string, e.g. "192.168.0.1/16"
+     */
+    public SubnetUtils(String cidrNotation) {
+        calculate(cidrNotation);
+    }
+
+    /**
+     * Constructor that takes a dotted decimal address and a dotted decimal mask. 
+     * @param address An IP address, e.g. "192.168.0.1"
+     * @param mask A dotted decimal netmask e.g. "255.255.0.0"
+     */
+    public SubnetUtils(String address, String mask) {
+        calculate(toCidrNotation(address, mask));
+    }
+
+    /**
+     * Convenience container for subnet summary information.
+     *
+     */
+    public final class SubnetInfo {
+        private SubnetInfo() {}
+
+        private int netmask()       { return netmask; }
+        private int network()       { return network; }
+        private int address()       { return address; }
+        private int broadcast()     { return broadcast; }
+        private int low()           { return network() + 1; }
+        private int high()          { return broadcast() - 1; }
+
+        /**
+         * Returns true if the parameter <code>address</code> is in the 
+         * range of usable endpoint addresses for this subnet. This excludes the
+         * network and broadcast adresses.
+         * @param address A dot-delimited IPv4 address, e.g. "192.168.0.1"
+         * @return True if in range, false otherwise
+         */
+        public boolean isInRange(String address)    { return isInRange(toInteger(address)); }
+        
+        private boolean isInRange(int address)      { 
+            int diff = address-low();
+            return (diff >= 0 && (diff <= (high()-low())));
+        }
+
+        public String getBroadcastAddress()         { return format(toArray(broadcast())); }
+        public String getNetworkAddress()           { return format(toArray(network())); }
+        public String getNetmask()                  { return format(toArray(netmask())); }
+        public String getAddress()                  { return format(toArray(address())); }
+        public String getLowAddress()               { return format(toArray(low())); }
+        public String getHighAddress()              { return format(toArray(high())); }
+        public int getAddressCount()                { return (broadcast() - low()); }
+
+        public int asInteger(String address)        { return toInteger(address); }
+        
+        public String getCidrSignature() { 
+            return toCidrNotation(
+                    format(toArray(address())), 
+                    format(toArray(netmask()))
+            );
+        }
+        
+        public String[] getAllAddresses() { 
+            String[] addresses = new String[getAddressCount()];
+            for (int add = low(), j=0; add <= high(); ++add, ++j) {
+                addresses[j] = format(toArray(add));
+            }
+            return addresses;
+        }
+        
+        @Override
+        public String toString() {
+        	final StringBuilder buf = new StringBuilder();
+        	buf.append("CIDR Signature:\t[").append(getCidrSignature()).append("]")
+        		.append(" Netmask: [").append(getNetmask()).append("]\n")
+        		.append("Network:\t[").append(getNetworkAddress()).append("]\n")
+        		.append("Broadcast:\t[").append(getBroadcastAddress()).append("]\n")
+        	 	.append("First Address:\t[").append(getLowAddress()).append("]\n")
+        	 	.append("Last Address:\t[").append(getHighAddress()).append("]\n")
+        	 	.append("# Addresses:\t[").append(getAddressCount()).append("]\n");        	 	
+        	return buf.toString();
+        }
+    }
+
+    /**
+     * Return a {@link SubnetInfo} instance that contains subnet-specific statistics
+     * @return new instance
+     */
+    public final SubnetInfo getInfo() { return new SubnetInfo(); }
+
+    /*
+     * Initialize the internal fields from the supplied CIDR mask
+     */
+    private void calculate(String mask) {
+        Matcher matcher = cidrPattern.matcher(mask);
+
+        if (matcher.matches()) {
+            address = matchAddress(matcher);
+
+            /* Create a binary netmask from the number of bits specification /x */
+            int cidrPart = rangeCheck(Integer.parseInt(matcher.group(5)), -1, NBITS-1);
+            for (int j = 0; j < cidrPart; ++j) {
+                netmask |= (1 << 31-j);
+            }
+            
+            rangeCheck(pop(netmask),0, NBITS);
+
+            /* Calculate base network address */
+            network = (address & netmask);
+
+            /* Calculate broadcast address */
+            broadcast = network | ~(netmask);
+        }
+        else 
+            throw new IllegalArgumentException("Could not parse [" + mask + "]");
+    }
+
+    /*
+     * Convert a dotted decimal format address to a packed integer format
+     */
+    private int toInteger(String address) {
+        Matcher matcher = addressPattern.matcher(address);
+        if (matcher.matches()) {
+            return matchAddress(matcher);
+        }
+        else
+            throw new IllegalArgumentException("Could not parse [" + address + "]");
+    }
+
+    /*
+     * Convenience method to extract the components of a dotted decimal address and 
+     * pack into an integer using a regex match
+     */
+    private int matchAddress(Matcher matcher) {
+        int addr = 0;
+        for (int i = 1; i <= 4; ++i) { 
+            int n = (rangeCheck(Integer.parseInt(matcher.group(i)), -1, 255));
+            addr |= ((n & 0xff) << 8*(4-i));
+        }
+        return addr;
+    }
+
+    /*
+     * Convert a packed integer address into a 4-element array
+     */
+    private int[] toArray(int val) {
+        int ret[] = new int[4];
+        for (int j = 3; j >= 0; --j)
+            ret[j] |= ((val >>> 8*(3-j)) & (0xff));
+        return ret;
+    }
+
+    /*
+     * Convert a 4-element array into dotted decimal format
+     */
+    private String format(int[] octets) {
+        StringBuilder str = new StringBuilder();
+        for (int i =0; i < octets.length; ++i){
+            str.append(octets[i]);
+            if (i != octets.length - 1) {
+                str.append("."); 
+            }
+        }
+        return str.toString();
+    }
+
+    /*
+     * Convenience function to check integer boundaries.
+     * Checks if a value x is in the range (begin,end].
+     * Returns x if it is in range, throws an exception otherwise.
+     */
+    private int rangeCheck(int value, int begin, int end) {
+        if (value > begin && value <= end) // (begin,end]
+            return value;
+
+        throw new IllegalArgumentException("Value [" + value + "] not in range ("+begin+","+end+"]");
+    }
+
+    /*
+     * Count the number of 1-bits in a 32-bit integer using a divide-and-conquer strategy
+     * see Hacker's Delight section 5.1 
+     */
+    int pop(int x) {
+        x = x - ((x >>> 1) & 0x55555555); 
+        x = (x & 0x33333333) + ((x >>> 2) & 0x33333333); 
+        x = (x + (x >>> 4)) & 0x0F0F0F0F; 
+        x = x + (x >>> 8); 
+        x = x + (x >>> 16); 
+        return x & 0x0000003F; 
+    } 
+
+    /* Convert two dotted decimal addresses to a single xxx.xxx.xxx.xxx/yy format
+     * by counting the 1-bit population in the mask address. (It may be better to count 
+     * NBITS-#trailing zeroes for this case)
+     */
+    private String toCidrNotation(String addr, String mask) {
+        return addr + "/" + pop(toInteger(mask));
+    }
+}
diff --git a/src/java/org/apache/commons/net/WhoisClient.java b/src/main/java/org/apache/commons/net/whois/WhoisClient.java
similarity index 95%
rename from src/java/org/apache/commons/net/WhoisClient.java
rename to src/main/java/org/apache/commons/net/whois/WhoisClient.java
index 19501a3..edfba73 100644
--- a/src/java/org/apache/commons/net/WhoisClient.java
+++ b/src/main/java/org/apache/commons/net/whois/WhoisClient.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,11 +14,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.commons.net;
+
+package org.apache.commons.net.whois;
 
 import java.io.IOException;
 import java.io.InputStream;
 
+import org.apache.commons.net.finger.FingerClient;
+
 /***
  * The WhoisClient class implements the client side of the Internet Whois
  * Protocol defined in RFC 954.   To query a host you create a
diff --git a/src/site/site.xml b/src/site/site.xml
index e756b7a..571a09a 100644
--- a/src/site/site.xml
+++ b/src/site/site.xml
@@ -1,45 +1,43 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
 <!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements.  See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License.  You may obtain a copy of the License at
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
 
-      http://www.apache.org/licenses/LICENSE-2.0
+       http://www.apache.org/licenses/LICENSE-2.0
 
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
 -->
-<project name="Net">
-    <bannerRight>
-        <name>Commons Net</name>
-        <src>/images/net-logo-white.png</src>
-        <href>/index.html</href>
-    </bannerRight>
+<project name="Commons Net">
 
-    <body>
-        <menu name="Net">
-            <item name="Overview"              href="/index.html"/>
-            <item name="Migration How-to"      href="/migration.html"/>
-            <item name="FAQ"                   href="/faq.html"/>
-            <item name="Download"              href="/download.html"/>
-            <item name="Release Notes"         href="/changes-report.html"/>
-        </menu>
+  <bannerRight>
+    <name>Commons Net</name>
+    <src>/images/net-logo-white.png</src>
+    <href>/index.html</href>
+  </bannerRight>
 
-        <menu name="Development">
-            <item name="To-Do List"            href="/tasks.html"/>
-            <item name="Coding Specifications" href="/code-standards.html"/>
-            <item name="Mailing Lists"         href="/mail-lists.html"/>
-            <item name="Issue Tracking"        href="/issue-tracking.html"/>
-            <item name="Source Repository"     href="/source-repository.html"/>
-            <item name="Javadoc (SVN latest)"  href="apidocs/index.html"/>
-        </menu>
-
-    </body>
+  <body>
+    <menu name="Documentation">
+      <item name="Migration How-to"      href="/migration.html"/>
+      <item name="FAQ"                   href="/faq.html"/>
+      <item name="Download"              href="/download.html"/>
+      <item name="Javadoc"               href="apidocs/index.html"/>
+      <item name="Release Notes"         href="/changes-report.html"/>
+      <item name="Issue Tracking"        href="/issue-tracking.html"/>
+    </menu>
+    <menu name="Development">
+      <item name="Coding Specifications" href="/code-standards.html"/>
+    </menu>
+    
+    ${reports}
+    
+  </body>
 
 </project>
diff --git a/src/site/xdoc/changes.xml b/src/site/xdoc/changes.xml
new file mode 100644
index 0000000..930898a
--- /dev/null
+++ b/src/site/xdoc/changes.xml
@@ -0,0 +1,608 @@
+<?xml version="1.0"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<document>
+	<properties>
+		<title>Changes</title>
+		<author email="rwinston@apache.org">Rory Winston</author>
+	</properties>
+
+
+	<body>
+		<release version="2.1" description="Fix release">
+			<action dev="rwinston" type="fix" issue="NET-215">
+				UNIXFTPEntryParser didn't preserve trailing whitespace in files
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-236">
+				method SubnetUtils.SubnetInfo.isInRange(addr) returns incorrect result
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-242">
+				Method createServerSocket of FTPSSocketFactory never called and thus UseClientMode is incorrect in a secured ftp transfer using active mode.
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-248">
+				Fix inconsistent command list in FTPCommand
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-250">
+				DefaultFTPFileEntryParserFactory did not work with Netware FTP server returning "NETWARE TYPE: L8"
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-257">
+				FTP.getReplyStrings() returned array of null Strings
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-259">
+				UnixFTPEntryParser regex did not match some directory entries
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-260">
+				SubnetUtils.SubnetInfo.isInRange(...) returned incorrect values
+			</action>
+			<action dev="rwinston" type="update" issue="NET-261">
+				SubnetUtils.SubnetInfo.isInRange(...) behaviour not documented
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-262">
+				SubnetUtils did not handle /31 and /32 CIDRs well
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-265">
+				UnixFTPEntryParser failed to parse entry in certain conditions
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-266">
+				FTPClient.listFiles() corrupted file name in certain circumstances
+			</action>
+			<action dev="rwinston" type="update" issue="NET-251">
+				Moved class "ThreadContainer" from Threader.java into its own source file
+			</action>
+			<action dev="rwinston" type="update" issue="NET-252">
+				Get rid of using deprecated API in VMSFTPEntryParser
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-256">
+				FTPSClient should accept a pre-configured SSLContext
+			</action>
+			<action dev="rwinston" type="add" issue="NET-263">
+				SubnetUtils / SubNetInfo toString() implementations
+			</action>
+			<action dev="rwinston" type="fix">
+				Improve NNTPClient handling of invalid articles
+			</action>
+			<action dev="rwinston" type="update">
+				Refactor examples package.
+			</action>
+			<action dev="sebb" type="add">
+				Javadoc fixes, improvements, and refactoring.
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-245">
+				Apply MFMT patch 
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-279">
+				Fix copying of reply lines collection
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-277">
+				Fix incorrect NNTP constant
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-276">
+				Use long instead of int for newsgroup counts
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-274">
+				Restore socket state after CCC command
+			</action>
+			<action dev="rwinston" type="fix">
+				Fix inconsistent handling of socket read/write buffer size
+			</action>
+		</release>
+
+		<release version="2.0" date="October 20, 2008" description="Java 5.0 release">
+			<action dev="rwinston" type="update">
+				Add null check in TelnetClient::disconnect().
+			</action>
+			<action dev="rwinston" type="remove">
+				Remove deprecated FTPFileIterator and FTPFileList classes.
+			</action>
+			<action dev="rwinston" type="add">
+				Add connection timeout functionality to SocketClient.
+			</action>
+			<action dev="rwinston" type="update">
+				Make the KeyManager and TrustManager settable (niklas@protocol7.com).
+			</action>
+			<action dev="rwinston" type="update">
+				Patch FTPSClient to set default SSLServerSocketFactory. Thanks niklas@protocol7.com
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-68">
+				Patch to prevent TFTPClient dropping last packet. Thanks palm@poplarware.com
+			</action>
+			<action dev="rwinston" type="update">
+				Change isConnected() method to delegate to underlying socket connection.
+			</action>
+			<action dev="rwinston" type="add">
+				FTPS (TLS and SSL) is now supported. Thanks to Jose Juan Montiel, Paul Ferraro, and Satoshi Ishigami.
+			</action>
+			<action dev="rwinston" type="update">
+				Commons::Net now uses Maven 2. The project.xml has been replaced with a pom.xml, and the source tree layout
+				has been changed accordingly.
+			</action>
+			<action dev="rwinston" type="remove">
+				Removed old ftp2 proposal directories.
+			</action>
+			<action dev="rwinston" type="update">
+				Commons::Net now uses JDK regex functionality, saving on an extra [oro] dependency. There are now
+				no external dependencies required.
+			</action>
+			<action dev="rwinston" type="fix">
+				Various syntactic issues (FindBugs issues, JDK 5.0 generics support)
+			</action>
+			<action dev="dfs" type="fix">
+				Applied Rob Hasselbaum's
+				rhasselbaum -> alumni.ithaca.edu
+				patch for PR 38688 fixing a
+				TelnetInputStream hang.
+			</action>
+			<action dev="dfs" type="update">
+				Exposed control connection of FTP
+				class via _controlInput_ and _controlOutput_
+				protected member variables in response
+				to PR 38309 reported by
+				josejuan.montiel@gmail.com.
+			</action>
+			<action dev="dfs" type="fix">
+				Reverted PR 32859 patch to TFTPClient
+				because it caused final packets to not
+				be sent.
+			</action>
+			<action dev="rwinston" type="update" issue="NET-36">
+				Make FTPClient extend SocketClient instead of TelnetClient. From jhindsley@providerlink.com
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-39">
+				Adds an "e" symbolic link flag to the Unix FTP parser. From denisgaebler@netscape.net
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-119">
+				Allow hidden files to be listed. Thanks to mario@ops.co.at
+			</action>
+			<action dev="rwinston" type="update">
+				Remove reflective check for Socket::isConnected() (no longer needed)
+			</action>
+			<action dev="rwinston" type="add" issue="NET-136">
+				Added WindowSizeOptionHandler for TelnetClient. Thanks to yuvalkashtan@gmail.com
+			</action>
+			<action dev="rwinston" type="update">
+				Refactored *Client classes under net/ package into separate subpackages, and move PrintCommandListener 
+				out of the examples/ package.
+			</action>
+			<action dev="rwinston" type="add">
+				Added an ant target to the Maven build to generate an FTP-only jar file, for clients who 
+				wish to use only FTP-based functionality.
+			</action>
+			<action dev="rwinston" type="update">
+				Custom SocketFactory interface has been replaced with the JDK SocketFactory implementation. Added
+				ServerSocketFactory instance to SocketClient.
+			</action>
+			<action dev="rwinston" type="update">
+				Removed redundant FTP.IMAGE_FILE_TYPE flag.
+			</action>
+			<action dev="rwinston" type="update">
+				Added heavily updated MVSFTPEntryParser from henrik.sorensen@balcab.ch
+			</action>
+			<action dev="rwinston" type="remove">
+				Removed deprecated classes FTPFileListParser, FTPFileListParserImpl, and DefaultFTPFileListParser. Also
+				removed associated deprecated methods from FTPClient.
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-164">
+				Added encoding to FingerClient. From Ulrich Mayring.
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-24">
+				Catch BindException in RCommandClient::connect().
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-178">
+				Add encoding specifier to SMTPClient.
+			</action>
+			<action dev="rwinston" type="add">
+				Add setters for socket send/receive buffer size to SocketClient.
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-177">
+				Fix PASV specifiers that broke previously. From Chris Eagle.
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-182">
+				Catch NPE in FTP parser factory method.
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-172">
+				Don't bind a UDP socket to NTP protocol port.
+			</action>
+			<action dev="rwinston" type="fix">
+				Better handling of user and group names with embedded spaces in FTP listings.
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-173">
+				Add configurable multiline parsing.
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-188">
+				Add fix for broken leap year date parsing.
+			</action>
+			<action dev="rwinston" type="add">
+				Add SubnetUtils class (suggested by Kenny McLeod)
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-169">
+				Add Unix-type handling for UNKNOWN Type: L8 syst() message systems.
+			</action>
+			<action dev="rwinston" type="fix" issue="NET-198">
+				Allow FTPTimestampParserImpl to take a predefined Calendar instance representing current time.
+			</action>
+			<action dev="sebb" type="fix" issue="NET-194">
+				Replace Exception with IOException
+			</action>
+			<action dev="sebb" type="update" issue="NET-214">
+				VMS file permission parsing
+			</action>
+			<action dev="sebb" type="fix" issue="NET-208">
+				TelnetInputStream swallows interruptedexception as IOException
+			</action>
+			<action dev="sebb" type="fix" issue="NET-223">
+				the data connection socket is not closed when an IOException occurred
+			</action>
+			<action dev="sebb" type="fix" issue="NET-230">
+				ParserInitializationException when connecting to a Unix FTP server: comparison string must be upper case
+			</action>
+			<action dev="sebb" type="fix" issue="NET-225">
+				FTPFileEntryParserImpl.preParse() doesn't remove unparsable entries at the end of the file list
+			</action>
+		</release>	
+
+
+		<release version="1.5.0" date="" description="">
+			<action dev="dfs" type="fix" issue="NET-3">
+				TelnetInputStream.java: Applied Rob
+				Hasselbaum's
+				rhasselbaum@alumni.ithaca.edu
+				patch for PR 38688 fixing a
+				TelnetInputStream hang.
+			</action>
+			<action dev="rwinston" type="fix"
+				issue="NET-73">
+				TelnetInputStream.java: Fixing another
+				potential deadlock for 
+				telnet and FTP (patch courtesy Rob Hasselbaum).
+			</action>
+			<action dev="dfs" type="update" issue="NET-57">
+				FTP.java: Exposed control connection of
+				FTP
+				class via _controlInput_ and
+				_controlOutput_
+				protected member variables in response
+				to PR 38309 reported by
+				josejuan.montiel@gmail.com.
+			</action>
+			<action dev="rwinston" type="fix"
+				issue="NET-68">
+				TFTPClient.java: Fix bug causing final
+				packets
+				to not be sent.
+			</action>
+			<action dev="rwinston" type="fix"
+				issue="NET-161">
+				TFTPClient.java: Fix sendFile() (related
+				to NET-68).
+			</action>
+			<action dev="rwinston" type="fix"
+				issue="NET-181">
+				TFTPClient.java: block number
+				wraparound.
+			</action>
+			<action dev="scohen" type="fix" issue="NET-16">
+				UNIXFTPEntryParser.java: support for
+				group names with
+				spaces (patch courtesy D. Kilzer).
+			</action>
+			<action dev="scohen" type="fix" issue="NET-62">
+				DefaultFTPFileEntryParserFactory.java:
+				Wrap 
+				NoClassDefFoundError in FTP parser exception
+				when ORO is not available.
+			</action>
+			<action dev="rwinston" type="add"
+				issue="NET-33">
+				FTPClient.java: Fix closing FTP
+				ServerSocket after timeout
+			</action>
+			<action dev="rwinston" type="add">
+				FTPClientConfig.java: Added an FTP
+				parser for Netware FTP servers.
+				Tested on Novell Netware 6.5.
+			</action>
+			<action dev="rwinston" type="fix"
+				issue="NET-188">
+				FTPTimestampParserImpl.java: Fix leap
+				year date parsing bug.
+			</action>
+			<action dev="rwinston" type="fix">
+				Article.java: Fix minor issues with NNTP
+				parsing.
+			</action>
+		</release> 
+
+
+
+		<release version="1.4.1" date="December 3, 2005" description="fix release to restore jdk 1.3 compatability">
+			<action dev="scohen" type="fix">
+				Applied patches for defect 37113. Code incompatible with jdk 1.3. Original patch submitted by Andrea Rombald
+			</action>
+			<action dev="scohen" type="fix">
+				Applied patches for defect 37522. updated project.xml to correct compatibility level.
+			</action>
+		</release>
+
+		<release version="1.4.0" date="May 7, 2005" description="Some additions and enhancements">
+			<action dev="dfs" type="fix">
+				Fixed typo in method name.
+				FTP.removeCommandListener() was missing
+				the L.  Problem reported by
+				Per.Lindberger@linkon.se.
+			</action>
+			<action dev="rwinston" type="fix">
+				Applied fix for PR 33942 and PR 31793. Original patch submitted by mario@ops.co.at
+			</action>
+			<action dev="rwinston" type="fix">
+				TFTPClient was ignoring final ACK (PR 32859). Thanks to perttu.auramo@ekahau.com
+			</action>
+			<action dev="rwinston" type="fix">
+				Applied fix for ACL parsing in the FTP client (PR 33972). Submitted by robertalasch@yahoo.com
+			</action>
+			<action dev="rwinston" type="fix">
+				Added missing NTP/SNTP unit tests to the codebase.
+			</action>
+			<action dev="dfs" type="fix">
+				Applied fix for POP3Client returning empty reply strings (PR 34133). Thanks to sammy_c@lineone.net
+			</action>
+			<action dev="rwinston" type="fix">
+				NTP port parameter was being ignored (PR 34219). Fixed by felix.eichhorn@3soft.de
+			</action>
+			<action dev="scohen" type="add">
+				An FTP parser for MVS was added. Submitted by wnoto@openfinance.com
+			</action>
+			<action dev="scohen" type="add">
+				Added functionality for extensible parsing of FTP responses, using a configurable format string. This should enable the FTP client to operate across many different locales and date formats.
+			</action>
+		</release>
+
+		<release version="1.3.0" date="December 15, 2004" description="many fixes and enhancements">
+			<action dev="rwinston" type="fix">
+				Applied patch for PR 31793. Thanks to mario@ops.co.at
+			</action>
+			<action dev="rwinston" type="add">
+				Added message threading functionality to the NNTP client.
+			</action>
+			<action dev="rwinston" type="update">
+				Added return code 521 to FTPReply.java - this should obviate the need for the Ant FTP task to manually declare it.
+			</action>
+			<action dev="rwinston" type="fix">
+				Add explicit notify() in TelnetInputStream::read(), so available() returns an accurate value. Thanks to tpalkot@gmail.com.
+			</action>
+			<action dev="rwinston" type="add">
+				Added SNTP/NTP components into the Commons-Net codebase, courtesy of
+				Jason Matthews.
+			</action>
+			<action dev="rwinston" type="add">
+				Added POP3 test suite, courtesy of Mike George mike.george@comcast.net.
+			</action>
+			<action dev="scohen" type="fix">
+				Applied fix for FTPClient returning null for certain timestamp formats (BUG #30737)
+			</action>
+			<action dev="rwinston" type="fix">
+				Build.xml fixes - dont include example classes in redistributable
+				.jar, remove test dependency from javadoc target, and exclude private members from generated javadoc.
+			</action>
+			<action dev="rwinston" type="fix">
+				Fixed bug in TFTPClient::setMaxTimeout(), spotted by steve@widge.net
+			</action>
+			<action dev="dfs" type="fix">
+				Some changes to facilitate compilation under JDK 5.0
+			</action>
+			<action dev="rwinston" type="fix">
+				Return correct NNTP article count when high and low watermarks are 0.
+				Spotted by jmordax@terra.es
+			</action>
+			<action dev="rwinston" type="fix">
+				Remove trailing null byte in TFTP packets. Thanks to gerard.dens@alcatel.be
+			</action>
+			<action dev="dfs" type="fix">
+				Many javadoc fixes.
+			</action>
+			<action dev="rwinston" type="update">
+				Allow FTPClient to set transfer buffer size.
+			</action>
+			<action dev="rwinston" type="update">
+				Ensure consistent handling of encoding throughout FTPClient
+				operations. Patch submitted by leif@tanukisoftware.com.
+			</action>
+			<action dev="dfs" type="fix">
+				Fix TelnetClient zombie thread issue
+			</action>	
+
+
+		</release>
+		<release version="1.3.0-dev" date="July 28, 2004"
+			description="regression fix">
+			<action dev="dfs" type="fix">
+				Fixed regression from migration to new parsers.  Most of the
+				new parsers parsed the file size as an integer instead of a
+				long.  Changed all of them to set the size to long.  This
+				problem was detected by the reporter of:
+				http://issues.apache.org/bugzilla/show_bug.cgi?id=30345
+			</action>
+		</release>
+		<release version="1.2.2" date="June 25, 2004" description="fix release">
+			<action dev="scohen" type="fix">
+				fixed bug in the way FTPClient.listFiles worked when a directory was not
+				specified.  Current directory was not being 'remembered'.  This was most 
+				problematic in the dependent ftp task of Ant.
+			</action>
+			<action dev="scohen" type="fix">
+				fixed handling of certain unusual "special" file types in the Unix parser.
+			</action>
+		</release>	
+
+		<release version="1.2.1" date="May 6, 2004" description="fix release">
+			<action dev="scohen" type="fix">
+				changed code that rendered package uncompilable under JDK 1.2
+			</action>
+		</release>	
+
+		<release version="1.2.0" date="April 30, 2004" description="autodetection of system for listings">
+			<action dev="scohen" type="fix">
+				Mario Ivankovits mario@ops.co.at added
+				functionality supporting correct handling of the &quot;dirstyle&quot; 
+				attribute of NT and OS400 servers that allows them to mimic Unix ftp servers.
+				and a bug fix affecting handling of sticky and suid bits on Unix FTP servers.
+			</action>
+			<action dev="scohen" type="add">
+				Mario Ivankovits mario@ops.co.at added parser for OS400.
+			</action>
+			<action dev="jbrekke,scohen" type="fix">
+				Added a functional junit test testing list parsing against real servers 
+				and fix several	bugs found through this test.
+			</action>
+			<action dev="dfs" type="add">
+				Ted Wise ctwise@bellsouth.net provided a
+				<a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=24078">
+					patch</a> to add the XHDR extended NNTP command.
+			</action>
+			<action dev="scohen,dfs" type="update">
+				Deprecated FTPFileListParser interface, DefaultFTPFileListParser
+				class, and the FTPClient.listFiles methods that accepted an
+				FTPFileListParser parameter.  These deprecated classes and methods
+				will be removed in version 2.0.
+			</action>
+			<action dev="scohen" type="add">
+				Added org.apache.commons.net.parser.FTPFileEntryParserFactory
+				interface and a default implementation:
+				DefaultFTPFileEntryParserFactory.  This addition facilitates the
+				autodetection of which FTPFileEntryParser to use to generate
+				listings.  FTPClient.listFiles methods were added that implement
+				autodetection.
+			</action>
+		</release>
+
+		<release version="1.1.1" date="TBD" description="last jdk1.1 compatible release">
+			<action dev="scohen" type="fix">
+				Removed all JDK 1.1 incompatibilities that had been introduced
+				unintentionally in previous versions.  Release 1.1.1 is the last 
+				JDK 1.1 compatible release.  Any future 1.1.x maintenance releases
+				will remain JDK !.1 compatible, but version 1.2 may break
+				compatibility and will be guaranteed to work with only J2SE 1.2
+				and later.
+			</action>
+		</release>
+
+		<release version="1.1.0" date="October 23, 2003" description="many enhancements and bug fixes">
+			<action dev="dfs" type="add">
+				Rory Winston Rory.Winston@telewest.co.uk provided
+				patches to add the following extended NNTP commands to
+				NNTPClient: XOVER, AUTHINFO USER, AUTHINFO PASS, and
+				LIST ACTIVE.
+			</action>
+			<action dev="dfs" type="fix">
+				Changed connection hooks for FTP, SMTP, POP3, and NNTP classes
+				to force use of an 8-bit US-ASCII superset (ISO-8859-1) for
+				protocol communication.  This was necessary because
+				InputStreamReader and OutputStreamWriter use the default
+				client-side character set encoding.  fasselin@ca.ibm.com
+				reported failure of SMTP on OS/390 which has EBCDIC as the
+				native character set.
+			</action>
+
+			<action dev="dfs" type="fix">
+				Applied variation of fix suggested by Matthieu Recouly
+				matthieu.recouly@laposte.net so that
+				UnixFTPEntryParser may handle listings of the form
+				<pre>
+					drwxr-xr-x 1 usernameftp 512 Jan 29 23:32 prog
+				</pre>
+				where the space between user name and group is omitted.
+			</action>
+			<action dev="dfs" type="fix">
+				Applied patch from Stephane Este-Gracias
+				sestegra@free.fr that fixes the parsing of
+				VMS listings by VMSFTPEntryParser..
+			</action>
+			<action dev="brekke" type="fix">
+				If the buffer queue run full, the run() method sometimes hangs forever.
+				Changed wait() to wait(100) as with other changes in TelnetInputStream.
+				Fix submitted From: J. Matysiak ( j.matysiak@cenit.de ).
+			</action>
+			<action dev="brekke" type="fix">
+				FTP.smnt(String dir) was not passing on the dir to the SMNT command as an argument.
+			</action>
+			<action dev="brekke" type="add">
+				Added a link to the FAQ currently hosted on the Apache Wiki.
+			</action>
+			<action dev="dfs" type="update">
+				Changed package private NNTP._reader and NNTP._writer member
+				variables to protected NNTP._reader_ and NNTP._writer_
+				variables as suggested by issue report 16995 to facilitate
+				extending NNTPClient functionality in subclasses.
+			</action>
+			<action dev="dfs" type="update">
+				Changed name of FTPClient.__openDataConnection() to
+				FTPClient._openDataConnection_() to remain consistent
+				with the convention in the code that protected members
+				are of the form _foo_.  At some point __openDataConnection()
+				had been changed from private to protected.
+			</action>
+			<action dev="brekke" type="add">
+				Added terminal option support to the telnet client with tests.
+				From Bruno D'Avanzo ( b.davanzo@inwind.it ).
+			</action>
+			<action dev="scohen" type="add">
+				New parsers merged with mainline with support for old list parsers.
+			</action>
+		</release>
+
+		<release version="1.0.0" date="February 23, 2003" description="first jakarta-commons release">
+			<action dev="brekke" type="add">
+				Added a migration document for moving from NetComponents to Commons/Net.
+			</action>
+			<action dev="brekke" type="fix">
+				Moved the ftp2 tree with tests to a proposal directory and setup 
+				a build for that code.  This can grow in this area so users don't 
+				think it is production ready.
+			</action>
+			<action dev="dfs" type="fix">
+				Cleaned up license header on some source.
+			</action>
+			<action dev="dfs" type="fix">
+				Moved .io and .util to .net.io and .net.util in preparation for
+				1.0 release.
+			</action>
+			<action dev="dfs" type="fix">
+				Fixed typo in NNTP.removeProtocolCommandListener() method name.  It
+				was missing an L.  From: joev@atg.com.
+			</action>
+			<action dev="brekke" type="add">
+				Various site updates including this changes doc and publish
+				date information.
+			</action>
+			<action dev="dfs" type="fix">
+				Patch for restarting FTP file transfers.  The offset was not
+				being sent immediately before the data transfer command on
+				account.  The bug was apparently introduced in NetComponents
+				when it was decided to always send a PORT command before each data 
+				transfer to avoid socket reuse problems on Windows.  
+				From: Tapan Karecha ( tapan@india.hp.com ).
+			</action>
+			<action dev="dfs" type="fix">
+				Applied a fix for potential deadlock in TelnetInputStream by
+				changing a wait() to a wait(100).
+				From: Tapan Karecha ( tapan@india.hp.com ).
+			</action>
+			<action dev="dfs" type="update">
+				FTP examples now use passive ftp connections.
+			</action>
+		</release>
+	</body>
+</document>
diff --git a/xdocs/code-standards.xml b/src/site/xdoc/code-standards.xml
similarity index 91%
rename from xdocs/code-standards.xml
rename to src/site/xdoc/code-standards.xml
index 9510f6d..85712f3 100644
--- a/xdocs/code-standards.xml
+++ b/src/site/xdoc/code-standards.xml
@@ -1,11 +1,11 @@
 <?xml version="1.0"?>
 <!--
    Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
 
        http://www.apache.org/licenses/LICENSE-2.0
 
@@ -43,7 +43,7 @@
 </p>
 
 <p>
-Below is a list of coding conventions that are specific to Apache Commons/Net
+Below is a list of coding conventions that are specific to Jakarta Commons/Net
 everything else not specificially mentioned here should follow the official
 <a href="http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html">Sun
 Java Coding Conventions</a>.
diff --git a/src/site/xdoc/download.xml b/src/site/xdoc/download.xml
new file mode 100644
index 0000000..97a7b58
--- /dev/null
+++ b/src/site/xdoc/download.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<document>
+
+  <properties>
+    <title>Jakarta Commons/Net Download</title>
+    <author email="brekke@apache.org">Jeffrey D. Brekke</author>
+  </properties>
+
+  <body>
+
+<section name="Release Builds">
+<p>
+You can download <a href="http://commons.apache.org/downloads/download_net.cgi">binary</a> or <a href="http://commons.apache.org/downloads/download_net.cgi">source</a> production releases.
+</p>
+    
+</section>
+
+<section name="Nightly Builds">
+
+<p>
+You will find the list of nightly builds <a href="http://jakarta.apache.org/builds/jakarta-commons/nightly/commons-net/">here</a>.
+</p>
+
+</section>
+
+</body>
+</document>
diff --git a/xdocs/download_net.xml b/src/site/xdoc/download_net.xml
similarity index 100%
rename from xdocs/download_net.xml
rename to src/site/xdoc/download_net.xml
diff --git a/xdocs/faq.xml b/src/site/xdoc/faq.xml
similarity index 64%
rename from xdocs/faq.xml
rename to src/site/xdoc/faq.xml
index afe0373..f4273c8 100644
--- a/xdocs/faq.xml
+++ b/src/site/xdoc/faq.xml
@@ -1,11 +1,11 @@
 <?xml version="1.0"?>
 <!--
    Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
 
        http://www.apache.org/licenses/LICENSE-2.0
 
@@ -20,7 +20,7 @@
 
   <properties>
     <title>Commons/Net FAQ</title>
-    <author email="user@commons.apache.org">Commons/User Mailing List</author>
+    <author email="commons-user@jakarta.apache.org">Commons/User Mailing List</author>
   </properties>
 
   <body>
@@ -34,7 +34,7 @@
         before posting to the mailing lists.
       </p>
       <p>
-        <a href="http://wiki.apache.org/commons/Net/FrequentlyAskedQuestions">CommonsNet/FrequentlyAskedQuestions</a> 
+        <a href="http://wiki.apache.org/jakarta-commons/Net/FrequentlyAskedQuestions">CommonsNet/FrequentlyAskedQuestions</a> 
       </p> 
     </section>
   </body>
diff --git a/xdocs/index.xml b/src/site/xdoc/index.xml
similarity index 67%
rename from xdocs/index.xml
rename to src/site/xdoc/index.xml
index 0546aba..809cc74 100644
--- a/xdocs/index.xml
+++ b/src/site/xdoc/index.xml
@@ -2,11 +2,11 @@
 <!DOCTYPE org.apache.commons.menus SYSTEM '../../commons-build/menus/menus.dtd'>
 <!--
    Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
 
        http://www.apache.org/licenses/LICENSE-2.0
 
@@ -19,15 +19,15 @@
 <document>
 
  <properties>
-  <title>Apache Commons Net</title>
-  <author email="dev@commons.apache.org">Commons Documentation Team</author>
+  <title>Jakarta Commons Net</title>
+  <author email="commons-dev@jakarta.apache.org">Commons Documentation Team</author>
  </properties>
 
  <body>
  
-   <section name="Apache Commons Net">
+   <section name="Jakarta Commons Net">
    <p>
-     Apache Commons Net implements the client side of many basic
+     Jakarta Commons Net implements the client side of many basic
      Internet protocols.  The purpose of the library is to provide
      fundamental protocol access, not higher-level
      abstractions. Therefore, some of the design violates
@@ -44,7 +44,7 @@
    <p>
      Supported protocols are:
      <ul>
-       <li>FTP</li>
+       <li>FTP/FTPS</li>
        <li>NNTP</li>
        <li>SMTP</li>
        <li>POP3</li>
@@ -62,15 +62,16 @@
    </section>
    <section name="Background">
    <p>
-    Apache Commons Net started as a commercial Java library called
+    Jakarta Commons Net started as a commercial Java library called
     NetComponents, originally developed by ORO, Inc. in the early
     days of Java.  After its 1.3.8 release in 1998, the source code was
     donated to the Apache Software Foundation and made available under
     the Apache License.  Since then, many programmers have contributed
-    to the continued development of Apache Commons Net.  The current
+    to the continued development of Jakarta Commons Net.  The current
     version numbering scheme bears no relation to the old.  In other
-    words, Apache Commons Net 1.0 succeeded and supplanted
-    NetComponents 1.3.8.
+    words, Jakarta Commons Net 1.0 succeeded and supplanted
+    NetComponents 1.3.8. The latest releases of Commons Net (2.0+) require
+    a JDK 5+ installation.
    </p>
    </section>
    <section name="Further Information">
@@ -78,8 +79,9 @@
 		   For more info, see the JavaDoc, or look at some of the following articles:
 		   <ul>
 			   <li><a href="http://www.informit.com/guides/content.asp?g=java&amp;seqNum=40">http://www.informit.com/guides/content.asp?g=java&amp;seqNum=40</a></li>
-				   <li><a href="http://www.onjava.com/pub/a/onjava/2003/06/25/commons.html?page=3">http://www.onjava.com/pub/a/onjava/2003/06/25/commons.html?page=3</a></li>
-				   </ul>
+			   <li><a href="http://www.onjava.com/pub/a/onjava/2003/06/25/commons.html?page=3">http://www.onjava.com/pub/a/onjava/2003/06/25/commons.html?page=3</a></li>
+			   <li><a href="http://safari.phptr.com/0131478303/ch04">http://safari.phptr.com/0131478303/ch04</a></li>
+		   </ul>
 				   </p>
    </section>
 </body>
diff --git a/xdocs/issue-tracking.xml b/src/site/xdoc/issue-tracking.xml
similarity index 100%
rename from xdocs/issue-tracking.xml
rename to src/site/xdoc/issue-tracking.xml
diff --git a/xdocs/migration.xml b/src/site/xdoc/migration.xml
similarity index 66%
rename from xdocs/migration.xml
rename to src/site/xdoc/migration.xml
index 3fcb865..98b3c6a 100644
--- a/xdocs/migration.xml
+++ b/src/site/xdoc/migration.xml
@@ -1,11 +1,11 @@
 <?xml version="1.0"?>
 <!--
    Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
 
        http://www.apache.org/licenses/LICENSE-2.0
 
@@ -19,7 +19,7 @@
 <document>
 
   <properties>
-    <title>Apache Commons/Net Migration How-to</title>
+    <title>Jakarta Commons/Net Migration How-to</title>
     <author email="brekke@apache.org">Jeffrey D. Brekke</author>
   </properties>
 
@@ -31,6 +31,13 @@
 </p>
 </section>
 
+<section name="Commons/Net 1.4.x to Commons/Net 2.0">
+	<p>
+		This version requires a JDK 5.0+ runtime. It has also been tested on JDK 6.0. There should
+		be no changes required to existing client code.
+	</p>
+</section>
+
 <section name="NetComponents 1.3.8  to  Commons/Net">
 <p>
 This version is a drop in replacement for NetComponents.  Only package names have changed.
diff --git a/xdocs/tasks.xml b/src/site/xdoc/tasks.xml
similarity index 67%
rename from xdocs/tasks.xml
rename to src/site/xdoc/tasks.xml
index 32e386e..3269824 100644
--- a/xdocs/tasks.xml
+++ b/src/site/xdoc/tasks.xml
@@ -1,11 +1,11 @@
 <?xml version="1.0"?>
 <!--
    Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
 
        http://www.apache.org/licenses/LICENSE-2.0
 
@@ -24,14 +24,6 @@
   </properties>
 
   <body>
-    <section name="Pre-1.4 Tasks">
-      <p>
-        <ul>
-          <li>Implement Extensible date format handling for FTPClient (DONE)</li>
-          <li>Scan the bug list</li>
-        </ul>
-      </p> 
-    </section>
     <section name="Wishlist">
       <p>
         <ul>
@@ -44,11 +36,6 @@
             org.apache.commons.net.util and org.apache.commons.net.io could be moved to their corresponding commons projects.
           </li>
           <li>
-            Divorce FTPClient from TelnetClient, getting rid of the 
-            TelnetClient threads which cause problems on some platforms 
-            (e.g., MacOS).
-          </li>
-          <li>
             Parse the client/server interactions without creating so many 
             strings. Many operations are slow because of this.
           </li>
@@ -59,9 +46,7 @@
             Make NNTPClient.listNewsgroups() and NNTPClient.listNewNews() 
             more efficient. Don't preparse into lots of little objects.
           </li>
-          <li>
-            TLS for FTP
-          </li>
+	  <li>FTP proxy support</li>
         </ul>
       </p>
     </section>
diff --git a/src/test/java/org/apache/commons/net/SubnetUtilsTest.java b/src/test/java/org/apache/commons/net/SubnetUtilsTest.java
new file mode 100644
index 0000000..66cbf53
--- /dev/null
+++ b/src/test/java/org/apache/commons/net/SubnetUtilsTest.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.net;
+
+import org.apache.commons.net.util.SubnetUtils;
+import org.apache.commons.net.util.SubnetUtils.SubnetInfo;
+
+import junit.framework.TestCase;
+
+public class SubnetUtilsTest extends TestCase {
+    
+    public void testParseSimpleNetmask() {
+        final String address = "192.168.0.1";
+        final String masks[] = new String[] { "255.0.0.0", "255.255.0.0", "255.255.255.0", "255.255.255.248"};
+        final String bcastAddresses[] = new String[] { "192.255.255.255", "192.168.255.255", "192.168.0.255", "192.168.0.7"};
+        final String lowAddresses[] = new String[] { "192.0.0.1", "192.168.0.1", "192.168.0.1", "192.168.0.1" };
+        final String highAddresses[] = new String[] { "192.255.255.254", "192.168.255.254", "192.168.0.254", "192.168.0.6" };
+        final String networkAddresses[] = new String[] { "192.0.0.0", "192.168.0.0", "192.168.0.0", "192.168.0.0" };
+        final String cidrSignatures[] = new String[] { "192.168.0.1/8", "192.168.0.1/16", "192.168.0.1/24", "192.168.0.1/29" };
+        final int usableAddresses[] = new int[] { 16777214, 65534, 254, 6 };
+        
+        for (int i = 0; i < masks.length; ++i) {
+            SubnetUtils utils = new SubnetUtils(address, masks[i]);
+            SubnetInfo info = utils.getInfo();
+            assertEquals(bcastAddresses[i], info.getBroadcastAddress());
+            assertEquals(cidrSignatures[i], info.getCidrSignature());
+            assertEquals(lowAddresses[i], info.getLowAddress());
+            assertEquals(highAddresses[i], info.getHighAddress());
+            assertEquals(networkAddresses[i], info.getNetworkAddress());
+            assertEquals(usableAddresses[i], info.getAddressCount());
+        }
+    }
+    
+    // TODO Lower address test
+    public void testAddresses() {
+        SubnetUtils utils = new SubnetUtils("192.168.0.1/29");
+        SubnetInfo info = utils.getInfo();
+        assertTrue(info.isInRange("192.168.0.1"));
+        // We don't count the broadcast address as usable
+        assertFalse(info.isInRange("192.168.0.7"));
+        assertFalse(info.isInRange("192.168.0.8"));
+        assertFalse(info.isInRange("10.10.2.1"));
+        assertFalse(info.isInRange("192.168.1.1"));
+        assertFalse(info.isInRange("192.168.0.255"));
+    }
+    
+    public void testZeroNetmaskBits() {
+    	try {
+    		@SuppressWarnings("unused")
+            SubnetUtils utils = new SubnetUtils("192.168.0.1/0");
+    		fail("Mask /0 should have generated an IllegalArgumentException");
+    	}
+    	catch (IllegalArgumentException expected) {
+    	}
+    }
+}
diff --git a/src/test/org/apache/commons/net/ftp/AllTests.java b/src/test/java/org/apache/commons/net/ftp/AllTests.java
similarity index 95%
rename from src/test/org/apache/commons/net/ftp/AllTests.java
rename to src/test/java/org/apache/commons/net/ftp/AllTests.java
index c5e0966..8cd3ebc 100644
--- a/src/test/org/apache/commons/net/ftp/AllTests.java
+++ b/src/test/java/org/apache/commons/net/ftp/AllTests.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
diff --git a/src/test/org/apache/commons/net/ftp/FTPClientConfigFunctionalTest.java b/src/test/java/org/apache/commons/net/ftp/FTPClientConfigFunctionalTest.java
similarity index 94%
rename from src/test/org/apache/commons/net/ftp/FTPClientConfigFunctionalTest.java
rename to src/test/java/org/apache/commons/net/ftp/FTPClientConfigFunctionalTest.java
index 2281740..272a5fe 100644
--- a/src/test/org/apache/commons/net/ftp/FTPClientConfigFunctionalTest.java
+++ b/src/test/java/org/apache/commons/net/ftp/FTPClientConfigFunctionalTest.java
@@ -1,4 +1,3 @@
-
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -7,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,14 +16,14 @@
  */
 package org.apache.commons.net.ftp;
 
-import junit.framework.TestCase;
 import java.io.IOException;
 import java.net.SocketException;
 import java.util.Calendar;
 import java.util.Comparator;
-import java.util.Iterator;
 import java.util.TreeSet;
 
+import junit.framework.TestCase;
+
 /*
  * This test was contributed in a different form by W. McDonald Buck
  * of Boulder, Colorado, to help fix some bugs with the FTPClientConfig
@@ -65,6 +64,7 @@
     /* 
      * @throws java.lang.Exception
      */
+    @Override
     protected void setUp() throws Exception {
         super.setUp();
         FTPConf = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
@@ -84,6 +84,7 @@
     /* 
      * @throws java.lang.Exception
      */
+    @Override
     protected void tearDown() throws Exception {
         FTP.disconnect();
         super.tearDown();
@@ -96,10 +97,11 @@
     }
 
     
-    private TreeSet getSortedList(FTPFile[] files) {
+    @SuppressWarnings("unchecked")
+    private TreeSet<FTPFile> getSortedList(FTPFile[] files) {
         // create a TreeSet which will sort each element
         // as it is added.
-        TreeSet sorted = new TreeSet(new Comparator() {
+        TreeSet<FTPFile> sorted = new TreeSet<FTPFile>(new Comparator() {
 
             public int compare(Object o1, Object o2) {
                 FTPFile f1 = (FTPFile) o1;
@@ -130,12 +132,11 @@
     public void testTimeZoneFunctionality() throws Exception {
         java.util.Date now = new java.util.Date();
         FTPFile[] files = FTP.listFiles();
-        TreeSet sorted = getSortedList(files);
+        TreeSet<FTPFile> sorted = getSortedList(files);
         //SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm z" );
         FTPFile lastfile = null;
         FTPFile firstfile = null;
-        for (Iterator it = sorted.iterator(); it.hasNext();) {
-            FTPFile thisfile = (FTPFile) it.next();
+        for (FTPFile thisfile : sorted) {
             if (firstfile == null) {
                 firstfile = thisfile;
             }
diff --git a/src/test/org/apache/commons/net/ftp/FTPClientConfigTest.java b/src/test/java/org/apache/commons/net/ftp/FTPClientConfigTest.java
similarity index 98%
rename from src/test/org/apache/commons/net/ftp/FTPClientConfigTest.java
rename to src/test/java/org/apache/commons/net/ftp/FTPClientConfigTest.java
index 351d7c0..222f11f 100644
--- a/src/test/org/apache/commons/net/ftp/FTPClientConfigTest.java
+++ b/src/test/java/org/apache/commons/net/ftp/FTPClientConfigTest.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
diff --git a/src/test/org/apache/commons/net/ftp/ListingFunctionalTest.java b/src/test/java/org/apache/commons/net/ftp/ListingFunctionalTest.java
similarity index 91%
rename from src/test/org/apache/commons/net/ftp/ListingFunctionalTest.java
rename to src/test/java/org/apache/commons/net/ftp/ListingFunctionalTest.java
index cb88c7a..9e7c263 100644
--- a/src/test/org/apache/commons/net/ftp/ListingFunctionalTest.java
+++ b/src/test/java/org/apache/commons/net/ftp/ListingFunctionalTest.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -59,7 +59,7 @@
                     "[.FREEWARE50.XTERM]"
                 }
             };
-        Class clasz = ListingFunctionalTest.class;
+        Class<?> clasz = ListingFunctionalTest.class;
         Method[] methods = clasz.getDeclaredMethods();
         TestSuite allSuites = new TestSuite("FTP Listing Functional Test Suite");
 
@@ -116,11 +116,11 @@
      *
      * @return
      */
-    private boolean findByName(List fileList,
+    private boolean findByName(List<?> fileList,
                                String string)
     {
         boolean found = false;
-        Iterator iter = fileList.iterator();
+        Iterator<?> iter = fileList.iterator();
 
         while (iter.hasNext() && !found)
         {
@@ -146,6 +146,7 @@
     /*
      * @see TestCase#setUp()
      */
+    @Override
     protected void setUp() throws Exception
     {
         super.setUp();
@@ -158,6 +159,7 @@
     /*
      * @see TestCase#tearDown()
      */
+    @Override
     protected void tearDown()
         throws Exception
     {
@@ -188,7 +190,7 @@
         client.changeWorkingDirectory(validPath);
 
         FTPListParseEngine engine = client.initiateListParsing();
-        List files = Arrays.asList(engine.getNext(25));
+        List<FTPFile> files = Arrays.asList(engine.getNext(25));
 
         assertTrue(files.toString(),
                    findByName(files, validFilename));
@@ -202,7 +204,7 @@
     {
         FTPListParseEngine engine = client.initiateListParsing(validParserKey,
                                                                validPath);
-        List files = Arrays.asList(engine.getNext(25));
+        List<FTPFile> files = Arrays.asList(engine.getNext(25));
 
         assertTrue(files.toString(),
                    findByName(files, validFilename));
@@ -215,7 +217,7 @@
         throws IOException
     {
         FTPListParseEngine engine = client.initiateListParsing(validPath);
-        List files = Arrays.asList(engine.getNext(25));
+        List<FTPFile> files = Arrays.asList(engine.getNext(25));
 
         assertTrue(files.toString(),
                    findByName(files, validFilename));
@@ -252,7 +254,7 @@
     {
         FTPClientConfig config = new FTPClientConfig(validParserKey);
         client.configure(config);
-        List files = Arrays.asList(client.listFiles(validPath));
+        List<FTPFile> files = Arrays.asList(client.listFiles(validPath));
 
         assertTrue(files.toString(),
                    findByName(files, validFilename));
@@ -263,7 +265,7 @@
     {
         client.changeWorkingDirectory(validPath);
 
-        List files = Arrays.asList(client.listFiles());
+        List<FTPFile> files = Arrays.asList(client.listFiles());
 
         assertTrue(files.toString(),
                    findByName(files, validFilename));
@@ -300,7 +302,7 @@
     public void testListFilesWithPathAndAutodetection()
         throws IOException
     {
-        List files = Arrays.asList(client.listFiles(validPath));
+        List<FTPFile> files = Arrays.asList(client.listFiles(validPath));
 
         assertTrue(files.toString(),
                    findByName(files, validFilename));
@@ -318,7 +320,7 @@
 
         assertNotNull(names);
 
-        List lnames = Arrays.asList(names);
+        List<String> lnames = Arrays.asList(names);
 
         assertTrue(lnames.toString(),
                    lnames.contains(validFilename));
@@ -330,7 +332,7 @@
     public void testListNamesWithPath()
         throws IOException
     {
-        List names = Arrays.asList(client.listNames(validPath));
+        List<String> names = Arrays.asList(client.listNames(validPath));
 
         assertTrue(names.toString(),
                    findByName(names, validFilename));
diff --git a/src/test/java/org/apache/commons/net/ftp/TestConnectTimeout.java b/src/test/java/org/apache/commons/net/ftp/TestConnectTimeout.java
new file mode 100644
index 0000000..f6824ce
--- /dev/null
+++ b/src/test/java/org/apache/commons/net/ftp/TestConnectTimeout.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.net.ftp;
+
+import java.io.IOException;
+import java.net.SocketException;
+import java.net.SocketTimeoutException;
+import java.net.UnknownHostException;
+
+import junit.framework.TestCase;
+
+/**
+ * Test the socket connect timeout functionality
+ * @author Rory <rwinston@apache.org>
+ *
+ */
+public class TestConnectTimeout extends TestCase {
+
+    public void testConnectTimeout() throws SocketException, IOException {
+        FTPClient client = new FTPClient();
+        client.setConnectTimeout(1000);
+        
+        try {
+            // Connect to a valid host on a bogus port
+            client.connect("ftp.microsoft.com", 1234);
+            assertTrue("Expecting SocketTimeoutException", false);
+        } 
+        catch (SocketTimeoutException se) {
+            assertTrue(true);
+        }
+        catch (UnknownHostException ue) {
+            // Not much we can do about this, we may be firewalled
+            assertTrue(true);
+        }
+        
+    }
+}
diff --git a/src/test/org/apache/commons/net/ftp/parser/AllTests.java b/src/test/java/org/apache/commons/net/ftp/parser/AllTests.java
similarity index 97%
rename from src/test/org/apache/commons/net/ftp/parser/AllTests.java
rename to src/test/java/org/apache/commons/net/ftp/parser/AllTests.java
index 7652e0c..38aadf2 100644
--- a/src/test/org/apache/commons/net/ftp/parser/AllTests.java
+++ b/src/test/java/org/apache/commons/net/ftp/parser/AllTests.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
diff --git a/src/test/org/apache/commons/net/ftp/parser/CompositeFTPParseTestFramework.java b/src/test/java/org/apache/commons/net/ftp/parser/CompositeFTPParseTestFramework.java
similarity index 95%
rename from src/test/org/apache/commons/net/ftp/parser/CompositeFTPParseTestFramework.java
rename to src/test/java/org/apache/commons/net/ftp/parser/CompositeFTPParseTestFramework.java
index 7afaddf..7971065 100644
--- a/src/test/org/apache/commons/net/ftp/parser/CompositeFTPParseTestFramework.java
+++ b/src/test/java/org/apache/commons/net/ftp/parser/CompositeFTPParseTestFramework.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -21,7 +21,7 @@
 
 /**
  * @author <a href="mario@ops.co.at">MarioIvankovits</a>
- * @version $Id$
+ * @version $Id: CompositeFTPParseTestFramework.java 155429 2005-02-26 13:13:04Z dirkv $
  */
 public abstract class CompositeFTPParseTestFramework extends FTPParseTestFramework
 {
@@ -36,6 +36,7 @@
     /**
      * @see FTPParseTestFramework#getGoodListing()
      */
+    @Override
     protected String[] getGoodListing()
     {
         return (getGoodListings()[0]);
@@ -62,6 +63,7 @@
     /**
      * @see FTPParseTestFramework#getBadListing()
      */
+    @Override
     protected String[] getBadListing()
     {
         return (getBadListings()[0]);
@@ -92,6 +94,7 @@
     /* (non-Javadoc)
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#testGoodListing()
      */
+    @Override
     public void testBadListing() throws Exception
     {
         String badsamples[][] = getBadListings();
diff --git a/src/test/org/apache/commons/net/ftp/parser/DefaultFTPFileEntryParserFactoryTest.java b/src/test/java/org/apache/commons/net/ftp/parser/DefaultFTPFileEntryParserFactoryTest.java
similarity index 98%
rename from src/test/org/apache/commons/net/ftp/parser/DefaultFTPFileEntryParserFactoryTest.java
rename to src/test/java/org/apache/commons/net/ftp/parser/DefaultFTPFileEntryParserFactoryTest.java
index 98b626c..cfaf521 100644
--- a/src/test/org/apache/commons/net/ftp/parser/DefaultFTPFileEntryParserFactoryTest.java
+++ b/src/test/java/org/apache/commons/net/ftp/parser/DefaultFTPFileEntryParserFactoryTest.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -70,7 +70,6 @@
         // check is case-insensitive.
         parser = factory.createFileEntryParser("UNKNOWN Type: L8");
 
-
         try {
             parser = factory.createFileEntryParser("OS2FTPFileEntryParser");
             fail("Exception should have been thrown. \"OS2FTPFileEntryParser\" is not a recognized key");
diff --git a/src/test/org/apache/commons/net/ftp/parser/EnterpriseUnixFTPEntryParserTest.java b/src/test/java/org/apache/commons/net/ftp/parser/EnterpriseUnixFTPEntryParserTest.java
similarity index 96%
rename from src/test/org/apache/commons/net/ftp/parser/EnterpriseUnixFTPEntryParserTest.java
rename to src/test/java/org/apache/commons/net/ftp/parser/EnterpriseUnixFTPEntryParserTest.java
index 7e11c64..720944d 100644
--- a/src/test/org/apache/commons/net/ftp/parser/EnterpriseUnixFTPEntryParserTest.java
+++ b/src/test/java/org/apache/commons/net/ftp/parser/EnterpriseUnixFTPEntryParserTest.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -26,7 +26,7 @@
 /**
  * Tests the EnterpriseUnixFTPEntryParser
  *
- * @version $Id$
+ * @version $Id: EnterpriseUnixFTPEntryParserTest.java 437134 2006-08-26 09:36:36Z rwinston $
  * @author <a href="mailto:Winston.Ojeda@qg.com">Winston Ojeda</a>
  */
 public class EnterpriseUnixFTPEntryParserTest extends FTPParseTestFramework
@@ -87,6 +87,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#testParseFieldsOnDirectory()
      */
+    @Override
     public void testParseFieldsOnDirectory() throws Exception
     {
         // Everything is a File for now.
@@ -95,6 +96,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#testParseFieldsOnFile()
      */
+    @Override
     public void testParseFieldsOnFile() throws Exception
     {
         FTPFile file = getParser().parseFTPEntry("-C--E-----FTP B QUA1I1      18128       5000000000 Aug 12 13:56 QUADTEST");
@@ -106,7 +108,7 @@
         assertEquals("QUADTEST",
                      file.getName());
         assertEquals(5000000000L, 
-                    file.getSize());
+                     file.getSize());
         assertEquals("QUA1I1",
                      file.getUser());
         assertEquals("18128",
@@ -129,6 +131,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getBadListing()
      */
+    @Override
     protected String[] getBadListing()
     {
 
@@ -138,6 +141,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getGoodListing()
      */
+    @Override
     protected String[] getGoodListing()
     {
 
@@ -147,6 +151,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getParser()
      */
+    @Override
     protected FTPFileEntryParser getParser()
     {
 
diff --git a/src/test/org/apache/commons/net/ftp/parser/FTPConfigEntryParserTest.java b/src/test/java/org/apache/commons/net/ftp/parser/FTPConfigEntryParserTest.java
similarity index 97%
rename from src/test/org/apache/commons/net/ftp/parser/FTPConfigEntryParserTest.java
rename to src/test/java/org/apache/commons/net/ftp/parser/FTPConfigEntryParserTest.java
index 8bd2896..5ea2ad0 100644
--- a/src/test/org/apache/commons/net/ftp/parser/FTPConfigEntryParserTest.java
+++ b/src/test/java/org/apache/commons/net/ftp/parser/FTPConfigEntryParserTest.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -18,7 +18,6 @@
 
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
-import java.util.Date;
 
 import junit.framework.TestCase;
 
@@ -82,9 +81,7 @@
         assertEquals(814, f.getSize());
 
         Calendar cal = Calendar.getInstance();
-        
-        Date refDate = new Date();
-        
+                
         cal.set(Calendar.MONTH, Calendar.MARCH);
         cal.set(Calendar.DATE, 2);
         cal.set(Calendar.HOUR_OF_DAY, 16);
@@ -147,8 +144,6 @@
 
         Calendar cal = Calendar.getInstance();
         
-        Date refDate = new Date();
-        
         cal.set(Calendar.MONTH, Calendar.MARCH);
         cal.set(Calendar.DATE, 2);
         cal.set(Calendar.HOUR_OF_DAY, 18);
diff --git a/src/test/org/apache/commons/net/ftp/parser/FTPParseTestFramework.java b/src/test/java/org/apache/commons/net/ftp/parser/FTPParseTestFramework.java
similarity index 96%
rename from src/test/org/apache/commons/net/ftp/parser/FTPParseTestFramework.java
rename to src/test/java/org/apache/commons/net/ftp/parser/FTPParseTestFramework.java
index 55ec8d4..738e6b4 100644
--- a/src/test/org/apache/commons/net/ftp/parser/FTPParseTestFramework.java
+++ b/src/test/java/org/apache/commons/net/ftp/parser/FTPParseTestFramework.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -24,7 +24,7 @@
 
 /**
  * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
- * @version $Id$
+ * @version $Id: FTPParseTestFramework.java 437134 2006-08-26 09:36:36Z rwinston $
  */
 public abstract class FTPParseTestFramework extends TestCase
 {
@@ -139,6 +139,7 @@
     /**
      * @see junit.framework.TestCase#setUp()
      */
+    @Override
     protected void setUp() throws Exception
     {
         super.setUp();
diff --git a/src/test/org/apache/commons/net/ftp/parser/FTPTimestampParserImplTest.java b/src/test/java/org/apache/commons/net/ftp/parser/FTPTimestampParserImplTest.java
similarity index 100%
rename from src/test/org/apache/commons/net/ftp/parser/FTPTimestampParserImplTest.java
rename to src/test/java/org/apache/commons/net/ftp/parser/FTPTimestampParserImplTest.java
diff --git a/src/test/java/org/apache/commons/net/ftp/parser/MVSFTPEntryParserTest.java b/src/test/java/org/apache/commons/net/ftp/parser/MVSFTPEntryParserTest.java
new file mode 100644
index 0000000..a8683b8
--- /dev/null
+++ b/src/test/java/org/apache/commons/net/ftp/parser/MVSFTPEntryParserTest.java
@@ -0,0 +1,238 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.net.ftp.parser;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestSuite;
+
+import org.apache.commons.net.ftp.FTPFile;
+import org.apache.commons.net.ftp.FTPFileEntryParser;
+
+/**
+ * Changed on August 31, 2006<br/>
+ * Test suite addapted to new MVSFTPEntryParser.java.
+ * @author <a href="mailto:henrik.sorensen@balcab.ch">Henrik Sorensen</a>
+ * 
+ * Created on Apr 6, 2005<br/>
+ * @author <a href="mailto:wnoto@openfinance.com">William Noto</a>
+ * @version $Id: MVSFTPEntryParserTest.java,v 1.16 2005/01/02 03:17:50 scohen Exp $
+ */
+public class MVSFTPEntryParserTest extends FTPParseTestFramework {
+
+    private static final String[] goodsamplesDatasetList = { /* Note, if the string begins with SAVE, the parsed entry is stored in the List saveftpfiles */
+            //  "Volume Unit    Referred Ext Used Recfm Lrecl BlkSz Dsorg Dsname",
+            "SAVE00 3390   2004/06/23  1    1  FB     128  6144  PS    INCOMING.RPTBM023.D061704",
+            "SAVE01 3390   2004/06/23  1    1  FB     128  6144  PO    INCOMING.RPTBM024.D061704",
+            "SAVE02 3390   2004/06/23  1    1  FB     128  6144  PO-E  INCOMING.RPTBM025.D061704",
+            "PSMLC1 3390   2005/04/04  1    1  VB   27994 27998  PS    file3.I",
+            "PSMLB9 3390   2005/04/04  1    1  VB   27994 27998  PS    file4.I.BU",
+            "PSMLB6 3390   2005/04/05  1    1  VB   27994 27998  PS    file3.I.BU",
+            "PSMLC6 3390   2005/04/05  1    1  VB   27994 27998  PS    file6.I",
+            "PSMLB7 3390   2005/04/04  1    1  VB   27994 27998  PS    file7.O",
+            "PSMLC6 3390   2005/04/05  1    1  VB   27994 27998  PS    file7.O.BU",
+            "FPFS49 3390   2004/06/23  1    1  FB     128  6144  PO-E  INCOMING.RPTBM026.D061704",
+            "FPFS41 3390   2004/06/23  1    1  FB     128  6144  PS    INCOMING.RPTBM056.D061704",
+            "FPFS25 3390   2004/06/23  1    1  FB     128  6144  PS    INCOMING.WTM204.D061704", };
+
+    private static final String[] goodsamplesMemberList = {/* Note, if the string begins with SAVE, the parsed entry is stored in the List saveftpfiles */
+            "Name      VV.MM   Created       Changed      Size  Init   Mod   Id",
+            "SAVE03    01.03 2002/09/12 2002/10/11 09:37    11    11     0 KIL001",
+            "SAVE04                                                              ", // no statistics
+            "TBSHELF1  01.03 2002/09/12 2002/10/11 09:37    11    11     0 KIL001",
+            "TBSHELF2  01.03 2002/09/12 2002/10/11 09:37    11    11     0 KIL001",
+            "TBSHELF3  01.03 2002/09/12 2002/10/11 09:37    11    11     0 KIL001",
+            "TBSHELF4  01.03 2002/09/12 2002/10/11 09:37    11    11     0 KIL001", };
+
+    private static final String[] goodsamplesJES1List = { /* no header for JES1 (JES Interface level 1) */
+    /* Note, if the string begins with SAVE, the parsed entry is stored in the List saveftpfiles */
+    "IBMUSER1  JOB01906  OUTPUT    3 Spool Files", };
+
+    private static final String[] goodsamplesJES2List = { /* JES2 (JES Interface level 2) */
+            /* Note, if the string begins with SAVE, the parsed entry is stored in the List saveftpfiles */
+            //"JOBNAME  JOBID    OWNER    STATUS CLASS",
+            "IBMUSER2 JOB01906 IBMUSER  OUTPUT A        RC=0000 3 spool files",
+            "IBMUSER  TSU01830 IBMUSER  OUTPUT TSU      ABEND=522 3 spool files", };
+
+    private static final String[] badsamples = {
+            "MigratedP201.$FTXPBI1.$CF2ITB.$AAB0402.I",
+            "PSMLC133902005/04/041VB2799427998PSfile1.I", "file2.O", };
+
+    /**
+     * @see junit.framework.TestCase#TestCase(String)
+     */
+    public MVSFTPEntryParserTest(String name) {
+        super(name);
+
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.commons.net.ftp.parser.CompositeFTPParseTestFramework#getBadListings()
+     */
+    @Override
+    protected String[] getBadListing() {
+        return badsamples;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.commons.net.ftp.parser.CompositeFTPParseTestFramework#getGoodListings()
+     */
+    @Override
+    protected String[] getGoodListing() {
+        return goodsamplesDatasetList;
+    }
+
+    /**
+     * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getAllGoodListings()
+     */
+    protected List<String[]> getAllGoodListings() {
+        List<String[]> l = new ArrayList<String[]>();
+        l.add(goodsamplesDatasetList);
+        l.add(goodsamplesMemberList);
+        l.add(goodsamplesJES1List);
+        l.add(goodsamplesJES2List);
+
+        return l;
+    }
+
+
+    /**
+     * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getParser()
+     */
+    @Override
+    protected FTPFileEntryParser getParser() {
+        return new MVSFTPEntryParser();
+    }
+
+    /**
+     * Method suite.
+     * 
+     * @return TestSuite
+     */
+    public static TestSuite suite() {
+        return (new TestSuite(MVSFTPEntryParserTest.class));
+    }
+
+    /* 
+     * note the testGoodListing has to be the first test invoked, because 
+     * some FTPFile entries are saved for the later tests
+     * 
+     * (non-Javadoc)
+     * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#testGoodListing()
+     */
+    @Override
+    public void testGoodListing() throws Exception {
+        String[] goodsamples = getGoodListing();
+        MVSFTPEntryParser parser = new MVSFTPEntryParser();
+        parser.setType(MVSFTPEntryParser.FILE_LIST_TYPE);
+        parser.setRegex(MVSFTPEntryParser.FILE_LIST_REGEX);
+        for (String test : goodsamples) {
+            FTPFile f = parser.parseFTPEntry(test);
+            assertNotNull("Failed to parse " + test, f);
+            doAdditionalGoodTests(test, f);
+        }
+    }
+
+    public void testMemberListing() throws Exception {
+        MVSFTPEntryParser parser = new MVSFTPEntryParser();
+        parser.setType(MVSFTPEntryParser.MEMBER_LIST_TYPE);
+        parser.setRegex(MVSFTPEntryParser.MEMBER_LIST_REGEX);
+        for (String test : goodsamplesMemberList) {
+            FTPFile f = parser.parseFTPEntry(test);
+            assertNotNull("Failed to parse " + test, f);
+            doAdditionalGoodTests(test, f);
+        }
+    }
+
+    public void testJesLevel1Listing() {
+        MVSFTPEntryParser parser = new MVSFTPEntryParser();
+        parser.setType(MVSFTPEntryParser.JES_LEVEL_1_LIST_TYPE);
+        parser.setRegex(MVSFTPEntryParser.JES_LEVEL_1_LIST_REGEX);
+        for (String test : goodsamplesJES1List) {
+            FTPFile f = parser.parseFTPEntry(test);
+            assertNotNull("Failed to parse " + test, f);
+            doAdditionalGoodTests(test, f);
+        }
+    }
+    
+    public void testJesLevel2Listing() {
+        MVSFTPEntryParser parser = new MVSFTPEntryParser();
+        parser.setType(MVSFTPEntryParser.JES_LEVEL_2_LIST_TYPE);
+        parser.setRegex(MVSFTPEntryParser.JES_LEVEL_2_LIST_REGEX);
+        for (String test : goodsamplesJES2List) {
+            FTPFile f = parser.parseFTPEntry(test);
+            assertNotNull("Failed to parse " + test, f);
+            doAdditionalGoodTests(test, f);
+        }
+    }
+
+    @Override
+    public void testParseFieldsOnDirectory() throws Exception {
+        MVSFTPEntryParser parser = new MVSFTPEntryParser();
+        parser.setType(MVSFTPEntryParser.FILE_LIST_TYPE);
+        parser.setRegex(MVSFTPEntryParser.FILE_LIST_REGEX);
+
+        FTPFile file = parser
+                .parseFTPEntry("SAVE01 3390   2004/06/23  1    1  FB     128  6144  PO    INCOMING.RPTBM024.D061704");
+        assertNotNull("Could not parse entry.", file);
+        assertTrue("Should have been a directory.", file.isDirectory());
+        assertEquals("INCOMING.RPTBM024.D061704", file.getName());
+
+        file = parser
+                .parseFTPEntry("SAVE02 3390   2004/06/23  1    1  FB     128  6144  PO-E  INCOMING.RPTBM025.D061704");
+        assertNotNull("Could not parse entry.", file);
+        assertTrue("Should have been a directory.", file.isDirectory());
+        assertEquals("INCOMING.RPTBM025.D061704", file.getName());
+
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#testParseFieldsOnFile()
+     */
+    @Override
+    public void testParseFieldsOnFile() throws Exception {
+        FTPFile file = null;
+        
+        MVSFTPEntryParser parser = new MVSFTPEntryParser(); 
+        
+        parser.setRegex(MVSFTPEntryParser.FILE_LIST_REGEX);
+        parser.setType(MVSFTPEntryParser.FILE_LIST_TYPE);
+        
+        file = parser.parseFTPEntry("SAVE00 3390   2004/06/23  1    1  FB     128  6144  PS    INCOMING.RPTBM023.D061704");
+        assertNotNull("Could not parse entry.", file);
+        assertTrue("Should have been a file.", file.isFile());
+        assertEquals("INCOMING.RPTBM023.D061704", file.getName());
+        assertNull("Timestamp should not have been set.", file.getTimestamp());
+
+        parser.setType(MVSFTPEntryParser.MEMBER_LIST_TYPE);
+        parser.setRegex(MVSFTPEntryParser.MEMBER_LIST_REGEX);
+        
+        file = parser.parseFTPEntry("SAVE03    01.03 2002/09/12 2002/10/11 09:37    11    11     0 KIL001");
+        assertNotNull("Could not parse entry.", file);
+        assertTrue("Should have been a file.", file.isFile());
+        assertEquals("SAVE03", file.getName());
+        assertNotNull("Timestamp should have been set.", file.getTimestamp());
+
+        file = parser.parseFTPEntry("SAVE04                                                              ");
+        assertNotNull("Could not parse entry.", file);
+        assertTrue("Should have been a file.", file.isFile());
+        assertEquals("SAVE04", file.getName());
+        assertNull("Timestamp should not have been set.", file.getTimestamp());
+
+    }
+}
diff --git a/src/test/org/apache/commons/net/ftp/parser/NTFTPEntryParserTest.java b/src/test/java/org/apache/commons/net/ftp/parser/NTFTPEntryParserTest.java
similarity index 85%
rename from src/test/org/apache/commons/net/ftp/parser/NTFTPEntryParserTest.java
rename to src/test/java/org/apache/commons/net/ftp/parser/NTFTPEntryParserTest.java
index 0aa983e..e8114a6 100644
--- a/src/test/org/apache/commons/net/ftp/parser/NTFTPEntryParserTest.java
+++ b/src/test/java/org/apache/commons/net/ftp/parser/NTFTPEntryParserTest.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -24,7 +24,7 @@
 
 /**
  * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
- * @version $Id$
+ * @version $Id: NTFTPEntryParserTest.java 629276 2008-02-19 23:31:25Z rwinston $
  */
 public class NTFTPEntryParserTest extends CompositeFTPParseTestFramework
 {
@@ -48,6 +48,7 @@
             "-rw-r--r--   1 root     root       190144 Apr 27  2001 zxJDBC-2.0.1b1.zip",
             "-rwxr-xr-x   2 500      500           166 Nov  2  2001 73131-testtes1.afp",
             "-rw-r--r--   1 500      500           166 Nov  9  2001 73131-testtes1.AFP",
+            "drwx------ 4 maxm Domain Users 512 Oct 2 10:59 .metadata",
         }
     };
 
@@ -86,6 +87,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.CompositeFTPParseTestFramework#getGoodListings()
      */
+    @Override
     protected String[][] getGoodListings()
     {
         return goodsamples;
@@ -94,6 +96,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.CompositeFTPParseTestFramework#getBadListings()
      */
+    @Override
     protected String[][] getBadListings()
     {
         return badsamples;
@@ -102,6 +105,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getParser()
      */
+    @Override
     protected FTPFileEntryParser getParser()
     {
        return new CompositeFileEntryParser(new FTPFileEntryParser[]
@@ -125,6 +129,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#testParseFieldsOnDirectory()
      */
+    @Override
     public void testParseFieldsOnDirectory() throws Exception
     {
         FTPFile dir = getParser().parseFTPEntry("12-05-96  05:03PM       <DIR>          absoft2");
@@ -144,10 +149,22 @@
         assertEquals(0, dir.getSize());
 
     }
+    
+    public void testParseLeadingDigits() {
+            FTPFile file = getParser().parseFTPEntry("05-22-97  12:08AM                  5000000000 10 years and under");
+            assertNotNull("Could not parse entry", file);
+            assertEquals("10 years and under", file.getName());
+            assertEquals(5000000000L, file.getSize());
+            
+            FTPFile dir = getParser().parseFTPEntry("12-03-96  06:38AM       <DIR>           10 years and under");
+            assertNotNull("Could not parse entry", dir);
+            assertEquals("10 years and under", dir.getName());
+    }
 
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#testParseFieldsOnFile()
      */
+    @Override
     public void testParseFieldsOnFile() throws Exception
     {
         FTPFile f = getParser().parseFTPEntry("05-22-97  12:08AM                  5000000000 AUTOEXEC.BAK");
@@ -171,21 +188,17 @@
         assertTrue("Should have been a file.",
                 f.isFile());
         assertEquals(17707, f.getSize());
-
-
-
-
-
     }
 
 
+    @Override
     protected void doAdditionalGoodTests(String test, FTPFile f)
     {
         if (test.indexOf("<DIR>") >= 0)
         {
                     assertEquals("directory.type",
                             FTPFile.DIRECTORY_TYPE, f.getType());
-                }
+        }
     }
 
     /**
@@ -209,5 +222,16 @@
         assertNotNull(f);
         assertEquals("name", "123 abc xyz", f.getName());
     }
-
+    
+    /**
+     * Test that group names with embedded spaces can be handled correctly
+     *
+     */
+    public void testGroupNameWithSpaces() {
+        FTPFile f = getParser().parseFTPEntry("drwx------ 4 maxm Domain Users 512 Oct 2 10:59 .metadata");
+        assertNotNull(f);
+        assertEquals("maxm", f.getUser());
+        assertEquals("Domain Users", f.getGroup());
+    }
+    
 }
diff --git a/src/test/org/apache/commons/net/ftp/parser/NetwareFTPEntryParserTest.java b/src/test/java/org/apache/commons/net/ftp/parser/NetwareFTPEntryParserTest.java
similarity index 93%
rename from src/test/org/apache/commons/net/ftp/parser/NetwareFTPEntryParserTest.java
rename to src/test/java/org/apache/commons/net/ftp/parser/NetwareFTPEntryParserTest.java
index 1704788..9dddbf0 100644
--- a/src/test/org/apache/commons/net/ftp/parser/NetwareFTPEntryParserTest.java
+++ b/src/test/java/org/apache/commons/net/ftp/parser/NetwareFTPEntryParserTest.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,21 +17,21 @@
 package org.apache.commons.net.ftp.parser;
 
 import java.util.Calendar;
-
+ 
 import junit.framework.TestSuite;
-
+ 
 import org.apache.commons.net.ftp.FTPFile;
 import org.apache.commons.net.ftp.FTPFileEntryParser;
 
 /**
  * @author <a href="mailto:rwinston@apache.org">Rory Winston</a>
- * @version $Id$
+ * @version $Id: NetwareFTPEntryParserTest.java 492109 2007-01-03 11:24:57Z rwinston $
  */
 public class NetwareFTPEntryParserTest extends FTPParseTestFramework {
 
     private static final String[] badsamples = {
         "a [-----F--] SCION_SYS                         512 Apr 13 23:52 SYS",
-        "d [----AF--]          0                        512 10-04-2001 _ADMIN"
+            "d [----AF--]          0                        512 10-04-2001 _ADMIN"
     };
 
     private static final String [] goodsamples = {
@@ -52,6 +52,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getBadListing()
      */
+    @Override
     protected String[] getBadListing() {
         return (badsamples);
     }
@@ -59,6 +60,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getGoodListing()
      */
+    @Override
     protected String[] getGoodListing() {
         return (goodsamples);
     }
@@ -66,6 +68,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getParser()
      */
+    @Override
     protected FTPFileEntryParser getParser() {
         return (new NetwareFTPEntryParser());
     }
@@ -73,7 +76,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#testParseFieldsOnDirectory()
      */
-    
+    @Override
     public void testParseFieldsOnDirectory() throws Exception {
         String reply = "d [-W---F--] testUser                        512 Apr 13 23:12 testFile";
         FTPFile f = getParser().parseFTPEntry(reply);
@@ -102,6 +105,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#testParseFieldsOnFile()
      */
+    @Override
     public void testParseFieldsOnFile() throws Exception {
         String reply = "- [R-CEAFMS] rwinston                        19968 Mar 12 15:20 Document name with spaces.doc";
         
@@ -128,4 +132,3 @@
     
     
 }
-
diff --git a/src/test/org/apache/commons/net/ftp/parser/OS2FTPEntryParserTest.java b/src/test/java/org/apache/commons/net/ftp/parser/OS2FTPEntryParserTest.java
similarity index 95%
rename from src/test/org/apache/commons/net/ftp/parser/OS2FTPEntryParserTest.java
rename to src/test/java/org/apache/commons/net/ftp/parser/OS2FTPEntryParserTest.java
index 79a2e55..e528037 100644
--- a/src/test/org/apache/commons/net/ftp/parser/OS2FTPEntryParserTest.java
+++ b/src/test/java/org/apache/commons/net/ftp/parser/OS2FTPEntryParserTest.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -23,7 +23,7 @@
 
 /**
  * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
- * @version $Id$
+ * @version $Id: OS2FTPEntryParserTest.java 437134 2006-08-26 09:36:36Z rwinston $
  */
 public class OS2FTPEntryParserTest extends FTPParseTestFramework
 {
@@ -76,6 +76,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#testParseFieldsOnDirectory()
      */
+    @Override
     public void testParseFieldsOnDirectory() throws Exception
     {
         FTPFile dir = getParser().parseFTPEntry("     0           DIR   11-28-97   09:42  PC");
@@ -91,6 +92,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#testParseFieldsOnFile()
      */
+    @Override
     public void testParseFieldsOnFile() throws Exception
     {
         FTPFile file = getParser().parseFTPEntry("5000000000      A          11-17-98   16:07  POPUPLOG.OS2");
@@ -106,6 +108,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getBadListing()
      */
+    @Override
     protected String[] getBadListing()
     {
 
@@ -115,6 +118,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getGoodListing()
      */
+    @Override
     protected String[] getGoodListing()
     {
 
@@ -124,6 +128,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getParser()
      */
+    @Override
     protected FTPFileEntryParser getParser()
     {
         ConfigurableFTPFileEntryParserImpl parser =
diff --git a/src/test/org/apache/commons/net/ftp/parser/OS400FTPEntryParserTest.java b/src/test/java/org/apache/commons/net/ftp/parser/OS400FTPEntryParserTest.java
similarity index 96%
rename from src/test/org/apache/commons/net/ftp/parser/OS400FTPEntryParserTest.java
rename to src/test/java/org/apache/commons/net/ftp/parser/OS400FTPEntryParserTest.java
index 97f453a..cf21f0b 100644
--- a/src/test/org/apache/commons/net/ftp/parser/OS400FTPEntryParserTest.java
+++ b/src/test/java/org/apache/commons/net/ftp/parser/OS400FTPEntryParserTest.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -23,7 +23,7 @@
 import java.util.Calendar;
 
 /**
- * @version $Id$
+ * @version $Id: OS400FTPEntryParserTest.java 155429 2005-02-26 13:13:04Z dirkv $
  */
 
 public class OS400FTPEntryParserTest extends CompositeFTPParseTestFramework
@@ -42,7 +42,6 @@
                 "----rwxr-x   1PEP       0           4019 Mar 18 18:58 einladung.zip",
                 "----rwxr-x   1 PEP      0  xx        422 Mar 24 14:06 readme",
                 "----rwxr-x   1 PEP      0           8492 Apr 07 30:13 build.xml",
-                "d---rwxr-x   2 PEP USR  0          45056 Mar 24 14:06 dir1",
                 "d---rwxr-x   2 PEP      0          45056Mar 24 14:06 zdir2"
             }
     };
@@ -76,6 +75,7 @@
     /**
      * @see FTPParseTestFramework#getBadListing()
      */
+    @Override
     protected String[][] getBadListings()
     {
         return badsamples;
@@ -84,6 +84,7 @@
     /**
      * @see FTPParseTestFramework#getGoodListing()
      */
+    @Override
     protected String[][] getGoodListings()
     {
         return goodsamples;
@@ -92,6 +93,7 @@
     /**
      * @see FTPParseTestFramework#getParser()
      */
+    @Override
     protected FTPFileEntryParser getParser()
     {
         return new CompositeFileEntryParser(new FTPFileEntryParser[]
@@ -104,6 +106,7 @@
     /**
      * @see FTPParseTestFramework#testParseFieldsOnDirectory()
      */
+    @Override
     public void testParseFieldsOnDirectory() throws Exception
     {
         FTPFile f = getParser().parseFTPEntry("PEP             36864 04/03/24 14:06:34 *DIR       dir1/");
@@ -131,6 +134,7 @@
                      df.format(f.getTimestamp().getTime()));
     }
 
+    @Override
     protected void doAdditionalGoodTests(String test, FTPFile f)
     {
         if (test.startsWith("d"))
@@ -143,6 +147,7 @@
     /**
      * @see FTPParseTestFramework#testParseFieldsOnFile()
      */
+    @Override
     public void testParseFieldsOnFile() throws Exception
     {
         FTPFile f = getParser().parseFTPEntry("PEP              5000000000 04/03/24 14:06:29 *STMF      build.xml");
diff --git a/src/test/org/apache/commons/net/ftp/parser/UnixFTPEntryParserTest.java b/src/test/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParserTest.java
similarity index 79%
rename from src/test/org/apache/commons/net/ftp/parser/UnixFTPEntryParserTest.java
rename to src/test/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParserTest.java
index 6d386de..c942300 100644
--- a/src/test/org/apache/commons/net/ftp/parser/UnixFTPEntryParserTest.java
+++ b/src/test/java/org/apache/commons/net/ftp/parser/UnixFTPEntryParserTest.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -25,7 +25,7 @@
 
 /**
  * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
- * @version $Id$
+ * @version $Id: UnixFTPEntryParserTest.java 629276 2008-02-19 23:31:25Z rwinston $
  */
 public class UnixFTPEntryParserTest extends FTPParseTestFramework {
 
@@ -89,6 +89,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getBadListing()
      */
+    @Override
     protected String[] getBadListing() {
         return (badsamples);
     }
@@ -96,6 +97,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getGoodListing()
      */
+    @Override
     protected String[] getGoodListing() {
         return (goodsamples);
     }
@@ -138,13 +140,84 @@
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getParser()
      */
+    @Override
     protected FTPFileEntryParser getParser() {
         return (new UnixFTPEntryParser());
     }
+    
+    public void testOwnerNameWithSpaces() {
+        FTPFile f = getParser().parseFTPEntry("drwxr-xr-x   2 john smith     group         4096 Mar  2 15:13 zxbox");
+        assertNotNull(f);
+        assertEquals("john smith", f.getUser());
+    }
+    
+    public void testOwnerAndGroupNameWithSpaces() {
+        FTPFile f = getParser().parseFTPEntry("drwxr-xr-x   2 john smith     test group         4096 Mar  2 15:13 zxbox");
+        assertNotNull(f);
+        assertEquals("john smith", f.getUser());
+        assertEquals("test group", f.getGroup());
+    }
+    
+    public void testGroupNameWithSpaces() {
+        FTPFile f = getParser().parseFTPEntry("drwx------ 4 maxm Domain Users 512 Oct 2 10:59 .metadata");
+        assertNotNull(f);
+        assertEquals("maxm", f.getUser());
+        assertEquals("Domain Users", f.getGroup());
+    }
+	
+	public void testTrailingSpaces() {
+		FTPFile f = getParser().parseFTPEntry("drwxr-xr-x   2 john smith     group         4096 Mar  2 15:13 zxbox     ");
+		assertNotNull(f);
+		assertEquals(f.getName(), "zxbox     ");	
+	}
+	
+	public void testNameWIthPunctuation() {
+		FTPFile f = getParser().parseFTPEntry("drwx------ 4 maxm Domain Users 512 Oct 2 10:59 abc(test)123.pdf");
+		assertNotNull(f);
+		assertEquals(f.getName(), "abc(test)123.pdf");	
+	}
+
+	public void testNoSpacesBeforeFileSize() {
+		FTPFile f = getParser().parseFTPEntry("drwxr-x---+1464 chrism   chrism     41472 Feb 25 13:17 20090225");
+		assertNotNull(f);
+		assertEquals(f.getSize(), 41472);
+		assertEquals(f.getType(), FTPFile.DIRECTORY_TYPE);
+		assertEquals(f.getUser(), "chrism");
+		assertEquals(f.getGroup(), "chrism");
+		assertEquals(f.getHardLinkCount(), 1464);
+	}
+	
+	public void testCorrectGroupNameParsing() {
+		FTPFile f = getParser().parseFTPEntry("-rw-r--r--   1 ftpuser  ftpusers 12414535 Mar 17 11:07 test 1999 abc.pdf");
+		assertNotNull(f);
+		assertEquals(f.getHardLinkCount(), 1);
+		assertEquals(f.getUser(), "ftpuser");
+		assertEquals(f.getGroup(), "ftpusers");
+		assertEquals(f.getSize(), 12414535);
+		assertEquals(f.getName(), "test 1999 abc.pdf");
+
+		Calendar cal = Calendar.getInstance();
+		cal.set(Calendar.MONTH, Calendar.MARCH);
+		cal.set(Calendar.DAY_OF_MONTH, 17);
+		cal.set(Calendar.HOUR_OF_DAY, 11);
+		cal.set(Calendar.MINUTE, 7);
+		cal.set(Calendar.SECOND, 0);
+		cal.set(Calendar.MILLISECOND, 0);
+		assertEquals(cal.getTime(), f.getTimestamp().getTime());
+	}
+	
+	public void testFilenamesWithEmbeddedNumbers() {
+		FTPFile f = getParser().parseFTPEntry("-rw-rw-rw-   1 user group 5840 Mar 19 09:34 123 456 abc.csv");
+		assertEquals(f.getName(), "123 456 abc.csv");
+		assertEquals(f.getSize(), 5840);
+		assertEquals(f.getUser(), "user");
+		assertEquals(f.getGroup(), "group");
+	}
 
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#testParseFieldsOnDirectory()
      */
+    @Override
     public void testParseFieldsOnDirectory() throws Exception {
         FTPFile f = getParser().parseFTPEntry("drwxr-xr-x   2 user     group         4096 Mar  2 15:13 zxbox");
         assertNotNull("Could not parse entry.", f);
@@ -204,6 +277,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#testParseFieldsOnFile()
      */
+    @Override
     public void testParseFieldsOnFile() throws Exception {
         FTPFile f = getParser()
                 .parseFTPEntry(
@@ -247,6 +321,7 @@
      * @param test
      * @param f
      */
+    @Override
     protected void doAdditionalGoodTests(String test, FTPFile f) {
         String link = f.getLink();
         if (null != link) {
@@ -285,8 +360,8 @@
                 int pos = 3*access + perm + 1;
                 char permchar = test.charAt(pos);
                 assertEquals("Permission " + test.substring(1,10), 
-                        new Boolean(f.hasPermission(access, perm)), 
-                        new Boolean(permchar != '-' && !Character.isUpperCase(permchar))); 
+                        Boolean.valueOf(f.hasPermission(access, perm)), 
+                        Boolean.valueOf(permchar != '-' && !Character.isUpperCase(permchar))); 
             }
         }
 
diff --git a/src/test/org/apache/commons/net/ftp/parser/VMSFTPEntryParserTest.java b/src/test/java/org/apache/commons/net/ftp/parser/VMSFTPEntryParserTest.java
similarity index 97%
rename from src/test/org/apache/commons/net/ftp/parser/VMSFTPEntryParserTest.java
rename to src/test/java/org/apache/commons/net/ftp/parser/VMSFTPEntryParserTest.java
index 30eb5ed..674013b 100644
--- a/src/test/org/apache/commons/net/ftp/parser/VMSFTPEntryParserTest.java
+++ b/src/test/java/org/apache/commons/net/ftp/parser/VMSFTPEntryParserTest.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -28,7 +28,7 @@
 /**
  * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
  * @author <a href="sestegra@free.fr">Stephane ESTE-GRACIAS</a>
- * @version $Id$
+ * @version $Id: VMSFTPEntryParserTest.java 657169 2008-05-16 19:07:02Z sebb $
  */
 public class VMSFTPEntryParserTest extends FTPParseTestFramework
 {
@@ -93,7 +93,7 @@
         parser.configure(null);
         FTPListParseEngine engine = new FTPListParseEngine(parser);
         engine.readServerList(
-                new ByteArrayInputStream(fullListing.getBytes()));
+                new ByteArrayInputStream(fullListing.getBytes()), null); // use default encoding
         FTPFile[] files = engine.getFiles();
         assertEquals(6, files.length);
         assertFileInListing(files, "2-JUN.LIS");
@@ -114,7 +114,7 @@
         parser.configure(null);
         FTPListParseEngine engine = new FTPListParseEngine(parser);
         engine.readServerList(
-                new ByteArrayInputStream(fullListing.getBytes()));
+                new ByteArrayInputStream(fullListing.getBytes()), null); // use default encoding
         FTPFile[] files = engine.getFiles();
         assertEquals(3, files.length);
         assertFileInListing(files, "1-JUN.LIS;1");
@@ -144,6 +144,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#testParseFieldsOnDirectory()
      */
+    @Override
     public void testParseFieldsOnDirectory() throws Exception
     {
 
@@ -182,6 +183,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#testParseFieldsOnFile()
      */
+    @Override
     public void testParseFieldsOnFile() throws Exception
     {
         FTPFile file = getParser().parseFTPEntry("1-JUN.LIS;1              9/9           2-JUN-1998 07:32:04  [GROUP,OWNER]    (RWED,RWED,RW,R)");
@@ -219,6 +221,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getBadListing()
      */
+    @Override
     protected String[] getBadListing()
     {
 
@@ -228,6 +231,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getGoodListing()
      */
+    @Override
     protected String[] getGoodListing()
     {
 
@@ -237,6 +241,7 @@
     /**
      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getParser()
      */
+    @Override
     protected FTPFileEntryParser getParser()
     {
         ConfigurableFTPFileEntryParserImpl parser =
diff --git a/src/test/org/apache/commons/net/ntp/TimeStampTest.java b/src/test/java/org/apache/commons/net/ntp/TimeStampTest.java
similarity index 98%
rename from src/test/org/apache/commons/net/ntp/TimeStampTest.java
rename to src/test/java/org/apache/commons/net/ntp/TimeStampTest.java
index 7c22aff..9178d58 100644
--- a/src/test/org/apache/commons/net/ntp/TimeStampTest.java
+++ b/src/test/java/org/apache/commons/net/ntp/TimeStampTest.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
diff --git a/src/test/org/apache/commons/net/pop3/AllTests.java b/src/test/java/org/apache/commons/net/pop3/AllTests.java
similarity index 97%
rename from src/test/org/apache/commons/net/pop3/AllTests.java
rename to src/test/java/org/apache/commons/net/pop3/AllTests.java
index 431db30..48f7bfc 100644
--- a/src/test/org/apache/commons/net/pop3/AllTests.java
+++ b/src/test/java/org/apache/commons/net/pop3/AllTests.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.commons.net.pop3;
 
 import junit.framework.Test;
diff --git a/src/test/org/apache/commons/net/pop3/POP3ClientCommandsTest.java b/src/test/java/org/apache/commons/net/pop3/POP3ClientCommandsTest.java
similarity index 99%
rename from src/test/org/apache/commons/net/pop3/POP3ClientCommandsTest.java
rename to src/test/java/org/apache/commons/net/pop3/POP3ClientCommandsTest.java
index b3e414a..5456eac 100644
--- a/src/test/org/apache/commons/net/pop3/POP3ClientCommandsTest.java
+++ b/src/test/java/org/apache/commons/net/pop3/POP3ClientCommandsTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.commons.net.pop3;
 
 import junit.framework.TestCase;
diff --git a/src/test/org/apache/commons/net/pop3/POP3ClientTest.java b/src/test/java/org/apache/commons/net/pop3/POP3ClientTest.java
similarity index 98%
rename from src/test/org/apache/commons/net/pop3/POP3ClientTest.java
rename to src/test/java/org/apache/commons/net/pop3/POP3ClientTest.java
index 3a18ba8..b397b94 100644
--- a/src/test/org/apache/commons/net/pop3/POP3ClientTest.java
+++ b/src/test/java/org/apache/commons/net/pop3/POP3ClientTest.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.commons.net.pop3;
 
 import junit.framework.TestCase;
diff --git a/src/test/org/apache/commons/net/pop3/POP3ConstructorTest.java b/src/test/java/org/apache/commons/net/pop3/POP3ConstructorTest.java
similarity index 98%
rename from src/test/org/apache/commons/net/pop3/POP3ConstructorTest.java
rename to src/test/java/org/apache/commons/net/pop3/POP3ConstructorTest.java
index 9d4e5bd..6fdf408 100644
--- a/src/test/org/apache/commons/net/pop3/POP3ConstructorTest.java
+++ b/src/test/java/org/apache/commons/net/pop3/POP3ConstructorTest.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.commons.net.pop3;
 
 import junit.framework.TestCase;
diff --git a/src/test/org/apache/commons/net/pop3/TestSetupParameters.java b/src/test/java/org/apache/commons/net/pop3/TestSetupParameters.java
similarity index 97%
rename from src/test/org/apache/commons/net/pop3/TestSetupParameters.java
rename to src/test/java/org/apache/commons/net/pop3/TestSetupParameters.java
index 180bc28..494478c 100644
--- a/src/test/org/apache/commons/net/pop3/TestSetupParameters.java
+++ b/src/test/java/org/apache/commons/net/pop3/TestSetupParameters.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.commons.net.pop3;
 
 /**
diff --git a/src/test/org/apache/commons/net/telnet/EchoOptionHandlerTest.java b/src/test/java/org/apache/commons/net/telnet/EchoOptionHandlerTest.java
similarity index 95%
rename from src/test/org/apache/commons/net/telnet/EchoOptionHandlerTest.java
rename to src/test/java/org/apache/commons/net/telnet/EchoOptionHandlerTest.java
index 3822b23..be49fe3 100644
--- a/src/test/org/apache/commons/net/telnet/EchoOptionHandlerTest.java
+++ b/src/test/java/org/apache/commons/net/telnet/EchoOptionHandlerTest.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -34,6 +34,7 @@
     /***
      * setUp for the test.
      ***/
+    @Override
     protected void setUp()
     {
         opthand1 = new EchoOptionHandler();
@@ -44,6 +45,7 @@
     /***
      * test of the constructors.
      ***/
+    @Override
     public void testConstructors()
     {
         assertEquals(opthand1.getOptionCode(), TelnetOption.ECHO);
@@ -54,6 +56,7 @@
      * test of client-driven subnegotiation.
      * Checks that no subnegotiation is made.
      ***/
+    @Override
     public void testStartSubnegotiation()
     {
         int resp1[] = opthand1.startSubnegotiationLocal();
@@ -67,6 +70,7 @@
      * test of server-driven subnegotiation.
      * Checks that no subnegotiation is made.
      ***/
+    @Override
     public void testAnswerSubnegotiation()
     {
         int subn[] =
diff --git a/src/test/org/apache/commons/net/telnet/InvalidTelnetOptionExceptionTest.java b/src/test/java/org/apache/commons/net/telnet/InvalidTelnetOptionExceptionTest.java
similarity index 96%
rename from src/test/org/apache/commons/net/telnet/InvalidTelnetOptionExceptionTest.java
rename to src/test/java/org/apache/commons/net/telnet/InvalidTelnetOptionExceptionTest.java
index bf8564c..6fd3a35 100644
--- a/src/test/org/apache/commons/net/telnet/InvalidTelnetOptionExceptionTest.java
+++ b/src/test/java/org/apache/commons/net/telnet/InvalidTelnetOptionExceptionTest.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -40,6 +40,7 @@
     /***
      * setUp for the test.
      ***/
+    @Override
     protected void setUp()
     {
         msg1 = "MSG";
diff --git a/src/test/org/apache/commons/net/telnet/SimpleOptionHandlerTest.java b/src/test/java/org/apache/commons/net/telnet/SimpleOptionHandlerTest.java
similarity index 95%
rename from src/test/org/apache/commons/net/telnet/SimpleOptionHandlerTest.java
rename to src/test/java/org/apache/commons/net/telnet/SimpleOptionHandlerTest.java
index a15860f..2a8156c 100644
--- a/src/test/org/apache/commons/net/telnet/SimpleOptionHandlerTest.java
+++ b/src/test/java/org/apache/commons/net/telnet/SimpleOptionHandlerTest.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -34,6 +34,7 @@
     /***
      * setUp for the test.
      ***/
+    @Override
     protected void setUp()
     {
         opthand1 = new SimpleOptionHandler(4);
@@ -44,6 +45,7 @@
     /***
      * test of the constructors.
      ***/
+    @Override
     public void testConstructors()
     {
         assertEquals(opthand1.getOptionCode(), 4);
@@ -56,6 +58,7 @@
      * test of client-driven subnegotiation.
      * Checks that no subnegotiation is made.
      ***/
+    @Override
     public void testStartSubnegotiation()
     {
 
@@ -70,6 +73,7 @@
      * test of server-driven subnegotiation.
      * Checks that no subnegotiation is made.
      ***/
+    @Override
     public void testAnswerSubnegotiation()
     {
         int subn[] =
diff --git a/src/test/org/apache/commons/net/telnet/SuppressGAOptionHandlerTest.java b/src/test/java/org/apache/commons/net/telnet/SuppressGAOptionHandlerTest.java
similarity index 95%
rename from src/test/org/apache/commons/net/telnet/SuppressGAOptionHandlerTest.java
rename to src/test/java/org/apache/commons/net/telnet/SuppressGAOptionHandlerTest.java
index ff3ca4f..8ac14e3 100644
--- a/src/test/org/apache/commons/net/telnet/SuppressGAOptionHandlerTest.java
+++ b/src/test/java/org/apache/commons/net/telnet/SuppressGAOptionHandlerTest.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -34,6 +34,7 @@
     /***
      * setUp for the test.
      ***/
+    @Override
     protected void setUp()
     {
         opthand1 = new SuppressGAOptionHandler();
@@ -44,6 +45,7 @@
     /***
      * test of the constructors.
      ***/
+    @Override
     public void testConstructors()
     {
         assertEquals(opthand1.getOptionCode(), TelnetOption.SUPPRESS_GO_AHEAD);
@@ -54,6 +56,7 @@
      * test of client-driven subnegotiation.
      * Checks that no subnegotiation is made.
      ***/
+    @Override
     public void testStartSubnegotiation()
     {
 
@@ -68,6 +71,7 @@
      * test of server-driven subnegotiation.
      * Checks that no subnegotiation is made.
      ***/
+    @Override
     public void testAnswerSubnegotiation()
     {
         int subn[] =
diff --git a/src/test/org/apache/commons/net/telnet/TelnetClientFunctionalTest.java b/src/test/java/org/apache/commons/net/telnet/TelnetClientFunctionalTest.java
similarity index 97%
rename from src/test/org/apache/commons/net/telnet/TelnetClientFunctionalTest.java
rename to src/test/java/org/apache/commons/net/telnet/TelnetClientFunctionalTest.java
index 2baec1d..db15a74 100644
--- a/src/test/org/apache/commons/net/telnet/TelnetClientFunctionalTest.java
+++ b/src/test/java/org/apache/commons/net/telnet/TelnetClientFunctionalTest.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -42,6 +42,7 @@
     /***
      * test setUp
      ***/
+    @Override
     protected void setUp()
     {
         tc1 = new TelnetClient();
diff --git a/src/test/org/apache/commons/net/telnet/TelnetClientTest.java b/src/test/java/org/apache/commons/net/telnet/TelnetClientTest.java
similarity index 99%
rename from src/test/org/apache/commons/net/telnet/TelnetClientTest.java
rename to src/test/java/org/apache/commons/net/telnet/TelnetClientTest.java
index 2272289..ff47f50 100644
--- a/src/test/org/apache/commons/net/telnet/TelnetClientTest.java
+++ b/src/test/java/org/apache/commons/net/telnet/TelnetClientTest.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -81,6 +81,7 @@
     /***
      * open connections needed for the tests for the test.
      ***/
+    @Override
     protected void setUp() throws Exception 
     {
         super.setUp();
@@ -131,7 +132,7 @@
                     case 3:
                         NOREAD = new TestConnection(server, client, port);
                         break;
-    
+                        
                }
                
                // only increment socket number on success
@@ -147,6 +148,7 @@
     /* 
      * @throws java.lang.Exception
      */
+    @Override
     protected void tearDown() throws Exception {
         NOREAD.close();
         ANSI.close();
@@ -760,8 +762,7 @@
     /***
      * test of setReaderThread
      ***/
-    // Test is problematic (see r708403), so disabled temporarily
-    public void donttestReaderThread() throws Exception
+    public void testSetReaderThread() throws Exception
     {
         boolean negotiation1_ok = false;
         boolean negotiation2_ok = false;
@@ -843,7 +844,7 @@
             boolean result = true;
             for(int ii=0; ii<a1.length; ii++)
             {
-
+                
                 if(a1[ii]!= a2[ii])
                     result = false;
             }
@@ -881,4 +882,4 @@
         }
     }
 
-}
+}
\ No newline at end of file
diff --git a/src/test/org/apache/commons/net/telnet/TelnetOptionHandlerTestAbstract.java b/src/test/java/org/apache/commons/net/telnet/TelnetOptionHandlerTestAbstract.java
similarity index 97%
rename from src/test/org/apache/commons/net/telnet/TelnetOptionHandlerTestAbstract.java
rename to src/test/java/org/apache/commons/net/telnet/TelnetOptionHandlerTestAbstract.java
index 61d0e13..6f2151b 100644
--- a/src/test/org/apache/commons/net/telnet/TelnetOptionHandlerTestAbstract.java
+++ b/src/test/java/org/apache/commons/net/telnet/TelnetOptionHandlerTestAbstract.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -41,6 +41,7 @@
      *     opthand2 = new EchoOptionHandler(true, true, true, true);
      *     opthand3 = new EchoOptionHandler(false, false, false, false);
      ***/
+    @Override
     protected abstract void setUp();
 
     /***
diff --git a/src/test/org/apache/commons/net/telnet/TelnetOptionTest.java b/src/test/java/org/apache/commons/net/telnet/TelnetOptionTest.java
similarity index 96%
rename from src/test/org/apache/commons/net/telnet/TelnetOptionTest.java
rename to src/test/java/org/apache/commons/net/telnet/TelnetOptionTest.java
index 9a0eb85..7282640 100644
--- a/src/test/org/apache/commons/net/telnet/TelnetOptionTest.java
+++ b/src/test/java/org/apache/commons/net/telnet/TelnetOptionTest.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
diff --git a/src/test/org/apache/commons/net/telnet/TelnetTestResponder.java b/src/test/java/org/apache/commons/net/telnet/TelnetTestResponder.java
similarity index 95%
rename from src/test/org/apache/commons/net/telnet/TelnetTestResponder.java
rename to src/test/java/org/apache/commons/net/telnet/TelnetTestResponder.java
index b77b131..8c9909e 100644
--- a/src/test/org/apache/commons/net/telnet/TelnetTestResponder.java
+++ b/src/test/java/org/apache/commons/net/telnet/TelnetTestResponder.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -42,7 +42,8 @@
      * @param is - InputStream on which to read.
      * @param os - OutputStream on which to answer.
      * @param inputs - Array of waited for Strings.
-     * @param inputs - Array of answers.
+     * @param outputs - Array of answers.
+     * @param timeout - milliseconds
      ***/
     public TelnetTestResponder(InputStream is, OutputStream os, String inputs[], String outputs[], long timeout)
     {
diff --git a/src/test/org/apache/commons/net/telnet/TelnetTestSimpleServer.java b/src/test/java/org/apache/commons/net/telnet/TelnetTestSimpleServer.java
similarity index 98%
rename from src/test/org/apache/commons/net/telnet/TelnetTestSimpleServer.java
rename to src/test/java/org/apache/commons/net/telnet/TelnetTestSimpleServer.java
index a5d17c8..d564c25 100644
--- a/src/test/org/apache/commons/net/telnet/TelnetTestSimpleServer.java
+++ b/src/test/java/org/apache/commons/net/telnet/TelnetTestSimpleServer.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
diff --git a/src/test/org/apache/commons/net/telnet/TerminalTypeOptionHandlerTest.java b/src/test/java/org/apache/commons/net/telnet/TerminalTypeOptionHandlerTest.java
similarity index 96%
rename from src/test/org/apache/commons/net/telnet/TerminalTypeOptionHandlerTest.java
rename to src/test/java/org/apache/commons/net/telnet/TerminalTypeOptionHandlerTest.java
index 11c0358..c9ab320 100644
--- a/src/test/org/apache/commons/net/telnet/TerminalTypeOptionHandlerTest.java
+++ b/src/test/java/org/apache/commons/net/telnet/TerminalTypeOptionHandlerTest.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -34,6 +34,7 @@
     /***
      * setUp for the test.
      ***/
+    @Override
     protected void setUp()
     {
         opthand1 = new TerminalTypeOptionHandler("VT100");
@@ -44,6 +45,7 @@
     /***
      * test of the constructors.
      ***/
+    @Override
     public void testConstructors()
     {
         assertEquals(opthand1.getOptionCode(), TelnetOption.TERMINAL_TYPE);
@@ -54,6 +56,7 @@
      * test of client-driven subnegotiation.
      * Checks that no subnegotiation is made.
      ***/
+    @Override
     public void testStartSubnegotiation()
     {
 
@@ -69,6 +72,7 @@
      * test of client-driven subnegotiation.
      * Checks that the terminal type is sent
      ***/
+    @Override
     public void testAnswerSubnegotiation()
     {
         int subn[] =
diff --git a/src/test/java/org/apache/commons/net/tftp/TFTPServer.java b/src/test/java/org/apache/commons/net/tftp/TFTPServer.java
new file mode 100644
index 0000000..ed404c2
--- /dev/null
+++ b/src/test/java/org/apache/commons/net/tftp/TFTPServer.java
@@ -0,0 +1,862 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.net.tftp;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.net.SocketTimeoutException;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import org.apache.commons.net.io.FromNetASCIIOutputStream;
+import org.apache.commons.net.io.ToNetASCIIInputStream;
+
+/**
+ * A fully multi-threaded tftp server. Can handle multiple clients at the same time. Implements RFC
+ * 1350 and wrapping block numbers for large file support.
+ * 
+ * To launch, just create an instance of the class. An IOException will be thrown if the server
+ * fails to start for reasons such as port in use, port denied, etc.
+ * 
+ * To stop, use the shutdown method.
+ * 
+ * To check to see if the server is still running (or if it stopped because of an error), call the
+ * isRunning() method.
+ * 
+ * By default, events are not logged to stdout/stderr. This can be changed with the
+ * setLog and setLogError methods.
+ * 
+ * <p>
+ * Example usage is below:
+ * 
+ * <code>
+ * public static void main(String[] args) throws Exception
+ *  {
+ *      if (args.length != 1)
+ *      {
+ *          System.out
+ *                  .println("You must provide 1 argument - the base path for the server to serve from.");
+ *          System.exit(1);
+ *      }
+ *
+ *      TFTPServer ts = new TFTPServer(new File(args[0]), new File(args[0]), GET_AND_PUT);
+ *      ts.setSocketTimeout(2000);
+ *
+ *      System.out.println("TFTP Server running.  Press enter to stop.");
+ *      new InputStreamReader(System.in).read();
+ *
+ *      ts.shutdown();
+ *      System.out.println("Server shut down.");
+ *      System.exit(0);
+ *  }
+ *
+ * </code>
+ * 
+ * 
+ * @author <A HREF="mailto:daniel.armbrust.list@gmail.com">Dan Armbrust</A>
+ * @since 2.0
+ */
+
+public class TFTPServer implements Runnable
+{
+    private static final int DEFAULT_TFTP_PORT = 69;
+    public static enum ServerMode { GET_ONLY, PUT_ONLY, GET_AND_PUT; }
+
+    private HashSet<TFTPTransfer> transfers_ = new HashSet<TFTPTransfer>();
+    private volatile boolean shutdownServer = false;
+    private TFTP serverTftp_;
+    private File serverReadDirectory_;
+    private File serverWriteDirectory_;
+    private int port_;
+    private Exception serverException = null;
+    private ServerMode mode_;
+
+    /* /dev/null output stream (default) */ 
+    private static final PrintStream nullStream = new PrintStream(
+            new OutputStream() { 
+                @Override
+                public void write(int b){}
+                @Override
+                public void write(byte[] b) throws IOException {}
+                }
+            );
+
+    // don't have access to a logger api, so we will log to these streams, which
+    // by default are set to a no-op logger
+    private PrintStream log_;
+    private PrintStream logError_;
+
+    private int maxTimeoutRetries_ = 3;
+    private int socketTimeout_;
+    private Thread serverThread;
+    
+    
+    /**
+     * Start a TFTP Server on the default port (69). Gets and Puts occur in the specified
+     * directories.
+     * 
+     * The server will start in another thread, allowing this constructor to return immediately.
+     * 
+     * If a get or a put comes in with a relative path that tries to get outside of the
+     * serverDirectory, then the get or put will be denied.
+     * 
+     * GET_ONLY mode only allows gets, PUT_ONLY mode only allows puts, and GET_AND_PUT allows both.
+     * Modes are defined as int constants in this class.
+     * 
+     * @param serverReadDirectory directory for GET requests
+     * @param serverWriteDirectory directory for PUT requests
+     * @param mode A value as specified above.
+     * @throws IOException if the server directory is invalid or does not exist.
+     */
+    public TFTPServer(File serverReadDirectory, File serverWriteDirectory, ServerMode mode)
+            throws IOException
+    {
+        this(serverReadDirectory, serverWriteDirectory, DEFAULT_TFTP_PORT, mode, null, null);
+    }
+
+    /**
+     * Start a TFTP Server on the specified port. Gets and Puts occur in the specified directory.
+     * 
+     * The server will start in another thread, allowing this constructor to return immediately.
+     * 
+     * If a get or a put comes in with a relative path that tries to get outside of the
+     * serverDirectory, then the get or put will be denied.
+     * 
+     * GET_ONLY mode only allows gets, PUT_ONLY mode only allows puts, and GET_AND_PUT allows both.
+     * Modes are defined as int constants in this class.
+     * 
+     * @param serverReadDirectory directory for GET requests
+     * @param serverWriteDirectory directory for PUT requests
+     * @param mode A value as specified above.
+     * @param log Stream to write log message to. If not provided, uses System.out
+     * @param errorLog Stream to write error messages to. If not provided, uses System.err.
+     * @throws IOException if the server directory is invalid or does not exist.
+     */
+    public TFTPServer(File serverReadDirectory, File serverWriteDirectory, int port, ServerMode mode,
+            PrintStream log, PrintStream errorLog) throws IOException
+    {
+        port_ = port;
+        mode_ = mode;
+        log_ = (log == null ? nullStream: log);
+        logError_ = (errorLog == null ? nullStream : errorLog);
+        launch(serverReadDirectory, serverWriteDirectory);
+    }
+
+    /**
+     * Set the max number of retries in response to a timeout. Default 3. Min 0.
+     * 
+     * @param retries
+     */
+    public void setMaxTimeoutRetries(int retries)
+    {
+        if (retries < 0)
+        {
+            throw new RuntimeException("Invalid Value");
+        }
+        maxTimeoutRetries_ = retries;
+    }
+
+    /**
+     * Get the current value for maxTimeoutRetries
+     */
+    public int getMaxTimeoutRetries()
+    {
+        return maxTimeoutRetries_;
+    }
+
+    /**
+     * Set the socket timeout in milliseconds used in transfers. Defaults to the value here:
+     * http://commons.apache.org/net/apidocs/org/apache/commons/net/tftp/TFTP.html#DEFAULT_TIMEOUT
+     * (5000 at the time I write this) Min value of 10.
+     */
+    public void setSocketTimeout(int timeout)
+    {
+        if (timeout < 10)
+        {
+            throw new RuntimeException("Invalid Value");
+        }
+        socketTimeout_ = timeout;
+    }
+
+    /**
+     * The current socket timeout used during transfers in milliseconds.
+     */
+    public int getSocketTimeout()
+    {
+        return socketTimeout_;
+    }
+
+    /*
+     * start the server, throw an error if it can't start.
+     */
+    private void launch(File serverReadDirectory, File serverWriteDirectory) throws IOException
+    {
+        log_.println("Starting TFTP Server on port " + port_ + ".  Read directory: "
+                + serverReadDirectory + " Write directory: " + serverWriteDirectory
+                + " Server Mode is " + mode_);
+
+        serverReadDirectory_ = serverReadDirectory.getCanonicalFile();
+        if (!serverReadDirectory_.exists() || !serverReadDirectory.isDirectory())
+        {
+            throw new IOException("The server read directory " + serverReadDirectory_
+                    + " does not exist");
+        }
+
+        serverWriteDirectory_ = serverWriteDirectory.getCanonicalFile();
+        if (!serverWriteDirectory_.exists() || !serverWriteDirectory.isDirectory())
+        {
+            throw new IOException("The server write directory " + serverWriteDirectory_
+                    + " does not exist");
+        }
+
+        serverTftp_ = new TFTP();
+
+        // This is the value used in response to each client.
+        socketTimeout_ = serverTftp_.getDefaultTimeout();
+
+        // we want the server thread to listen forever.
+        serverTftp_.setDefaultTimeout(0);
+
+        serverTftp_.open(port_);
+
+        serverThread = new Thread(this);
+        serverThread.setDaemon(true);
+        serverThread.start();
+    }
+
+    @Override
+    protected void finalize() throws Throwable
+    {
+        shutdown();
+    }
+
+    /**
+     * check if the server thread is still running.
+     * 
+     * @return true if running, false if stopped.
+     * @throws Exception throws the exception that stopped the server if the server is stopped from
+     *             an exception.
+     */
+    public boolean isRunning() throws Exception
+    {
+        if (shutdownServer && serverException != null)
+        {
+            throw serverException;
+        }
+        return !shutdownServer;
+    }
+
+    public void run()
+    {
+        try
+        {
+            while (!shutdownServer)
+            {
+                TFTPPacket tftpPacket;
+
+                tftpPacket = serverTftp_.receive();
+
+                TFTPTransfer tt = new TFTPTransfer(tftpPacket);
+                synchronized(transfers_)
+                {
+                    transfers_.add(tt);
+                }
+
+                Thread thread = new Thread(tt);
+                thread.setDaemon(true);
+                thread.start();
+            }
+        }
+        catch (Exception e)
+        {
+            if (!shutdownServer)
+            {
+                serverException = e;
+                logError_.println("Unexpected Error in TFTP Server - Server shut down! + " + e);
+            }
+        }
+        finally
+        {
+            shutdownServer = true; // set this to true, so the launching thread can check to see if it started.
+            if (serverTftp_ != null && serverTftp_.isOpen())
+            {
+                serverTftp_.close();
+            }
+        }
+    }
+
+    /**
+     * Stop the tftp server (and any currently running transfers) and release all opened network
+     * resources.
+     */
+    public void shutdown()
+    {
+        shutdownServer = true;
+
+        synchronized(transfers_)
+        {
+            Iterator<TFTPTransfer> it = transfers_.iterator();
+            while (it.hasNext())
+            {
+                it.next().shutdown();
+            }
+        }
+
+        try
+        {
+            serverTftp_.close();
+        }
+        catch (RuntimeException e)
+        {
+            // noop
+        }
+        
+        try {
+            serverThread.join();
+        } catch (InterruptedException e) {
+            // we've done the best we could, return
+        }
+    }
+
+    /*
+     * An instance of an ongoing transfer.
+     */
+    private class TFTPTransfer implements Runnable
+    {
+        private TFTPPacket tftpPacket_;
+
+        private boolean shutdownTransfer = false;
+
+        TFTP transferTftp_ = null;
+
+        public TFTPTransfer(TFTPPacket tftpPacket)
+        {
+            tftpPacket_ = tftpPacket;
+        }
+
+        public void shutdown()
+        {
+            shutdownTransfer = true;
+            try
+            {
+                transferTftp_.close();
+            }
+            catch (RuntimeException e)
+            {
+                // noop
+            }
+        }
+
+        public void run()
+        {
+            try
+            {
+                transferTftp_ = new TFTP();
+
+                transferTftp_.beginBufferedOps();
+                transferTftp_.setDefaultTimeout(socketTimeout_);
+
+                transferTftp_.open();
+
+                if (tftpPacket_ instanceof TFTPReadRequestPacket)
+                {
+                    handleRead(((TFTPReadRequestPacket) tftpPacket_));
+                }
+                else if (tftpPacket_ instanceof TFTPWriteRequestPacket)
+                {
+                    handleWrite((TFTPWriteRequestPacket) tftpPacket_);
+                }
+                else
+                {
+                    log_.println("Unsupported TFTP request (" + tftpPacket_ + ") - ignored.");
+                }
+            }
+            catch (Exception e)
+            {
+                if (!shutdownTransfer)
+                {
+                    logError_
+                            .println("Unexpected Error in during TFTP file transfer.  Transfer aborted. "
+                                    + e);
+                }
+            }
+            finally
+            {
+                try
+                {
+                    if (transferTftp_ != null && transferTftp_.isOpen())
+                    {
+                        transferTftp_.endBufferedOps();
+                        transferTftp_.close();
+                    }
+                }
+                catch (Exception e)
+                {
+                    // noop
+                }
+                synchronized(transfers_)
+                {
+                    transfers_.remove(this);
+                }
+            }
+        }
+
+        /*
+         * Handle a tftp read request.
+         */
+        private void handleRead(TFTPReadRequestPacket trrp) throws IOException, TFTPPacketException
+        {
+            InputStream is = null;
+            try
+            {
+                if (mode_ == ServerMode.PUT_ONLY)
+                {
+                    transferTftp_.bufferedSend(new TFTPErrorPacket(trrp.getAddress(), trrp
+                            .getPort(), TFTPErrorPacket.ILLEGAL_OPERATION,
+                            "Read not allowed by server."));
+                    return;
+                }
+
+                try
+                {
+                    is = new BufferedInputStream(new FileInputStream(buildSafeFile(
+                            serverReadDirectory_, trrp.getFilename(), false)));
+                }
+                catch (FileNotFoundException e)
+                {
+                    transferTftp_.bufferedSend(new TFTPErrorPacket(trrp.getAddress(), trrp
+                            .getPort(), TFTPErrorPacket.FILE_NOT_FOUND, e.getMessage()));
+                    return;
+                }
+                catch (Exception e)
+                {
+                    transferTftp_.bufferedSend(new TFTPErrorPacket(trrp.getAddress(), trrp
+                            .getPort(), TFTPErrorPacket.UNDEFINED, e.getMessage()));
+                    return;
+                }
+
+                if (trrp.getMode() == TFTP.NETASCII_MODE)
+                {
+                    is = new ToNetASCIIInputStream(is);
+                }
+
+                byte[] temp = new byte[TFTPDataPacket.MAX_DATA_LENGTH];
+
+                TFTPPacket answer;
+
+                int block = 1;
+                boolean sendNext = true;
+
+                int readLength = TFTPDataPacket.MAX_DATA_LENGTH;
+
+                TFTPDataPacket lastSentData = null;
+
+                // We are reading a file, so when we read less than the
+                // requested bytes, we know that we are at the end of the file.
+                while (readLength == TFTPDataPacket.MAX_DATA_LENGTH && !shutdownTransfer)
+                {
+                    if (sendNext)
+                    {
+                        readLength = is.read(temp);
+                        if (readLength == -1)
+                        {
+                            readLength = 0;
+                        }
+
+                        lastSentData = new TFTPDataPacket(trrp.getAddress(), trrp.getPort(), block,
+                                temp, 0, readLength);
+                        transferTftp_.bufferedSend(lastSentData);
+                    }
+
+                    answer = null;
+
+                    int timeoutCount = 0;
+
+                    while (!shutdownTransfer
+                            && (answer == null || !answer.getAddress().equals(trrp.getAddress()) || answer
+                                    .getPort() != trrp.getPort()))
+                    {
+                        // listen for an answer.
+                        if (answer != null)
+                        {
+                            // The answer that we got didn't come from the
+                            // expected source, fire back an error, and continue
+                            // listening.
+                            log_.println("TFTP Server ignoring message from unexpected source.");
+                            transferTftp_.bufferedSend(new TFTPErrorPacket(answer.getAddress(),
+                                    answer.getPort(), TFTPErrorPacket.UNKNOWN_TID,
+                                    "Unexpected Host or Port"));
+                        }
+                        try
+                        {
+                            answer = transferTftp_.bufferedReceive();
+                        }
+                        catch (SocketTimeoutException e)
+                        {
+                            if (timeoutCount >= maxTimeoutRetries_)
+                            {
+                                throw e;
+                            }
+                            // didn't get an ack for this data. need to resend
+                            // it.
+                            timeoutCount++;
+                            transferTftp_.bufferedSend(lastSentData);
+                            continue;
+                        }
+                    }
+
+                    if (answer == null || !(answer instanceof TFTPAckPacket))
+                    {
+                        if (!shutdownTransfer)
+                        {
+                            logError_
+                                    .println("Unexpected response from tftp client during transfer ("
+                                            + answer + ").  Transfer aborted.");
+                        }
+                        break;
+                    }
+                    else
+                    {
+                        // once we get here, we know we have an answer packet
+                        // from the correct host.
+                        TFTPAckPacket ack = (TFTPAckPacket) answer;
+                        if (ack.getBlockNumber() != block)
+                        {
+                            /*
+                             * The origional tftp spec would have called on us to resend the
+                             * previous data here, however, that causes the SAS Syndrome.
+                             * http://www.faqs.org/rfcs/rfc1123.html section 4.2.3.1 The modified
+                             * spec says that we ignore a duplicate ack. If the packet was really
+                             * lost, we will time out on receive, and resend the previous data at
+                             * that point.
+                             */
+                            sendNext = false;
+                        }
+                        else
+                        {
+                            // send the next block
+                            block++;
+                            if (block > 65535)
+                            {
+                                // wrap the block number
+                                block = 0;
+                            }
+                            sendNext = true;
+                        }
+                    }
+                }
+            }
+            finally
+            {
+                try
+                {
+                    if (is != null)
+                    {
+                        is.close();
+                    }
+                }
+                catch (IOException e)
+                {
+                    // noop
+                }
+            }
+        }
+
+        /*
+         * handle a tftp write request.
+         */
+        private void handleWrite(TFTPWriteRequestPacket twrp) throws IOException,
+                TFTPPacketException
+        {
+            OutputStream bos = null;
+            try
+            {
+                if (mode_ == ServerMode.GET_ONLY)
+                {
+                    transferTftp_.bufferedSend(new TFTPErrorPacket(twrp.getAddress(), twrp
+                            .getPort(), TFTPErrorPacket.ILLEGAL_OPERATION,
+                            "Write not allowed by server."));
+                    return;
+                }
+
+                int lastBlock = 0;
+                String fileName = twrp.getFilename();
+
+                try
+                {
+                    File temp = buildSafeFile(serverWriteDirectory_, fileName, true);
+                    if (temp.exists())
+                    {
+                        transferTftp_.bufferedSend(new TFTPErrorPacket(twrp.getAddress(), twrp
+                                .getPort(), TFTPErrorPacket.FILE_EXISTS, "File already exists"));
+                        return;
+                    }
+                    bos = new BufferedOutputStream(new FileOutputStream(temp));
+                    
+                    if (twrp.getMode() == TFTP.NETASCII_MODE)
+                    {
+                        bos = new FromNetASCIIOutputStream(bos);
+                    }
+                }
+                catch (Exception e)
+                {
+                    transferTftp_.bufferedSend(new TFTPErrorPacket(twrp.getAddress(), twrp
+                            .getPort(), TFTPErrorPacket.UNDEFINED, e.getMessage()));
+                    return;
+                }
+
+                TFTPAckPacket lastSentAck = new TFTPAckPacket(twrp.getAddress(), twrp.getPort(), 0);
+                transferTftp_.bufferedSend(lastSentAck);
+
+                while (true)
+                {
+                    // get the response - ensure it is from the right place.
+                    TFTPPacket dataPacket = null;
+
+                    int timeoutCount = 0;
+
+                    while (!shutdownTransfer
+                            && (dataPacket == null
+                                    || !dataPacket.getAddress().equals(twrp.getAddress()) || dataPacket
+                                    .getPort() != twrp.getPort()))
+                    {
+                        // listen for an answer.
+                        if (dataPacket != null)
+                        {
+                            // The data that we got didn't come from the
+                            // expected source, fire back an error, and continue
+                            // listening.
+                            log_.println("TFTP Server ignoring message from unexpected source.");
+                            transferTftp_.bufferedSend(new TFTPErrorPacket(dataPacket.getAddress(),
+                                    dataPacket.getPort(), TFTPErrorPacket.UNKNOWN_TID,
+                                    "Unexpected Host or Port"));
+                        }
+
+                        try
+                        {
+                            dataPacket = transferTftp_.bufferedReceive();
+                        }
+                        catch (SocketTimeoutException e)
+                        {
+                            if (timeoutCount >= maxTimeoutRetries_)
+                            {
+                                throw e;
+                            }
+                            // It didn't get our ack. Resend it.
+                            transferTftp_.bufferedSend(lastSentAck);
+                            timeoutCount++;
+                            continue;
+                        }
+                    }
+
+                    if (dataPacket != null && dataPacket instanceof TFTPWriteRequestPacket)
+                    {
+                        // it must have missed our initial ack. Send another.
+                        lastSentAck = new TFTPAckPacket(twrp.getAddress(), twrp.getPort(), 0);
+                        transferTftp_.bufferedSend(lastSentAck);
+                    }
+                    else if (dataPacket == null || !(dataPacket instanceof TFTPDataPacket))
+                    {
+                        if (!shutdownTransfer)
+                        {
+                            logError_
+                                    .println("Unexpected response from tftp client during transfer ("
+                                            + dataPacket + ").  Transfer aborted.");
+                        }
+                        break;
+                    }
+                    else
+                    {
+                        int block = ((TFTPDataPacket) dataPacket).getBlockNumber();
+                        byte[] data = ((TFTPDataPacket) dataPacket).getData();
+                        int dataLength = ((TFTPDataPacket) dataPacket).getDataLength();
+                        int dataOffset = ((TFTPDataPacket) dataPacket).getDataOffset();
+
+                        if (block > lastBlock || (lastBlock == 65535 && block == 0))
+                        {
+                            // it might resend a data block if it missed our ack
+                            // - don't rewrite the block.
+                            bos.write(data, dataOffset, dataLength);
+                            lastBlock = block;
+                        }
+
+                        lastSentAck = new TFTPAckPacket(twrp.getAddress(), twrp.getPort(), block);
+                        transferTftp_.bufferedSend(lastSentAck);
+                        if (dataLength < TFTPDataPacket.MAX_DATA_LENGTH)
+                        {
+                            // end of stream signal - The tranfer is complete.
+                            bos.close();
+
+                            // But my ack may be lost - so listen to see if I
+                            // need to resend the ack.
+                            for (int i = 0; i < maxTimeoutRetries_; i++)
+                            {
+                                try
+                                {
+                                    dataPacket = transferTftp_.bufferedReceive();
+                                }
+                                catch (SocketTimeoutException e)
+                                {
+                                    // this is the expected route - the client
+                                    // shouldn't be sending any more packets.
+                                    break;
+                                }
+
+                                if (dataPacket != null
+                                        && (!dataPacket.getAddress().equals(twrp.getAddress()) || dataPacket
+                                                .getPort() != twrp.getPort()))
+                                {
+                                    // make sure it was from the right client...
+                                    transferTftp_
+                                            .bufferedSend(new TFTPErrorPacket(dataPacket
+                                                    .getAddress(), dataPacket.getPort(),
+                                                    TFTPErrorPacket.UNKNOWN_TID,
+                                                    "Unexpected Host or Port"));
+                                }
+                                else
+                                {
+                                    // This means they sent us the last
+                                    // datapacket again, must have missed our
+                                    // ack. resend it.
+                                    transferTftp_.bufferedSend(lastSentAck);
+                                }
+                            }
+
+                            // all done.
+                            break;
+                        }
+                    }
+                }
+            }
+            finally
+            {
+                if (bos != null)
+                {
+                    bos.close();
+                }
+            }
+        }
+
+        /*
+         * Utility method to make sure that paths provided by tftp clients do not get outside of the
+         * serverRoot directory.
+         */
+        private File buildSafeFile(File serverDirectory, String fileName, boolean createSubDirs)
+                throws IOException
+        {
+            File temp = new File(serverDirectory, fileName);
+            temp = temp.getCanonicalFile();
+
+            if (!isSubdirectoryOf(serverDirectory, temp))
+            {
+                throw new IOException("Cannot access files outside of tftp server root.");
+            }
+
+            // ensure directory exists (if requested)
+            if (createSubDirs)
+            {
+                createDirectory(temp.getParentFile());
+            }
+
+            return temp;
+        }
+
+        /*
+         * recursively create subdirectories
+         */
+        private void createDirectory(File file) throws IOException
+        {
+            File parent = file.getParentFile();
+            if (parent == null)
+            {
+                throw new IOException("Unexpected error creating requested directory");
+            }
+            if (!parent.exists())
+            {
+                // recurse...
+                createDirectory(parent);
+            }
+
+            if (parent.isDirectory())
+            {
+                if (file.isDirectory())
+                {
+                    return;
+                }
+                boolean result = file.mkdir();
+                if (!result)
+                {
+                    throw new IOException("Couldn't create requested directory");
+                }
+            }
+            else
+            {
+                throw new IOException(
+                        "Invalid directory path - file in the way of requested folder");
+            }
+        }
+
+        /*
+         * recursively check to see if one directory is a parent of another.
+         */
+        private boolean isSubdirectoryOf(File parent, File child)
+        {
+            File childsParent = child.getParentFile();
+            if (childsParent == null)
+            {
+                return false;
+            }
+            if (childsParent.equals(parent))
+            {
+                return true;
+            }
+            else
+            {
+                return isSubdirectoryOf(parent, childsParent);
+            }
+        }
+    }
+
+    /**
+     * Set the stream object to log debug / informational messages. By default, this is a no-op
+     * 
+     * @param log
+     */
+    public void setLog(PrintStream log)
+    {
+        this.log_ = log;
+    }
+
+    /**
+     * Set the stream object to log error messsages. By default, this is a no-op
+     * 
+     * @param logError
+     */
+    public void setLogError(PrintStream logError)
+    {
+        this.logError_ = logError;
+    }
+}
diff --git a/src/test/java/org/apache/commons/net/tftp/TFTPServerPathTest.java b/src/test/java/org/apache/commons/net/tftp/TFTPServerPathTest.java
new file mode 100644
index 0000000..d2d8208
--- /dev/null
+++ b/src/test/java/org/apache/commons/net/tftp/TFTPServerPathTest.java
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.net.tftp;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import org.apache.commons.net.tftp.TFTPServer.ServerMode;
+
+import junit.framework.TestCase;
+
+/**
+ * Some basic tests to ensure that the TFTP Server is honoring its read/write mode, and preventing
+ * files from being read or written from outside of the assigned roots.
+ * 
+ * @author <A HREF="mailto:daniel.armbrust.list@gmail.com">Dan Armbrust</A>
+ * 
+ */
+public class TFTPServerPathTest extends TestCase
+{
+    String filePrefix = "tftp-";
+    File serverDirectory = new File(System.getProperty("java.io.tmpdir"));
+
+    public void testReadOnly() throws IOException
+    {
+        // Start a read-only server
+        TFTPServer tftpS = new TFTPServer(serverDirectory, serverDirectory, 6900,
+                ServerMode.GET_ONLY, null, null);
+
+        // Create our TFTP instance to handle the file transfer.
+        TFTPClient tftp = new TFTPClient();
+        tftp.open();
+        tftp.setSoTimeout(2000);
+
+        // make a file to work with.
+        File file = new File(serverDirectory, filePrefix + "source.txt");
+        file.createNewFile();
+
+        // Read the file from the tftp server.
+        File out = new File(serverDirectory, filePrefix + "out");
+
+        // cleanup old failed runs
+        out.delete();
+        assertTrue("Couldn't clear output location", !out.exists());
+
+        FileOutputStream output = new FileOutputStream(out);
+
+        tftp.receiveFile(file.getName(), TFTP.BINARY_MODE, output, "localhost", 6900);
+        output.close();
+
+        assertTrue("file not created", out.exists());
+
+        out.delete();
+
+        FileInputStream fis = new FileInputStream(file);
+        try
+        {
+            tftp.sendFile(out.getName(), TFTP.BINARY_MODE, fis, "localhost", 6900);
+            fail("Server allowed write");
+        }
+        catch (IOException e)
+        {
+            // expected path
+        }
+        fis.close();
+        file.delete();
+        tftpS.shutdown();
+    }
+
+    public void testWriteOnly() throws IOException
+    {
+        // Start a write-only server
+        TFTPServer tftpS = new TFTPServer(serverDirectory, serverDirectory, 6900,
+                ServerMode.PUT_ONLY, null, null);
+
+        // Create our TFTP instance to handle the file transfer.
+        TFTPClient tftp = new TFTPClient();
+        tftp.open();
+        tftp.setSoTimeout(2000);
+
+        // make a file to work with.
+        File file = new File(serverDirectory, filePrefix + "source.txt");
+        file.createNewFile();
+
+        File out = new File(serverDirectory, filePrefix + "out");
+
+        // cleanup old failed runs
+        out.delete();
+        assertTrue("Couldn't clear output location", !out.exists());
+
+        FileOutputStream output = new FileOutputStream(out);
+
+        try
+        {
+            tftp.receiveFile(file.getName(), TFTP.BINARY_MODE, output, "localhost", 6900);
+            fail("Server allowed read");
+        }
+        catch (IOException e)
+        {
+            // expected path
+        }
+        output.close();
+        out.delete();
+
+        FileInputStream fis = new FileInputStream(file);
+        tftp.sendFile(out.getName(), TFTP.BINARY_MODE, fis, "localhost", 6900);
+
+        fis.close();
+
+        assertTrue("file not created", out.exists());
+
+        // cleanup
+        file.delete();
+        out.delete();
+        tftpS.shutdown();
+    }
+
+    public void testWriteOutsideHome() throws IOException
+    {
+        // Start a server
+        TFTPServer tftpS = new TFTPServer(serverDirectory, serverDirectory, 6900,
+                ServerMode.GET_AND_PUT, null, null);
+
+        // Create our TFTP instance to handle the file transfer.
+        TFTPClient tftp = new TFTPClient();
+        tftp.open();
+
+        File file = new File(serverDirectory, filePrefix + "source.txt");
+        file.createNewFile();
+
+        assertFalse("test construction error", new File(serverDirectory, "../foo").exists());
+
+        FileInputStream fis = new FileInputStream(file);
+        try
+        {
+            tftp.sendFile("../foo", TFTP.BINARY_MODE, fis, "localhost", 6900);
+            fail("Server allowed write!");
+        }
+        catch (IOException e)
+        {
+            // expected path
+        }
+
+        fis.close();
+
+        assertFalse("file created when it should not have been",
+                new File(serverDirectory, "../foo").exists());
+
+        // cleanup
+        file.delete();
+
+        tftpS.shutdown();
+    }
+    
+    
+}
diff --git a/src/test/java/org/apache/commons/net/tftp/TFTPTest.java b/src/test/java/org/apache/commons/net/tftp/TFTPTest.java
new file mode 100644
index 0000000..298c090
--- /dev/null
+++ b/src/test/java/org/apache/commons/net/tftp/TFTPTest.java
@@ -0,0 +1,244 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.net.tftp;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.commons.net.tftp.TFTPServer.ServerMode;
+
+import junit.framework.TestCase;
+
+/**
+ * Test the TFTP Server and TFTP Client by creating some files in the system temp folder and then
+ * uploading and downloading them.
+ * 
+ * @author <A HREF="mailto:daniel.armbrust.list@gmail.com">Dan Armbrust</A>
+ * 
+ */
+public class TFTPTest extends TestCase
+{
+    static TFTPServer tftpS;
+    static File serverDirectory = new File(System.getProperty("java.io.tmpdir"));
+    static String filePrefix = "tftp-";
+    static File[] files = new File[8];
+
+    static int testsLeftToRun = 6;
+
+    // only want to do this once...
+    static
+    {
+        try
+        {
+            files[0] = createFile(new File(serverDirectory, filePrefix + "empty.txt"), 0);
+            files[1] = createFile(new File(serverDirectory, filePrefix + "small.txt"), 1);
+            files[2] = createFile(new File(serverDirectory, filePrefix + "511.txt"), 511);
+            files[3] = createFile(new File(serverDirectory, filePrefix + "512.txt"), 512);
+            files[4] = createFile(new File(serverDirectory, filePrefix + "513.txt"), 513);
+            files[5] = createFile(new File(serverDirectory, filePrefix + "med.txt"), 1000 * 1024);
+            files[6] = createFile(new File(serverDirectory, filePrefix + "big.txt"), 5000 * 1024);
+            files[7] = createFile(new File(serverDirectory, filePrefix + "huge.txt"), 37000 * 1024);
+
+            // Start the server
+            tftpS = new TFTPServer(serverDirectory, serverDirectory, 6900, ServerMode.GET_AND_PUT,
+                    null, null);
+            tftpS.setSocketTimeout(2000);
+        }
+        catch (IOException e)
+        {
+            e.printStackTrace();
+        }
+
+    }
+
+    @Override
+    protected void tearDown() throws Exception
+    {
+        testsLeftToRun--;
+        if (testsLeftToRun <= 0)
+        {
+            if (tftpS != null)
+            {
+                tftpS.shutdown();
+            }
+            for (int i = 0; i < files.length; i++)
+            {
+                files[i].delete();
+            }
+        }
+        super.tearDown();
+    }
+
+    /*
+     * Create a file, size specified in bytes
+     */
+    private static File createFile(File file, int size) throws IOException
+    {
+        OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
+        byte[] temp = "0".getBytes();
+        for (int i = 0; i < size; i++)
+        {
+            os.write(temp);
+        }
+        os.close();
+        return file;
+    }
+
+    public void testTFTPBinaryDownloads() throws Exception
+    {
+        // test with the smaller files
+        for (int i = 0; i < 6; i++)
+        {
+            testDownload(TFTP.BINARY_MODE, files[i]);
+        }
+    }
+
+    public void testASCIIDownloads() throws Exception
+    {
+        // test with the smaller files
+        for (int i = 0; i < 6; i++)
+        {
+            testDownload(TFTP.ASCII_MODE, files[i]);
+        }
+    }
+
+    public void testTFTPBinaryUploads() throws Exception
+    {
+        // test with the smaller files
+        for (int i = 0; i < 6; i++)
+        {
+            testUpload(TFTP.BINARY_MODE, files[i]);
+        }
+    }
+
+    public void testASCIIUploads() throws Exception
+    {
+        // test with the smaller files
+        for (int i = 0; i < 6; i++)
+        {
+            testUpload(TFTP.ASCII_MODE, files[i]);
+        }
+    }
+
+    public void testHugeUploads() throws Exception
+    {
+        for (int i = 5; i < files.length; i++)
+        {
+            testUpload(TFTP.BINARY_MODE, files[i]);
+        }
+    }
+
+    public void testHugeDownloads() throws Exception
+    {
+        // test with the smaller files
+        for (int i = 5; i < files.length; i++)
+        {
+            testDownload(TFTP.BINARY_MODE, files[i]);
+        }
+    }
+
+    private void testDownload(int mode, File file) throws IOException
+    {
+        // Create our TFTP instance to handle the file transfer.
+        TFTPClient tftp = new TFTPClient();
+        tftp.open();
+        tftp.setSoTimeout(2000);
+
+        File out = new File(serverDirectory, filePrefix + "download");
+
+        // cleanup old failed runs
+        out.delete();
+        assertTrue("Couldn't clear output location", !out.exists());
+
+        FileOutputStream output = new FileOutputStream(out);
+
+        tftp.receiveFile(file.getName(), mode, output, "localhost", 6900);
+        output.close();
+
+        assertTrue("file not created", out.exists());
+        assertTrue("files not identical on file " + file, filesIdentical(out, file));
+
+        // delete the downloaded file
+        out.delete();
+    }
+
+    private void testUpload(int mode, File file) throws Exception
+    {
+        // Create our TFTP instance to handle the file transfer.
+        TFTPClient tftp = new TFTPClient();
+        tftp.open();
+        tftp.setSoTimeout(2000);
+
+        File in = new File(serverDirectory, filePrefix + "upload");
+        // cleanup old failed runs
+        in.delete();
+        assertTrue("Couldn't clear output location", !in.exists());
+
+        FileInputStream fis = new FileInputStream(file);
+        tftp.sendFile(in.getName(), mode, fis, "localhost", 6900);
+        fis.close();
+
+        // need to give the server a bit of time to receive our last packet, and
+        // close out its file buffers, etc.
+        Thread.sleep(100);
+        assertTrue("file not created", in.exists());
+        assertTrue("files not identical on file " + file, filesIdentical(file, in));
+
+        in.delete();
+    }
+
+    private boolean filesIdentical(File a, File b) throws IOException
+    {
+        if (!a.exists() || !b.exists())
+        {
+            return false;
+        }
+
+        if (a.length() != b.length())
+        {
+            return false;
+        }
+
+        InputStream fisA = new BufferedInputStream(new FileInputStream(a));
+        InputStream fisB = new BufferedInputStream(new FileInputStream(b));
+
+        int aBit = fisA.read();
+        int bBit = fisB.read();
+
+        while (aBit != -1)
+        {
+            if (aBit != bBit)
+            {
+                fisA.close();
+                fisB.close();
+                return false;
+            }
+            aBit = fisA.read();
+            bBit = fisB.read();
+        }
+
+        fisA.close();
+        fisB.close();
+        return true;
+    }
+}
diff --git a/src/test/org/apache/commons/net/time/TimeTCPClientTest.java b/src/test/java/org/apache/commons/net/time/TimeTCPClientTest.java
similarity index 97%
rename from src/test/org/apache/commons/net/time/TimeTCPClientTest.java
rename to src/test/java/org/apache/commons/net/time/TimeTCPClientTest.java
index 6dce92a..c5fdea2 100644
--- a/src/test/org/apache/commons/net/time/TimeTCPClientTest.java
+++ b/src/test/java/org/apache/commons/net/time/TimeTCPClientTest.java
@@ -6,7 +6,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -22,7 +22,6 @@
 import java.util.TimeZone;
 
 import junit.framework.TestCase;
-import org.apache.commons.net.TimeTCPClient;
 
 public class TimeTCPClientTest extends TestCase
 {
diff --git a/src/test/org/apache/commons/net/time/TimeTestSimpleServer.java b/src/test/java/org/apache/commons/net/time/TimeTestSimpleServer.java
similarity index 98%
rename from src/test/org/apache/commons/net/time/TimeTestSimpleServer.java
rename to src/test/java/org/apache/commons/net/time/TimeTestSimpleServer.java
index 1a0f5ec..ef81ce7 100644
--- a/src/test/org/apache/commons/net/time/TimeTestSimpleServer.java
+++ b/src/test/java/org/apache/commons/net/time/TimeTestSimpleServer.java
@@ -1,3 +1,5 @@
+package org.apache.commons.net.time;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -6,7 +8,7 @@
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +16,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.commons.net.time;
 
 import java.io.DataOutputStream;
 import java.io.IOException;
diff --git a/src/test/org/apache/commons/net/ftp/parser/MVSFTPEntryParserTest.java b/src/test/org/apache/commons/net/ftp/parser/MVSFTPEntryParserTest.java
deleted file mode 100644
index 5e35b06..0000000
--- a/src/test/org/apache/commons/net/ftp/parser/MVSFTPEntryParserTest.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.commons.net.ftp.parser;
-
-import junit.framework.TestSuite;
-
-import org.apache.commons.net.ftp.FTPFile;
-import org.apache.commons.net.ftp.FTPFileEntryParser;
-
-/**
- * Created on Apr 6, 2005<br/>
- * @author <a href="mailto:wnoto@openfinance.com">William Noto</a>
- * @version $Id$
- */
-public class MVSFTPEntryParserTest extends FTPParseTestFramework 
-{
-    private static final String [] goodsamples  = 
-    {
-        "Migrated                                                file1.I",
-        "Migrated                                                file2.I",
-        "PSMLC1 3390   2005/04/04  1    1  VB   27994 27998  PS  file3.I",
-        "PSMLB9 3390   2005/04/04  1    1  VB   27994 27998  PS  file4.I.BU",
-        "PSMLB6 3390   2005/04/05  1    1  VB   27994 27998  PS  file3.I.BU",
-        "PSMLC6 3390   2005/04/05  1    1  VB   27994 27998  PS  file6.I",
-        "Migrated                                                file6.O",
-        "PSMLB7 3390   2005/04/04  1    1  VB   27994 27998  PS  file7.O",
-        "PSMLC6 3390   2005/04/05  1    1  VB   27994 27998  PS  file7.O.BU",
-        "FPFS42 3390   2004/06/23  1    1  FB     128  6144  PS  INCOMING.RPTBM023.D061704",
-        "FPFS41 3390   2004/06/23  1    1  FB     128  6144  PS  INCOMING.RPTBM056.D061704",
-        "FPFS25 3390   2004/06/23  1    1  FB     128  6144  PS  INCOMING.WTM204.D061704",                
-    };
-    
-    private static final String [] badsamples = 
-    {
-        "MigratedP201.$FTXPBI1.$CF2ITB.$AAB0402.I",
-        "PSMLC133902005/04/041VB2799427998PSfile1.I",
-        "file2.O",
-    };
-    
-    /**
-     * @see junit.framework.TestCase#TestCase(String)
-     */
-    public MVSFTPEntryParserTest (String name) 
-    {
-        super(name);
-    }
-    
-    /* (non-Javadoc)
-     * @see org.apache.commons.net.ftp.parser.CompositeFTPParseTestFramework#getBadListings()
-     */
-    protected String[] getBadListing() {
-        return badsamples;
-    }
-    /* (non-Javadoc)
-     * @see org.apache.commons.net.ftp.parser.CompositeFTPParseTestFramework#getGoodListings()
-     */
-    protected String[] getGoodListing() {
-        return goodsamples;
-    }
-
-    
-    /**
-     * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getParser()
-     */
-    protected FTPFileEntryParser getParser()
-    {
-        return new CompositeFileEntryParser(new FTPFileEntryParser[]
-        {
-            new MVSFTPEntryParser(),
-        });
-    }
-    
-    /**
-     * Method suite.
-     * 
-     * @return TestSuite
-     */
-    public static TestSuite suite()
-    {
-        return(new TestSuite(MVSFTPEntryParserTest.class));
-    }
-    
-    public void testParseFieldsOnDirectory() throws Exception
-    {
-        // I don't really know how to test this because the MVS system that I 
-        // connect with does not allow me to create directories.         
-    }
-    
-    /* (non-Javadoc)
-     * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#testParseFieldsOnFile()
-     */
-    public void testParseFieldsOnFile() throws Exception {
-        FTPFile file = getParser().parseFTPEntry("Migrated                                                file1.I");
-        assertNotNull("Could not parse entry.", file);
-        assertTrue("Should have been a file.", file.isFile());
-        assertEquals("file1.I", file.getName());
-        
-        FTPFile file2 = getParser().parseFTPEntry("PSMLC1 3390   2005/04/04  1    1  VB   27994 27998  PS  file2.I");
-        assertNotNull("Could not parse entry.", file2);
-        assertTrue("Should have been a file.", file2.isFile());
-        assertEquals("file2.I", file2.getName());
-    }    
-}
diff --git a/xdocs/changes.xml b/xdocs/changes.xml
deleted file mode 100644
index 4f36361..0000000
--- a/xdocs/changes.xml
+++ /dev/null
@@ -1,387 +0,0 @@
-<?xml version="1.0"?>
-<!--
-Licensed to the Apache Software Foundation (ASF) under one or more
-contributor license agreements.  See the NOTICE file distributed with
-this work for additional information regarding copyright ownership.
-The ASF licenses this file to You under the Apache License, Version 2.0
-(the "License"); you may not use this file except in compliance with
-the License.  You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-<document>
-	<properties>
-		<title>Changes</title>
-		<author email="rwinston@apache.org">Rory Winston</author>
-	</properties>
-	
-	<body>
-
-		<release version="1.5.0" date="" description="">
-			<action dev="dfs" type="fix" issue="NET-3">
-				TelnetInputStream.java: Applied Rob Hasselbaum's
-				&lt;rhasselbaum -> alumni.ithaca.edu&gt;
-				patch for PR 38688 fixing a TelnetInputStream hang.
-			</action>
-			<action dev="rwinston" type="fix" issue="NET-73">
-				TelnetInputStream.java: Fixing another potential deadlock for 
-                        telnet and FTP (patch courtesy Rob Hasselbaum).
-			</action>
-			<action dev="dfs" type="update" issue="NET-57">
-				FTP.java: Exposed control connection of FTP
-				class via _controlInput_ and _controlOutput_
-				protected member variables in response
-				to PR 38309 reported by &lt;josejuan.montiel@gmail.com&gt;.
-			</action>
-			<action dev="rwinston" type="fix" issue="NET-68">
-				TFTPClient.java: Fix bug causing final packets to not be sent.
-			</action>
-			<action dev="rwinston" type="fix" issue="NET-161">
-				TFTPClient.java: Fix sendFile() (related to NET-68).
-			</action>
-			<action dev="rwinston" type="fix" issue="NET-181">
-				TFTPClient.java: block number wraparound.
-			</action>
-			<action dev="scohen" type="fix" issue="NET-16">
-				UNIXFTPEntryParser.java: support for group names with spaces (patch courtesy D. Kilzer).
-			</action>
-			<action dev="scohen" type="fix" issue="NET-62">
-				DefaultFTPFileEntryParserFactory.java: 
-				Wrap NoClassDefFoundError in FTP parser exception when ORO is not available.
-			</action>
-			<action dev="rwinston" type="add" issue="NET-33">
-				FTPClient.java: Fix closing FTP ServerSocket after timeout
-			</action>
-			<action dev="rwinston" type="add">
-				FTPClientConfig.java: Added an FTP parser for Netware FTP servers.
-                        Tested on Novell Netware 6.5.
-			</action>
-			<action dev="rwinston" type="fix" issue="NET-188">
-				FTPTimestampParserImpl.java: Fix leap year date parsing bug.
-			</action>
-			<action dev="rwinston" type="fix">
-				Article.java: Fix minor issues with NNTP parsing.
-			</action>
-			<action dev="sebb" type="fix" issue="NET-195">
-				NtpV3Impl.java: Avoid double-checked locking
-			</action>
-			<action dev="sebb" type="fix" issue="NET-197">
-				FTPFileEntryParserImpl.java: Fix Javadoc for preParse()
-			</action>
-			<action dev="rwinston" type="fix" issue="NET-201">
-				UnixFTPEntryParser.java: Support Solaris special devices
-			</action>
-			<action dev="sebb" type="fix" issue="NET-205">
-				*FTPEntryParser.java: Keep files with unparseable dates in list
-			</action>
-			<action dev="sebb" type="fix" issue="NET-206">
-				DefaultFTPFileEntryParserFactory.java, TFTPRequestPacket.java: Fix String conversions in non-English Locales
-			</action>
-			<action dev="sebb" type="fix" issue="NET-211">
-				FTPTimestampParserImpl.java: Fix lenient future dates at year boundary
-			</action>
-            <action dev="sebb" type="fix" issue="NET-194">
-                Replace Exception with IOException
-            </action>
-            <action dev="rwinston" type="update" issue="NET-214">
-                VMS file permission parsing
-            </action>
-            <action dev="sebb" type="fix" issue="NET-208">
-                TelnetInputStream swallows interruptedexception as IOException
-            </action>
-            <action dev="sebb" type="fix" issue="NET-223">
-                the data connection socket is not closed when an IOException occurred
-            </action>
-            <action dev="sebb" type="fix" issue="NET-231">
-                ParserInitializationException when connecting to a Unix FTP server: comparison string must be upper case
-                Added check for AS/400 response.
-            </action>
-            <action dev="sebb" type="fix" issue="NET-225">
-                FTPFileEntryParserImpl.preParse() doesn't remove unparsable entries at the end of the file list
-            </action>
-		</release> 
-		
-		<release version="1.4.1" date="December 3, 2005" description="fix release to restore jdk 1.3 compatability">
-			<action dev="scohen" type="fix">
-				Applied patches for defect 37113. Code incompatible with jdk 1.3. Original patch submitted by &lt;Andrea Rombald&gt;
-			</action>
-			<action dev="scohen" type="fix">
-				Applied patches for defect 37522. updated project.xml to correct compatibility level.
-			</action>
-		</release>
-		
-		<release version="1.4.0" date="May 7, 2005" description="Some additions and enhancements">
-			<action dev="dfs" type="fix">
-				Fixed typo in method name.
-				FTP.removeCommandListener() was missing
-				the L.  Problem reported by
-				&lt;Per.Lindberger@linkon.se&gt;.
-			</action>
-			<action dev="rwinston" type="fix">
-				Applied fix for PR 33942 and PR 31793. Original patch submitted by &lt;mario@ops.co.at&gt;
-			</action>
-			<action dev="rwinston" type="fix">
-				TFTPClient was ignoring final ACK (PR 32859). Thanks to &lt;perttu.auramo@ekahau.com&gt;
-			</action>
-			<action dev="rwinston" type="fix">
-				Applied fix for ACL parsing in the FTP client (PR 33972). Submitted by &lt;robertalasch@yahoo.com&gt;
-			</action>
-			<action dev="rwinston" type="fix">
-				Added missing NTP/SNTP unit tests to the codebase.
-			</action>
-			<action dev="dfs" type="fix">
-				Applied fix for POP3Client returning empty reply strings (PR 34133). Thanks to &lt;sammy_c@lineone.net&gt;
-			</action>
-			<action dev="rwinston" type="fix">
-				NTP port parameter was being ignored (PR 34219). Fixed by &lt;felix.eichhorn@3soft.de&gt;
-			</action>
-			<action dev="scohen" type="add">
-				An FTP parser for MVS was added. Submitted by &lt;wnoto@openfinance.com&gt;
-			</action>
-			<action dev="scohen" type="add">
-				Added functionality for extensible parsing of FTP responses, using a configurable format string. This should enable the FTP client to operate across many different locales and date formats.
-			</action>
-		</release>
-		
-		<release version="1.3.0" date="December 15, 2004" description="many fixes and enhancements">
-			<action dev="rwinston" type="fix">
-				Applied patch for PR 31793. Thanks to &lt;mario@ops.co.at&gt;
-			</action>
-			<action dev="rwinston" type="add">
-				Added message threading functionality to the NNTP client.
-			</action>
-			<action dev="rwinston" type="update">
-				Added return code 521 to FTPReply.java - this should obviate the need for the Ant FTP task to manually declare it.
-			</action>
-			<action dev="rwinston" type="fix">
-				Add explicit notify() in TelnetInputStream::read(), so available() returns an accurate value. Thanks to &lt;tpalkot@gmail.com&gt;.
-			</action>
-			<action dev="rwinston" type="add">
-				Added SNTP/NTP components into the Commons-Net codebase, courtesy of
-				Jason Matthews.
-			</action>
-			<action dev="rwinston" type="add">
-				Added POP3 test suite, courtesy of Mike George &lt;mike.george@comcast.net&gt;.
-			</action>
-			<action dev="scohen" type="fix">
-				Applied fix for FTPClient returning null for certain timestamp formats (BUG #30737)
-			</action>
-			<action dev="rwinston" type="fix">
-				Build.xml fixes - dont include example classes in redistributable
-				.jar, remove test dependency from javadoc target, and exclude private members from generated javadoc.
-			</action>
-			<action dev="rwinston" type="fix">
-				Fixed bug in TFTPClient::setMaxTimeout(), spotted by &lt;steve@widge.net&gt;
-			</action>
-			<action dev="dfs" type="fix">
-				Some changes to facilitate compilation under JDK 5.0
-			</action>
-			<action dev="rwinston" type="fix">
-				Return correct NNTP article count when high and low watermarks are 0.
-				Spotted by &lt;jmordax@terra.es&gt;
-			</action>
-			<action dev="rwinston" type="fix">
-				Remove trailing null byte in TFTP packets. Thanks to &lt;gerard.dens@alcatel.be&gt;
-			</action>
-			<action dev="dfs" type="fix">
-				Many javadoc fixes.
-			</action>
-			<action dev="rwinston" type="update">
-				Allow FTPClient to set transfer buffer size.
-			</action>
-			<action dev="rwinston" type="update">
-				Ensure consistent handling of encoding throughout FTPClient
-				operations. Patch submitted by &lt;leif@tanukisoftware.com&gt;.
-			</action>
-			<action dev="dfs" type="fix">
-				Fix TelnetClient zombie thread issue
-			</action>	
-
-
-		</release>
-		<release version="1.3.0-dev" date="July 28, 2004"
-			description="regression fix">
-			<action dev="dfs" type="fix">
-				Fixed regression from migration to new parsers.  Most of the
-				new parsers parsed the file size as an integer instead of a
-				long.  Changed all of them to set the size to long.  This
-				problem was detected by the reporter of:
-				http://issues.apache.org/bugzilla/show_bug.cgi?id=30345
-			</action>
-		</release>
-		<release version="1.2.2" date="June 25, 2004" description="fix release">
-			<action dev="scohen" type="fix">
-				fixed bug in the way FTPClient.listFiles worked when a directory was not
-				specified.  Current directory was not being 'remembered'.  This was most 
-				problematic in the dependent ftp task of Ant.
-			</action>
-			<action dev="scohen" type="fix">
-				fixed handling of certain unusual "special" file types in the Unix parser.
-			</action>
-		</release>	
-
-		<release version="1.2.1" date="May 6, 2004" description="fix release">
-			<action dev="scohen" type="fix">
-				changed code that rendered package uncompilable under JDK 1.2
-			</action>
-		</release>	
-
-		<release version="1.2.0" date="April 30, 2004" description="autodetection of system for listings">
-			<action dev="scohen" type="fix">
-				Mario Ivankovits &lt;mario@ops.co.at&gt; added
-				functionality supporting correct handling of the &quot;dirstyle&quot; 
-				attribute of NT and OS400 servers that allows them to mimic Unix ftp servers.
-				and a bug fix affecting handling of sticky and suid bits on Unix FTP servers.
-			</action>
-			<action dev="scohen" type="add">
-				Mario Ivankovits &lt;mario@ops.co.at&gt; added parser for OS400.
-			</action>
-			<action dev="jbrekke,scohen" type="fix">
-				Added a functional junit test testing list parsing against real servers 
-				and fix several	bugs found through this test.
-			</action>
-			<action dev="dfs" type="add">
-				Ted Wise &lt;ctwise@bellsouth.net&gt; provided a
-				<a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=24078">
-					patch</a> to add the XHDR extended NNTP command.
-			</action>
-			<action dev="scohen,dfs" type="update">
-				Deprecated FTPFileListParser interface, DefaultFTPFileListParser
-				class, and the FTPClient.listFiles methods that accepted an
-				FTPFileListParser parameter.  These deprecated classes and methods
-				will be removed in version 2.0.
-			</action>
-			<action dev="scohen" type="add">
-				Added org.apache.commons.net.parser.FTPFileEntryParserFactory
-				interface and a default implementation:
-				DefaultFTPFileEntryParserFactory.  This addition facilitates the
-				autodetection of which FTPFileEntryParser to use to generate
-				listings.  FTPClient.listFiles methods were added that implement
-				autodetection.
-			</action>
-		</release>
-
-		<release version="1.1.1" date="TBD" description="last jdk1.1 compatible release">
-			<action dev="scohen" type="fix">
-				Removed all JDK 1.1 incompatibilities that had been introduced
-				unintentionally in previous versions.  Release 1.1.1 is the last 
-				JDK 1.1 compatible release.  Any future 1.1.x maintenance releases
-				will remain JDK !.1 compatible, but version 1.2 may break
-				compatibility and will be guaranteed to work with only J2SE 1.2
-				and later.
-			</action>
-		</release>
-
-		<release version="1.1.0" date="October 23, 2003" description="many enhancements and bug fixes">
-			<action dev="dfs" type="add">
-				Rory Winston &lt;Rory.Winston@telewest.co.uk&gt; provided
-				patches to add the following extended NNTP commands to
-				NNTPClient: XOVER, AUTHINFO USER, AUTHINFO PASS, and
-				LIST ACTIVE.
-			</action>
-			<action dev="dfs" type="fix">
-				Changed connection hooks for FTP, SMTP, POP3, and NNTP classes
-				to force use of an 8-bit US-ASCII superset (ISO-8859-1) for
-				protocol communication.  This was necessary because
-				InputStreamReader and OutputStreamWriter use the default
-				client-side character set encoding.  fasselin@ca.ibm.com
-				reported failure of SMTP on OS/390 which has EBCDIC as the
-				native character set.
-			</action>
-
-			<action dev="dfs" type="fix">
-				Applied variation of fix suggested by Matthieu Recouly
-				&lt;matthieu.recouly@laposte.net&gt; so that
-				UnixFTPEntryParser may handle listings of the form
-				<pre>
-					drwxr-xr-x 1 usernameftp 512 Jan 29 23:32 prog
-				</pre>
-				where the space between user name and group is omitted.
-			</action>
-			<action dev="dfs" type="fix">
-				Applied patch from Stephane Este-Gracias
-				&lt;sestegra@free.fr&gt; that fixes the parsing of
-				VMS listings by VMSFTPEntryParser..
-			</action>
-			<action dev="brekke" type="fix">
-				If the buffer queue run full, the run() method sometimes hangs forever.
-				Changed wait() to wait(100) as with other changes in TelnetInputStream.
-				Fix submitted From: J. Matysiak ( j.matysiak@cenit.de ).
-			</action>
-			<action dev="brekke" type="fix">
-				FTP.smnt(String dir) was not passing on the dir to the SMNT command as an argument.
-			</action>
-			<action dev="brekke" type="add">
-				Added a link to the FAQ currently hosted on the Apache Wiki.
-			</action>
-			<action dev="dfs" type="update">
-				Changed package private NNTP._reader and NNTP._writer member
-				variables to protected NNTP._reader_ and NNTP._writer_
-				variables as suggested by issue report 16995 to facilitate
-				extending NNTPClient functionality in subclasses.
-			</action>
-			<action dev="dfs" type="update">
-				Changed name of FTPClient.__openDataConnection() to
-				FTPClient._openDataConnection_() to remain consistent
-				with the convention in the code that protected members
-				are of the form _foo_.  At some point __openDataConnection()
-				had been changed from private to protected.
-			</action>
-			<action dev="brekke" type="add">
-				Added terminal option support to the telnet client with tests.
-				From Bruno D'Avanzo ( b.davanzo@inwind.it ).
-			</action>
-			<action dev="scohen" type="add">
-				New parsers merged with mainline with support for old list parsers.
-			</action>
-		</release>
-
-		<release version="1.0.0" date="February 23, 2003" description="first jakarta-commons release">
-			<action dev="brekke" type="add">
-				Added a migration document for moving from NetComponents to Commons/Net.
-			</action>
-			<action dev="brekke" type="fix">
-				Moved the ftp2 tree with tests to a proposal directory and setup 
-				a build for that code.  This can grow in this area so users don't 
-				think it is production ready.
-			</action>
-			<action dev="dfs" type="fix">
-				Cleaned up license header on some source.
-			</action>
-			<action dev="dfs" type="fix">
-				Moved .io and .util to .net.io and .net.util in preparation for
-				1.0 release.
-			</action>
-			<action dev="dfs" type="fix">
-				Fixed typo in NNTP.removeProtocolCommandListener() method name.  It
-				was missing an L.  From: joev@atg.com.
-			</action>
-			<action dev="brekke" type="add">
-				Various site updates including this changes doc and publish
-				date information.
-			</action>
-			<action dev="dfs" type="fix">
-				Patch for restarting FTP file transfers.  The offset was not
-				being sent immediately before the data transfer command on
-				account.  The bug was apparently introduced in NetComponents
-				when it was decided to always send a PORT command before each data 
-				transfer to avoid socket reuse problems on Windows.  
-				From: Tapan Karecha ( tapan@india.hp.com ).
-			</action>
-			<action dev="dfs" type="fix">
-				Applied a fix for potential deadlock in TelnetInputStream by
-				changing a wait() to a wait(100).
-				From: Tapan Karecha ( tapan@india.hp.com ).
-			</action>
-			<action dev="dfs" type="update">
-				FTP examples now use passive ftp connections.
-			</action>
-		</release>
-	</body>
-</document>
diff --git a/xdocs/cvs-usage.xml b/xdocs/cvs-usage.xml
deleted file mode 100644
index c41f931..0000000
--- a/xdocs/cvs-usage.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1" ?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements.  See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License.  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<document>
- <properties>
-  <title>Source repository</title>
-  <author email="dev@commons.apache.org">Commons Documentation Team</author>
- </properties>
- <body>
-<!-- ================================================== -->
-<section name="Source repository">
-<p>
-  Apache Commons Net is hosted on the Apache
-  <a href="http://subversion.tigris.org/">subversion</a> repository.
-</p>
-<p>
-  The project URL is:<br />
-  <code>http://svn.apache.org/repos/asf/commons/proper/net/trunk</code>
-</p>
-<p>
-  The best way to view the repository is via the
-  <a href="http://svn.apache.org/viewvc/commons/proper/net/trunk/">subversion viewer</a>.
-</p>
-<p>
-  The alternative is to use the
-  <a href="http://svn.apache.org/repos/asf/commons/proper/net/trunk/">native subversion</a> display.
-</p>
-<p>
-  For more information on subversion and creating patches see the
-  <a href="http://www.apache.org/dev/contributors.html">Apache Contributors Guide</a>.
-</p>
-</section>
-<!-- ================================================== -->
-</body>
-</document>
\ No newline at end of file
diff --git a/xdocs/download.xml b/xdocs/download.xml
deleted file mode 100644
index 4383f96..0000000
--- a/xdocs/download.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0"?>
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
--->
-
-<document>
-
-  <properties>
-    <title>Apache Commons/Net Download</title>
-    <author email="brekke@apache.org">Jeffrey D. Brekke</author>
-  </properties>
-
-  <body>
-
-<section name="Release Builds">
-<p>
-You can download <a href="http://commons.apache.org/downloads/download_net.cgi">source or binary</a> production releases.
-</p>
-    
-</section>
-
-<section name="Nightly Builds">
-
-<p>
-You will find the list of nightly builds <a href="http://people.apache.org/builds/commons/nightly/commons-net/">here</a>.
-</p>
-
-</section>
-
-</body>
-</document>
diff --git a/xdocs/images/jakarta-logo-blue.gif b/xdocs/images/jakarta-logo-blue.gif
deleted file mode 100644
index de02eea..0000000
--- a/xdocs/images/jakarta-logo-blue.gif
+++ /dev/null
Binary files differ
diff --git a/xdocs/images/net-logo-white.png b/xdocs/images/net-logo-white.png
deleted file mode 100644
index a535576..0000000
--- a/xdocs/images/net-logo-white.png
+++ /dev/null
Binary files differ
diff --git a/xdocs/images/net-logo-white.xcf b/xdocs/images/net-logo-white.xcf
deleted file mode 100644
index 10977eb..0000000
--- a/xdocs/images/net-logo-white.xcf
+++ /dev/null
Binary files differ
diff --git a/xdocs/navigation.xml b/xdocs/navigation.xml
deleted file mode 100644
index 3e40c63..0000000
--- a/xdocs/navigation.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!DOCTYPE org.apache.commons.menus SYSTEM 'http://commons.apache.org/build/maven-build.dtd'>
-<!--
-   Licensed to the Apache Software Foundation (ASF) under one or more
-  contributor license agreements.  See the NOTICE file distributed with
-  this work for additional information regarding copyright ownership.
-  The ASF licenses this file to You under the Apache License, Version 2.0
-  (the "License"); you may not use this file except in compliance with
-  the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
--->
-<project name="Apache Commons/Net">
-
-  <title>Apache Commons/Net</title>
-
-  <body>
-    <links>
-      <item name="Apache"  href="http://www.apache.org"/>
-      <item name="Commons" href="http://commons.apache.org/"/>
-    </links>
-    <menu name="Documentation">
-      <item name="Migration How-to"      href="/migration.html"/>
-      <item name="FAQ"                   href="/faq.html"/>
-      <item name="Download"              href="/download.html"/>
-      <item name="Javadoc"               href="apidocs/index.html"/>
-      <item name="Release Notes"         href="/changes-report.html"/>
-    </menu>
-    <menu name="Development">
-      <item name="To-Do List" href="/tasks.html"/>
-      <item name="Coding Specifications" href="/code-standards.html"/>
-      <item name="Issue Tracking"        href="/issue-tracking.html"/>
-      <item name="Source Repository"     href="/cvs-usage.html"/>
-    </menu>
-
-    &commons;
-  </body>
-
-</project>
diff --git a/xdocs/style/project.css b/xdocs/style/project.css
deleted file mode 100644
index c1d541c..0000000
--- a/xdocs/style/project.css
+++ /dev/null
@@ -1 +0,0 @@
-@import url("http://commons.apache.org/style/commons-maven.css");