Index: /trunk/images/closechangeset.svg
===================================================================
--- /trunk/images/closechangeset.svg	(revision 2641)
+++ /trunk/images/closechangeset.svg	(revision 2641)
@@ -0,0 +1,225 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="24"
+   height="24"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   version="1.0"
+   sodipodi:docname="closechangeset.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   inkscape:export-filename="C:\data\projekte\eclipse-3.5-ws\JOSM\images\closechangeset.png"
+   inkscape:export-xdpi="90"
+   inkscape:export-ydpi="90">
+  <defs
+     id="defs4">
+    <linearGradient
+       id="linearGradient1400">
+      <stop
+         id="stop1401"
+         offset="0.0000000"
+         style="stop-color:#000000;stop-opacity:0.67843139;" />
+      <stop
+         id="stop1403"
+         offset="0.56999999"
+         style="stop-color:#000000;stop-opacity:0.32941177;" />
+      <stop
+         id="stop1402"
+         offset="1.0000000"
+         style="stop-color:#000000;stop-opacity:0.00000000;" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient1400"
+       id="linearGradient17450"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.1148815,0,0,0.111489,-49.944348,-46.709945)"
+       x1="537.42401"
+       y1="580.16663"
+       x2="539.39642"
+       y2="510.39194" />
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="6.1230318e-14 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective10" />
+    <inkscape:perspective
+       id="perspective3269"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4004"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4054"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective4104"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective2556"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       sodipodi:type="inkscape:persp3d" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="11.2"
+     inkscape:cx="6.0335269"
+     inkscape:cy="25.086803"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1103"
+     inkscape:window-height="824"
+     inkscape:window-x="150"
+     inkscape:window-y="77"
+     inkscape:snap-global="true" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Ebene 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <path
+       sodipodi:type="inkscape:offset"
+       inkscape:radius="4.5834389"
+       inkscape:original="M 547.25 494.90625 C 547.15581 494.91224 547.06196 494.92267 546.96875 494.9375 C 546.73282 494.97719 546.68628 494.99521 546.84375 494.96875 C 524.84282 498.66333 486.64226 504.70723 464.125 512.78125 C 463.15567 513.13537 462.43455 513.95957 462.21875 514.96875 C 462.15787 515.25343 462.16594 515.52974 462.1875 515.8125 C 462.05699 516.6851 462.30033 517.57519 462.90625 518.25 C 470.3466 526.58465 475.04831 536.96666 477.65625 546.5625 C 480.26419 556.15834 480.71815 565.04611 480 569.8125 C 479.30782 574.40653 476.22839 582.0513 474.59375 588.9375 C 473.77643 592.3806 473.25435 595.69511 473.90625 598.84375 C 474.55815 601.99239 477.07104 604.95638 480.71875 605.78125 C 480.7809 605.79364 480.84344 605.80407 480.90625 605.8125 C 502.83748 609.49724 508.3071 611.152 530.28125 619.03125 C 531.00412 619.2851 531.77801 619.24067 532.46875 618.9375 C 532.87181 618.81636 533.26667 618.66906 533.71875 618.53125 C 555.08828 610.94998 576.58139 605.04634 597.875 601.46875 C 597.95919 601.45151 598.0426 601.43065 598.125 601.40625 C 601.50992 600.51027 603.68441 597.45149 604.21875 594.40625 C 604.75309 591.36101 604.30268 588.11024 603.59375 584.6875 C 602.17588 577.84201 599.46382 570.20636 598.75 565.46875 C 598.03185 560.70236 598.51706 551.81459 601.125 542.21875 C 603.73294 532.62291 608.43467 522.24088 615.875 513.90625 C 616.46759 513.24343 616.73797 512.38142 616.625 511.53125 C 616.62371 511.52157 616.62638 511.50967 616.625 511.5 C 616.65564 511.14932 616.62753 510.78679 616.53125 510.4375 C 616.25916 509.45037 615.50959 508.67713 614.53125 508.375 C 592.67011 501.65325 570.38545 497.83074 547.875 494.9375 C 547.66833 494.90533 547.45885 494.89485 547.25 494.90625 z "
+       style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:6.00000191;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="path2509"
+       d="M 546.96875,490.34375 C 546.73069,490.35889 546.48536,490.3688 546.25,490.40625 C 546.23958,490.40621 546.22917,490.40621 546.21875,490.40625 C 546.18701,490.41159 546.10787,490.43747 546.09375,490.4375 C 546.08297,490.43753 546.00824,490.4694 546,490.46875 C 524.03634,494.156 485.91874,500.0939 462.5625,508.46875 C 460.12832,509.35802 458.2957,511.44805 457.75,514 C 457.64304,514.50016 457.69346,514.75022 457.6875,515.125 L 457.65625,515.125 C 457.64549,515.19696 457.66489,515.27144 457.65625,515.34375 C 457.65949,515.59267 457.61289,515.99741 457.625,516.15625 L 457.71875,516.15625 C 457.7004,517.9925 458.20677,519.87224 459.5,521.3125 C 466.31992,528.95215 470.75702,538.69215 473.21875,547.75 C 475.67414,556.78454 476.01944,565.47005 475.46875,569.125 C 474.96335,572.47938 471.88234,580.4719 470.125,587.875 C 469.25632,591.53448 468.52638,595.53153 469.40625,599.78125 C 470.41647,604.66054 474.20882,609.00402 479.71875,610.25 C 479.74989,610.26075 479.78114,610.27117 479.8125,610.28125 C 479.96915,610.31248 480.122,610.32238 480.28125,610.34375 C 502.11416,614.01197 506.78015,615.47725 528.71875,623.34375 C 528.72917,623.34379 528.73958,623.34379 528.75,623.34375 C 530.40543,623.92509 532.17716,623.80119 533.75,623.25 L 533.78125,623.3125 C 534.02995,623.23775 534.12934,623.18613 534.3125,623.125 C 534.56656,623.04021 534.89238,622.95811 535.0625,622.90625 C 535.12544,622.88677 535.18796,622.86593 535.25,622.84375 C 556.41348,615.33558 577.64691,609.52458 598.625,606 C 598.67726,605.99049 598.72935,605.98007 598.78125,605.96875 C 598.99443,605.9251 599.2296,605.87406 599.4375,605.8125 C 604.84753,604.38048 607.90888,599.80302 608.71875,595.1875 C 609.42483,591.16351 608.84138,587.35958 608.09375,583.75 C 606.57774,576.43069 603.84834,568.54503 603.28125,564.78125 C 602.73348,561.14567 603.10468,552.44974 605.5625,543.40625 C 608.02422,534.34841 612.46135,524.60837 619.28125,516.96875 C 620.51026,515.59409 621.05725,513.76559 621.0625,511.90625 L 621.1875,511.90625 C 621.20597,511.69481 621.124,511.46534 621.125,511.25 C 621.11555,511.14318 621.17044,511.04431 621.15625,510.9375 C 621.32932,512.23623 621.34875,512.19262 621.15625,510.84375 L 621.09375,510.84375 C 621.06785,510.30541 621.08958,509.77048 620.9375,509.21875 C 620.25532,506.74384 618.3293,504.75794 615.875,504 C 593.64408,497.16455 571.10612,493.3158 548.46875,490.40625 C 547.94647,490.32495 547.52805,490.31493 547,490.34375 C 546.98958,490.34371 546.97917,490.34371 546.96875,490.34375 z"
+       transform="matrix(0.1135532,0,0,0.111489,-49.335921,-46.595244)" />
+    <path
+       style="fill:#868686;fill-opacity:1;stroke:none;stroke-width:6.00000191;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 12.924605,8.4666578 C 12.913779,8.4673258 12.902997,8.4684873 12.89229,8.4701416 C 12.865186,8.4745657 12.859837,8.4765759 12.877931,8.4736259 C 12.786503,8.4888493 12.705252,8.5391968 12.652552,8.6132887 C 12.599857,8.6873791 12.580157,8.7789571 12.597907,8.8673206 C 13.063685,11.178246 12.549429,13.423784 12.411222,14.69262 C 12.368911,15.081069 12.239522,15.593805 12.127614,16.117589 C 12.015699,16.641374 11.918992,17.175433 11.97324,17.661015 C 11.987118,17.776601 12.061895,17.876879 12.170691,17.925802 L 12.170691,17.967609 C 12.208734,17.966363 12.256131,17.965642 12.314297,17.96064 L 12.314297,17.957156 C 12.326251,17.957763 12.338236,17.957763 12.350195,17.957156 C 13.408446,17.851867 14.413515,17.156796 15.706891,15.929452 C 17.00026,14.702105 18.596283,12.915142 20.808352,10.511782 C 20.887089,10.42697 20.915822,10.309046 20.884563,10.198996 C 20.853304,10.088942 20.766372,10.001956 20.653979,9.9682752 C 18.142536,9.2188742 15.58244,8.792705 12.996401,8.4701416 C 12.972662,8.4665551 12.948593,8.4653868 12.924605,8.4666578 z"
+       id="path2444" />
+    <path
+       style="fill:#868686;fill-opacity:1;stroke:none;stroke-width:6.00000191;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 12.89588,8.4701416 C 12.889866,8.4711476 12.883882,8.4723092 12.877931,8.4736259 C 10.350431,8.8855312 5.9618883,9.5593602 3.3750696,10.459523 C 3.2637103,10.499003 3.1810754,10.591254 3.1562839,10.703766 C 3.131498,10.816276 3.1680252,10.933259 3.2530097,11.013483 C 5.6953752,13.323085 7.3848559,15.082627 8.745786,16.260433 C 10.106717,17.438241 11.183197,18.073268 12.350195,17.957156 C 12.441799,17.948375 12.525979,17.904399 12.583977,17.835025 C 12.641968,17.765654 12.66896,17.676651 12.65894,17.587849 C 12.621333,17.251276 12.694381,16.759684 12.802537,16.253466 C 12.9107,15.74725 13.046291,15.227179 13.096921,14.7623 C 13.224499,13.591049 13.776479,11.21938 13.276427,8.7384122 C 13.241924,8.5658384 13.075658,8.448632 12.89588,8.4701416 z"
+       id="path2453" />
+    <path
+       style="fill:url(#linearGradient17450);fill-opacity:1;stroke:none;stroke-width:6.00000191;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 12.924605,8.4666578 C 12.914969,8.4672523 12.905428,8.4687664 12.89588,8.4701416 C 12.894703,8.4703113 12.893467,8.4699603 12.89229,8.4701416 C 12.865186,8.4745657 12.859837,8.4765759 12.877931,8.4736259 C 10.350431,8.8855312 5.9618883,9.5593602 3.3750696,10.459523 C 3.2637103,10.499003 3.1808704,10.590893 3.1560777,10.703404 C 3.1312858,10.815918 3.1680252,10.933259 3.2530097,11.013483 C 5.6953752,13.323085 7.3848559,15.082627 8.745786,16.260433 C 10.037021,17.377925 11.07132,18.005298 12.170691,17.967609 C 12.187819,17.96705 12.214268,17.964912 12.235314,17.964124 C 12.261459,17.962615 12.288066,17.962907 12.314297,17.96064 C 12.326256,17.959609 12.33821,17.95835 12.350195,17.957156 C 13.408446,17.851867 14.413515,17.156796 15.706891,15.929452 C 17.00026,14.702105 18.596283,12.915142 20.808352,10.511782 C 20.887089,10.42697 20.915001,10.308271 20.883741,10.198221 C 20.852484,10.088165 20.766372,10.001956 20.653979,9.9682752 C 18.142536,9.2188742 15.58244,8.792705 12.996401,8.4701416 C 12.985745,8.4685309 12.974844,8.4707738 12.964093,8.4701416 C 12.950893,8.4693629 12.937823,8.4659578 12.924605,8.4666578 z"
+       id="path2521" />
+    <image
+       y="0.1322051"
+       x="2.9311147"
+       id="image3271"
+       height="10.642858"
+       width="10.464286"
+       sodipodi:absref="C:\data\projekte\eclipse-3.5-ws\JOSM\images\data\node.png"
+       xlink:href="data\node.png" />
+    <image
+       y="5.1982875"
+       x="9.66008"
+       id="image4176"
+       height="12.25"
+       width="11.982143"
+       sodipodi:absref="C:\data\projekte\eclipse-3.5-ws\JOSM\images\data\node.png"
+       xlink:href="data\node.png" />
+    <image
+       y="5.3641677"
+       x="2.6339738"
+       id="image4172"
+       height="12.25"
+       width="11.982143"
+       sodipodi:absref="C:\data\projekte\eclipse-3.5-ws\JOSM\images\data\node.png"
+       xlink:href="data\node.png" />
+    <path
+       style="fill:#a5a5a5;fill-opacity:1;stroke:none;stroke-width:6.00000191;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 3.4720008,10.511782 C 3.3397013,10.519066 3.2234186,10.599308 3.1728865,10.718192 C 3.1223611,10.837074 3.1465234,10.973543 3.2350604,11.069226 C 4.0898189,11.998449 4.6299567,13.155928 4.929564,14.22576 C 5.2291652,15.295591 5.2813174,16.28648 5.1988132,16.81788 C 5.1192951,17.330065 4.7655289,18.18237 4.577736,18.950107 C 4.483846,19.333974 4.4238601,19.703506 4.4987542,20.054543 C 4.5736483,20.405583 4.8623293,20.736036 5.2813861,20.827999 C 5.2885284,20.82938 5.2957144,20.830542 5.3029246,20.831482 C 7.8224215,21.242291 8.4507791,21.426777 10.975205,22.305229 C 11.075864,22.339532 11.187223,22.326668 11.276769,22.270388 C 12.904219,21.248857 13.986669,20.640894 14.716034,20.099835 C 15.445405,19.558779 15.843565,19.021368 15.922294,18.298593 C 15.971357,17.848175 15.760389,17.402269 15.455586,16.904981 C 15.150784,16.407691 14.727881,15.86447 14.252921,15.30581 C 13.302995,14.188491 12.144834,13.010651 11.352162,12.117921 C 11.294712,12.052911 11.213767,12.011761 11.125989,12.002947 C 8.4177034,11.74705 6.0994113,11.399503 3.6084268,10.532686 C 3.5648694,10.516858 3.5184637,10.509748 3.4720008,10.511782 z"
+       id="path2442" />
+    <path
+       style="fill:#a5a5a5;fill-opacity:1;stroke:none;stroke-width:6.00000191;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 20.549866,10.027502 C 20.502912,10.027678 20.45649,10.037164 20.413446,10.055376 C 18.059083,11.053067 13.700468,11.846209 11.061368,11.999464 C 10.90453,12.009545 10.77458,12.121322 10.745444,12.271218 C 10.243386,14.754362 10.7937,17.126645 10.921358,18.298593 C 10.996794,18.991157 11.209678,19.832623 11.341392,20.507468 C 11.429257,20.957667 11.611714,22.312547 10.975205,22.305229 C 11.130072,22.345111 11.231615,22.290452 11.370111,22.249484 C 13.825078,21.404256 16.294237,20.746064 18.740483,20.347201 C 18.750156,20.345279 18.759737,20.342954 18.769205,20.340235 C 19.158069,20.240343 19.407877,19.899322 19.469263,19.559812 C 19.530648,19.220301 19.478906,18.857876 19.397461,18.476278 C 19.234574,17.713081 18.923009,16.861791 18.841003,16.333599 C 18.758502,15.802198 18.814244,14.81131 19.113848,13.741478 C 19.413453,12.67165 19.953595,11.514168 20.808352,10.584948 C 20.899121,10.486418 20.921679,10.346618 20.865792,10.22609 C 20.809907,10.105569 20.686056,10.026918 20.549866,10.027502 z"
+       id="path2440"
+       sodipodi:nodetypes="csccsscccsssssssc" />
+    <path
+       style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:6.00000191;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 10.537223,12.022665 C 10.447196,14.256974 10.661346,16.197299 10.70595,17.326981 C 10.743661,18.281725 10.912576,19.442522 11.007513,20.372838 C 11.053826,20.826622 11.12298,21.948094 10.908157,22.514315 L 11.370111,22.466273 C 11.231615,22.521717 11.130072,22.595683 10.975205,22.541713 C 11.611714,22.551617 11.429257,20.718054 11.341392,20.108799 C 11.209678,19.195529 10.996794,18.05677 10.921358,17.119522 C 10.833595,16.029147 10.545219,14.169517 10.537223,12.022665 z"
+       id="path2495"
+       sodipodi:nodetypes="csssccssc" />
+    <image
+       y="1.4718096"
+       x="9.2844448"
+       id="image4178"
+       height="10.642858"
+       width="10.464286"
+       sodipodi:absref="C:\data\projekte\eclipse-3.5-ws\JOSM\images\data\node.png"
+       xlink:href="data\node.png" />
+    <rect
+       style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.87631428;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect3338"
+       width="9.4060545"
+       height="6.6698389"
+       x="8.1271439"
+       y="15.640499" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#141414;stroke-width:0.87631428;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 8.999263,14.173084 C 9.3611495,8.0531779 16.498669,8.7512039 16.195519,14.229232"
+       id="path3259"
+       sodipodi:nodetypes="cc" />
+    <rect
+       style="opacity:1;fill:#f7f678;fill-opacity:1;fill-rule:evenodd;stroke:#f1a638;stroke-width:0.87631428;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="rect2562"
+       width="9.4060545"
+       height="6.6698389"
+       x="6.9738712"
+       y="14.817385" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#f1a638;stroke-width:0.87631428;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 9.155356,17.3719 L 14.467152,17.3719 L 14.467152,17.3719"
+       id="path3334" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#f1a638;stroke-width:0.87631428;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 9.2075087,19.118763 L 14.454684,19.118763 L 14.454684,19.118763"
+       id="path3336" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#555555;stroke-width:0.87631428;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 8.305253,14.034544 C 8.6671395,7.9146379 15.804659,8.6126639 15.501509,14.090691"
+       id="path3348"
+       sodipodi:nodetypes="cc" />
+  </g>
+</svg>
Index: /trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java	(revision 2640)
+++ /trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java	(revision 2641)
@@ -22,4 +22,5 @@
 import org.openstreetmap.josm.io.OsmServerLocationReader;
 import org.openstreetmap.josm.io.OsmServerReader;
+import org.openstreetmap.josm.io.OsmTransferCancelledException;
 import org.openstreetmap.josm.io.OsmTransferException;
 import org.xml.sax.SAXException;
@@ -94,5 +95,8 @@
                     return;
                 }
-                if (e instanceof OsmTransferException) {
+                if (e instanceof OsmTransferCancelledException) {
+                    setCanceled(true);
+                    return;
+                } else if (e instanceof OsmTransferException) {
                     rememberException(e);
                 } else {
Index: /trunk/src/org/openstreetmap/josm/actions/upload/ApiPreconditionCheckerHook.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/upload/ApiPreconditionCheckerHook.java	(revision 2640)
+++ /trunk/src/org/openstreetmap/josm/actions/upload/ApiPreconditionCheckerHook.java	(revision 2641)
@@ -17,4 +17,5 @@
 import org.openstreetmap.josm.io.OsmApi;
 import org.openstreetmap.josm.io.OsmApiInitializationException;
+import org.openstreetmap.josm.io.OsmTransferCancelledException;
 
 public class ApiPreconditionCheckerHook implements UploadHook {
@@ -38,4 +39,6 @@
                     return false;
             }
+        } catch(OsmTransferCancelledException e){
+            return false;
         } catch (OsmApiInitializationException e) {
             ExceptionDialogUtil.explainOsmTransferException(e);
Index: /trunk/src/org/openstreetmap/josm/data/Preferences.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/Preferences.java	(revision 2640)
+++ /trunk/src/org/openstreetmap/josm/data/Preferences.java	(revision 2641)
@@ -26,4 +26,5 @@
 import java.util.Map.Entry;
 import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.logging.Logger;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -32,5 +33,4 @@
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.gui.preferences.ProxyPreferences;
 import org.openstreetmap.josm.tools.ColorHelper;
 
@@ -44,4 +44,5 @@
  */
 public class Preferences {
+    static private final Logger logger = Logger.getLogger(Preferences.class.getName());
 
     /**
@@ -731,14 +732,4 @@
     public void updateSystemProperties() {
         Properties sysProp = System.getProperties();
-        if (getBoolean(ProxyPreferences.PROXY_ENABLE)) {
-            sysProp.put("proxySet", "true");
-            sysProp.put("http.proxyHost", get(ProxyPreferences.PROXY_HOST));
-            sysProp.put("proxyPort", get(ProxyPreferences.PROXY_PORT));
-            if (!getBoolean(ProxyPreferences.PROXY_ANONYMOUS)) {
-                sysProp.put("proxyUser", get(ProxyPreferences.PROXY_USER));
-                sysProp.put("proxyPassword", get(ProxyPreferences.PROXY_PASS));
-            }
-
-        }
         sysProp.put("http.agent", Version.getInstance().getAgentString());
         System.setProperties(sysProp);
Index: /trunk/src/org/openstreetmap/josm/data/ServerSidePreferences.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/ServerSidePreferences.java	(revision 2640)
+++ /trunk/src/org/openstreetmap/josm/data/ServerSidePreferences.java	(revision 2641)
@@ -25,6 +25,6 @@
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.Preferences.Bookmark;
 import org.openstreetmap.josm.io.OsmConnection;
+import org.openstreetmap.josm.io.OsmTransferException;
 import org.openstreetmap.josm.io.XmlWriter;
 import org.openstreetmap.josm.tools.Base64;
@@ -66,4 +66,6 @@
                 return b.toString();
             } catch (IOException e) {
+                e.printStackTrace();
+            } catch(OsmTransferException e) {
                 e.printStackTrace();
             }
Index: /trunk/src/org/openstreetmap/josm/gui/MainApplication.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/MainApplication.java	(revision 2640)
+++ /trunk/src/org/openstreetmap/josm/gui/MainApplication.java	(revision 2641)
@@ -9,4 +9,6 @@
 import java.awt.event.WindowAdapter;
 import java.awt.event.WindowEvent;
+import java.net.Authenticator;
+import java.net.ProxySelector;
 import java.util.Arrays;
 import java.util.Collection;
@@ -19,4 +21,7 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.io.DefaultProxySelector;
+import org.openstreetmap.josm.io.auth.CredentialsManagerFactory;
+import org.openstreetmap.josm.io.auth.DefaultAuthenticator;
 import org.openstreetmap.josm.plugins.PluginHandler;
 import org.openstreetmap.josm.tools.BugReportExceptionHandler;
@@ -97,4 +102,11 @@
         }
         Main.pref.updateSystemProperties();
+
+        Authenticator.setDefault(
+                new DefaultAuthenticator(
+                        CredentialsManagerFactory.getCredentialManager()
+                )
+        );
+        ProxySelector.setDefault(new DefaultProxySelector(ProxySelector.getDefault()));
 
         if (argList.contains("--help") || argList.contains("-?") || argList.contains("-h")) {
Index: /trunk/src/org/openstreetmap/josm/gui/io/CredentialDialog.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/io/CredentialDialog.java	(revision 2641)
+++ /trunk/src/org/openstreetmap/josm/gui/io/CredentialDialog.java	(revision 2641)
@@ -0,0 +1,321 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.io;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
+import javax.swing.AbstractAction;
+import javax.swing.BorderFactory;
+import javax.swing.JCheckBox;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JPasswordField;
+import javax.swing.JTextField;
+import javax.swing.KeyStroke;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.JMultilineLabel;
+import org.openstreetmap.josm.gui.SideButton;
+import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction;
+import org.openstreetmap.josm.gui.help.HelpUtil;
+import org.openstreetmap.josm.io.OsmApi;
+import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.WindowGeometry;
+
+public class CredentialDialog extends JDialog {
+
+    static public CredentialDialog getOsmApiCredentialDialog(String username, String password) {
+        CredentialDialog dialog = new CredentialDialog();
+        dialog.prepareForOsmApiCredentials(username, password);
+        dialog.pack();
+        return dialog;
+    }
+
+    static public CredentialDialog getHttpProxyCredentialDialog(String username, String password) {
+        CredentialDialog dialog = new CredentialDialog();
+        dialog.prepareForProxyCredentials(username, password);
+        dialog.pack();
+        return dialog;
+    }
+
+    private boolean canceled;
+    private CredentialPanel pnlCredentials;
+
+    public boolean isCanceled() {
+        return canceled;
+    }
+
+    protected void setCanceled(boolean canceled) {
+        this.canceled = canceled;
+    }
+
+    @Override
+    public void setVisible(boolean visible) {
+        if (visible) {
+            WindowGeometry.centerInWindow(Main.parent, new Dimension(350,300)).apply(this);
+        }
+        super.setVisible(visible);
+    }
+
+    protected JPanel createButtonPanel() {
+        JPanel pnl = new JPanel(new FlowLayout());
+        pnl.add(new SideButton(new OKAction()));
+        pnl.add(new SideButton(new CancelAction()));
+        pnl.add(new SideButton(new ContextSensitiveHelpAction(HelpUtil.ht("/Dialog/PasswordDialog"))));
+        return pnl;
+    }
+
+    protected void build() {
+        getContentPane().setLayout(new BorderLayout());
+        getContentPane().add(createButtonPanel(), BorderLayout.SOUTH);
+
+        addWindowListener(new WindowEventHander());
+        getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "escape");
+        getRootPane().getActionMap().put("escape", new CancelAction());
+
+        getRootPane().setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+    }
+
+    public CredentialDialog() {
+        setModal(true);
+        try {
+            setAlwaysOnTop(true);
+        } catch(SecurityException e) {
+            System.out.println(tr("Warning: failed to put Credential Dialog always on top. Caught security exception."));
+        }
+        build();
+    }
+
+    public void prepareForOsmApiCredentials(String username, String password) {
+        setTitle(tr("Enter credentials for OSM API"));
+        getContentPane().add(pnlCredentials = new OsmApiCredentialsPanel(), BorderLayout.CENTER);
+        pnlCredentials.init(username, password);
+        validate();
+    }
+
+    public void prepareForProxyCredentials(String username, String password) {
+        setTitle(tr("Enter credentials for HTTP proxy"));
+        getContentPane().add(pnlCredentials = new HttpProxyCredentialsPanel(), BorderLayout.CENTER);
+        pnlCredentials.init(username, password);
+        validate();
+    }
+
+    public String getUsername() {
+        if (pnlCredentials== null) return null;
+        return pnlCredentials.getUserName();
+    }
+
+    public char[] getPassword() {
+        if (pnlCredentials== null) return null;
+        return pnlCredentials.getPassword();
+    }
+
+    public boolean isSaveCredentials() {
+        if (pnlCredentials== null) return false;
+        return pnlCredentials.isSaveCredentials();
+    }
+
+    private static class CredentialPanel extends JPanel {
+        protected JTextField tfUserName;
+        protected JPasswordField tfPassword;
+        protected JCheckBox cbSaveCredentials;
+        protected JMultilineLabel lblHeading;
+        protected JMultilineLabel lblWarning;
+
+        protected void build() {
+            tfUserName = new JTextField(20);
+            tfPassword = new JPasswordField(20);
+            tfUserName.addFocusListener(new SelectAllOnFocusHandler());
+            tfPassword.addFocusListener(new SelectAllOnFocusHandler());
+            cbSaveCredentials =  new JCheckBox(tr("Save user and password (unencrypted)"));
+
+            setLayout(new GridBagLayout());
+            GridBagConstraints gc = new GridBagConstraints();
+            gc.gridwidth = 2;
+            gc.gridheight = 1;
+            gc.fill = GridBagConstraints.HORIZONTAL;
+            gc.weightx = 1.0;
+            gc.weighty = 0.0;
+            gc.insets = new Insets(0,0,10,0);
+            add(lblHeading = new JMultilineLabel(""), gc);
+
+            gc.gridx = 0;
+            gc.gridy = 1;
+            gc.gridwidth = 1;
+            gc.gridheight = 1;
+            gc.fill = GridBagConstraints.HORIZONTAL;
+            gc.weightx = 0.0;
+            gc.weighty = 0.0;
+            gc.insets = new Insets(0,0,10,10);
+            add(new JLabel(tr("Username")), gc);
+            gc.gridx = 1;
+            gc.gridy = 1;
+            gc.weightx = 1.0;
+            add(tfUserName, gc);
+            gc.gridx = 0;
+            gc.gridy = 2;
+            gc.weightx = 0.0;
+            add(new JLabel(tr("Password")), gc);
+
+            gc.gridx = 1;
+            gc.gridy = 2;
+            gc.weightx = 0.0;
+            add(tfPassword, gc);
+
+            gc.gridx = 0;
+            gc.gridy = 3;
+            gc.gridwidth = 2;
+            gc.gridheight = 1;
+            gc.fill = GridBagConstraints.BOTH;
+            gc.weightx = 1.0;
+            gc.weighty = 0.0;
+            lblWarning = new JMultilineLabel(tr(""));
+            lblWarning.setFont(lblWarning.getFont().deriveFont(Font.ITALIC));
+            add(lblWarning, gc);
+
+            gc.gridx = 0;
+            gc.gridy = 4;
+            gc.weighty = 0.0;
+            add(cbSaveCredentials, gc);
+
+            // consume the remaining space
+            gc.gridx = 0;
+            gc.gridy = 5;
+            gc.weighty = 1.0;
+            add(new JPanel(),gc);
+
+        }
+
+        public CredentialPanel() {
+        }
+
+        public void init(String username, String password) {
+            username = username == null ? "" : username;
+            password = password == null ? "" : password;
+            tfUserName.setText(username);
+            tfPassword.setText(password);
+            cbSaveCredentials.setSelected(!username.equals("") && ! password.equals(""));
+        }
+
+        public void startUserInput() {
+            tfUserName.requestFocusInWindow();
+        }
+
+        public String getUserName() {
+            return tfUserName.getText();
+        }
+
+        public char[] getPassword() {
+            return tfPassword.getPassword();
+        }
+
+        public boolean isSaveCredentials() {
+            return cbSaveCredentials.isSelected();
+        }
+    }
+
+    private static class OsmApiCredentialsPanel extends CredentialPanel {
+
+        @Override
+        protected void build() {
+            super.build();
+            tfUserName.setToolTipText(tr("Please enter the user name of your OSM account"));
+            tfPassword.setToolTipText(tr("Please enter the password name of your OSM account"));
+            lblHeading.setText(
+                    tr("<html>Authenticating at the OSM API ''{0}'' failed. Please enter a valid username and a valid password.</html>",
+                            OsmApi.getOsmApi().getBaseUrl()));
+            lblWarning.setText(tr("Warning: The password is transferred unencrypted."));
+        }
+
+        public OsmApiCredentialsPanel() {
+            build();
+        }
+    }
+
+    private static class HttpProxyCredentialsPanel extends CredentialPanel {
+        @Override
+        protected void build() {
+            super.build();
+            tfUserName.setToolTipText(tr("Please enter the user name for authenticating at your proxy server"));
+            tfPassword.setToolTipText(tr("Please enter the password for authenticating at your proxy server"));
+            lblHeading.setText(
+                    tr("<html>Authenticating at the HTTP proxy ''{0}'' failed. Please enter a valid username and a valid password.</html>",
+                            System.getProperty("http.proxyHost") + ":" + System.getProperty("http.proxyPort")));
+            lblWarning.setText(tr("<html>Warning: depending on the authentication method the proxy server uses the password may be transferred unencrypted.</html>"));
+        }
+
+        public HttpProxyCredentialsPanel() {
+            build();
+        }
+    }
+
+    static private class SelectAllOnFocusHandler extends FocusAdapter {
+        @Override
+        public void focusGained(FocusEvent e) {
+            if (e.getSource() instanceof JTextField) {
+                JTextField tf = (JTextField)e.getSource();
+                tf.selectAll();
+            }
+        }
+    }
+
+    class OKAction extends AbstractAction {
+        public OKAction() {
+            putValue(NAME, tr("Authenticate"));
+            putValue(SHORT_DESCRIPTION, tr("Authenticate with the supplied username and password"));
+            putValue(SMALL_ICON, ImageProvider.get("ok"));
+        }
+
+        public void actionPerformed(ActionEvent arg0) {
+            setCanceled(false);
+            setVisible(false);
+        }
+    }
+
+    class CancelAction extends AbstractAction {
+        public CancelAction() {
+            putValue(NAME, tr("Cancel"));
+            putValue(SHORT_DESCRIPTION, tr("Cancel authentication"));
+            putValue(SMALL_ICON, ImageProvider.get("cancel"));
+        }
+
+        public void cancel() {
+            setCanceled(true);
+            setVisible(false);
+        }
+
+        public void actionPerformed(ActionEvent arg0) {
+            cancel();
+        }
+    }
+
+    class WindowEventHander extends WindowAdapter {
+
+        @Override
+        public void windowActivated(WindowEvent e) {
+            if (pnlCredentials != null) {
+                pnlCredentials.startUserInput();
+            }
+        }
+
+        @Override
+        public void windowClosing(WindowEvent e) {
+            new CancelAction().cancel();
+        }
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/gui/io/UploadPrimitivesTask.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/io/UploadPrimitivesTask.java	(revision 2640)
+++ /trunk/src/org/openstreetmap/josm/gui/io/UploadPrimitivesTask.java	(revision 2641)
@@ -29,4 +29,5 @@
 import org.openstreetmap.josm.io.OsmApiPrimitiveGoneException;
 import org.openstreetmap.josm.io.OsmServerWriter;
+import org.openstreetmap.josm.io.OsmTransferCancelledException;
 import org.openstreetmap.josm.io.OsmTransferException;
 import org.openstreetmap.josm.tools.ImageProvider;
@@ -239,4 +240,7 @@
                     //
                     break;
+                } catch(OsmTransferCancelledException e) {
+                    uploadCancelled = true;
+                    return;
                 } catch(OsmApiPrimitiveGoneException e) {
                     // try to recover from  410 Gone
Index: /trunk/src/org/openstreetmap/josm/gui/preferences/PreferenceDialog.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/preferences/PreferenceDialog.java	(revision 2640)
+++ /trunk/src/org/openstreetmap/josm/gui/preferences/PreferenceDialog.java	(revision 2641)
@@ -44,5 +44,5 @@
     // some common tabs
     public final JPanel display = createPreferenceTab("display", tr("Display Settings"), tr("Various settings that influence the visual representation of the whole program."));
-    public final JPanel connection = createPreferenceTab("connection", I18n.tr("Connection Settings"), I18n.tr("Connection Settings for the OSM server."),true);
+    public final JPanel connection = createPreferenceTab("connection", I18n.tr("Connection Settings"), I18n.tr("Connection Settings for the OSM server."),false);
     public final JPanel map = createPreferenceTab("map", I18n.tr("Map Settings"), I18n.tr("Settings for the map projection and data interpretation."));
     public final JPanel audio = createPreferenceTab("audio", I18n.tr("Audio Settings"), I18n.tr("Settings for the audio player and audio markers."));
Index: /trunk/src/org/openstreetmap/josm/gui/preferences/ProxyPreferences.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/preferences/ProxyPreferences.java	(revision 2640)
+++ /trunk/src/org/openstreetmap/josm/gui/preferences/ProxyPreferences.java	(revision 2641)
@@ -4,11 +4,19 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-
-import javax.swing.Box;
-import javax.swing.JCheckBox;
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.net.ProxySelector;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.swing.ButtonGroup;
 import javax.swing.JLabel;
+import javax.swing.JPanel;
 import javax.swing.JPasswordField;
+import javax.swing.JRadioButton;
 import javax.swing.JSeparator;
 import javax.swing.JTextField;
@@ -16,7 +24,11 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.JMultilineLabel;
+import org.openstreetmap.josm.io.DefaultProxySelector;
 import org.openstreetmap.josm.tools.GBC;
 
 public class ProxyPreferences implements PreferenceSetting {
+
+
 
     public static class Factory implements PreferenceSettingFactory {
@@ -26,69 +38,296 @@
     }
 
-    public static final String PROXY_ENABLE = "proxy.enable";
-    public static final String PROXY_HOST = "proxy.host";
-    public static final String PROXY_PORT = "proxy.port";
-    public static final String PROXY_ANONYMOUS = "proxy.anonymous";
+    public enum ProxyPolicy {
+        NO_PROXY("no-proxy"),
+        USE_SYSTEM_SETTINGS("use-system-settings"),
+        USE_HTTP_PROXY("use-http-proxy"),
+        USE_SOCKS_PROXY("use-socks-proxy");
+
+        private String policyName;
+        ProxyPolicy(String policyName) {
+            this.policyName = policyName;
+        }
+
+        public String getName() {
+            return policyName;
+        }
+
+        static public ProxyPolicy fromName(String policyName) {
+            if (policyName == null) return null;
+            policyName = policyName.trim().toLowerCase();
+            for(ProxyPolicy pp: values()) {
+                if (pp.getName().equals(policyName))
+                    return pp;
+            }
+            return null;
+        }
+    }
+
+    public static final String PROXY_POLICY = "proxy.policy";
+    public static final String PROXY_HTTP_HOST = "proxy.http.host";
+    public static final String PROXY_HTTP_PORT = "proxy.http.port";
+    public static final String PROXY_SOCKS_HOST = "proxy.socks.host";
+    public static final String PROXY_SOCKS_PORT = "proxy.socks.port";
     public static final String PROXY_USER = "proxy.user";
     public static final String PROXY_PASS = "proxy.pass";
 
-    private JCheckBox proxyEnable = new JCheckBox(tr("Enable proxy server"));
-    private JTextField proxyHost = new JTextField(20);
-    private JTextField proxyPort = new JTextField(5);
-    private JCheckBox proxyAnonymous = new JCheckBox(tr("Anonymous"));
-    private JTextField proxyUser = new JTextField(20);
-    private JPasswordField proxyPass = new JPasswordField(20);
+    private ButtonGroup bgProxyPolicy;
+    private Map<ProxyPolicy, JRadioButton> rbProxyPolicy;
+    private JTextField tfProxyHttpHost;
+    private JTextField tfProxyHttpPort;
+    private JTextField tfProxySocksHost;
+    private JTextField tfProxySocksPort;
+    private JTextField tfProxyHttpUser;
+    private JPasswordField tfProxyHttpPassword;
+
+    protected JPanel buildHttpProxyConfigurationPanel() {
+        JPanel pnl = new JPanel(new GridBagLayout()) {
+            @Override
+            public Dimension getMinimumSize() {
+                return getPreferredSize();
+            }
+        };
+        GridBagConstraints gc = new GridBagConstraints();
+
+        gc.anchor = GridBagConstraints.WEST;
+        gc.insets = new Insets(5,5,0,0);
+        pnl.add(new JLabel("Host:"), gc);
+
+        gc.gridx = 1;
+        pnl.add(tfProxyHttpHost = new JTextField(20),gc);
+
+        gc.gridy = 1;
+        gc.gridx = 0;
+        pnl.add(new JLabel("Port:"), gc);
+
+        gc.gridx = 1;
+        gc.weightx = 0.0;
+        pnl.add(tfProxyHttpPort = new JTextField(5),gc);
+
+        gc.gridy = 2;
+        gc.gridx = 0;
+        gc.gridwidth = 2;
+        gc.fill = GridBagConstraints.BOTH;
+        gc.weightx = 1.0;
+        gc.weighty = 1.0;
+        pnl.add(new JMultilineLabel(tr("Please enter a username and a password if your proxy requires authentication.")), gc);
+
+        gc.gridy = 3;
+        gc.gridx = 0;
+        gc.gridwidth = 1;
+        gc.weightx = 0.0;
+        gc.fill = GridBagConstraints.NONE;
+        pnl.add(new JLabel("User:"), gc);
+
+        gc.gridy = 3;
+        gc.gridx = 1;
+        pnl.add(tfProxyHttpUser = new JTextField(20),gc);
+
+        gc.gridy = 4;
+        gc.gridx = 0;
+        pnl.add(new JLabel("Password:"), gc);
+
+        gc.gridx = 1;
+        pnl.add(tfProxyHttpPassword = new JPasswordField(20),gc);
+        return pnl;
+    }
+
+    protected JPanel buildSocksProxyConfigurationPanel() {
+        JPanel pnl = new JPanel(new GridBagLayout()) {
+            @Override
+            public Dimension getMinimumSize() {
+                return getPreferredSize();
+            }
+        };
+        GridBagConstraints gc = new GridBagConstraints();
+        gc.anchor = GridBagConstraints.WEST;
+        gc.insets = new Insets(5,5,0,0);
+        pnl.add(new JLabel("Host:"), gc);
+
+        gc.gridx = 1;
+        pnl.add(tfProxySocksHost = new JTextField(20),gc);
+
+        gc.gridy = 1;
+        gc.gridx = 0;
+        pnl.add(new JLabel("Port:"), gc);
+
+        gc.gridx = 1;
+        pnl.add(tfProxySocksPort = new JTextField(5),gc);
+
+        // add an extra spacer, otherwise the layout is broken
+        gc.gridy = 2;
+        gc.gridx = 0;
+        gc.gridwidth = 2;
+        gc.fill = GridBagConstraints.BOTH;
+        gc.weightx = 1.0;
+        gc.weighty = 1.0;
+        pnl.add(new JPanel(), gc);
+        return pnl;
+    }
+
+    protected JPanel buildProxySettingsPanel() {
+        JPanel pnl = new JPanel(new GridBagLayout());
+        GridBagConstraints gc = new GridBagConstraints();
+
+        bgProxyPolicy = new ButtonGroup();
+        rbProxyPolicy = new HashMap<ProxyPolicy, JRadioButton>();
+        ProxyPolicyChangeListener policyChangeListener = new ProxyPolicyChangeListener();
+        for (ProxyPolicy pp: ProxyPolicy.values()) {
+            rbProxyPolicy.put(pp, new JRadioButton());
+            bgProxyPolicy.add(rbProxyPolicy.get(pp));
+            rbProxyPolicy.get(pp).addItemListener(policyChangeListener);
+        }
+        gc.gridx = 0;
+        gc.gridy = 0;
+        gc.fill = GridBagConstraints.NONE;
+        gc.anchor = GridBagConstraints.FIRST_LINE_START;
+        pnl.add(rbProxyPolicy.get(ProxyPolicy.NO_PROXY),gc);
+        gc.gridx = 1;
+        gc.fill = GridBagConstraints.HORIZONTAL;
+        gc.weightx = 1.0;
+        pnl.add(new JLabel(tr("No proxy")), gc);
+
+        gc.gridx = 0;
+        gc.gridy = 1;
+        gc.fill = GridBagConstraints.NONE;
+        gc.anchor = GridBagConstraints.FIRST_LINE_START;
+        pnl.add(rbProxyPolicy.get(ProxyPolicy.USE_SYSTEM_SETTINGS),gc);
+        gc.gridx = 1;
+        gc.fill = GridBagConstraints.HORIZONTAL;
+        gc.weightx = 1.0;
+        gc.weighty = 0.0;
+        String msg;
+        if (DefaultProxySelector.willJvmRetrieveSystemProxies()) {
+            msg = tr("Use standard system settings");
+        } else {
+            msg = tr("Use standard system settings (disabled. Start JOSM with <tt>-Djava.net.useSystemProxies=true</tt> to enable)");
+        }
+        pnl.add(new JMultilineLabel("<html>" + msg + "</html>"), gc);
+
+        gc.gridx = 0;
+        gc.gridy = 2;
+        gc.fill = GridBagConstraints.NONE;
+        gc.anchor = GridBagConstraints.FIRST_LINE_START;
+        pnl.add(rbProxyPolicy.get(ProxyPolicy.USE_HTTP_PROXY),gc);
+        gc.gridx = 1;
+        gc.fill = GridBagConstraints.HORIZONTAL;
+        gc.weightx = 1.0;
+        pnl.add(new JLabel(tr("Manually configure a HTTP proxy")),gc);
+
+        gc.gridx = 1;
+        gc.gridy = 3;
+        gc.fill = GridBagConstraints.HORIZONTAL;
+        gc.weightx = 1.0;
+        gc.weighty = 0.0;
+        pnl.add(buildHttpProxyConfigurationPanel(),gc);
+
+        gc.gridx = 0;
+        gc.gridy = 4;
+        gc.fill = GridBagConstraints.NONE;
+        gc.anchor = GridBagConstraints.FIRST_LINE_START;
+        pnl.add(rbProxyPolicy.get(ProxyPolicy.USE_SOCKS_PROXY),gc);
+        gc.gridx = 1;
+        gc.fill = GridBagConstraints.HORIZONTAL;
+        gc.weightx = 1.0;
+        pnl.add(new JLabel(tr("Use a SOCKS proxy")),gc);
+
+        gc.gridx = 1;
+        gc.gridy = 5;
+        gc.fill = GridBagConstraints.BOTH;
+        gc.anchor = GridBagConstraints.WEST;
+        gc.weightx = 1.0;
+        gc.weighty = 0.0;
+        pnl.add(buildSocksProxyConfigurationPanel(),gc);
+
+        return pnl;
+    }
+
+    protected void initFromPreferences() {
+        String policy = Main.pref.get(PROXY_POLICY, null);
+        ProxyPolicy pp = ProxyPolicy.fromName(policy);
+        pp = pp == null? ProxyPolicy.NO_PROXY: pp;
+        rbProxyPolicy.get(pp).setSelected(true);
+        String value = Main.pref.get("proxy.host", null);
+        if (value != null) {
+            // legacy support
+            tfProxyHttpHost.setText(value);
+            Main.pref.put("proxy.host", null);
+        } else {
+            tfProxyHttpHost.setText(Main.pref.get(PROXY_HTTP_HOST, ""));
+        }
+        value = Main.pref.get("proxy.port", null);
+        if (value != null) {
+            // legacy support
+            tfProxyHttpPort.setText(value);
+            Main.pref.put("proxy.port", null);
+        } else {
+            tfProxyHttpPort.setText(Main.pref.get(PROXY_HTTP_PORT, ""));
+        }
+        tfProxySocksHost.setText(Main.pref.get(PROXY_SOCKS_HOST, ""));
+        tfProxySocksPort.setText(Main.pref.get(PROXY_SOCKS_PORT, ""));
+        tfProxyHttpUser.setText(Main.pref.get(PROXY_USER, ""));
+        tfProxyHttpPassword.setText(Main.pref.get(PROXY_PASS, ""));
+
+        if (pp.equals(ProxyPolicy.USE_SYSTEM_SETTINGS) && ! DefaultProxySelector.willJvmRetrieveSystemProxies()) {
+            System.err.println(tr("Warning: JOSM is configured to use proxies from the system setting, but the JVM is not configured to retrieve them. Resetting preferences to ''No proxy''"));
+            pp = ProxyPolicy.NO_PROXY;
+            rbProxyPolicy.get(pp).setSelected(true);
+        }
+    }
+
+    protected void updateEnabledState() {
+        tfProxyHttpHost.setEnabled(rbProxyPolicy.get(ProxyPolicy.USE_HTTP_PROXY).isSelected());
+        tfProxyHttpPort.setEnabled(rbProxyPolicy.get(ProxyPolicy.USE_HTTP_PROXY).isSelected());
+        tfProxyHttpUser.setEnabled(rbProxyPolicy.get(ProxyPolicy.USE_HTTP_PROXY).isSelected());
+        tfProxyHttpPassword.setEnabled(rbProxyPolicy.get(ProxyPolicy.USE_HTTP_PROXY).isSelected());
+        tfProxySocksHost.setEnabled(rbProxyPolicy.get(ProxyPolicy.USE_SOCKS_PROXY).isSelected());
+        tfProxySocksPort.setEnabled(rbProxyPolicy.get(ProxyPolicy.USE_SOCKS_PROXY).isSelected());
+
+        rbProxyPolicy.get(ProxyPolicy.USE_SYSTEM_SETTINGS).setEnabled(DefaultProxySelector.willJvmRetrieveSystemProxies());
+    }
+
+    class ProxyPolicyChangeListener implements ItemListener {
+        public void itemStateChanged(ItemEvent arg0) {
+            updateEnabledState();
+        }
+    }
 
     public void addGui(PreferenceDialog gui) {
-        proxyEnable.setSelected(Main.pref.getBoolean(PROXY_ENABLE));
-        proxyEnable.addActionListener(new ActionListener(){
-            public void actionPerformed(ActionEvent e) {
-                proxyHost.setEnabled(proxyEnable.isSelected());
-                proxyPort.setEnabled(proxyEnable.isSelected());
-                proxyAnonymous.setEnabled(proxyEnable.isSelected());
-                proxyUser.setEnabled(proxyEnable.isSelected() && !proxyAnonymous.isSelected());
-                proxyPass.setEnabled(proxyEnable.isSelected() && !proxyAnonymous.isSelected());
-            }
-        });
-        proxyHost.setEnabled(Main.pref.getBoolean(PROXY_ENABLE));
-        proxyHost.setText(Main.pref.get(PROXY_HOST));
-        proxyPort.setEnabled(Main.pref.getBoolean(PROXY_ENABLE));
-        proxyPort.setText(Main.pref.get(PROXY_PORT));
-        proxyAnonymous.setEnabled(Main.pref.getBoolean(PROXY_ENABLE));
-        proxyAnonymous.setSelected(Main.pref.getBoolean(PROXY_ANONYMOUS));
-        proxyAnonymous.addActionListener(new ActionListener(){
-            public void actionPerformed(ActionEvent e) {
-                proxyUser.setEnabled(proxyEnable.isSelected() && !proxyAnonymous.isSelected());
-                proxyPass.setEnabled(proxyEnable.isSelected() && !proxyAnonymous.isSelected());
-            }
-        });
-        proxyUser.setEnabled(Main.pref.getBoolean(PROXY_ENABLE) && (Main.pref.getBoolean(PROXY_ANONYMOUS)));
-        proxyUser.setText(Main.pref.get(PROXY_USER));
-        proxyPass.setEnabled(Main.pref.getBoolean(PROXY_ENABLE) && (Main.pref.getBoolean(PROXY_ANONYMOUS)));
-        proxyPass.setText(Main.pref.get(PROXY_USER));
-
         gui.connection.add(new JSeparator(SwingConstants.HORIZONTAL), GBC.eol().fill(GBC.HORIZONTAL));
         gui.connection.add(new JLabel(tr("Proxy Settings")), GBC.eol());
-        gui.connection.add(proxyEnable, GBC.eol().insets(20, 0, 0, 0));
-        gui.connection.add(new JLabel(tr("Proxy server host")), GBC.std());
-        gui.connection.add(proxyHost, GBC.eol().fill(GBC.HORIZONTAL).insets(5,0,0,5));
-        gui.connection.add(new JLabel(tr("Proxy server port")), GBC.std());
-        gui.connection.add(proxyPort, GBC.eol().fill(GBC.HORIZONTAL).insets(5,0,0,5));
-        gui.connection.add(proxyAnonymous, GBC.eop().insets(20, 0, 0, 0));
-        gui.connection.add(new JLabel(tr("Proxy server username")), GBC.std());
-        gui.connection.add(proxyUser, GBC.eol().fill(GBC.HORIZONTAL).insets(5,0,0,5));
-        gui.connection.add(new JLabel(tr("Proxy server password")), GBC.std());
-        gui.connection.add(proxyPass, GBC.eol().fill(GBC.HORIZONTAL).insets(5,0,0,5));
-
-        gui.connection.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.VERTICAL));
+        gui.connection.add(buildProxySettingsPanel(), GBC.eol().insets(20,10,0,0));
+
+        initFromPreferences();
+        updateEnabledState();
     }
 
     public boolean ok() {
-        Main.pref.put(PROXY_ENABLE, proxyEnable.isSelected());
-        Main.pref.put(PROXY_HOST, proxyHost.getText());
-        Main.pref.put(PROXY_PORT, proxyPort.getText());
-        Main.pref.put(PROXY_ANONYMOUS, proxyAnonymous.isSelected());
-        Main.pref.put(PROXY_USER, proxyUser.getText());
-        Main.pref.put(PROXY_PASS, new String(proxyPass.getPassword()));
+        ProxyPolicy policy = null;
+        for (ProxyPolicy pp: ProxyPolicy.values()) {
+            if (rbProxyPolicy.get(pp).isSelected()) {
+                policy = pp;
+                break;
+            }
+        }
+        if (policy == null) {
+            policy = ProxyPolicy.NO_PROXY;
+        }
+        Main.pref.put(PROXY_POLICY, policy.getName());
+        Main.pref.put(PROXY_HTTP_HOST, tfProxyHttpHost.getText());
+        Main.pref.put(PROXY_HTTP_PORT, tfProxyHttpPort.getText());
+        Main.pref.put(PROXY_SOCKS_HOST, tfProxySocksHost.getText());
+        Main.pref.put(PROXY_SOCKS_PORT, tfProxySocksPort.getText());
+        Main.pref.put(PROXY_USER, tfProxyHttpUser.getText());
+        Main.pref.put(PROXY_PASS, String.valueOf(tfProxyHttpPassword.getPassword()));
+
+        // remove these legacy property keys
+        Main.pref.put("proxy.anonymous", null);
+        Main.pref.put("proxy.enable", null);
+
+        // update the proxy selector
+        ProxySelector selector = ProxySelector.getDefault();
+        if (selector instanceof DefaultProxySelector) {
+            ((DefaultProxySelector)selector).initFromPreferences();
+        }
         return false;
     }
Index: /trunk/src/org/openstreetmap/josm/gui/preferences/ServerAccessPreference.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/preferences/ServerAccessPreference.java	(revision 2640)
+++ /trunk/src/org/openstreetmap/josm/gui/preferences/ServerAccessPreference.java	(revision 2641)
@@ -2,6 +2,19 @@
 package org.openstreetmap.josm.gui.preferences;
 
-import org.openstreetmap.josm.io.CredentialsManager;
-import org.openstreetmap.josm.io.OsmConnection;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.Font;
+import java.net.PasswordAuthentication;
+import java.net.Authenticator.RequestorType;
+
+import javax.swing.JLabel;
+import javax.swing.JPasswordField;
+import javax.swing.JTextField;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.io.auth.CredentialsManager;
+import org.openstreetmap.josm.io.auth.CredentialsManagerException;
+import org.openstreetmap.josm.io.auth.CredentialsManagerFactory;
+import org.openstreetmap.josm.tools.GBC;
 
 public class ServerAccessPreference implements PreferenceSetting {
@@ -14,15 +27,64 @@
 
     /**
-     * Provide username and password input editfields.
-     * Store the values if user hits OK.
+     * Editfield for the Base url to the REST API from OSM.
      */
-    private CredentialsManager.PreferenceAdditions credentialsPA = OsmConnection.credentialsManager.newPreferenceAdditions();
+    final private JTextField osmDataServerURL = new JTextField(20);
+    /**
+     * Editfield for the username to the OSM account.
+     */
+    final private JTextField osmDataUsername = new JTextField(20);
+    /**
+     * Passwordfield for the userpassword of the REST API.
+     */
+    final private JPasswordField osmDataPassword = new JPasswordField(20);
 
     public void addGui(PreferenceDialog gui) {
-        credentialsPA.addPreferenceOptions(gui.connection);
+        CredentialsManager cm = CredentialsManagerFactory.getCredentialManager();
+        String oldServerURL = Main.pref.get("osm-server.url", "http://api.openstreetmap.org/api");
+        String oldUsername;
+        String oldPassword;
+        try {
+            PasswordAuthentication credentials =  cm.lookup(RequestorType.SERVER);
+            oldUsername = (credentials == null | credentials.getUserName() == null) ? "" : credentials.getUserName();
+            oldPassword = (credentials == null | credentials.getPassword() == null) ? "" : String.valueOf(credentials.getPassword());
+        } catch(CredentialsManagerException e) {
+            e.printStackTrace();
+            oldUsername = "";
+            oldPassword = "";
+        }
+
+        osmDataServerURL.setText(oldServerURL);
+        osmDataUsername.setText(oldUsername);
+        osmDataPassword.setText(oldPassword);
+        osmDataServerURL.setToolTipText(tr("The base URL for the OSM server (REST API)"));
+        osmDataUsername.setToolTipText(tr("Login name (e-mail) to the OSM account."));
+        osmDataPassword.setToolTipText(tr("Login password to the OSM account. Leave blank to not store any password."));
+
+        gui.connection.add(new JLabel(tr("Base Server URL")), GBC.std());
+        gui.connection.add(osmDataServerURL, GBC.eol().fill(GBC.HORIZONTAL).insets(5,0,0,5));
+        gui.connection.add(new JLabel(tr("OSM username (e-mail)")), GBC.std());
+        gui.connection.add(osmDataUsername, GBC.eol().fill(GBC.HORIZONTAL).insets(5,0,0,5));
+        gui.connection.add(new JLabel(tr("OSM password")), GBC.std());
+        gui.connection.add(osmDataPassword, GBC.eol().fill(GBC.HORIZONTAL).insets(5,0,0,0));
+        JLabel warning = new JLabel(tr("<html>" +
+                "WARNING: The password is stored in plain text in the preferences file.<br>" +
+                "The password is transferred in plain text to the server, encoded in the URL.<br>" +
+        "<b>Do not use a valuable Password.</b></html>"));
+        warning.setFont(warning.getFont().deriveFont(Font.ITALIC));
+        gui.connection.add(warning, GBC.eop().fill(GBC.HORIZONTAL));
     }
 
     public boolean ok() {
-        credentialsPA.preferencesChanged();
+        CredentialsManager cm = CredentialsManagerFactory.getCredentialManager();
+        Main.pref.put("osm-server.url", osmDataServerURL.getText());
+        try {
+            cm.store(RequestorType.SERVER, new PasswordAuthentication(
+                    osmDataUsername.getText(),
+                    osmDataPassword.getPassword()
+            ));
+        } catch(CredentialsManagerException e) {
+            // FIXME: Message dialog with an error message?
+            e.printStackTrace();
+        }
         return false;
     }
Index: unk/src/org/openstreetmap/josm/io/CredentialsManager.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/CredentialsManager.java	(revision 2640)
+++ 	(revision )
@@ -1,61 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.io;
-
-import org.openstreetmap.josm.io.OsmConnection.OsmAuth;
-
-/**
- * Manages how username and password are stored. In addition all
- * username/password-related user interaction is encapsulated here.
- */
-public interface CredentialsManager {
-    enum Key {
-        OSM_SERVER_URL("url"),
-        USERNAME("username"),
-        PASSWORD("password");
-        final private String pname;
-        private Key(String name) {
-            pname = name;
-        }
-        @Override public String toString() {
-            return pname;
-        }
-    };
-
-    /**
-     * Should throw or return non-null, possibly empty String.
-     */
-    public String lookup(Key key) throws CMException;
-
-    /**
-     * May silently fail to store.
-     */
-    public void store(Key key, String secret) throws CMException;
-
-    /**
-     * If authentication using the stored credentials fails, this method is
-     * called to promt for new username/password.
-     */
-    public java.net.PasswordAuthentication getPasswordAuthentication(OsmAuth caller);
-
-    /**
-     * Credentials-related preference gui.
-     */
-    public interface PreferenceAdditions {
-        public void addPreferenceOptions(javax.swing.JPanel panel);
-        public void preferencesChanged();
-    }
-    public PreferenceAdditions newPreferenceAdditions();
-
-    public class CMException extends Exception {
-        public CMException() {super();}
-        public CMException(String message, Throwable cause) {super(message, cause);}
-        public CMException(String message) {super(message);}
-        public CMException(Throwable cause) {super(cause);}
-    }
-    public class NoContentException extends CMException {
-        public NoContentException() {super();}
-        public NoContentException(String message, Throwable cause) {super(message, cause);}
-        public NoContentException(String message) {super(message);}
-        public NoContentException(Throwable cause) {super(cause);}
-    }
-}
Index: /trunk/src/org/openstreetmap/josm/io/DefaultProxySelector.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/DefaultProxySelector.java	(revision 2641)
+++ /trunk/src/org/openstreetmap/josm/io/DefaultProxySelector.java	(revision 2641)
@@ -0,0 +1,169 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.io;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.SocketAddress;
+import java.net.URI;
+import java.net.Proxy.Type;
+import java.util.Collections;
+import java.util.List;
+import java.util.logging.Logger;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.preferences.ProxyPreferences;
+import org.openstreetmap.josm.gui.preferences.ProxyPreferences.ProxyPolicy;
+
+/**
+ * This is the default proxy selector used in JOSM.
+ * 
+ */
+public class DefaultProxySelector extends ProxySelector {
+    static private final Logger logger = Logger.getLogger(DefaultProxySelector.class.getName());
+
+    /**
+     * The {@see ProxySelector} provided by the JDK will retrieve proxy information
+     * from the system settings, if the system property <tt>java.net.useSystemProxies</tt>
+     * is defined <strong>at startup</strong>. It has no effect if the property is set
+     * later by the application.
+     *
+     * We therefore read the property at class loading time and remember it's value.
+     */
+    private static boolean JVM_WILL_USE_SYSTEM_PROXIES = false;
+    {
+        String v = System.getProperty("java.net.useSystemProxies");
+        if (v != null && v.equals(Boolean.TRUE.toString())) {
+            JVM_WILL_USE_SYSTEM_PROXIES = true;
+        }
+    }
+
+    /**
+     * The {@see ProxySelector} provided by the JDK will retrieve proxy information
+     * from the system settings, if the system property <tt>java.net.useSystemProxies</tt>
+     * is defined <strong>at startup</strong>. If the property is set later by the application,
+     * this has no effect.
+     * 
+     * @return true, if <tt>java.net.useSystemProxies</tt> was set to true at class initialization time
+     * 
+     */
+    public static boolean willJvmRetrieveSystemProxies() {
+        return JVM_WILL_USE_SYSTEM_PROXIES;
+    }
+
+    private ProxyPolicy proxyPolicy;
+    private InetSocketAddress httpProxySocketAddress;
+    private InetSocketAddress socksProxySocketAddress;
+    private ProxySelector delegate;
+
+    /**
+     * A typical example is:
+     * <pre>
+     *    PropertySelector delegate = PropertySelector.getDefault();
+     *    PropertySelector.setDefault(new DefaultPropertySelector(delegate));
+     * </pre>
+     * 
+     * @param delegate the proxy selector to delegate to if system settings are used. Usually
+     * this is the proxy selector found by ProxySelector.getDefault() before this proxy
+     * selector is installed
+     */
+    public DefaultProxySelector(ProxySelector delegate) {
+        this.delegate = delegate;
+        initFromPreferences();
+    }
+
+    protected int parseProxyPortValue(String property, String value) {
+        if (value == null) return 0;
+        int port = 0;
+        try {
+            port = Integer.parseInt(value);
+        } catch(NumberFormatException e){
+            System.err.println(tr("Unexpected format for port number in in preference ''{0}''. Got ''{1}''. Proxy won't be used.", property, value));
+            return 0;
+        }
+        if (port <= 0 || port >  65535) {
+            System.err.println(tr("Illegal port number in preference ''{0}''. Got {1}. Proxy won't be used.", property, port));
+            return 0;
+        }
+        return port;
+    }
+
+    /**
+     * Initializes the proxy selector from the setting in the preferences.
+     * 
+     */
+    public void initFromPreferences() {
+        String value = Main.pref.get(ProxyPreferences.PROXY_POLICY);
+        if (value == null) {
+            System.err.println(tr("Warning: no preference ''{0}'' found. Will use no proxy.", ProxyPreferences.PROXY_POLICY));
+            proxyPolicy = ProxyPolicy.NO_PROXY;
+        } else {
+            proxyPolicy= ProxyPolicy.fromName(value);
+            if (proxyPolicy == null) {
+                System.err.println(tr("Warning: unexpected value for preference ''{0}'' found. Got ''{1}''. Will use no proxy.", ProxyPreferences.PROXY_POLICY, value));
+                proxyPolicy = ProxyPolicy.NO_PROXY;
+            }
+        }
+        String host = Main.pref.get(ProxyPreferences.PROXY_HTTP_HOST, null);
+        int port = parseProxyPortValue(ProxyPreferences.PROXY_HTTP_PORT, Main.pref.get(ProxyPreferences.PROXY_HTTP_PORT, null));
+        if (host != null && ! host.trim().equals("") && port > 0) {
+            httpProxySocketAddress = new InetSocketAddress(host,port);
+        } else {
+            httpProxySocketAddress = null;
+            if (proxyPolicy.equals(ProxyPolicy.USE_HTTP_PROXY)) {
+                System.err.println(tr("Warning: Unexpected parameters for HTTP proxy. Got host ''{0}'' and port ''{1}''. Proxy won't be used", host, port));
+            }
+        }
+
+        host = Main.pref.get(ProxyPreferences.PROXY_SOCKS_HOST, null);
+        port = parseProxyPortValue(ProxyPreferences.PROXY_SOCKS_PORT, Main.pref.get(ProxyPreferences.PROXY_SOCKS_PORT, null));
+        if (host != null && ! host.trim().equals("") && port > 0) {
+            socksProxySocketAddress = new InetSocketAddress(host,port);
+        } else {
+            socksProxySocketAddress = null;
+            if (proxyPolicy.equals(ProxyPolicy.USE_SOCKS_PROXY)) {
+                System.err.println(tr("Warning: Unexpected parameters for SOCKS proxy. Got host ''{0}'' and port ''{1}''. Proxy won't be used", host, port));
+            }
+        }
+    }
+
+    @Override
+    public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
+        // Just log something. The network stack will also throw an exception which will be caught
+        // somewhere else
+        //
+        System.out.println(tr("Error: Connection to proxy ''{0}'' for URI ''{1}'' failed. Exception was: {2}", sa.toString(), uri.toString(), ioe.toString()));
+    }
+
+    @Override
+    public List<Proxy> select(URI uri) {
+        Proxy proxy;
+        switch(proxyPolicy) {
+        case USE_SYSTEM_SETTINGS:
+            if (!JVM_WILL_USE_SYSTEM_PROXIES) {
+                System.err.println(tr("Warning: the JVM is not configured to lookup proxies from the system settings. The property ''java.net.useSystemProxies'' was missing at startup time. Won't use a proxy."));
+                return Collections.singletonList(Proxy.NO_PROXY);
+            }
+            // delegate to the former proxy selector
+            List<Proxy> ret = delegate.select(uri);
+            return ret;
+        case NO_PROXY:
+            return Collections.singletonList(Proxy.NO_PROXY);
+        case USE_HTTP_PROXY:
+            if (httpProxySocketAddress == null)
+                return Collections.singletonList(Proxy.NO_PROXY);
+            proxy = new Proxy(Type.HTTP, httpProxySocketAddress);
+            return Collections.singletonList(proxy);
+        case USE_SOCKS_PROXY:
+            if (socksProxySocketAddress == null)
+                return Collections.singletonList(Proxy.NO_PROXY);
+            proxy = new Proxy(Type.SOCKS, socksProxySocketAddress);
+            return Collections.singletonList(proxy);
+        }
+        // should not happen
+        return null;
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/io/MultiPartFormOutputStream.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/MultiPartFormOutputStream.java	(revision 2640)
+++ /trunk/src/org/openstreetmap/josm/io/MultiPartFormOutputStream.java	(revision 2641)
@@ -92,5 +92,4 @@
         this.out = new DataOutputStream(os);
         this.boundary = boundary;
-        initAuthentication();
     }
 
Index: /trunk/src/org/openstreetmap/josm/io/OsmApi.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/OsmApi.java	(revision 2640)
+++ /trunk/src/org/openstreetmap/josm/io/OsmApi.java	(revision 2641)
@@ -23,4 +23,5 @@
 import java.util.HashMap;
 
+import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.parsers.SAXParserFactory;
 
@@ -147,9 +148,8 @@
      * @exception OsmApiInitializationException thrown, if an exception occurs
      */
-    public void initialize(ProgressMonitor monitor) throws OsmApiInitializationException {
+    public void initialize(ProgressMonitor monitor) throws OsmApiInitializationException, OsmTransferCancelledException {
         if (initialized)
             return;
         cancel = false;
-        initAuthentication();
         try {
             String s = sendRequest("GET", "capabilities", null,monitor, false);
@@ -169,7 +169,18 @@
             osmWriter.setVersion(version);
             initialized = true;
-        } catch (Exception ex) {
+        } catch(IOException e) {
             initialized = false;
-            throw new OsmApiInitializationException(ex);
+            throw new OsmApiInitializationException(e);
+        } catch(SAXException e) {
+            initialized = false;
+            throw new OsmApiInitializationException(e);
+        } catch(ParserConfigurationException e) {
+            initialized = false;
+            throw new OsmApiInitializationException(e);
+        } catch(OsmTransferCancelledException e){
+            throw e;
+        } catch(OsmTransferException e) {
+            initialized = false;
+            throw new OsmApiInitializationException(e);
         }
     }
@@ -436,5 +447,5 @@
                 monitor.setCustomText(tr("Starting retry {0} of {1} in {2} seconds ...", getMaxRetries() - retry,getMaxRetries(), 10-i));
             }
-            if (cancel || isAuthCancelled())
+            if (cancel)
                 throw new OsmTransferCancelledException();
             try {
@@ -563,4 +574,10 @@
                 case HttpURLConnection.HTTP_GONE:
                     throw new OsmApiPrimitiveGoneException(errorHeader, errorBody);
+                case HttpURLConnection.HTTP_UNAUTHORIZED:
+                case HttpURLConnection.HTTP_PROXY_AUTH:
+                    // if we get here with HTTP_UNAUTHORIZED or HTTP_PROXY_AUTH the user canceled the
+                    // username/password dialog. Throw an OsmTransferCancelledException.
+                    //
+                    throw new OsmTransferCancelledException();
                 case HttpURLConnection.HTTP_CONFLICT:
                     if (ChangesetClosedException.errorHeaderMatchesPattern(errorHeader))
@@ -583,8 +600,10 @@
                 }
                 throw new OsmTransferException(e);
+            } catch(IOException e){
+                throw new OsmTransferException(e);
+            } catch(OsmTransferCancelledException e){
+                throw e;
             } catch(OsmTransferException e) {
                 throw e;
-            } catch (Exception e) {
-                throw new OsmTransferException(e);
             }
         }
Index: /trunk/src/org/openstreetmap/josm/io/OsmConnection.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/OsmConnection.java	(revision 2640)
+++ /trunk/src/org/openstreetmap/josm/io/OsmConnection.java	(revision 2641)
@@ -2,11 +2,6 @@
 package org.openstreetmap.josm.io;
 
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import java.awt.Font;
-import java.awt.GridBagLayout;
-import java.net.Authenticator;
 import java.net.HttpURLConnection;
-import java.net.PasswordAuthentication;
+import java.net.Authenticator.RequestorType;
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
@@ -16,14 +11,8 @@
 import java.util.logging.Logger;
 
-import javax.swing.JCheckBox;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JPasswordField;
-import javax.swing.JTextField;
-
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.gui.ExtendedDialog;
+import org.openstreetmap.josm.io.auth.CredentialsManagerException;
+import org.openstreetmap.josm.io.auth.CredentialsManagerFactory;
+import org.openstreetmap.josm.io.auth.CredentialsManagerResponse;
 import org.openstreetmap.josm.tools.Base64;
-import org.openstreetmap.josm.tools.GBC;
 
 /**
@@ -38,14 +27,4 @@
     protected boolean cancel = false;
     protected HttpURLConnection activeConnection;
-    /**
-     * Handles password storage and some related gui-components.
-     * It can be set by a plugin. This may happen at startup and
-     * by changing the preferences.
-     * Syncronize on this object to get or set a consistent
-     * username/password pair.
-     */
-    public static CredentialsManager credentialsManager = new PlainCredentialsManager();
-
-    private static OsmAuth authentication = new OsmAuth();
 
     /**
@@ -53,44 +32,9 @@
      */
     static {
-        // TODO: current authentication handling is sub-optimal in that it seems to use the same authenticator for
-        // any kind of request. HTTP requests executed by plugins, e.g. to password-protected WMS servers,
-        // will use the same username/password which is undesirable.
         try {
             HttpURLConnection.setFollowRedirects(true);
-            Authenticator.setDefault(authentication);
         } catch (SecurityException e) {
+            e.printStackTrace();
         }
-    }
-
-    /**
-     * The authentication class handling the login requests.
-     */
-    public static class OsmAuth extends Authenticator {
-        /**
-         * Set to true, when the autenticator tried the password once.
-         */
-        public boolean passwordtried = false;
-        /**
-         * Whether the user cancelled the password dialog
-         */
-        public boolean authCancelled = false;
-        @Override protected PasswordAuthentication getPasswordAuthentication() {
-            return credentialsManager.getPasswordAuthentication(this);
-        }
-    }
-
-    /**
-     * Must be called before each connection attemp to initialize the authentication.
-     */
-    protected final void initAuthentication() {
-        authentication.authCancelled = false;
-        authentication.passwordtried = false;
-    }
-
-    /**
-     * @return Whether the connection was cancelled.
-     */
-    protected final boolean isAuthCancelled() {
-        return authentication.authCancelled;
     }
 
@@ -115,17 +59,31 @@
     }
 
-    protected void addAuth(HttpURLConnection con) throws CharacterCodingException {
+    protected void addAuth(HttpURLConnection con) throws OsmTransferException {
         CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
-        String auth;
+        CredentialsManagerResponse response;
+        String token;
         try {
-            synchronized (credentialsManager) {
-                auth = credentialsManager.lookup(CredentialsManager.Key.USERNAME) + ":" +
-                credentialsManager.lookup(CredentialsManager.Key.PASSWORD);
+            synchronized (CredentialsManagerFactory.getCredentialManager()) {
+                response = CredentialsManagerFactory.getCredentialManager().getCredentials(RequestorType.SERVER, false /* don't know yet whether the credentials will succeed */);
             }
-        } catch (CredentialsManager.CMException e) {
-            auth = ":";
+        } catch (CredentialsManagerException e) {
+            throw new OsmTransferException(e);
         }
-        ByteBuffer bytes = encoder.encode(CharBuffer.wrap(auth));
-        con.addRequestProperty("Authorization", "Basic "+Base64.encode(bytes));
+        if (response == null) {
+            token = ":";
+        } else if (response.isCanceled()) {
+            cancel = true;
+            return;
+        } else {
+            String username= response.getUsername() == null ? "" : response.getUsername();
+            String password = response.getPassword() == null ? "" : String.valueOf(response.getPassword());
+            token = username + ":" + password;
+            try {
+                ByteBuffer bytes = encoder.encode(CharBuffer.wrap(token));
+                con.addRequestProperty("Authorization", "Basic "+Base64.encode(bytes));
+            } catch(CharacterCodingException e) {
+                throw new OsmTransferException(e);
+            }
+        }
     }
 
@@ -139,146 +97,3 @@
         return cancel;
     }
-    /**
-     * Default implementation of the CredentialsManager interface.
-     * Saves passwords in plain text file.
-     */
-    public static class PlainCredentialsManager implements CredentialsManager {
-        public String lookup(CredentialsManager.Key key) throws CMException {
-            String secret = Main.pref.get("osm-server." + key.toString(), null);
-            if (secret == null) throw new CredentialsManager.NoContentException();
-            return secret;
-        }
-        public void store(CredentialsManager.Key key, String secret) {
-            Main.pref.put("osm-server." + key.toString(), secret);
-        }
-        public PasswordAuthentication getPasswordAuthentication(OsmAuth caller) {
-            String username, password;
-            try {
-                username = lookup(Key.USERNAME);
-            } catch (CMException e) {
-                username = "";
-            }
-            try {
-                password = lookup(Key.PASSWORD);
-            } catch (CMException e) {
-                password = "";
-            }
-            if (caller.passwordtried || username.equals("") || password.equals("")) {
-                JPanel p = new JPanel(new GridBagLayout());
-                if (!username.equals("") && !password.equals("")) {
-                    p.add(new JLabel(tr("Incorrect password or username.")), GBC.eop());
-                }
-                p.add(new JLabel(tr("Username")), GBC.std().insets(0,0,10,0));
-                JTextField usernameField = new JTextField(username, 20);
-                p.add(usernameField, GBC.eol());
-                p.add(new JLabel(tr("Password")), GBC.std().insets(0,0,10,0));
-                JPasswordField passwordField = new JPasswordField(password, 20);
-                p.add(passwordField, GBC.eol());
-                JLabel warning = new JLabel(tr("Warning: The password is transferred unencrypted."));
-                warning.setFont(warning.getFont().deriveFont(Font.ITALIC));
-                p.add(warning, GBC.eop());
-
-                JCheckBox savePassword = new JCheckBox(tr("Save user and password (unencrypted)"),
-                        !username.equals("") && !password.equals(""));
-                p.add(savePassword, GBC.eop());
-
-                ExtendedDialog dialog = new ExtendedDialog(
-                        Main.parent,
-                        tr("Enter Password"),
-                        new String[] {tr("Login"), tr("Cancel")}
-                );
-                dialog.setContent(p);
-                dialog.setButtonIcons( new String[] {"ok.png", "cancel.png"});
-                dialog.showDialog();
-
-                if (dialog.getValue() != 1) {
-                    caller.authCancelled = true;
-                    return null;
-                }
-                username = usernameField.getText();
-                password = String.valueOf(passwordField.getPassword());
-                if (savePassword.isSelected()) {
-                    store(Key.USERNAME, username);
-                    store(Key.PASSWORD, password);
-                }
-                if (username.equals(""))
-                    return null;
-            }
-            caller.passwordtried = true;
-            return new PasswordAuthentication(username, password.toCharArray());
-        }
-        public PreferenceAdditions newPreferenceAdditions() {
-            return new PreferenceAdditions() {
-                /**
-                 * Editfield for the Base url to the REST API from OSM.
-                 */
-                final private JTextField osmDataServerURL = new JTextField(20);
-                /**
-                 * Editfield for the username to the OSM account.
-                 */
-                final private JTextField osmDataUsername = new JTextField(20);
-                /**
-                 * Passwordfield for the userpassword of the REST API.
-                 */
-                final private JPasswordField osmDataPassword = new JPasswordField(20);
-
-                private String oldServerURL = "";
-                private String oldUsername = "";
-                private String oldPassword = "";
-
-                public void addPreferenceOptions(JPanel panel) {
-                    try {
-                        oldServerURL = lookup(Key.OSM_SERVER_URL); // result is not null (see CredentialsManager)
-                    } catch (CMException e) {
-                        oldServerURL = "";
-                    }
-                    if (oldServerURL.equals("")) {
-                        oldServerURL = "http://api.openstreetmap.org/api";
-                    }
-                    try {
-                        oldUsername = lookup(Key.USERNAME);
-                    } catch (CMException e) {
-                        oldUsername = "";
-                    }
-                    try {
-                        oldPassword = lookup(Key.PASSWORD);
-                    } catch (CMException e) {
-                        oldPassword = "";
-                    }
-                    osmDataServerURL.setText(oldServerURL);
-                    osmDataUsername.setText(oldUsername);
-                    osmDataPassword.setText(oldPassword);
-                    osmDataServerURL.setToolTipText(tr("The base URL for the OSM server (REST API)"));
-                    osmDataUsername.setToolTipText(tr("Login name (e-mail) to the OSM account."));
-                    osmDataPassword.setToolTipText(tr("Login password to the OSM account. Leave blank to not store any password."));
-                    panel.add(new JLabel(tr("Base Server URL")), GBC.std());
-                    panel.add(osmDataServerURL, GBC.eol().fill(GBC.HORIZONTAL).insets(5,0,0,5));
-                    panel.add(new JLabel(tr("OSM username (e-mail)")), GBC.std());
-                    panel.add(osmDataUsername, GBC.eol().fill(GBC.HORIZONTAL).insets(5,0,0,5));
-                    panel.add(new JLabel(tr("OSM password")), GBC.std());
-                    panel.add(osmDataPassword, GBC.eol().fill(GBC.HORIZONTAL).insets(5,0,0,0));
-                    JLabel warning = new JLabel(tr("<html>" +
-                            "WARNING: The password is stored in plain text in the preferences file.<br>" +
-                            "The password is transferred in plain text to the server, encoded in the URL.<br>" +
-                    "<b>Do not use a valuable Password.</b></html>"));
-                    warning.setFont(warning.getFont().deriveFont(Font.ITALIC));
-                    panel.add(warning, GBC.eop().fill(GBC.HORIZONTAL));
-                }
-                public void preferencesChanged() {
-                    String newServerURL = osmDataServerURL.getText();
-                    String newUsername = osmDataUsername.getText();
-                    String newPassword = String.valueOf(osmDataPassword.getPassword());
-                    if (!oldServerURL.equals(newServerURL)) {
-                        store(Key.OSM_SERVER_URL, newServerURL);
-                    }
-                    if (!oldUsername.equals(newUsername)) {
-                        store(Key.USERNAME, newUsername);
-                    }
-                    if (!oldPassword.equals(newPassword)) {
-                        store(Key.PASSWORD, newPassword);
-                    }
-                }
-            };
-        }
-    }
 }
Index: /trunk/src/org/openstreetmap/josm/io/OsmServerReader.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/OsmServerReader.java	(revision 2640)
+++ /trunk/src/org/openstreetmap/josm/io/OsmServerReader.java	(revision 2641)
@@ -10,5 +10,5 @@
 import java.net.MalformedURLException;
 import java.net.URL;
-import java.nio.charset.CharacterCodingException;
+import java.util.logging.Logger;
 import java.util.zip.GZIPInputStream;
 import java.util.zip.Inflater;
@@ -29,5 +29,5 @@
  */
 public abstract class OsmServerReader extends OsmConnection {
-
+    static private final Logger logger = Logger.getLogger(OsmServerReader.class.getName());
     private OsmApi api = OsmApi.getOsmApi();
     private boolean doAuthenticate = false;
@@ -68,12 +68,9 @@
             }
 
-            try {
-                if (doAuthenticate) {
-                    addAuth(activeConnection);
-                }
-            } catch(CharacterCodingException e) {
-                System.err.println(tr("Error: failed to add authentication credentials to the connection."));
-                throw new OsmTransferException(e);
+            if (doAuthenticate) {
+                addAuth(activeConnection);
             }
+            if (cancel)
+                throw new OsmTransferCancelledException();
             if (Main.pref.getBoolean("osm-server.use-compression", true)) {
                 activeConnection.setRequestProperty("Accept-Encoding", "gzip, deflate");
@@ -86,9 +83,13 @@
                 activeConnection.connect();
             } catch (Exception e) {
+                e.printStackTrace();
                 throw new OsmTransferException(tr("Couldn't connect to the OSM server. Please check your internet connection."), e);
             }
             try {
-                if (isAuthCancelled() && activeConnection.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED)
+                if (activeConnection.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED)
                     throw new OsmApiException(HttpURLConnection.HTTP_UNAUTHORIZED,null,null);
+
+                if (activeConnection.getResponseCode() == HttpURLConnection.HTTP_PROXY_AUTH)
+                    throw new OsmTransferCancelledException();
 
                 if (activeConnection.getResponseCode() != HttpURLConnection.HTTP_OK) {
Index: /trunk/src/org/openstreetmap/josm/io/auth/CredentialsManager.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/auth/CredentialsManager.java	(revision 2641)
+++ /trunk/src/org/openstreetmap/josm/io/auth/CredentialsManager.java	(revision 2641)
@@ -0,0 +1,48 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.io.auth;
+
+import java.net.PasswordAuthentication;
+import java.net.Authenticator.RequestorType;
+
+/**
+ * A CredentialManager manages two credentials:
+ * <ul>
+ *   <li>the credential for {@see RequestorType#SERVER} which is equal to the OSM API credentials
+ *   in JOSM</li>
+ *   <li>the credential for {@see RequestorType#PROXY} which is equal to the credentials for an
+ *   optional HTTP proxy server a user may use</li>
+ *  </ul>
+ */
+public interface CredentialsManager {
+
+    /**
+     * Looks up the credentials for a given type.
+     * 
+     * @param the type of service. {@see RequestorType#SERVER} for the OSM API server, {@see RequestorType#PROXY}
+     * for a proxy server
+     * @return the credentials
+     * @throws CredentialsManagerException thrown if a problem occurs in a implementation of this interface
+     */
+    public PasswordAuthentication lookup(RequestorType requestorType) throws CredentialsManagerException;
+
+    /**
+     * Saves the credentials in <code>credentials</code> for the given service type.
+     * 
+     * @param the type of service. {@see RequestorType#SERVER} for the OSM API server, {@see RequestorType#PROXY}
+     * for a proxy server
+     * @param credentials the credentials
+     * @throws CredentialsManagerException thrown if a problem occurs in a implementation of this interface
+     */
+    public void store(RequestorType requestorType, PasswordAuthentication credentials) throws CredentialsManagerException;
+
+    /**
+     * 
+     * @param requestorType  the type of service. {@see RequestorType#SERVER} for the OSM API server, {@see RequestorType#PROXY}
+     * for a proxy server
+     * @param noSuccessWithLastResponse true, if the last request with the supplied credentials failed; false otherwise.
+     * If true, implementations of this interface are adviced prompt user for new credentials.
+     * @throws CredentialsManagerException thrown if a problem occurs in a implementation of this interface
+
+     */
+    public CredentialsManagerResponse getCredentials(RequestorType requestorType, boolean noSuccessWithLastResponse) throws CredentialsManagerException;
+}
Index: /trunk/src/org/openstreetmap/josm/io/auth/CredentialsManagerException.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/auth/CredentialsManagerException.java	(revision 2641)
+++ /trunk/src/org/openstreetmap/josm/io/auth/CredentialsManagerException.java	(revision 2641)
@@ -0,0 +1,10 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.io.auth;
+
+public class CredentialsManagerException extends Exception {
+    public CredentialsManagerException() {super();}
+    public CredentialsManagerException(String message, Throwable cause) {super(message, cause);}
+    public CredentialsManagerException(String message) {super(message);}
+    public CredentialsManagerException(Throwable cause) {super(cause);}
+
+}
Index: /trunk/src/org/openstreetmap/josm/io/auth/CredentialsManagerFactory.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/auth/CredentialsManagerFactory.java	(revision 2641)
+++ /trunk/src/org/openstreetmap/josm/io/auth/CredentialsManagerFactory.java	(revision 2641)
@@ -0,0 +1,23 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.io.auth;
+
+/**
+ * CredentialManagerFactory is a factory for the single credential manager used.
+ * 
+ * Currently, it defaults to replying an instance of {@see JosmPreferencesCredentialManager}.
+ * 
+ */
+public class CredentialsManagerFactory {
+    private static CredentialsManager instance;
+
+    /**
+     * Replies the single credential manager used in JOSM
+     * 
+     * @return the single credential manager used in JOSM
+     */
+    static public CredentialsManager getCredentialManager() {
+        if (instance == null)
+            return new JosmPreferencesCredentialManager();
+        return instance;
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/io/auth/CredentialsManagerResponse.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/auth/CredentialsManagerResponse.java	(revision 2641)
+++ /trunk/src/org/openstreetmap/josm/io/auth/CredentialsManagerResponse.java	(revision 2641)
@@ -0,0 +1,34 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.io.auth;
+
+/**
+ * CredentialsManagerResponse represents the response from {@see CredentialsManager#getCredentials(java.net.Authenticator.RequestorType, boolean)}.
+ * 
+ * The response consists of the username and the password the requested credentials consists of.
+ * In addition, it provides information whether authentication was canceled by the user, i.e.
+ * because he or she canceled a username/password dialog (see {@see #isCanceled()}.
+ * 
+ */
+public class CredentialsManagerResponse {
+    private String username;
+    private char[] password;
+    private boolean canceled;
+    public String getUsername() {
+        return username;
+    }
+    public void setUsername(String username) {
+        this.username = username;
+    }
+    public char[] getPassword() {
+        return password;
+    }
+    public void setPassword(char[] password) {
+        this.password = password;
+    }
+    public boolean isCanceled() {
+        return canceled;
+    }
+    public void setCanceled(boolean cancelled) {
+        this.canceled = cancelled;
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/io/auth/DefaultAuthenticator.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/auth/DefaultAuthenticator.java	(revision 2641)
+++ /trunk/src/org/openstreetmap/josm/io/auth/DefaultAuthenticator.java	(revision 2641)
@@ -0,0 +1,48 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.io.auth;
+
+import java.net.Authenticator;
+import java.net.PasswordAuthentication;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Logger;
+
+/**
+ * This is the default authenticator used in JOSM. It delegates lookup of credentials
+ * for the OSM API and an optional proxy server to the currently configured
+ * {@see CredentialsManager}.
+ * 
+ */
+public  class DefaultAuthenticator extends Authenticator {
+    private static final Logger logger = Logger.getLogger(DefaultAuthenticator.class.getName());
+
+    private CredentialsManager credentialManager;
+    private final Map<RequestorType, Boolean> credentialsTried = new HashMap<RequestorType, Boolean>();
+
+    /**
+     * 
+     * @param credentialManager the credential manager
+     */
+    public DefaultAuthenticator(CredentialsManager credentialManager) {
+        this.credentialManager = credentialManager;
+    }
+
+    /**
+     * Called by the Java http stack when either the OSM API server or a proxy requires
+     * authentication.
+     * 
+     */
+    @Override protected PasswordAuthentication getPasswordAuthentication() {
+        try {
+            boolean tried = credentialsTried.get(getRequestorType()) != null;
+            CredentialsManagerResponse response = credentialManager.getCredentials(getRequestorType(), tried);
+            if (response == null || response.isCanceled())
+                return null;
+            credentialsTried.put(getRequestorType(), true);
+            return new PasswordAuthentication(response.getUsername(), response.getPassword());
+        } catch(CredentialsManagerException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+}
Index: /trunk/src/org/openstreetmap/josm/io/auth/JosmPreferencesCredentialManager.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/auth/JosmPreferencesCredentialManager.java	(revision 2641)
+++ /trunk/src/org/openstreetmap/josm/io/auth/JosmPreferencesCredentialManager.java	(revision 2641)
@@ -0,0 +1,106 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.io.auth;
+
+import java.net.PasswordAuthentication;
+import java.net.Authenticator.RequestorType;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.io.CredentialDialog;
+import org.openstreetmap.josm.gui.preferences.ProxyPreferences;
+
+/**
+ * This is the default credential manager in JOSM. It keeps username and password for both
+ * the OSM API and an optional HTTP proxy in the JOSM preferences file.
+ *
+ */
+public class JosmPreferencesCredentialManager implements CredentialsManager {
+
+    /**
+     * @see CredentialsManager#lookup(RequestorType)
+     */
+    public PasswordAuthentication lookup(RequestorType requestorType) throws CredentialsManagerException{
+        if (requestorType == null)
+            return null;
+        String user;
+        String password;
+        switch(requestorType) {
+        case SERVER:
+            user = Main.pref.get("osm-server.username", null);
+            password = Main.pref.get("osm-server.password", null);
+            if (user == null)
+                return null;
+            return new PasswordAuthentication(user, password == null ? null : password.toCharArray());
+        case PROXY:
+            user = Main.pref.get(ProxyPreferences.PROXY_USER, null);
+            password = Main.pref.get(ProxyPreferences.PROXY_PASS, null);
+            if (user == null)
+                return null;
+            return new PasswordAuthentication(user, password == null ? null : password.toCharArray());
+        }
+        return null;
+    }
+
+    /**
+     * @see CredentialsManager#store(RequestorType, PasswordAuthentication)
+     */
+    public void store(RequestorType requestorType, PasswordAuthentication credentials) throws CredentialsManagerException {
+        if (requestorType == null)
+            return;
+        switch(requestorType) {
+        case SERVER:
+            Main.pref.put("osm-server.username", credentials.getUserName());
+            if (credentials.getPassword() == null) {
+                Main.pref.put("osm-server.password", null);
+            } else {
+                Main.pref.put("osm-server.password", String.valueOf(credentials.getPassword()));
+            }
+            break;
+        case PROXY:
+            Main.pref.put("proxy.username", credentials.getUserName());
+            if (credentials.getPassword() == null) {
+                Main.pref.put("proxy.password", null);
+            } else {
+                Main.pref.put("proxy.password", String.valueOf(credentials.getPassword()));
+            }
+            break;
+        }
+    }
+
+    /**
+     * @see CredentialsManager#getCredentials(RequestorType, boolean)
+     */
+    public CredentialsManagerResponse getCredentials(RequestorType requestorType, boolean noSuccessWithLastResponse) throws CredentialsManagerException{
+        if (requestorType == null)
+            return null;
+        PasswordAuthentication credentials =  lookup(requestorType);
+        String username = (credentials == null || credentials.getUserName() == null) ? "" : credentials.getUserName();
+        String password = (credentials == null || credentials.getPassword() == null) ? "" : String.valueOf(credentials.getPassword());
+
+        CredentialsManagerResponse response = new CredentialsManagerResponse();
+
+        if (noSuccessWithLastResponse|| username.equals("") || password.equals("")) {
+            CredentialDialog dialog = null;
+            switch(requestorType) {
+            case SERVER: dialog = CredentialDialog.getOsmApiCredentialDialog(username, password); break;
+            case PROXY: dialog = CredentialDialog.getHttpProxyCredentialDialog(username, password); break;
+            }
+            dialog.setVisible(true);
+            response.setCanceled(dialog.isCanceled());
+            if (dialog.isCanceled())
+                return response;
+            response.setUsername(dialog.getUsername());
+            response.setPassword(dialog.getPassword());
+            if (dialog.isSaveCredentials()) {
+                store(requestorType, new PasswordAuthentication(
+                        response.getUsername(),
+                        response.getPassword()
+                ));
+            }
+        } else {
+            response.setUsername(username);
+            response.setPassword(password.toCharArray());
+            response.setCanceled(false);
+        }
+        return response;
+    }
+}
Index: /trunk/test/functional/org/openstreetmap/josm/io/UploadStrategySelectionPanelTest.java
===================================================================
--- /trunk/test/functional/org/openstreetmap/josm/io/UploadStrategySelectionPanelTest.java	(revision 2640)
+++ /trunk/test/functional/org/openstreetmap/josm/io/UploadStrategySelectionPanelTest.java	(revision 2641)
@@ -55,5 +55,5 @@
     }
 
-    public static void main(String args[]) throws OsmApiInitializationException {
+    public static void main(String args[]) throws OsmApiInitializationException, OsmTransferCancelledException{
         JOSMFixture josmFixture = JOSMFixture.createFunctionalTestFixture();
         OsmApi.getOsmApi().initialize(NullProgressMonitor.INSTANCE);
