diff --git a/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient3/HTTPProxyConfigurator.java b/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient3/HTTPProxyConfigurator.java
new file mode 100644
index 0000000..e47f4f4
--- /dev/null
+++ b/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient3/HTTPProxyConfigurator.java
@@ -0,0 +1,463 @@
+/*
+ * 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.axis2.transport.http.impl.httpclient3;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.description.Parameter;
+import org.apache.axis2.transport.http.HTTPConstants;
+import org.apache.axis2.transport.http.HTTPTransportConstants;
+import org.apache.axis2.transport.http.HttpTransportProperties;
+import org.apache.commons.httpclient.Credentials;
+import org.apache.commons.httpclient.HostConfiguration;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpState;
+import org.apache.commons.httpclient.NTCredentials;
+import org.apache.commons.httpclient.UsernamePasswordCredentials;
+import org.apache.commons.httpclient.auth.AuthScope;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.xml.namespace.QName;
+import java.net.URL;
+import java.util.StringTokenizer;
+
+public class HTTPProxyConfigurator {
+
+    private static Log log = LogFactory.getLog(HTTPProxyConfigurator.class);
+
+    /**
+     * Configure HTTP Proxy settings of commons-httpclient HostConfiguration.
+     * Proxy settings can be get from axis2.xml, Java proxy settings or can be
+     * override through property in message context.
+     * <p/>
+     * HTTP Proxy setting element format: <parameter name="Proxy">
+     * <Configuration> <ProxyHost>example.org</ProxyHost>
+     * <ProxyPort>3128</ProxyPort> <ProxyUser>EXAMPLE/John</ProxyUser>
+     * <ProxyPassword>password</ProxyPassword> <Configuration> <parameter>
+     * 
+     * @param messageContext
+     *            in message context for
+     * @param httpClient
+     *            commons-httpclient instance
+     * @param config
+     *            commons-httpclient HostConfiguration
+     * @throws AxisFault
+     *             if Proxy settings are invalid
+     */
+    public static void configure(MessageContext messageContext, HttpClient httpClient,
+            HostConfiguration config) throws AxisFault {
+
+        Credentials proxyCredentials = null;
+        String proxyHost = null;
+        String nonProxyHosts = null;
+        Integer proxyPort = -1;
+        String proxyUser = null;
+        String proxyPassword = null;
+
+        // Getting configuration values from Axis2.xml
+        Parameter proxySettingsFromAxisConfig = messageContext.getConfigurationContext()
+                .getAxisConfiguration().getParameter(HTTPTransportConstants.ATTR_PROXY);
+        if (proxySettingsFromAxisConfig != null) {
+            OMElement proxyConfiguration = getProxyConfigurationElement(proxySettingsFromAxisConfig);
+            proxyHost = getProxyHost(proxyConfiguration);
+            proxyPort = getProxyPort(proxyConfiguration);
+            proxyUser = getProxyUser(proxyConfiguration);
+            proxyPassword = getProxyPassword(proxyConfiguration);
+            if (proxyUser != null) {
+                if (proxyPassword == null) {
+                    proxyPassword = "";
+                }
+
+                proxyCredentials = new UsernamePasswordCredentials(proxyUser, proxyPassword);
+
+                int proxyUserDomainIndex = proxyUser.indexOf("\\");
+                if (proxyUserDomainIndex > 0) {
+                    String domain = proxyUser.substring(0, proxyUserDomainIndex);
+                    if (proxyUser.length() > proxyUserDomainIndex + 1) {
+                        String user = proxyUser.substring(proxyUserDomainIndex + 1);
+                        proxyCredentials = new NTCredentials(user, proxyPassword, proxyHost, domain);
+                    }
+                }
+
+            }
+
+        }
+
+        // If there is runtime proxy settings, these settings will override
+        // settings from axis2.xml
+        HttpTransportProperties.ProxyProperties proxyProperties = (HttpTransportProperties.ProxyProperties) messageContext
+                .getProperty(HTTPConstants.PROXY);
+        if (proxyProperties != null) {
+            String proxyHostProp = proxyProperties.getProxyHostName();
+            if (proxyHostProp == null || proxyHostProp.length() <= 0) {
+                throw new AxisFault("HTTP Proxy host is not available. Host is a MUST parameter");
+            } else {
+                proxyHost = proxyHostProp;
+            }
+            proxyPort = proxyProperties.getProxyPort();
+
+            // Overriding credentials
+            String userName = proxyProperties.getUserName();
+            String password = proxyProperties.getPassWord();
+            String domain = proxyProperties.getDomain();
+
+            if (userName != null && password != null && domain != null) {
+                proxyCredentials = new NTCredentials(userName, password, proxyHost, domain);
+            } else if (userName != null && domain == null) {
+                proxyCredentials = new UsernamePasswordCredentials(userName, password);
+            }
+
+        }
+
+        // Overriding proxy settings if proxy is available from JVM settings
+        String host = System.getProperty(HTTPTransportConstants.HTTP_PROXY_HOST);
+        if (host != null) {
+            proxyHost = host;
+        }
+
+        String port = System.getProperty(HTTPTransportConstants.HTTP_PROXY_PORT);
+        if (port != null) {
+            proxyPort = Integer.parseInt(port);
+        }
+
+        if (proxyCredentials != null) {
+            httpClient.getParams().setAuthenticationPreemptive(true);
+            HttpState cachedHttpState = (HttpState) messageContext
+                    .getProperty(HTTPConstants.CACHED_HTTP_STATE);
+            if (cachedHttpState != null) {
+                httpClient.setState(cachedHttpState);
+            }
+            httpClient.getState().setProxyCredentials(AuthScope.ANY, proxyCredentials);
+        }
+        config.setProxy(proxyHost, proxyPort);
+    }
+
+    private static OMElement getProxyConfigurationElement(Parameter proxySettingsFromAxisConfig)
+            throws AxisFault {
+        OMElement proxyConfigurationElement = proxySettingsFromAxisConfig.getParameterElement()
+                .getFirstElement();
+        if (proxyConfigurationElement == null) {
+            log.error(HTTPTransportConstants.PROXY_CONFIGURATION_NOT_FOUND);
+            throw new AxisFault(HTTPTransportConstants.PROXY_CONFIGURATION_NOT_FOUND);
+        }
+        return proxyConfigurationElement;
+    }
+
+    private static String getProxyHost(OMElement proxyConfiguration) throws AxisFault {
+        OMElement proxyHostElement = proxyConfiguration.getFirstChildWithName(new QName(
+                HTTPTransportConstants.PROXY_HOST_ELEMENT));
+        if (proxyHostElement == null) {
+            log.error(HTTPTransportConstants.PROXY_HOST_ELEMENT_NOT_FOUND);
+            throw new AxisFault(HTTPTransportConstants.PROXY_HOST_ELEMENT_NOT_FOUND);
+        }
+        String proxyHost = proxyHostElement.getText();
+        if (proxyHost == null) {
+            log.error(HTTPTransportConstants.PROXY_HOST_ELEMENT_WITH_EMPTY_VALUE);
+            throw new AxisFault(HTTPTransportConstants.PROXY_HOST_ELEMENT_WITH_EMPTY_VALUE);
+        }
+        return proxyHost;
+    }
+
+    private static Integer getProxyPort(OMElement proxyConfiguration) throws AxisFault {
+        OMElement proxyPortElement = proxyConfiguration.getFirstChildWithName(new QName(
+                HTTPTransportConstants.PROXY_PORT_ELEMENT));
+        if (proxyPortElement == null) {
+            log.error(HTTPTransportConstants.PROXY_PORT_ELEMENT_NOT_FOUND);
+            throw new AxisFault(HTTPTransportConstants.PROXY_PORT_ELEMENT_NOT_FOUND);
+        }
+        String proxyPort = proxyPortElement.getText();
+        if (proxyPort == null) {
+            log.error(HTTPTransportConstants.PROXY_PORT_ELEMENT_WITH_EMPTY_VALUE);
+            throw new AxisFault(HTTPTransportConstants.PROXY_PORT_ELEMENT_WITH_EMPTY_VALUE);
+        }
+        return Integer.parseInt(proxyPort);
+    }
+
+    private static String getProxyUser(OMElement proxyConfiguration) {
+        OMElement proxyUserElement = proxyConfiguration.getFirstChildWithName(new QName(
+                HTTPTransportConstants.PROXY_USER_ELEMENT));
+        if (proxyUserElement == null) {
+            return null;
+        }
+        String proxyUser = proxyUserElement.getText();
+        if (proxyUser == null) {
+            log.warn("Empty user name element in HTTP Proxy settings.");
+            return null;
+        }
+
+        return proxyUser;
+    }
+
+    private static String getProxyPassword(OMElement proxyConfiguration) {
+        OMElement proxyPasswordElement = proxyConfiguration.getFirstChildWithName(new QName(
+                HTTPTransportConstants.PROXY_PASSWORD_ELEMENT));
+        if (proxyPasswordElement == null) {
+            return null;
+        }
+        String proxyUser = proxyPasswordElement.getText();
+        if (proxyUser == null) {
+            log.warn("Empty user name element in HTTP Proxy settings.");
+            return null;
+        }
+
+        return proxyUser;
+    }
+
+    /**
+     * Check whether http proxy is configured or active. This is not a deep
+     * check.
+     * 
+     * @param messageContext
+     *            in message context
+     * @param targetURL
+     *            URL of the edpoint which we are sending the request
+     * @return true if proxy is enabled, false otherwise
+     */
+    public static boolean isProxyEnabled(MessageContext messageContext, URL targetURL) {
+        boolean proxyEnabled = false;
+
+        Parameter param = messageContext.getConfigurationContext().getAxisConfiguration()
+                .getParameter(HTTPTransportConstants.ATTR_PROXY);
+
+        // If configuration is over ridden
+        Object obj = messageContext.getProperty(HTTPConstants.PROXY);
+
+        // From Java Networking Properties
+        String sp = System.getProperty(HTTPTransportConstants.HTTP_PROXY_HOST);
+
+        if (param != null || obj != null || sp != null) {
+            proxyEnabled = true;
+        }
+
+        boolean isNonProxyHost = validateNonProxyHosts(targetURL.getHost());
+
+        return proxyEnabled && !isNonProxyHost;
+    }
+
+    /**
+     * Validates for names that shouldn't be listered as proxies. The
+     * http.nonProxyHosts can be set to specify the hosts which should be
+     * connected to directly (not through the proxy server). The value of the
+     * http.nonProxyHosts property can be a list of hosts, each separated by a
+     * |; it can also take a regular expression for matches; for example:
+     * *.sfbay.sun.com would match any fully qualified hostname in the sfbay
+     * domain.
+     * <p/>
+     * For more information refer to :
+     * http://java.sun.com/features/2002/11/hilevel_network.html
+     * <p/>
+     * false : validation fail : User can use the proxy true : validation pass ;
+     * User can't use the proxy
+     * 
+     * @return boolean
+     */
+    private static boolean validateNonProxyHosts(String host) {
+        // From system property http.nonProxyHosts
+        String nonProxyHosts = System.getProperty(HTTPTransportConstants.HTTP_NON_PROXY_HOSTS);
+        return isHostInNonProxyList(host, nonProxyHosts);
+    }
+
+    /**
+     * Check if the specified host is in the list of non proxy hosts.
+     * 
+     * @param host
+     *            host name
+     * @param nonProxyHosts
+     *            string containing the list of non proxy hosts
+     * @return true/false
+     */
+    public static boolean isHostInNonProxyList(String host, String nonProxyHosts) {
+        if ((nonProxyHosts == null) || (host == null)) {
+            return false;
+        }
+
+        /*
+         * The http.nonProxyHosts system property is a list enclosed in double
+         * quotes with items separated by a vertical bar.
+         */
+        StringTokenizer tokenizer = new StringTokenizer(nonProxyHosts, "|\"");
+
+        while (tokenizer.hasMoreTokens()) {
+            String pattern = tokenizer.nextToken();
+            if (match(pattern, host, false)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Matches a string against a pattern. The pattern contains two special
+     * characters: '*' which means zero or more characters,
+     * 
+     * @param pattern
+     *            the (non-null) pattern to match against
+     * @param str
+     *            the (non-null) string that must be matched against the pattern
+     * @param isCaseSensitive
+     * @return <code>true</code> when the string matches against the pattern,
+     *         <code>false</code> otherwise.
+     */
+    private static boolean match(String pattern, String str, boolean isCaseSensitive) {
+
+        char[] patArr = pattern.toCharArray();
+        char[] strArr = str.toCharArray();
+        int patIdxStart = 0;
+        int patIdxEnd = patArr.length - 1;
+        int strIdxStart = 0;
+        int strIdxEnd = strArr.length - 1;
+        char ch;
+        boolean containsStar = false;
+
+        for (int i = 0; i < patArr.length; i++) {
+            if (patArr[i] == '*') {
+                containsStar = true;
+                break;
+            }
+        }
+        if (!containsStar) {
+
+            // No '*'s, so we make a shortcut
+            if (patIdxEnd != strIdxEnd) {
+                return false; // Pattern and string do not have the same size
+            }
+            for (int i = 0; i <= patIdxEnd; i++) {
+                ch = patArr[i];
+                if (isCaseSensitive && (ch != strArr[i])) {
+                    return false; // Character mismatch
+                }
+                if (!isCaseSensitive
+                        && (Character.toUpperCase(ch) != Character.toUpperCase(strArr[i]))) {
+                    return false; // Character mismatch
+                }
+            }
+            return true; // String matches against pattern
+        }
+        if (patIdxEnd == 0) {
+            return true; // Pattern contains only '*', which matches anything
+        }
+
+        // Process characters before first star
+        while ((ch = patArr[patIdxStart]) != '*' && (strIdxStart <= strIdxEnd)) {
+            if (isCaseSensitive && (ch != strArr[strIdxStart])) {
+                return false; // Character mismatch
+            }
+            if (!isCaseSensitive
+                    && (Character.toUpperCase(ch) != Character.toUpperCase(strArr[strIdxStart]))) {
+                return false; // Character mismatch
+            }
+            patIdxStart++;
+            strIdxStart++;
+        }
+        if (strIdxStart > strIdxEnd) {
+
+            // All characters in the string are used. Check if only '*'s are
+            // left in the pattern. If so, we succeeded. Otherwise failure.
+            for (int i = patIdxStart; i <= patIdxEnd; i++) {
+                if (patArr[i] != '*') {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        // Process characters after last star
+        while ((ch = patArr[patIdxEnd]) != '*' && (strIdxStart <= strIdxEnd)) {
+            if (isCaseSensitive && (ch != strArr[strIdxEnd])) {
+                return false; // Character mismatch
+            }
+            if (!isCaseSensitive
+                    && (Character.toUpperCase(ch) != Character.toUpperCase(strArr[strIdxEnd]))) {
+                return false; // Character mismatch
+            }
+            patIdxEnd--;
+            strIdxEnd--;
+        }
+        if (strIdxStart > strIdxEnd) {
+
+            // All characters in the string are used. Check if only '*'s are
+            // left in the pattern. If so, we succeeded. Otherwise failure.
+            for (int i = patIdxStart; i <= patIdxEnd; i++) {
+                if (patArr[i] != '*') {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        // process pattern between stars. padIdxStart and patIdxEnd point
+        // always to a '*'.
+        while ((patIdxStart != patIdxEnd) && (strIdxStart <= strIdxEnd)) {
+            int patIdxTmp = -1;
+
+            for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
+                if (patArr[i] == '*') {
+                    patIdxTmp = i;
+                    break;
+                }
+            }
+            if (patIdxTmp == patIdxStart + 1) {
+
+                // Two stars next to each other, skip the first one.
+                patIdxStart++;
+                continue;
+            }
+
+            // Find the pattern between padIdxStart & padIdxTmp in str between
+            // strIdxStart & strIdxEnd
+            int patLength = (patIdxTmp - patIdxStart - 1);
+            int strLength = (strIdxEnd - strIdxStart + 1);
+            int foundIdx = -1;
+
+            strLoop: for (int i = 0; i <= strLength - patLength; i++) {
+                for (int j = 0; j < patLength; j++) {
+                    ch = patArr[patIdxStart + j + 1];
+                    if (isCaseSensitive && (ch != strArr[strIdxStart + i + j])) {
+                        continue strLoop;
+                    }
+                    if (!isCaseSensitive
+                            && (Character.toUpperCase(ch) != Character
+                                    .toUpperCase(strArr[strIdxStart + i + j]))) {
+                        continue strLoop;
+                    }
+                }
+                foundIdx = strIdxStart + i;
+                break;
+            }
+            if (foundIdx == -1) {
+                return false;
+            }
+            patIdxStart = patIdxTmp;
+            strIdxStart = foundIdx + patLength;
+        }
+
+        // All characters in the string are used. Check if only '*'s are left
+        // in the pattern. If so, we succeeded. Otherwise failure.
+        for (int i = patIdxStart; i <= patIdxEnd; i++) {
+            if (patArr[i] != '*') {
+                return false;
+            }
+        }
+        return true;
+    }
+
+}
diff --git a/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient3/HTTPSenderImpl.java b/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient3/HTTPSenderImpl.java
index 2c09c35..566db64 100644
--- a/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient3/HTTPSenderImpl.java
+++ b/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient3/HTTPSenderImpl.java
@@ -538,11 +538,11 @@
         }
         // proxy configuration
 
-        if (HTTPProxcyConfigurator.isProxyEnabled(msgCtx, targetURL)) {
+        if (HTTPProxyConfigurator.isProxyEnabled(msgCtx, targetURL)) {
             if (log.isDebugEnabled()) {
                 log.debug("Configuring HTTP proxy.");
             }
-            HTTPProxcyConfigurator.configure(msgCtx, client, config);
+            HTTPProxyConfigurator.configure(msgCtx, client, config);
         }
 
         return config;
diff --git a/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient4/HTTPProxyConfigurator.java b/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient4/HTTPProxyConfigurator.java
index 67615f4..df7587e 100644
--- a/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient4/HTTPProxyConfigurator.java
+++ b/modules/transport/http/src/org/apache/axis2/transport/http/impl/httpclient4/HTTPProxyConfigurator.java
@@ -87,6 +87,9 @@
                 if (proxyPassword == null) {
                     proxyPassword = "";
                 }
+
+                proxyCredentials = new UsernamePasswordCredentials(proxyUser, proxyPassword);
+
                 int proxyUserDomainIndex = proxyUser.indexOf("\\");
                 if (proxyUserDomainIndex > 0) {
                     String domain = proxyUser.substring(0, proxyUserDomainIndex);
@@ -96,9 +99,7 @@
                                                              domain);
                     }
                 }
-                proxyCredentials = new UsernamePasswordCredentials(proxyUser, proxyPassword);
             }
-
         }
 
         // If there is runtime proxy settings, these settings will override
