Example usage for java.net Proxy NO_PROXY

List of usage examples for java.net Proxy NO_PROXY

Introduction

In this page you can find the example usage for java.net Proxy NO_PROXY.

Prototype

Proxy NO_PROXY

To view the source code for java.net Proxy NO_PROXY.

Click Source Link

Document

A proxy setting that represents a DIRECT connection, basically telling the protocol handler not to use any proxying.

Usage

From source file:org.eclipse.mylyn.commons.http.HttpUtil.java

private static void configureHttpClientProxy(AbstractHttpClient client, HttpContext context,
        AbstractWebLocation location) {/*from   w ww  . j  a va  2  s.c o  m*/
    String host = getHost(location.getUrl());

    Proxy proxy;
    if (isRepositoryHttps(location.getUrl())) {
        proxy = location.getProxyForHost(host, IProxyData.HTTPS_PROXY_TYPE);
    } else {
        proxy = location.getProxyForHost(host, IProxyData.HTTP_PROXY_TYPE);
    }

    if (proxy != null && !Proxy.NO_PROXY.equals(proxy)) {
        InetSocketAddress address = (InetSocketAddress) proxy.address();

        client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,
                new HttpHost(address.getHostName(), address.getPort()));

        if (proxy instanceof AuthenticatedProxy) {
            AuthenticatedProxy authProxy = (AuthenticatedProxy) proxy;
            Credentials credentials = getCredentials(authProxy.getUserName(), authProxy.getPassword(),
                    address.getAddress());
            if (credentials instanceof NTCredentials) {
                List<String> authpref = new ArrayList<String>();
                authpref.add(AuthPolicy.NTLM);
                authpref.add(AuthPolicy.BASIC);
                authpref.add(AuthPolicy.DIGEST);
                client.getParams().setParameter(AuthPNames.PROXY_AUTH_PREF, authpref);
            } else {
                List<String> authpref = new ArrayList<String>();
                authpref.add(AuthPolicy.BASIC);
                authpref.add(AuthPolicy.DIGEST);
                authpref.add(AuthPolicy.NTLM);
                client.getParams().setParameter(AuthPNames.PROXY_AUTH_PREF, authpref);
            }
            AuthScope proxyAuthScope = new AuthScope(address.getHostName(), address.getPort(),
                    AuthScope.ANY_REALM);
            client.getCredentialsProvider().setCredentials(proxyAuthScope, credentials);
        }
    } else {
        client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, null);
    }
}

From source file:com.vuze.plugin.azVPN_PIA.Checker.java

private boolean callRPCforPort(File pathPIAManagerData, InetAddress bindIP, StringBuilder sReply) {
    InetAddress[] resolve = null;
    try {//from w  ww .  j ava2  s. c  o  m
        // Let's assume the client_id.txt file is the one for port forwarding.
        File fileClientID = new File(pathPIAManagerData, "client_id.txt");
        String clientID;
        if (fileClientID.isFile() && fileClientID.canRead()) {
            clientID = FileUtil.readFileAsString(fileClientID, -1);
        } else {
            clientID = config.getPluginStringParameter("client.id", null);
            if (clientID == null) {
                clientID = RandomUtils.generateRandomAlphanumerics(20);
                config.setPluginParameter("client.id", clientID);
            }
        }

        HttpPost post = new HttpPost(PIA_RPC_URL);

        String user = config.getPluginStringParameter(PluginPIA.CONFIG_USER);
        String pass = new String(config.getPluginByteParameter(PluginPIA.CONFIG_P, new byte[0]), "utf-8");

        if (user == null || user.length() == 0 || pass == null || pass.length() == 0) {
            return false;
        }

        List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
        urlParameters.add(new BasicNameValuePair("user", user));
        urlParameters.add(new BasicNameValuePair("pass", pass));
        urlParameters.add(new BasicNameValuePair("client_id", clientID));
        urlParameters.add(new BasicNameValuePair("local_ip", bindIP.getHostAddress()));

        // Call needs to be from the VPN interface (the bindIP)
        RequestConfig requestConfig = RequestConfig.custom().setLocalAddress(bindIP).setConnectTimeout(10000)
                .build();

        post.setConfig(requestConfig);

        post.setEntity(new UrlEncodedFormEntity(urlParameters));

        CloseableHttpClient httpClient = HttpClients.createDefault();

        // If Vuze has a proxy set up (Tools->Options->Connection->Proxy), then
        // we'll need to disable it for the URL
        AEProxySelector selector = AEProxySelectorFactory.getSelector();
        if (selector != null) {
            resolve = SystemDefaultDnsResolver.INSTANCE.resolve(PIA_DOMAIN);

            for (InetAddress address : resolve) {
                selector.setProxy(new InetSocketAddress(address, 443), Proxy.NO_PROXY);
            }
        }

        CloseableHttpResponse response = httpClient.execute(post);
        BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));

        StringBuffer result = new StringBuffer();
        String line = "";
        while ((line = rd.readLine()) != null) {
            result.append(line);
        }

        boolean gotPort = false;
        // should be {"port":xyz}

        Map<?, ?> mapResult = JSONUtils.decodeJSON(result.toString());
        if (mapResult.containsKey("port")) {
            Object oPort = mapResult.get("port");
            if (oPort instanceof Number) {
                gotPort = true;
                Number nPort = (Number) oPort;
                int port = nPort.intValue();

                addReply(sReply, CHAR_GOOD, "pia.port.from.rpc", new String[] { Integer.toString(port) });

                changePort(port, sReply);
            }
        }

        if (!gotPort) {
            addReply(sReply, CHAR_WARN, "pia.rpc.bad", new String[] { result.toString() });

            // mapResult.containsKey("error")
            return false;
        }
    } catch (Exception e) {
        e.printStackTrace();
        addReply(sReply, CHAR_BAD, "pia.rpc.no.connect", new String[] { bindIP + ": " + e.getMessage() });

        return false;
    } finally {
        AEProxySelector selector = AEProxySelectorFactory.getSelector();
        if (selector != null && resolve != null) {
            for (InetAddress address : resolve) {
                AEProxySelectorFactory.getSelector().removeProxy(new InetSocketAddress(address, 443));
            }
        }
    }
    return true;
}

From source file:com.blackducksoftware.integration.hub.jenkins.PostBuildScanDescriptor.java

/**
 * Performs on-the-fly validation of the form field 'serverUrl'.
 *
 *///from w  w w . j  a  va 2 s .  com
public FormValidation doCheckServerUrl(@QueryParameter("serverUrl") final String serverUrl)
        throws IOException, ServletException {
    if (StringUtils.isBlank(serverUrl)) {
        return FormValidation.error(Messages.HubBuildScan_getPleaseSetServerUrl());
    }
    URL url;
    try {
        url = new URL(serverUrl);
        try {
            url.toURI();
        } catch (final URISyntaxException e) {
            return FormValidation.error(e, Messages.HubBuildScan_getNotAValidUrl());
        }
    } catch (final MalformedURLException e) {
        return FormValidation.error(e, Messages.HubBuildScan_getNotAValidUrl());
    }
    try {
        Proxy proxy = null;

        final Jenkins jenkins = Jenkins.getInstance();
        if (jenkins != null) {
            final ProxyConfiguration proxyConfig = jenkins.proxy;
            if (proxyConfig != null) {
                proxy = ProxyConfiguration.createProxy(url.getHost(), proxyConfig.name, proxyConfig.port,
                        proxyConfig.noProxyHost);

                if (proxy != null && proxy != Proxy.NO_PROXY) {

                    if (StringUtils.isNotBlank(proxyConfig.getUserName())
                            && StringUtils.isNotBlank(proxyConfig.getPassword())) {
                        Authenticator.setDefault(new Authenticator() {
                            @Override
                            public PasswordAuthentication getPasswordAuthentication() {
                                return new PasswordAuthentication(proxyConfig.getUserName(),
                                        proxyConfig.getPassword().toCharArray());
                            }
                        });
                    } else {
                        Authenticator.setDefault(null);
                    }
                }
            }
        }

        URLConnection connection = null;
        if (proxy != null) {
            connection = url.openConnection(proxy);
        } else {
            connection = url.openConnection();
        }

        connection.getContent();
    } catch (final IOException ioe) {
        return FormValidation.error(ioe, Messages.HubBuildScan_getCanNotReachThisServer_0_(serverUrl));
    } catch (final RuntimeException e) {
        return FormValidation.error(e, Messages.HubBuildScan_getNotAValidUrl());
    }
    return FormValidation.ok();
}

From source file:org.eclipsetrader.directa.internal.core.connector.StreamingConnector.java

@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public void run() {
    int n = 0;//from   w  w  w.  ja v a 2s.com
    byte bHeader[] = new byte[4];

    sTit = new HashSet<String>();
    sTit2 = new HashSet<String>();

    // Apertura del socket verso il server
    try {
        Proxy socksProxy = Proxy.NO_PROXY;
        if (Activator.getDefault() != null) {
            BundleContext context = Activator.getDefault().getBundle().getBundleContext();
            ServiceReference reference = context.getServiceReference(IProxyService.class.getName());
            if (reference != null) {
                IProxyService proxyService = (IProxyService) context.getService(reference);
                IProxyData[] proxyData = proxyService.select(new URI(null, streamingServer, null, null));
                for (int i = 0; i < proxyData.length; i++) {
                    if (IProxyData.SOCKS_PROXY_TYPE.equals(proxyData[i].getType())
                            && proxyData[i].getHost() != null) {
                        socksProxy = new Proxy(Proxy.Type.SOCKS,
                                new InetSocketAddress(proxyData[i].getHost(), proxyData[i].getPort()));
                        break;
                    }
                }
                context.ungetService(reference);
            }
        }
        socket = new Socket(socksProxy);
        socket.connect(new InetSocketAddress(streamingServer, streamingPort));
        os = socket.getOutputStream();
        is = new DataInputStream(socket.getInputStream());
    } catch (Exception e) {
        Activator.log(
                new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, "Error connecting to streaming server", e)); //$NON-NLS-1$
        try {
            if (socket != null) {
                socket.close();
                socket = null;
            }
        } catch (Exception e1) {
            // Do nothing
        }
        return;
    }

    // Login
    try {
        os.write(CreaMsg.creaLoginMsg(WebConnector.getInstance().getUrt(), WebConnector.getInstance().getPrt(),
                "flashBook", streamingVersion)); //$NON-NLS-1$
        os.flush();

        byte bHeaderLogin[] = new byte[4];
        n = is.read(bHeaderLogin);
        int lenMsg = Util.getMessageLength(bHeaderLogin, 2);
        if ((char) bHeaderLogin[0] != '#' && n != -1) {
            return;
        }

        byte msgResp[] = new byte[lenMsg];
        is.read(msgResp);
        if (Util.byteToInt(bHeaderLogin[1]) == CreaMsg.ERROR_MSG) {
            ErrorMessage eMsg = new ErrorMessage(msgResp);
            Activator.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0,
                    "Error connecting to streaming server: " + eMsg.sMessageError, null)); //$NON-NLS-1$
            return;
        }
        try {
            os.write(CreaMsg.creaStartDataMsg());
            os.flush();
        } catch (Exception e) {
            thread = null;
            Activator.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, "Error starting data stream", e)); //$NON-NLS-1$
            return;
        }
    } catch (Exception e) {
        Activator.log(
                new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, "Error connecting to streaming server", e)); //$NON-NLS-1$
        return;
    }

    // Forces the subscriptions update on startup
    subscriptionsChanged = true;

    while (!isStopping()) {
        if (subscriptionsChanged) {
            try {
                updateStreamSubscriptions();
            } catch (Exception e) {
                thread = null;
                Activator.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0,
                        "Error updating stream subscriptions", e)); //$NON-NLS-1$
                break;
            }
        }

        // Legge l'header di un messaggio (se c'e')
        try {
            if ((n = is.read(bHeader)) == -1) {
                continue;
            }
            while (n < 4) {
                int r = is.read(bHeader, n, 4 - n);
                n += r;
            }
        } catch (Exception e) {
            Activator.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0, "Error reading data", e)); //$NON-NLS-1$
            break;
        }

        // Verifica la correttezza dell'header e legge il resto del messaggio
        Header h = new Header();
        h.start = (char) Util.byteToInt(bHeader[0]);
        if (h.start == '#') {
            h.tipo = Util.getByte(bHeader[1]);
            h.len = Util.getMessageLength(bHeader, 2);
            byte mes[] = new byte[h.len];
            try {
                n = is.read(mes);
                while (n < h.len) {
                    int r = is.read(mes, n, h.len - n);
                    n += r;
                }
            } catch (Exception e) {
            }

            if (h.tipo == CreaMsg.ERROR_MSG) {
                ErrorMessage eMsg = new ErrorMessage(mes);
                Activator.log(new Status(IStatus.WARNING, Activator.PLUGIN_ID, 0,
                        "Message from server: " + eMsg.sMessageError, null)); //$NON-NLS-1$
            } else if (h.tipo == Message.TIP_ECHO) {
                try {
                    os.write(new byte[] { bHeader[0], bHeader[1], bHeader[2], bHeader[3], mes[0], mes[1] });
                    os.flush();
                } catch (Exception e) {
                    // Do nothing
                }
            } else if (h.len > 0) {
                DataMessage obj;
                try {
                    obj = Message.decodeMessage(mes);
                    if (obj == null) {
                        continue;
                    }
                } catch (Exception e) {
                    Activator.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0,
                            "Error decoding incoming message", e)); //$NON-NLS-1$
                    continue;
                }

                processMessage(obj);
            }
        }
    }

    try {
        os.write(CreaMsg.creaStopDataMsg());
        os.flush();
    } catch (Exception e) {
        Activator.log(new Status(IStatus.WARNING, Activator.PLUGIN_ID, 0, "Error stopping data stream", e)); //$NON-NLS-1$
    }

    try {
        os.write(CreaMsg.creaLogoutMsg());
        os.flush();
    } catch (Exception e) {
        Activator.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0,
                "Error closing connection to streaming server", e)); //$NON-NLS-1$
    }

    try {
        os.close();
        is.close();
        socket.close();
    } catch (Exception e) {
        Activator.log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, 0,
                "Error closing connection to streaming server", e)); //$NON-NLS-1$
    }

    os = null;
    is = null;
    socket = null;

    if (!isStopping()) {
        thread = new Thread(this, name + " - Data Reader"); //$NON-NLS-1$
        try {
            Thread.sleep(2 * 1000);
        } catch (Exception e) {
            // Do nothing
        }
        thread.start();
    }
}

From source file:com.intellij.util.net.HttpConfigurable.java

public static boolean isRealProxy(Proxy proxy) {
    return !Proxy.NO_PROXY.equals(proxy) && !Proxy.Type.DIRECT.equals(proxy.type());
}

From source file:org.broad.igv.util.HttpUtils.java

/**
 * The "real" connection method//  w  w w  .j  av  a2  s  .c  o m
 *
 * @param url
 * @param requestProperties
 * @param method
 * @return
 * @throws java.io.IOException
 */
private HttpURLConnection openConnection(URL url, Map<String, String> requestProperties, String method,
        int redirectCount) throws IOException {

    //Encode query string portions
    url = StringUtils.encodeURLQueryString(url);
    if (log.isTraceEnabled()) {
        log.trace(url);
    }

    //Encode base portions. Right now just spaces, most common case
    //TODO This is a hack and doesn't work for all characters which need it
    if (StringUtils.countChar(url.toExternalForm(), ' ') > 0) {
        String newPath = url.toExternalForm().replaceAll(" ", "%20");
        url = new URL(newPath);
    }

    Proxy sysProxy = null;
    boolean igvProxySettingsExist = proxySettings != null && proxySettings.useProxy;
    //Only check for system proxy if igv proxy settings not found
    if (!igvProxySettingsExist) {
        sysProxy = getSystemProxy(url.toExternalForm());
    }
    boolean useProxy = sysProxy != null || igvProxySettingsExist;

    HttpURLConnection conn;
    if (useProxy) {
        Proxy proxy = sysProxy;
        if (igvProxySettingsExist) {
            if (proxySettings.type == Proxy.Type.DIRECT) {
                proxy = Proxy.NO_PROXY;
            } else {
                proxy = new Proxy(proxySettings.type,
                        new InetSocketAddress(proxySettings.proxyHost, proxySettings.proxyPort));
            }
        }
        conn = (HttpURLConnection) url.openConnection(proxy);

        if (igvProxySettingsExist && proxySettings.auth && proxySettings.user != null
                && proxySettings.pw != null) {
            byte[] bytes = (proxySettings.user + ":" + proxySettings.pw).getBytes();

            String encodedUserPwd = String.valueOf(Base64Coder.encode(bytes));
            conn.setRequestProperty("Proxy-Authorization", "Basic " + encodedUserPwd);
        }
    } else {
        conn = (HttpURLConnection) url.openConnection();
    }

    if (GSUtils.isGenomeSpace(url)) {
        conn.setRequestProperty("Accept", "application/json,text/plain");
    } else {
        conn.setRequestProperty("Accept", "text/plain");
    }

    //------//
    //There seems to be a bug with JWS caches
    //So we avoid caching

    //This default is persistent, really should be available statically but isn't
    conn.setDefaultUseCaches(false);
    conn.setUseCaches(false);
    //------//

    conn.setConnectTimeout(Globals.CONNECT_TIMEOUT);
    conn.setReadTimeout(Globals.READ_TIMEOUT);
    conn.setRequestMethod(method);
    conn.setRequestProperty("Connection", "Keep-Alive");
    if (requestProperties != null) {
        for (Map.Entry<String, String> prop : requestProperties.entrySet()) {
            conn.setRequestProperty(prop.getKey(), prop.getValue());
        }
    }
    conn.setRequestProperty("User-Agent", Globals.applicationString());

    if (method.equals("PUT")) {
        return conn;
    } else {

        int code = conn.getResponseCode();

        if (log.isDebugEnabled()) {
            //logHeaders(conn);
        }

        // Redirects.  These can occur even if followRedirects == true if there is a change in protocol,
        // for example http -> https.
        if (code >= 300 && code < 400) {

            if (redirectCount > MAX_REDIRECTS) {
                throw new IOException("Too many redirects");
            }

            String newLocation = conn.getHeaderField("Location");
            log.debug("Redirecting to " + newLocation);

            return openConnection(new URL(newLocation), requestProperties, method, redirectCount++);
        }

        // TODO -- handle other response codes.
        else if (code >= 400) {

            String message;
            if (code == 404) {
                message = "File not found: " + url.toString();
                throw new FileNotFoundException(message);
            } else if (code == 401) {
                // Looks like this only happens when user hits "Cancel".
                // message = "Not authorized to view this file";
                // JOptionPane.showMessageDialog(null, message, "HTTP error", JOptionPane.ERROR_MESSAGE);
                redirectCount = MAX_REDIRECTS + 1;
                return null;
            } else {
                message = conn.getResponseMessage();
            }
            String details = readErrorStream(conn);
            log.error("URL: " + url.toExternalForm() + ". error stream: " + details);
            log.error("Code: " + code + ". " + message);
            HttpResponseException exc = new HttpResponseException(code);
            throw exc;
        }
    }
    return conn;
}

From source file:org.eclipse.mylyn.commons.net.WebUtil.java

/**
 * @since 3.1//from   w  ww  .jav  a 2 s.  c  om
 */
@SuppressWarnings("deprecation")
public static Proxy getProxy(String host, String proxyType) {
    Assert.isNotNull(host);
    Assert.isNotNull(proxyType);
    IProxyService service = CommonsNetPlugin.getProxyService();
    if (service != null && service.isProxiesEnabled()) {
        // TODO e3.5 move to new proxy API
        IProxyData data = service.getProxyDataForHost(host, proxyType);
        if (data != null && data.getHost() != null) {
            String proxyHost = data.getHost();
            int proxyPort = data.getPort();
            // change the IProxyData default port to the Java default port
            if (proxyPort == -1) {
                proxyPort = 0;
            }

            AuthenticationCredentials credentials = null;
            if (data.isRequiresAuthentication()) {
                credentials = new AuthenticationCredentials(data.getUserId(), data.getPassword());
            }
            return createProxy(proxyHost, proxyPort, credentials);
        }
    } else {
        try {
            // fall back to JDK proxy selector
            URI uri = new URI(proxyType, "//" + host, null); //$NON-NLS-1$
            List<Proxy> proxies = ProxySelector.getDefault().select(uri);
            if (proxies != null && proxies.size() > 0) {
                Proxy proxy = proxies.iterator().next();
                if (proxy != Proxy.NO_PROXY) {
                    return proxy;
                }
            }
        } catch (URISyntaxException e) {
            // ignore
        }
    }
    return null;
}

From source file:com.cloudbees.jenkins.plugins.bitbucket.client.BitbucketCloudApiClient.java

private void setClientProxyParams(String host, HttpClientBuilder builder) {
    Jenkins jenkins = Jenkins.getInstance();
    ProxyConfiguration proxyConfig = null;
    if (jenkins != null) {
        proxyConfig = jenkins.proxy;/*  w  ww. java2s .  c o m*/
    }

    Proxy proxy = Proxy.NO_PROXY;
    if (proxyConfig != null) {
        proxy = proxyConfig.createProxy(host);
    }

    if (proxy.type() != Proxy.Type.DIRECT) {
        final InetSocketAddress proxyAddress = (InetSocketAddress) proxy.address();
        LOGGER.fine("Jenkins proxy: " + proxy.address());
        builder.setProxy(new HttpHost(proxyAddress.getHostName(), proxyAddress.getPort()));
        String username = proxyConfig.getUserName();
        String password = proxyConfig.getPassword();
        if (username != null && !"".equals(username.trim())) {
            LOGGER.fine("Using proxy authentication (user=" + username + ")");
            CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
            credentialsProvider.setCredentials(AuthScope.ANY,
                    new UsernamePasswordCredentials(username, password));
            AuthCache authCache = new BasicAuthCache();
            authCache.put(HttpHost.create(proxyAddress.getHostName()), new BasicScheme());
            context = HttpClientContext.create();
            context.setCredentialsProvider(credentialsProvider);
            context.setAuthCache(authCache);
        }
    }
}

From source file:com.blackducksoftware.integration.hub.jenkins.PostBuildHubScan.java

public void addProxySettingsToScanner(final IntLogger logger, final JenkinsScanExecutor scan)
        throws BDJenkinsHubPluginException, HubIntegrationException, URISyntaxException, MalformedURLException {
    final Jenkins jenkins = Jenkins.getInstance();
    if (jenkins != null) {
        final ProxyConfiguration proxyConfig = jenkins.proxy;
        if (proxyConfig != null) {

            final URL serverUrl = new URL(getHubServerInfo().getServerUrl());

            final Proxy proxy = ProxyConfiguration.createProxy(serverUrl.getHost(), proxyConfig.name,
                    proxyConfig.port, proxyConfig.noProxyHost);

            if (proxy != Proxy.NO_PROXY && proxy.address() != null) {
                final InetSocketAddress proxyAddress = (InetSocketAddress) proxy.address();
                if (StringUtils.isNotBlank(proxyAddress.getHostName()) && proxyAddress.getPort() != 0) {
                    if (StringUtils.isNotBlank(jenkins.proxy.getUserName())
                            && StringUtils.isNotBlank(jenkins.proxy.getPassword())) {
                        scan.setProxyHost(proxyAddress.getHostName());
                        scan.setProxyPort(proxyAddress.getPort());
                        scan.setProxyUsername(jenkins.proxy.getUserName());
                        scan.setProxyPassword(jenkins.proxy.getPassword());

                    } else {
                        scan.setProxyHost(proxyAddress.getHostName());
                        scan.setProxyPort(proxyAddress.getPort());
                    }// w  w w.j  ava  2  s .c  om
                    if (logger != null) {
                        logger.debug("Using proxy: '" + proxyAddress.getHostName() + "' at Port: '"
                                + proxyAddress.getPort() + "'");
                    }
                }
            }
        }
    }
}