/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.harmony.luni.tests.java.net;

import dalvik.annotation.BrokenTest;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
import junit.framework.TestCase;
import tests.support.Support_Configuration;
import tests.support.Support_PortManager;
import tests.support.Support_TestWebData;
import tests.support.Support_TestWebServer;
import tests.support.resource.Support_Resources;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FilePermission;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.CacheRequest;
import java.net.CacheResponse;
import java.net.FileNameMap;
import java.net.HttpURLConnection;
import java.net.JarURLConnection;
import java.net.MalformedURLException;
import java.net.ResponseCache;
import java.net.SocketPermission;
import java.net.SocketTimeoutException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.net.UnknownServiceException;
import java.security.Permission;
import java.text.ParseException;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

@TestTargetClass(
   value = URLConnection.class,
   untestedMethods = {
       @TestTargetNew(
           level = TestLevel.NOT_NECESSARY,
           notes = "Default implementation returns always null according to spec.",
           method = "getHeaderField",
           args = {int.class}
       ),
       @TestTargetNew(
           level = TestLevel.NOT_NECESSARY,
           notes = "Default implementation returns always null according to spec.",
           method = "getHeaderFieldKey",
           args = {int.class}
       )
   }
) 
public class URLConnectionTest extends TestCase {
    
    private static final String testString = "Hello World";
    
    private URLConnection fileURLCon;
    
    private URL fileURL;
    
    private JarURLConnection jarURLCon;
    
    private URL jarURL;
    
    private URLConnection gifURLCon;
    
    private URL gifURL;

    public boolean isGetCalled;

    public boolean isPutCalled;
    
    private Map<String, List<String>> mockHeaderMap;

    private InputStream mockIs = new MockInputStream();

    public boolean isCacheWriteCalled;

    public boolean isAbortCalled;
    
    /**
     * @tests {@link java.net.URLConnection#addRequestProperty(String, String)}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "Exceptions checked only. Cannot test positive test since getter method is not supported.",
        method = "addRequestProperty",
        args = {java.lang.String.class, java.lang.String.class}
    )
    public void test_addRequestProperty() throws MalformedURLException,
            IOException {
        
        
        MockURLConnection u = new MockURLConnection(new URL(
                "http://www.apache.org"));

        try {
            // Regression for HARMONY-604
            u.addRequestProperty(null, "someValue");
            fail("Expected NullPointerException");
        } catch (NullPointerException e) {
            // expected
        }
        
        u.connect();
        try {
            // state of connection is checked first
            // so no NPE in case of null 'field' param
            u.addRequestProperty(null, "someValue");
            fail("Expected IllegalStateException");
        } catch (IllegalStateException e) {
            // expected
        }
        
    }

    /**
     * @tests {@link java.net.URLConnection#setRequestProperty(String, String)}
     */
    @TestTargetNew(
        level = TestLevel.PARTIAL_COMPLETE,
        notes = "Exceptions checked only -> only partially implemented.",
        method = "setRequestProperty",
        args = {java.lang.String.class, java.lang.String.class}
    )
    public void test_setRequestProperty() throws MalformedURLException,
            IOException {

        MockURLConnection u = new MockURLConnection(new URL(
                "http://www.apache.org"));
        try {
            u.setRequestProperty(null, "someValue");
            fail("Expected NullPointerException");
        } catch (NullPointerException e) {
            // expected
        }
        
        try {
            u.setRequestProperty("user-agent", "Mozilla/5.0 (Windows; U; Windows NT 5.0; de-DE; rv:1.7.5) Gecko/20041122 Firefox/1.0");
        } catch (NullPointerException e) {
            fail("Unexpected Exception");
        }
        
        u.connect();
        
        try {
            // state of connection is checked first
            // so no NPE in case of null 'field' param
            u.setRequestProperty(null, "someValue");
            fail("Expected IllegalStateException");
        } catch (IllegalStateException e) {
            // expected
        }
    }

    /**
     * @tests {@link java.net.URLConnection#setUseCaches(boolean)}
     */
    @TestTargetNew(
        level = TestLevel.PARTIAL_COMPLETE,
        notes = "Complete together with getUseCaches test.",
        method = "setUseCaches",
        args = {boolean.class}
    )
    public void test_setUseCachesZ() throws MalformedURLException, IOException {

        // Regression for HARMONY-71
        MockURLConnection u = new MockURLConnection(new URL(
                "http://www.apache.org"));
        u.connect();
        try {
            u.setUseCaches(true);
            fail("Assert 0: expected an IllegalStateException");
        } catch (IllegalStateException e) {
            // expected
        }
    }

    /**
     * @tests {@link java.net.URLConnection#setAllowUserInteraction(boolean)}
     */
    @TestTargetNew(
        level = TestLevel.PARTIAL,
        notes = "Exceptions checked only.",
        method = "setAllowUserInteraction",
        args = {boolean.class}
    )
    public void test_setAllowUserInteractionZ() throws MalformedURLException,
            IOException {

        // Regression for HARMONY-72
        MockURLConnection u = new MockURLConnection(new URL(
                "http://www.apache.org"));
        u.connect();
        try {
            u.setAllowUserInteraction(false);
            fail("Assert 0: expected an IllegalStateException");
        } catch (IllegalStateException e) {
            // expected
        }
    }
    
    static class MockURLConnection extends URLConnection {

        public MockURLConnection(URL url) {
            super(url);
        }

        @Override
        public void connect() {
            connected = true;
        }
    }
    
    static class NewHandler extends URLStreamHandler {
        protected URLConnection openConnection(URL u) throws IOException {
            return new HttpURLConnection(u) {
                @Override
                public void connect() throws IOException {
                    connected = true;
                }

                @Override
                public void disconnect() {
                    // do nothing
                }

                @Override
                public boolean usingProxy() {
                    return false;
                }
            };
        }
    }
    
    class MockCachedResponseCache extends ResponseCache {

        public CacheResponse get(URI arg0, String arg1, Map arg2)
                throws IOException {
            if (null == arg0 || null == arg1 || null == arg2) {
                throw new NullPointerException();
            }
            isGetCalled = true;
            return new MockCacheResponse();
        }

        public CacheRequest put(URI arg0, URLConnection arg1)
                throws IOException {
            if (null == arg0 || null == arg1) {
                throw new NullPointerException();
            }
            isPutCalled = true;
            return new MockCacheRequest();
        }
    }
    
    class MockNonCachedResponseCache extends ResponseCache {

        public CacheResponse get(URI arg0, String arg1, Map arg2)
                throws IOException {
            isGetCalled = true;
            return null;
        }

        public CacheRequest put(URI arg0, URLConnection arg1)
                throws IOException {
            isPutCalled = true;
            return new MockCacheRequest();
        }
    }
    
    class MockCacheRequest extends CacheRequest {

        public OutputStream getBody() throws IOException {
            isCacheWriteCalled = true;
            return new MockOutputStream();
        }

        public void abort() {
            isAbortCalled = true;
        }

    }
    
    class MockInputStream extends InputStream {

        public int read() throws IOException {
            return 4711;
        }

        public int read(byte[] arg0, int arg1, int arg2) throws IOException {
            return 1;
        }

        public int read(byte[] arg0) throws IOException {
            return 1;
        }

    }
    
    class MockOutputStream extends OutputStream {

        public void write(int b) throws IOException {
            isCacheWriteCalled = true;
        }

        public void write(byte[] b, int off, int len) throws IOException {
            isCacheWriteCalled = true;
        }

        public void write(byte[] b) throws IOException {
            isCacheWriteCalled = true;
        }
    }
    
    class MockCacheResponse extends CacheResponse {

        public Map<String, List<String>> getHeaders() throws IOException {
            return mockHeaderMap;
        }

        public InputStream getBody() throws IOException {
            return mockIs;
        }
    }
    

    private static int port;

    static String getContentType(String fileName) throws IOException {
        String resourceName = "org/apache/harmony/luni/tests/" + fileName;
        URL url = ClassLoader.getSystemClassLoader().getResource(resourceName);
        assertNotNull("Cannot find test resource " + resourceName, url);
        return url.openConnection().getContentType();
    }

    URL url;
    
    URL url2;

    URLConnection uc;

    URLConnection uc2;

    Support_TestWebServer server;
    
    @Override
    public void setUp() throws Exception {
        super.setUp();
        
//        ftpURL = new URL(Support_Configuration.testFTPURL);
       
        port = Support_PortManager.getNextPort();
        server = new Support_TestWebServer();
        server.initServer(port, false);
        url = new URL("http://localhost:" + port + "/test1");
        uc = url.openConnection();
        url2 =  new URL("http://localhost:" + port + "/test2");
        uc2 = url2.openConnection();
        
        fileURL = createTempHelloWorldFile();
        fileURLCon = fileURL.openConnection();
        
        jarURLCon = openJarURLConnection();
        jarURL = jarURLCon.getURL();
        
        gifURLCon = openGifURLConnection();
        gifURL = gifURLCon.getURL();
    }

    @Override
    public void tearDown()throws Exception {
        super.tearDown();
        server.close();
        ((HttpURLConnection) uc).disconnect();
        ((HttpURLConnection) uc2).disconnect();
//        if (((FtpURLConnection) ftpURLCon).getInputStream() !=  null) {
//        ((FtpURLConnection) ftpURLCon).getInputStream().close();
//        }
    }

    /**
     * @throws URISyntaxException 
     * @throws ClassNotFoundException 
     * @tests {@link java.net.URLConnection#addRequestProperty(java.lang.String,java.lang.String)}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "From harmony branch.",
        method = "addRequestProperty",
        args = {java.lang.String.class, java.lang.String.class}
    )
    public void test_addRequestPropertyLjava_lang_StringLjava_lang_String()
            throws IOException, ClassNotFoundException, URISyntaxException {
        uc.setRequestProperty("prop", "yo");
        uc.setRequestProperty("prop", "yo2");
        assertEquals("yo2", uc.getRequestProperty("prop"));
        Map<String, List<String>> map = uc.getRequestProperties();
        List<String> props = uc.getRequestProperties().get("prop");
        assertEquals(1, props.size());

        try {
            // the map should be unmodifiable
            map.put("hi", Arrays.asList(new String[] { "bye" }));
            fail("could modify map");
        } catch (UnsupportedOperationException e) {
            // Expected
        }
        try {
            // the list should be unmodifiable
            props.add("hi");
            fail("could modify list");
        } catch (UnsupportedOperationException e) {
            // Expected
        }

        JarURLConnection con1 = openJarURLConnection();
        map = con1.getRequestProperties();
        assertNotNull(map);
        assertEquals(0, map.size());
        try {
            // the map should be unmodifiable
            map.put("hi", Arrays.asList(new String[] { "bye" }));
            fail();
        } catch (UnsupportedOperationException e) {
            // Expected
        }
    }

    public void testHttpPostHeaders() throws IOException {
        String path = "/" + Math.random();
        HttpURLConnection connection = (HttpURLConnection)
                new URL("http://localhost:" + port + path).openConnection();

        // post a request
        connection.setDoOutput(true);
        OutputStreamWriter writer
                = new OutputStreamWriter(connection.getOutputStream());
        writer.write("hello");
        writer.flush();
        assertEquals(200, connection.getResponseCode());

        // validate the request by asking the server what was received
        Map<String, String> headers = server.pathToRequest().get(path).getHeaders();
        assertEquals("*, */*", headers.get("Accept"));
        assertEquals("application/x-www-form-urlencoded", headers.get("Content-Type"));
        assertEquals("5", headers.get("Content-Length"));
        assertEquals("localhost:" + port, headers.get("Host"));
        // TODO: test User-Agent?
    }

    /**
     * @throws IOException 
     * @tests {@link java.net.URLConnection#getAllowUserInteraction()}
     */
    @TestTargets({
        @TestTargetNew(
            level = TestLevel.COMPLETE,
            notes = "From harmony branch.",
            method = "getAllowUserInteraction",
            args = {}
        ),
        @TestTargetNew(
            level = TestLevel.SUFFICIENT,
            notes = "From harmony branch.",
            method = "setAllowUserInteraction",
            args = {boolean.class}
        )
    })
    public void test_getAllowUserInteraction() throws IOException {
        uc.setAllowUserInteraction(false);
        assertFalse("getAllowUserInteraction should have returned false", uc
                .getAllowUserInteraction());

        uc.setAllowUserInteraction(true);
        assertTrue("getAllowUserInteraction should have returned true", uc
                .getAllowUserInteraction());
        
        uc.connect();
        
        try {
            uc.setAllowUserInteraction(false);
            fail("Exception expected");
        } catch (IllegalStateException e) {
            //ok
        }
        
        // test if setAllowUserInteraction works
        URL serverURL = new URL("http://onearth.jpl.nasa.gov/landsat.cgi");
        
        // connect to server
        URLConnection uc2 = serverURL.openConnection();
        HttpURLConnection conn = (HttpURLConnection) uc2;
        uc2.setAllowUserInteraction(true);
  
        uc2.setDoInput(true);
        uc2.setDoOutput(true);
        
        // get reference to stream to post to
        OutputStream os = uc2.getOutputStream();
        
        InputStream in = uc2.getInputStream();
        
        
        int contentLength = uc2.getContentLength();
        String contentType = uc2.getContentType();
        int numBytesRead = 0;
        int allBytesRead = 0;

        byte[] buffer = new byte[4096];
        
        do {
            
        numBytesRead = in.read(buffer);
        allBytesRead += allBytesRead + numBytesRead;
        
        } while (numBytesRead > 0);
        
        assertTrue(allBytesRead > 0);
       
        uc2.connect();
        
        numBytesRead = in.read(buffer);
        
        assertEquals(-1, numBytesRead);
    }
    
    /**
     * @throws IOException 
     * @tests {@link java.net.URLConnection#connect()}
     */
    @TestTargetNew(
      level = TestLevel.COMPLETE,
      notes = "",
      method = "connect",
      args = {}
    )
    public void test_connect() throws IOException {
       
        uc.connect();
        ((HttpURLConnection) uc).disconnect();
        uc.connect();
        
        try {
            uc.setDoOutput(false);
        } catch (Exception e) {
            // ok
        }
    }

    /**
     * @tests {@link java.net.URLConnection#getContent()}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "From harmony branch.",
        method = "getContent",
        args = {}
    )
    public void test_getContent() throws IOException {
        byte[] ba = new byte[testString.getBytes().length];
        String buf = null;
        
        Object obj = fileURLCon.getContent();
        if (obj instanceof String) { 
            buf = (String) obj;
            assertTrue("Incorrect content returned from fileURL: "+buf,
                    testString.equals(buf.trim()));
        } else if (obj instanceof InputStream) {
            InputStream i = (InputStream) obj;
            BufferedReader r = new BufferedReader(new InputStreamReader(i),testString.getBytes().length);
            buf = r.readLine();
            assertTrue("Incorrect content returned from fileURL: "+buf,
                    testString.equals(buf.trim()));
        } else {
            fail("Some unkown type is returned "+obj.toString());
        }
        
        //Exception test
        URL url = new URL("http://a/b/c/?y");
        URLConnection fakeCon = url.openConnection();
        try {
        fakeCon.getContent();
        } catch (IOException e) {
            //ok
        }
        
        ((HttpURLConnection) uc).disconnect();
        try {
            uc.getContent();
        } catch (IOException e) {
            //ok
        }
        
    }

    /**
     * @tests {@link java.net.URLConnection#getContent(Class[])}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "From harmony branch.",
        method = "getContent",
        args = {java.lang.Class[].class}
    )
    public void test_getContent_LjavalangClass() throws IOException {
        byte[] ba = new byte[600];
        
        fileURLCon.setDoInput(true);
        fileURLCon.connect();
        
        InputStream  helloWorld2 = (InputStream) fileURLCon.getContent(new Class[] {InputStream.class});
        assertNotNull(helloWorld2);
        BufferedReader r = new BufferedReader(new InputStreamReader(helloWorld2),testString.getBytes().length);
        assertTrue("Incorrect content returned from fileURL",
                testString.equals(r.readLine().trim()));
        
        String test = (String) fileURLCon.getContent(new Class[] {String.class} );
        assertNull(test);
        
        //Exception test
        ((HttpURLConnection) uc).disconnect();
        try {
            uc.getContent();
        } catch (IOException e) {
            //ok
        }

        try {
            ((InputStream) fileURLCon.getContent(null)).read(ba, 0, 600);
            fail("should throw NullPointerException");
        } catch (NullPointerException e) {
            // expected
        }

        try {
            ((InputStream) fileURLCon.getContent(new Class[] {})).read(ba, 0, 600);
            fail("should throw NullPointerException");
        } catch (NullPointerException e) {
            // expected
        }

        try {
            ((InputStream) fileURLCon.getContent(new Class[] { Class.class })).read(ba,
                    0, 600);
            fail("should throw NullPointerException");
        } catch (NullPointerException e) {
            // expected
        }
    }

    /**
     * @throws IOException 
     * @tests {@link java.net.URLConnection#getContentEncoding()}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "",
        method = "getContentEncoding",
        args = {}
    )
    @BrokenTest("Fails in CTS, passes in CoreTestRunner")
    public void test_getContentEncoding() throws IOException {
        // faulty setup
        try {
        
        fileURLCon.getContentEncoding();
        fail("Exception expected");
        } catch (Throwable e) {
            //ok
        }
        
        // positive case
        
        URL url = new URL("http://www.amazon.com/");
        
        URLConnection con = url.openConnection();
        con.setRequestProperty("Accept-Encoding", "gzip");
        con.connect();
        
        assertEquals(con.getContentEncoding(), "gzip");
        
        
        uc2.setRequestProperty("Accept-Encoding", "bla");
        uc2.connect();
        
        assertNull(uc2.getContentEncoding());
        
    }

    /**
     * @tests {@link java.net.URLConnection#getContentLength()}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "",
        method = "getContentLength",
        args = {}
    )
    public void test_getContentLength() {
        assertEquals(testString.getBytes().length,
                fileURLCon.getContentLength());
        assertEquals(Support_TestWebData.test1.length, uc.getContentLength());
        assertEquals(Support_TestWebData.test2.length, uc2.getContentLength());
        
        assertNotNull(jarURLCon.getContentLength());
        assertNotNull(gifURLCon.getContentLength());
    }

    /**
     * @tests {@link java.net.URLConnection#getContentType()}
     */
    @TestTargetNew(
        level = TestLevel.SUFFICIENT,
        notes = "only default encoding may be tested",
        method = "getContentType",
        args = {}
    )
    public void test_getContentType() throws IOException, MalformedURLException {
        
        assertTrue("getContentType failed: " + fileURLCon.getContentType(),
                fileURLCon.getContentType().contains("text/plain"));
        
        URLConnection htmlFileCon = openHTMLFile();
        String contentType = htmlFileCon.getContentType();
        if (contentType != null) {
            assertTrue(contentType.equalsIgnoreCase("text/html"));
        }
        
        
        /*
        contentType = uc.getContentType();
        if (contentType != null) {
        assertTrue(contentType.equalsIgnoreCase("text/html"));
        }

        contentType = gifURLCon.getContentType();
        if (contentType != null) {
        assertTrue(contentType.equalsIgnoreCase("image/gif"));
        }
        */
        
    }

    /**
     * @tests {@link java.net.URLConnection#getDate()}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "From harmony branch. URLConnection.getDate crashes in cases " +
                "where the returned expiration date doesn't seems to be " +
                "parsable. The RI just returns 0.",
        method = "getDate",
        args = {}
    )
    public void test_getDate() {
        // should be greater than 930000000000L which represents the past
        assertTrue("getDate gave wrong date: " + uc.getDate(),
                    uc.getDate() > 930000000000L);
    }

    /**
     * @throws IOException 
     * @tests {@link java.net.URLConnection#getDefaultAllowUserInteraction()}
     */
    @TestTargets({
        @TestTargetNew(
            level = TestLevel.COMPLETE,
            notes = "From harmony branch.",
            method = "getDefaultAllowUserInteraction",
            args = {}
        ),
        @TestTargetNew(
            level = TestLevel.COMPLETE,
            notes = "From harmony branch.",
            method = "setDefaultAllowUserInteraction",
            args = {boolean.class}
        )
    })
    public void test_getDefaultAllowUserInteraction() throws IOException {
        boolean oldSetting = URLConnection.getDefaultAllowUserInteraction();

        URLConnection.setDefaultAllowUserInteraction(false);
        assertFalse(
                "getDefaultAllowUserInteraction should have returned false",
                URLConnection.getDefaultAllowUserInteraction());

        URLConnection.setDefaultAllowUserInteraction(true);
        assertTrue("getDefaultAllowUserInteraction should have returned true",
                URLConnection.getDefaultAllowUserInteraction());

        URLConnection.setDefaultAllowUserInteraction(oldSetting);
    }

    /**
     * @tests {@link java.net.URLConnection#getDefaultRequestProperty(String)}
     */
    @TestTargets({
        @TestTargetNew(
            level = TestLevel.COMPLETE,
            notes = "From harmony branch.",
            method = "getDefaultRequestProperty",
            args = {java.lang.String.class}
        ),
        @TestTargetNew(
            level = TestLevel.COMPLETE,
            notes = "From harmony branch.",
            method = "setDefaultRequestProperty",
            args = {java.lang.String.class, java.lang.String.class}
        )
    })
    @SuppressWarnings("deprecation")
    public void test_getDefaultRequestPropertyLjava_lang_String() {
        URLConnection.setDefaultRequestProperty("Shmoo", "Blah");
        assertNull("setDefaultRequestProperty should have returned: null",
                URLConnection.getDefaultRequestProperty("Shmoo"));

        URLConnection.setDefaultRequestProperty("Shmoo", "Boom");
        assertNull("setDefaultRequestProperty should have returned: null",
                URLConnection.getDefaultRequestProperty("Shmoo"));

        assertNull("setDefaultRequestProperty should have returned: null",
                URLConnection.getDefaultRequestProperty("Kapow"));

        URLConnection.setDefaultRequestProperty("Shmoo", null);
    }

    /**
     * @throws IOException 
     * @tests {@link  java.net.URLConnection#getDefaultUseCaches()}
     */
    @TestTargets({
        @TestTargetNew(
            level = TestLevel.COMPLETE,
            notes = "From harmony branch.",
            method = "getDefaultUseCaches",
            args = {}
        ),
        @TestTargetNew(
            level = TestLevel.COMPLETE,
            notes = "From harmony branch.",
            method = "setDefaultUseCaches",
            args = {boolean.class}
        )
    })
    public void test_getDefaultUseCaches_CachedRC() throws IOException {
        boolean oldSetting = uc.getDefaultUseCaches();
        
        ResponseCache old = ResponseCache.getDefault();
        ResponseCache rc = new MockCachedResponseCache();
        ResponseCache.setDefault(rc);
        
        // Recreate the connection so that we get the cache from ResponseCache.
        uc2 = url2.openConnection();
        
        uc2.setUseCaches(true);
        
        uc.setDefaultUseCaches(false);

        // uc unaffected
        assertTrue(uc.getUseCaches());
        // uc2 unaffected
        assertTrue(uc2.getUseCaches());
        
        //test get
        assertFalse("getDefaultUseCaches should have returned false", uc
                .getDefaultUseCaches());
        
        // subsequent connections should have default value
        URL url3 =  new URL("http://localhost:" + port + "/test2");
        URLConnection uc3 = url3.openConnection();
        assertFalse(uc3.getUseCaches());
        
        // test if uc does not cache but uc2 does
        isGetCalled = false;
        isPutCalled = false;
        
        // test uc
        uc.setDoOutput(true);
        assertFalse(isGetCalled);
        uc.connect();
        assertFalse(isGetCalled);
        assertFalse(isPutCalled);
        OutputStream os = uc.getOutputStream();
        assertFalse(isPutCalled);
        assertFalse(isGetCalled);
        
        os.close();
        
        //uc2 should be unaffected
        uc2.setDoOutput(true);
        assertFalse(isGetCalled);
        uc2.connect();
        assertTrue(isGetCalled);
        assertFalse(isPutCalled);

        uc.setDefaultUseCaches(oldSetting);
        ResponseCache.setDefault(null);
    }

    /**
     * @throws IOException 
     * @tests {@link java.net.URLConnection#getDoInput()}
     */
    @TestTargets({
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "From harmony branch.",
        method = "getDoInput",
        args = {}
    ),
    @TestTargetNew(
            level = TestLevel.COMPLETE,
            notes = "From harmony branch.",
            method = "setDoInput",
            args = {boolean.class}
        )
    })
    public void test_getDoInput() throws IOException {
        assertTrue("Should be set to true by default", uc.getDoInput());

        fileURLCon.setDoInput(true);
        assertTrue("Should have been set to true", fileURLCon.getDoInput());

        uc2.setDoInput(false);
        assertFalse("Should have been set to false", uc2.getDoInput());

        fileURLCon.connect();
        fileURLCon.getInputStream();
        
        uc2.connect();
        try {
            uc2.getInputStream();
        } catch (Throwable e) {
            // ok
        }

    }

    /**
     * @throws IOException 
     * @tests {@link java.net.URLConnection#getDoOutput()}
     */
    @TestTargets({
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "From harmony branch.",
        method = "getDoOutput",
        args = {}
    ),
    @TestTargetNew(
            level = TestLevel.COMPLETE,
            notes = "From harmony branch.",
            method = "setDoOutput",
            args = {boolean.class}
        )
    })
    public void test_getDoOutput() throws IOException {
        assertFalse("Should be set to false by default", uc.getDoOutput());

        uc.setDoOutput(true);
        assertTrue("Should have been set to true", uc.getDoOutput());
        
        uc.connect();
        uc.getOutputStream();

        uc2.setDoOutput(false);
        assertFalse("Should have been set to false", uc2.getDoOutput());
        uc2.connect();
        
        try{
            uc2.getOutputStream();
        } catch (Throwable e) {
            //ok
        }
    }

    /**
     * @throws IOException 
     * @tests {@link java.net.URLConnection#getExpiration()}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "From harmony branch. URLConnection.getExpiration crashes in " +
                "cases where the returned expiration date doesn't seems to " +
                "be parsable. The RI just returns 0.",
        method = "getExpiration",
        args = {}
    )
    public void test_getExpiration() throws IOException {
        
        uc.connect();
        // should be unknown
        assertEquals("getExpiration returned wrong expiration", 0, uc
                .getExpiration());
        
        uc2.connect();
        assertTrue("getExpiration returned wrong expiration: " + uc2
                .getExpiration(), uc2.getExpiration() > 0);
    }

    /**
     * @tests {@link java.net.URLConnection#getFileNameMap()}
     */
    @TestTargetNew(
        level = TestLevel.PARTIAL,
        notes = "From harmony branch.",
        method = "getFileNameMap",
        args = {}
    )
    public void test_getFileNameMap() {
        // Tests for the standard MIME types -- users may override these
        // in their JRE
        
        FileNameMap mapOld = URLConnection.getFileNameMap();
        
        try {
        // These types are defaulted
        assertEquals("text/html", mapOld.getContentTypeFor(".htm"));
        assertEquals("text/html", mapOld.getContentTypeFor(".html"));
        assertEquals("text/plain", mapOld.getContentTypeFor(".text"));
        assertEquals("text/plain", mapOld.getContentTypeFor(".txt"));

        // These types come from the properties file :
        // not black-box testing. Special tests moved to setContentType
        /*
        assertEquals("application/pdf", map.getContentTypeFor(".pdf"));
        assertEquals("application/zip", map.getContentTypeFor(".zip"));
        assertEquals("image/gif", map.getContentTypeFor("gif"));
        */

        URLConnection.setFileNameMap(new FileNameMap() {
            public String getContentTypeFor(String fileName) {
                return "Spam!";
            }
        });
       
            assertEquals("Incorrect FileNameMap returned", "Spam!",
                    URLConnection.getFileNameMap().getContentTypeFor(null));
        } finally {
            // unset the map so other tests don't fail
            URLConnection.setFileNameMap(mapOld);
        }
        // RI fails since it does not support fileName that does not begin with
        // '.'
        
    }

    /**
     * @tests {@link java.net.URLConnection#getHeaderFieldDate(java.lang.String, long)}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "",
        method = "getHeaderFieldDate",
        args = {java.lang.String.class, long.class}
    )
    public void test_getHeaderFieldDateLjava_lang_StringJ() {
        Support_TestWebData params = Support_TestWebData.testParams[0];

        long hf;
        hf = uc.getHeaderFieldDate("Content-Encoding", Long.MIN_VALUE);
        assertEquals("Long value returned for header field 'Content-Encoding':",
                Long.MIN_VALUE, hf);
        hf = uc.getHeaderFieldDate("Content-Length", Long.MIN_VALUE);
        assertEquals("Long value returned for header field 'Content-Length': ",
                Long.MIN_VALUE, hf);
        hf = uc.getHeaderFieldDate("Content-Type", Long.MIN_VALUE);
        assertEquals("Long value returned for header field 'Content-Type': ",
                Long.MIN_VALUE, hf);
        hf = uc.getHeaderFieldDate("content-type", Long.MIN_VALUE);
        assertEquals("Long value returned for header field 'content-type': ",
                Long.MIN_VALUE, hf);
        hf = uc.getHeaderFieldDate("Date", Long.MIN_VALUE);
        assertTrue("Wrong value returned for header field 'Date': " + hf,
                new Date().getTime() - hf < 5000);
        hf = uc.getHeaderFieldDate("SERVER", Long.MIN_VALUE);
        assertEquals("Long value returned for header field 'SERVER': ",
                Long.MIN_VALUE, hf);
        hf = uc.getHeaderFieldDate("Last-Modified", Long.MIN_VALUE);
        assertEquals("Long value returned for header field 'Last-Modified': ",
                Long.MIN_VALUE, hf);
    }

    /**
     * @tests {@link java.net.URLConnection#getHeaderField(int)}
     */
    @TestTargetNew(
        level = TestLevel.NOT_NECESSARY,
        notes = "not supported. Always returns null.From harmony branch.",
        method = "getHeaderField",
        args = {int.class}
    )
    public void DISABLED_test_getHeaderFieldI() {
        int i = 0;
        String hf;
        boolean foundResponse = false;
        while ((hf = uc.getHeaderField(i++)) != null) {
            if (hf.equals(Support_Configuration.HomeAddressSoftware)) {
                foundResponse = true;
            }
        }
        assertTrue("Could not find header field containing \""
                + Support_Configuration.HomeAddressSoftware + "\"",
                foundResponse);

        i = 0;
        foundResponse = false;
        while ((hf = uc.getHeaderField(i++)) != null) {
            if (hf.equals(Support_Configuration.HomeAddressResponse)) {
                foundResponse = true;
            }
        }
        assertTrue("Could not find header field containing \""
                + Support_Configuration.HomeAddressResponse + "\"",
                foundResponse);
    }

    /**
     * @tests {@link java.net.URLConnection#getHeaderFieldKey(int)}
     */
    @TestTargetNew(
        level = TestLevel.NOT_NECESSARY,
        notes = "Not supported. Current implementation returns always null according to spec.",
        method = "getHeaderFieldKey",
        args = {int.class}
    )
    public void DISABLED_test_getHeaderFieldKeyI() {
        String hf;
        boolean foundResponse = false;
        for (int i = 0; i < 100; i++) {
            hf = uc.getHeaderFieldKey(i);
            if (hf != null && hf.toLowerCase().equals("content-type")) {
                foundResponse = true;
                break;
            }
        }
        assertTrue(
                "Could not find header field key containing \"content-type\"",
                foundResponse);
    }
    
    /**
     * @throws IOException 
     * @tests {@link java.net.URLConnection#getHeaderFieldInt(String, int)}
     */
    @TestTargetNew(
        level = TestLevel.SUFFICIENT,
        notes = "",
        method = "getHeaderFieldInt",
        args = {java.lang.String.class, int.class}
    )
    public void test_getHeaderFieldInt() throws IOException, ParseException {
        Support_TestWebData params = Support_TestWebData.testParams[1];

        int hf = 0;
        hf = uc2.getHeaderFieldInt("Content-Encoding", Integer.MIN_VALUE);
        assertEquals(Integer.MIN_VALUE, hf);
        hf = uc2.getHeaderFieldInt("Content-Length", Integer.MIN_VALUE);
        assertEquals(params.testLength, hf);
        hf = uc2.getHeaderFieldInt("Content-Type", Integer.MIN_VALUE);
        assertEquals(Integer.MIN_VALUE, hf);
        hf = uc2.getHeaderFieldInt("Date", Integer.MIN_VALUE);
        assertEquals(Integer.MIN_VALUE, hf);
        hf = uc2.getHeaderFieldInt("Expires", Integer.MIN_VALUE);
        assertEquals(Integer.MIN_VALUE, hf);
        hf = uc2.getHeaderFieldInt("SERVER", Integer.MIN_VALUE);
        assertEquals(Integer.MIN_VALUE, hf);
        hf = uc2.getHeaderFieldInt("Last-Modified", Integer.MIN_VALUE);
        assertEquals(Integer.MIN_VALUE, hf);
        hf = uc2.getHeaderFieldInt("accept-ranges", Integer.MIN_VALUE);
        assertEquals(Integer.MIN_VALUE, hf);
        hf = uc2.getHeaderFieldInt("DoesNotExist", Integer.MIN_VALUE);
        assertEquals(Integer.MIN_VALUE, hf);
        
    }

    /**
     * @tests {@link java.net.URLConnection#getHeaderField(java.lang.String)}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "",
        method = "getHeaderField",
        args = {java.lang.String.class}
    )
    public void test_getHeaderFieldLjava_lang_String() {
        Support_TestWebData params = Support_TestWebData.testParams[0];

        String hf;
        hf = uc.getHeaderField("Content-Encoding");
        assertNull("String value returned for header field 'Content-Encoding':",
                hf);
        hf = uc.getHeaderField("Content-Length");
        assertEquals("Wrong value returned for header field 'Content-Length': ",
                String.valueOf(params.testLength), hf);
        hf = uc.getHeaderField("Content-Type");
        assertEquals("Wrong value returned for header field 'Content-Type': ",
                params.testType, hf);
        hf = uc.getHeaderField("content-type");
        assertEquals("Wrong value returned for header field 'content-type': ",
                params.testType, hf);
        hf = uc.getHeaderField("Date");
        assertTrue("Wrong string value returned for header field 'Date': "
                + hf, hf.length() > 20);
        hf = uc.getHeaderField("SERVER");
        assertEquals("Wrong value returned for header field 'SERVER': ",
                "TestWebServer" + port, hf);
        hf = uc.getHeaderField("Last-Modified");
        assertNull("Wrong string value returned for 'Last-Modified': "
                + hf, hf);
    }

    /**
     * @throws URISyntaxException 
     * @throws ClassNotFoundException 
     * @tests {@link java.net.URLConnection#getHeaderFields()}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "",
        method = "getHeaderFields",
        args = {}
    )
    public void test_getHeaderFields() throws IOException, ClassNotFoundException, URISyntaxException {
        Support_TestWebData params = Support_TestWebData.testParams[1];

        try {
            uc2.getInputStream();
        } catch (IOException e) {
            fail("Error in test setup: "+e.getMessage());
        }

        Map<String, List<String>> headers = uc2.getHeaderFields();
        assertNotNull(headers);

        List<String> list = headers.get("content-type");
        if (list == null) {
            list = headers.get("Content-Type");
        }
        if (list == null) {
            list = headers.get("Content-type");
        }

        assertNotNull(list);
        String contentType = (String) list.get(0);
        assertEquals(params.testType, contentType);

        // there should be at least 2 headers
        assertTrue("Not more than one header in URL connection",
                headers.size() > 1);
        
        headers = jarURLCon.getHeaderFields();
        assertNotNull(headers);
        assertEquals(0, headers.size());

        try {
            // the map should be unmodifiable
            headers.put("hi", Arrays.asList(new String[] { "bye" }));
            fail("The map should be unmodifiable");
        } catch (UnsupportedOperationException e) {
            // Expected
        }
    }
    
    /**
     * @throws IOException 
     * @tests {@link java.net.URLConnection#getLastModified()}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "From harmony branch.",
        method = "getLastModified",
        args = {}
    )
    public void test_getLastModified() throws IOException {
        
        URL url4 = new URL(Support_Configuration.hTTPURLwLastModified);
        URLConnection uc4 = url4.openConnection();
        
        uc4.connect();
        
        if (uc4.getLastModified() == 0) {
            System.out
                    .println("WARNING: Server does not support 'Last-Modified', test_getLastModified() not run");
            return;
        }
        
        long millis = uc4.getHeaderFieldDate("Last-Modified", 0);
        
        assertEquals(
                "Returned wrong getLastModified value.  Wanted: "
                        + " got: " + uc4.getLastModified(),
                millis, uc4.getLastModified());
        
        
        ((HttpURLConnection) uc).disconnect();
    }
    
    @TestTargetNew(
      level = TestLevel.COMPLETE,
      notes = "",
      method = "getOutputStream",
      args = {}
    )
    public void test_getOutputStream() throws IOException {
        String posted = "this is a test";
        URLConnection uc3 = new URL(Support_Configuration.hTTPURLgoogle)
                .openConnection();
        uc3.setDoOutput(true);
        uc3.connect();

        BufferedWriter w = new BufferedWriter(new OutputStreamWriter(uc3
                .getOutputStream()), posted.getBytes().length);

        w.write(posted);
        w.flush();
        w.close();

        int code = ((HttpURLConnection) uc3).getResponseCode();


        // writing to url not allowed
        assertEquals("Got different responseCode ", 405, code);


        // try exception testing
        try {
            fileURLCon.setDoOutput(true);
            fileURLCon.connect();
            fileURLCon.getOutputStream();
        } catch (UnknownServiceException e) {
            // ok cannot write to fileURL
        }

        ((HttpURLConnection) uc2).disconnect();

        try {
            uc2.getOutputStream();
            fail("Exception expected");
        } catch (IOException e) {
            // ok
        }
    }

    /**
     * @tests {@link java.net.URLConnection#getPermission()}
     */
    @TestTargetNew(
        level = TestLevel.SUFFICIENT,
        notes = "From harmony branch.",
        method = "getPermission",
        args = {}
    )
    public void test_getPermission() throws Exception {
        java.security.Permission p = uc.getPermission();
        assertTrue("Permission of wrong type: " + p.toString(),
                p instanceof java.net.SocketPermission);
        assertTrue("Permission has wrong name: " + p.getName(), p.getName()
                .contains("localhost:" + port));

        URL fileUrl = new URL("file:myfile");
        Permission perm = new FilePermission("myfile", "read");
        Permission result = fileUrl.openConnection().getPermission();
        assertTrue("Wrong file: permission 1:" + perm + " , " + result, result
                .equals(perm));

        fileUrl = new URL("file:/myfile/");
        perm = new FilePermission("/myfile", "read");
        result = fileUrl.openConnection().getPermission();
        assertTrue("Wrong file: permission 2:" + perm + " , " + result, result
                .equals(perm));

        fileUrl = new URL("file:///host/volume/file");
        perm = new FilePermission("/host/volume/file", "read");
        result = fileUrl.openConnection().getPermission();
        assertTrue("Wrong file: permission 3:" + perm + " , " + result, result
                .equals(perm));

        URL httpUrl = new URL("http://home/myfile/");
        assertTrue("Wrong http: permission", httpUrl.openConnection()
                .getPermission().equals(
                        new SocketPermission("home:80", "connect")));
        httpUrl = new URL("http://home2:8080/myfile/");
        assertTrue("Wrong http: permission", httpUrl.openConnection()
                .getPermission().equals(
                        new SocketPermission("home2:8080", "connect")));
        URL ftpUrl = new URL("ftp://home/myfile/");
        assertTrue("Wrong ftp: permission", ftpUrl.openConnection()
                .getPermission().equals(
                        new SocketPermission("home:21", "connect")));
        ftpUrl = new URL("ftp://home2:22/myfile/");
        assertTrue("Wrong ftp: permission", ftpUrl.openConnection()
                .getPermission().equals(
                        new SocketPermission("home2:22", "connect")));

        URL jarUrl = new URL("jar:file:myfile!/");
        perm = new FilePermission("myfile", "read");
        result = jarUrl.openConnection().getPermission();
        assertTrue("Wrong jar: permission:" + perm + " , " + result, result
                .equals(new FilePermission("myfile", "read")));
    }

    /**
     * @tests {@link java.net.URLConnection#getRequestProperties()}
     */
    @TestTargetNew(
        level = TestLevel.PARTIAL_COMPLETE,
        notes = "implementation test.From harmony branch.",
        method = "getRequestProperties",
        args = {}
    )
    public void test_getRequestProperties() {
        uc.setRequestProperty("whatever", "you like");
        Map headers = uc.getRequestProperties();

        // content-length should always appear
        List header = (List) headers.get("whatever");
        assertNotNull(header);

        assertEquals("you like", header.get(0));

        assertTrue(headers.size() >= 1);

        try {
            // the map should be unmodifiable
            headers.put("hi", "bye");
            fail();
        } catch (UnsupportedOperationException e) {
        }
        try {
            // the list should be unmodifiable
            header.add("hi");
            fail();
        } catch (UnsupportedOperationException e) {
        }

    }

    /**
     * @tests {@link java.net.URLConnection#getRequestProperties()}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "Exceptions checked only.From harmony branch.",
        method = "getRequestProperties",
        args = {}
    )
    public void test_getRequestProperties_Exception() throws IOException {
        URL url = new URL("http", "test", 80, "index.html", new NewHandler());
        URLConnection urlCon = url.openConnection();
        urlCon.connect();

        try {
            urlCon.getRequestProperties();
            fail("should throw IllegalStateException");
        } catch (IllegalStateException e) {
            // expected
        }
        
    }

    /**
     * @tests {@link java.net.URLConnection#getRequestProperty(java.lang.String)}
     */
    @TestTargetNew(
        level = TestLevel.PARTIAL_COMPLETE,
        notes = "Exceptions checked only.From harmony branch.",
        method = "getRequestProperty",
        args = { String.class }
    )
    public void test_getRequestProperty_LString_Exception() throws IOException {
        URL url = new URL("http", "test", 80, "index.html", new NewHandler());
        URLConnection urlCon = url.openConnection();
        urlCon.setRequestProperty("test", "testProperty");
        assertNull(urlCon.getRequestProperty("test"));

        urlCon.connect();
        try {
            urlCon.getRequestProperty("test");
            fail("should throw IllegalStateException");
        } catch (IllegalStateException e) {
            // expected
        }
    }

    /**
     * @tests {@link java.net.URLConnection#getRequestProperty(java.lang.String)}
     */
    @TestTargetNew(
        level = TestLevel.PARTIAL_COMPLETE,
        notes = "From harmony branch.",
        method = "getRequestProperty",
        args = {java.lang.String.class}
    )
    public void test_getRequestPropertyLjava_lang_String() {
        uc.setRequestProperty("Yo", "yo");
        assertTrue("Wrong property returned: " + uc.getRequestProperty("Yo"),
                uc.getRequestProperty("Yo").equals("yo"));
        assertNull("Wrong property returned: " + uc.getRequestProperty("No"),
                uc.getRequestProperty("No"));
    }

    /**
     * @tests {@link java.net.URLConnection#getURL()}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "Exceptions checked only -> only partially implemented. From harmony branch.",
        method = "getURL",
        args = {}
    )
    public void test_getURL() {
        assertTrue("Incorrect URL returned", uc.getURL().equals(url));
    }

    /**
     * @throws IOException 
     * @tests {@link java.net.URLConnection#getUseCaches()}
     */
    @TestTargets({
        @TestTargetNew(
            level = TestLevel.COMPLETE,
            notes = "Exceptions checked in setUseCaches. From harmony branch.",
            method = "getUseCaches",
            args = {}
        ),
        @TestTargetNew(
            level = TestLevel.PARTIAL_COMPLETE,
            notes = "Exceptions checked in setUseCaches. From harmony branch.",
            method = "setUseCaches",
            args = {boolean.class}
        )
    })
    public void test_getUseCaches() throws IOException {
        uc2.setUseCaches(false);
        assertTrue("getUseCaches should have returned false", !uc2
                .getUseCaches());
        uc2.setUseCaches(true);
        assertTrue("getUseCaches should have returned true", uc2.getUseCaches());
        
        uc2.connect();
        
        
        try {
        uc2.setUseCaches(false);
        fail("Exception expected");
        } catch (IllegalStateException e) {
            //ok
        }
        
        ((HttpURLConnection) uc2).disconnect();
        
    }
    
    /**
     * @tests {@link java.net.URLConnection#guessContentTypeFromName(String)}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "",
        method = "guessContentTypeFromName",
        args = {java.lang.String.class}
    )
    public void test_guessContentTypeFromName()
            throws IOException {
        
        URLConnection htmlFileCon = openHTMLFile();
        String[] expected = new String[] {"text/html",
                "text/plain" };
        String[] resources = new String[] { 
                htmlFileCon.getURL().toString(),
                fileURL.toString()
                };
        for (int i = 0; i < resources.length; i++) {
                String mime = URLConnection.guessContentTypeFromName( resources[i]);
                assertEquals("checking " + resources[i] + " expected " + expected[i]+"got " + expected[i],
                expected[i], mime);
        }

        // Try simple case
        try {
            URLConnection.guessContentTypeFromStream(null);
            fail("should throw NullPointerException");
        } catch (NullPointerException e) {
            // expected
        }
    }

    /**
     * @tests {@link java.net.URLConnection#guessContentTypeFromStream(java.io.InputStream)}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "",
        method = "guessContentTypeFromStream",
        args = {java.io.InputStream.class}
    )
    public void test_guessContentTypeFromStreamLjava_io_InputStream()
            throws IOException {
        assertContentTypeEquals("ASCII", "text/html", "<html>");
        assertContentTypeEquals("ASCII", "text/html", "<head>");
        assertContentTypeEquals("ASCII", "text/html", "<head ");
        assertContentTypeEquals("ASCII", "text/html", "<body");
        assertContentTypeEquals("ASCII", "text/html", "<BODY ");
        assertContentTypeEquals("ASCII", "application/xml", "<?xml ");

        assertContentTypeEquals("UTF-8", "text/html", "<html>");
        assertContentTypeEquals("UTF-8", "text/html", "<head>");
        assertContentTypeEquals("UTF-8", "text/html", "<head ");
        assertContentTypeEquals("UTF-8", "text/html", "<body");
        assertContentTypeEquals("UTF-8", "text/html", "<BODY ");
        assertContentTypeEquals("UTF-8", "application/xml", "<?xml ");
        
        //"UTF-16BE", "UTF-16LE", "UTF-32BE" and
        //"UTF-32LE" are not supported

        // Try simple case
        try {
            URLConnection.guessContentTypeFromStream(null);
            fail("should throw NullPointerException");
        } catch (NullPointerException e) {
            // expected
        }
        /* not supported
        // Test magic bytes
        byte[][] bytes = new byte[][] { { 'P', 'K' }, { 'G', 'I' } };
        expected = new String[] { "application/zip", "image/gif" };

        for (int i = 0; i < bytes.length; i++) {
            InputStream is = new ByteArrayInputStream(bytes[i]);
            assertEquals(expected[i], URLConnection
                    .guessContentTypeFromStream(is));
        }
        */
    }

    void assertContentTypeEquals(String encoding, String expected,
            String header) throws IOException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        String encodedString = new String(header.getBytes(), encoding);
        InputStream is = new ByteArrayInputStream(encodedString.getBytes());
        String mime = URLConnection.guessContentTypeFromStream(is);
        assertEquals("checking '" + header + "' with " + encoding,
                expected, mime);
    }

    /**
     * @tests {@link java.net.URLConnection#setConnectTimeout(int)}
     */
    @TestTargets({
        @TestTargetNew(
            level = TestLevel.COMPLETE,
            notes = "",
            method = "setConnectTimeout",
            args = {int.class}
        ),
        @TestTargetNew(
            level = TestLevel.COMPLETE,
            notes = "",
            method = "getConnectTimeout",
            args = {}
        )
    })
    public void test_setConnectTimeoutI() throws Exception {
        URLConnection uc = new URL("http://localhost").openConnection();
        assertEquals(0, uc.getConnectTimeout());
        uc.setConnectTimeout(0);
        assertEquals(0, uc.getConnectTimeout());
        try {
            uc.setConnectTimeout(-100);
            fail("should throw IllegalArgumentException");
        } catch (IllegalArgumentException e) {
            // correct
        }
        assertEquals(0, uc.getConnectTimeout());
        uc.setConnectTimeout(100);
        assertEquals(100, uc.getConnectTimeout());
        try {
            uc.setConnectTimeout(-1);
            fail("should throw IllegalArgumentException");
        } catch (IllegalArgumentException e) {
            // correct
        }
        assertEquals(100, uc.getConnectTimeout());
        
        uc2.setConnectTimeout(2);
        
        try {
        uc2.connect();
        } catch (SocketTimeoutException e) {
            //ok
        }
        
    }

    /**
     * @throws IOException
     * @tests {@link java.net.URLConnection#setFileNameMap(java.net.FileNameMap)}
     */
    @TestTargets({
        @TestTargetNew(
            level = TestLevel.COMPLETE,
            notes = "",
            method = "setFileNameMap",
            args = {java.net.FileNameMap.class}
        ),
        @TestTargetNew(
            level = TestLevel.COMPLETE,
            notes = "",
            method = "getFileNameMap",
            args = {}
        )
    })
    public void test_setFileNameMapLjava_net_FileNameMap() throws IOException {
        FileNameMap mapOld = URLConnection.getFileNameMap();
        // nothing happens if set null
        URLConnection.setFileNameMap(null);
        // take no effect
        assertNotNull(URLConnection.getFileNameMap());
        
        try {
        URLConnection.setFileNameMap(new java.net.FileNameMap(){
                        public String getContentTypeFor(String fileName) {
                           if (fileName==null || fileName.length()<1)
                      return null;
                    String name=fileName.toLowerCase();
                    String type=null;
                    if (name.endsWith(".xml"))
                      type="text/xml";
                    else if (name.endsWith(".dtd"))
                      type="text/dtd";
                    else if (name.endsWith(".pdf"))
                        type = "application/pdf";
                    else if (name.endsWith(".zip"))
                        type = "application/zip";
                    else if (name.endsWith(".gif"))
                        type = "image/gif";
                    else 
                      type="application/unknown";
                    return type;
                         }
              });
        FileNameMap mapNew = URLConnection.getFileNameMap();
        assertEquals("application/pdf", mapNew.getContentTypeFor(".pdf"));
        assertEquals("application/zip", mapNew.getContentTypeFor(".zip"));
        assertEquals("image/gif", mapNew.getContentTypeFor(".gif"));
        } finally {
    
        URLConnection.setFileNameMap(mapOld); 
        }
    }

    /**
     * @tests {@link java.net.URLConnection#setIfModifiedSince(long)}
     */
    @TestTargets ( {
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "",
        method = "setIfModifiedSince",
        args = {long.class}
    ),
    @TestTargetNew(
        level = TestLevel.PARTIAL_COMPLETE,
        notes = "From harmony branch.",
        method = "getIfModifiedSince",
        args = {}
        )
    })
    public void test_setIfModifiedSinceJ() throws IOException {
        URL url = new URL("http://localhost:8080/");
        URLConnection connection = url.openConnection();
        Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
        cal.clear();
        cal.set(2000, Calendar.MARCH, 5);

        long sinceTime = cal.getTime().getTime();
        connection.setIfModifiedSince(sinceTime);
        assertEquals("Wrong date set", sinceTime, connection
                .getIfModifiedSince());
       
        // content should be returned
        
        uc2.setIfModifiedSince(sinceTime);
        uc2.connect();
        
        
        assertEquals(200,((HttpURLConnection) uc2).getResponseCode());
        
        try {
            uc2.setIfModifiedSince(2);
            fail("Exception expected");
        } catch (IllegalStateException e) {
            //ok
        }
        
        ((HttpURLConnection) uc2).disconnect();
        
        
    }
    
    @TestTargetNew(
        level = TestLevel.SUFFICIENT,
        notes = "test that page was not renewed in time indicated -> page returned event though it should not.",
        method = "getIfModifiedSince",
        args = {}
    )
    public void test_getIfModifiedSinceJ() throws IOException {
        
        uc2.setIfModifiedSince(Calendar.getInstance().getTimeInMillis());
        uc2.connect();
        
        assertEquals(200,((HttpURLConnection) uc2).getResponseCode());
        
    }
    

    /**
     * @tests {@link java.net.URLConnection#setReadTimeout(int)}
     */
    @TestTargets({
        @TestTargetNew(
            level = TestLevel.COMPLETE,
            notes = "Test for SocketTimeoutException fails: instead undocumented UnknownServiceException is thrown.",
            method = "setReadTimeout",
            args = {int.class}
        ),
        @TestTargetNew(
                level = TestLevel.COMPLETE,
                notes = "Test for SocketTimeoutException fails: instead undocumented UnknownServiceException is thrown.",
                method = "getReadTimeout",
                args = {}
            )
    })
    public void test_setReadTimeoutI() throws Exception {
        assertEquals(0, uc.getReadTimeout());
        uc.setReadTimeout(0);
        assertEquals(0, uc.getReadTimeout());
        try {
            uc.setReadTimeout(-100);
            fail("should throw IllegalArgumentException");
        } catch (IllegalArgumentException e) {
            // correct
        }
        assertEquals(0, uc.getReadTimeout());
        uc.setReadTimeout(100);
        assertEquals(100, uc.getReadTimeout());
        try {
            uc.setReadTimeout(-1);
            fail("should throw IllegalArgumentException");
        } catch (IllegalArgumentException e) {
            // correct
        }
        assertEquals(100, uc.getReadTimeout());
        
        byte[] ba = new byte[600];
        
        uc2.setReadTimeout(5);
        uc2.setDoInput(true);
        uc2.connect();
  
        try {
        ((InputStream) uc2.getInputStream()).read(ba, 0, 600);
        } catch (SocketTimeoutException e) {
            //ok
        } catch ( UnknownServiceException e) {
            fail(""+e.getMessage());
        }
    }

    /**
     * @tests {@link java.net.URLConnection#toString()}
     */
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        notes = "",
        method = "toString",
        args = {}
    )
    public void test_toString() {
        
        assertTrue("Wrong toString: " + uc.toString(), uc.toString().indexOf(
                "URLConnection") > 0);
        assertTrue("Wrong toString: " + uc.toString(), uc.toString().indexOf(
                uc.getURL().toString()) > 0);
    }
    
    @TestTargetNew(
      level = TestLevel.SUFFICIENT,
      notes = "protected constructor",
      method = "URLConnection",
      args = {java.net.URL.class}
    )
    public void test_URLConnection() {
        String url = uc2.getURL().toString();
        assertEquals(url2.toString(), url);
    }
    
    @TestTargetNew(
        level = TestLevel.PARTIAL_COMPLETE,
        notes = "",
        method = "getInputStream",
        args = {}
      )
    public void testGetInputStream() throws IOException {
        fileURLCon.setDoInput(true);
        fileURLCon.connect();

        BufferedReader buf = new BufferedReader(new InputStreamReader(
                fileURLCon.getInputStream()), testString.getBytes().length);

        String nextline;
        while ((nextline = buf.readLine()) != null) {
            assertEquals(testString, nextline);
        }

        buf.close();

        assertNotNull(uc.getInputStream());

        ((HttpURLConnection) uc2).disconnect();

        assertNotNull(uc2.getInputStream());

    }
    
    @TestTargetNew(
            level = TestLevel.PARTIAL_COMPLETE,
            notes = "Verifies SecurityException.",
            method = "setContentHandlerFactory",
            args = {java.net.ContentHandlerFactory.class}
     )
    public void test_setContentHandlerFactory() {
        SecurityManager sm = new SecurityManager() {
            
            public void checkPermission(Permission perm) {
            }
            
            public void checkSetFactory() {
                throw new SecurityException();
            }
        };
        SecurityManager old_sm = System.getSecurityManager();
        System.setSecurityManager(sm);
        try {
            uc.setContentHandlerFactory(null);
            fail("SecurityException was not thrown.");
        } catch(SecurityException se) {
            //exception
        } finally {
            System.setSecurityManager(old_sm);
        }
      
    }    
    
    private URLConnection openGifURLConnection() throws IOException {
        String cts = System.getProperty("java.io.tmpdir");
        File tmpDir = new File(cts);
        Support_Resources.copyFile(tmpDir, null, "Harmony.GIF");
        URL fUrl1 = new URL("file:/" + tmpDir.getPath()
                + "/Harmony.GIF");
        URLConnection con1 = fUrl1.openConnection();
        return con1;
    }
    
    private JarURLConnection openJarURLConnection()
            throws MalformedURLException, IOException {
        String cts = System.getProperty("java.io.tmpdir");
        File tmpDir = new File(cts);
        Support_Resources.copyFile(tmpDir, null, "hyts_att.jar");
        URL fUrl1 = new URL("jar:file:" + tmpDir.getPath()
                + "/hyts_att.jar!/");
        JarURLConnection con1 = (JarURLConnection) fUrl1.openConnection();
        return con1;
    }
    
    private URLConnection openHTMLFile() throws IOException {
        String cts = System.getProperty("java.io.tmpdir");
        File tmpDir = new File(cts);
        Support_Resources.copyFile(tmpDir, null, "hyts_htmltest.html");
        URL fUrl1 = new URL("file:/" + tmpDir.getPath()
                + "/hyts_htmltest.html");
        URLConnection con1 = fUrl1.openConnection();
        return con1;
    }
    
    private URL createTempHelloWorldFile() throws MalformedURLException {
        // create content to read
        File tmpDir = new File(System.getProperty("java.io.tmpdir"));
        File sampleFile = null;
        try {
            if (tmpDir.isDirectory()) {
                sampleFile = File.createTempFile("openStreamTest", ".txt",
                        tmpDir);
                sampleFile.deleteOnExit();
            } else {
                fail("Error in test setup tmpDir does not exist");
            }

            FileWriter fstream = new FileWriter(sampleFile);
            BufferedWriter out = new BufferedWriter(fstream, testString.getBytes().length);
            out.write(testString);
            // Close the output stream
            out.close();
        } catch (Exception e) {// Catch exception if any
            fail("Error: in test setup" + e.getMessage());
        }
        
        // read content from file
        return sampleFile.toURL();
    }
}
