text:
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.net;

import android.annotation.SuppressLint;
import android.content.Context;
import android.net.http.HttpResponseCache;
import android.support.annotation.IntDef;
import android.support.annotation.VisibleForTesting;
import android.util.Log;

import java.io.File;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Constructor;
import java.net.IDN;
import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandlerFactory;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.regex.Pattern;

import javax.net.ssl.HttpsURLConnection;

/**
 * An engine to process {@link UrlRequest}s, which uses the best HTTP stack
 * available on the current platform.
 */
public abstract class CronetEngine {
    /**
     * A builder for {@link CronetEngine}s, which allows runtime configuration of
     * {@code CronetEngine}. Configuration options are set on the builder and
     * then {@link #build} is called to create the {@code CronetEngine}.
     */
    public static class Builder {
        /**
         * A class which provides a method for loading the cronet native library. Apps needing to
         * implement custom library loading logic can inherit from this class and pass an instance
         * to {@link CronetEngine.Builder#setLibraryLoader}. For example, this might be required
         * to work around {@code UnsatisfiedLinkError}s caused by flaky installation on certain
         * older devices.
         */
        public abstract static class LibraryLoader {
            /**
             * Loads the native library.
             * @param libName name of the library to load
             */
            public abstract void loadLibrary(String libName);
        }

        /**
         * A hint that a host supports QUIC.
         * @hide only used by internal implementation.
         */
        public static class QuicHint {
            // The host.
            public final String mHost;
            // Port of the server that supports QUIC.
            public final int mPort;
            // Alternate protocol port.
            public final int mAlternatePort;

            QuicHint(String host, int port, int alternatePort) {
                mHost = host;
                mPort = port;
                mAlternatePort = alternatePort;
            }
        }

        /**
         * A public key pin.
         * @hide only used by internal implementation.
         */
        public static class Pkp {
            // Host to pin for.
            public final String mHost;
            // Array of SHA-256 hashes of keys.
            public final byte[][] mHashes;
            // Should pin apply to subdomains?
            public final boolean mIncludeSubdomains;
            // When the pin expires.
            public final Date mExpirationDate;

            Pkp(String host, byte[][] hashes, boolean includeSubdomains, Date expirationDate) {
                mHost = host;
                mHashes = hashes;
                mIncludeSubdomains = includeSubdomains;
                mExpirationDate = expirationDate;
            }
        }

        private static final Pattern INVALID_PKP_HOST_NAME = Pattern.compile("^[0-9\\.]*$");

        // Private fields are simply storage of configuration for the resulting CronetEngine.
        // See setters below for verbose descriptions.
        private final Context mContext;
        private final List<QuicHint> mQuicHints = new LinkedList<QuicHint>();
        private final List<Pkp> mPkps = new LinkedList<>();
        private boolean mPublicKeyPinningBypassForLocalTrustAnchorsEnabled;
        private String mUserAgent;
        private String mStoragePath;
        private boolean mLegacyModeEnabled;
        private LibraryLoader mLibraryLoader;
        private String mLibraryName;
        private boolean mQuicEnabled;
        private boolean mHttp2Enabled;
        private boolean mSdchEnabled;
        private String mDataReductionProxyKey;
        private String mDataReductionProxyPrimaryProxy;
        private String mDataReductionProxyFallbackProxy;
        private String mDataReductionProxySecureProxyCheckUrl;
        private boolean mDisableCache;
        private int mHttpCacheMode;
        private long mHttpCacheMaxSize;
        private String mExperimentalOptions;
        private long mMockCertVerifier;
        private boolean mNetworkQualityEstimatorEnabled;
        private String mCertVerifierData;

        /**
         * Default config enables SPDY, disables QUIC, SDCH and HTTP cache.
         * @param context Android {@link Context} for engine to use.
         */
        public Builder(Context context) {
            mContext = context;
            setLibraryName("cronet");
            enableLegacyMode(false);
            enableQuic(false);
            enableHttp2(true);
            enableSDCH(false);
            enableHttpCache(HTTP_CACHE_DISABLED, 0);
            enableNetworkQualityEstimator(false);
            enablePublicKeyPinningBypassForLocalTrustAnchors(true);
        }

        /**
         * Constructs a User-Agent string including application name and version,
         * system build version, model and id, and Cronet version.
         *
         * @return User-Agent string.
         */
        public String getDefaultUserAgent() {
            return UserAgent.from(mContext);
        }

        /**
         * Overrides the User-Agent header for all requests. An explicitly
         * set User-Agent header (set using
         * {@link UrlRequest.Builder#addHeader}) will override a value set
         * using this function.
         *
         * @param userAgent the User-Agent string to use for all requests.
         * @return the builder to facilitate chaining.
         */
        public Builder setUserAgent(String userAgent) {
            mUserAgent = userAgent;
            return this;
        }

        /**
         * @hide only used by internal implementation.
         */
        public String getUserAgent() {
            return mUserAgent;
        }

        /**
         * Sets directory for HTTP Cache and Cookie Storage. The directory must
         * exist.
         *

         * NOTE: Do not use the same storage directory with more than one
         * {@code CronetEngine} at a time. Access to the storage directory does
         * not support concurrent access by multiple {@code CronetEngine}s.
         *
         * @param value path to existing directory.
         * @return the builder to facilitate chaining.
         */
        public Builder setStoragePath(String value) {
            if (!new File(value).isDirectory()) {
                throw new IllegalArgumentException(
                        "Storage path must be set to existing directory");
            }
            mStoragePath = value;
            return this;
        }

        /**
         * @hide only used by internal implementation.
         */
        public String storagePath() {
            return mStoragePath;
        }

        /**
         * Sets whether the resulting {@link CronetEngine} uses an
         * implementation based on the system's
         * {@link java.net.HttpURLConnection} implementation, or if this is
         * only done as a backup if the native implementation fails to load.
         * Defaults to disabled.
         * @param value {@code true} makes the resulting {@link CronetEngine}
         *              use an implementation based on the system's
         *              {@link java.net.HttpURLConnection} implementation
         *              without trying to load the native implementation.
         *              {@code false} makes the resulting {@code CronetEngine}
         *              use the native implementation, or if that fails to load,
         *              falls back to an implementation based on the system's
         *              {@link java.net.HttpURLConnection} implementation.
         * @return the builder to facilitate chaining.
         * @deprecated Not supported by the new API.
         * @hide
         */
        @Deprecated
        public Builder enableLegacyMode(boolean value) {
            mLegacyModeEnabled = value;
            return this;
        }

        /**
         * @hide only used by internal implementation.
         */
        public boolean legacyMode() {
            return mLegacyModeEnabled;
        }

        /**
         * Overrides the name of the native library backing Cronet.
         * @param libName the name of the native library backing Cronet.
         * @return the builder to facilitate chaining.
         * @hide only used by internal implementation.
         */
        public Builder setLibraryName(String libName) {
            mLibraryName = libName;
            return this;
        }

        /**
         * @hide only used by internal implementation.
         */
        public String libraryName() {
            return mLibraryName;
        }

        /**
         * Sets a {@link LibraryLoader} to be used to load the native library.
         * If not set, the library will be loaded using {@link System#loadLibrary}.
         * @param loader {@code LibraryLoader} to be used to load the native library.
         * @return the builder to facilitate chaining.
         */
        public Builder setLibraryLoader(LibraryLoader loader) {
            mLibraryLoader = loader;
            return this;
        }

        /**
         * @hide only used by internal implementation.
         */
        public LibraryLoader libraryLoader() {
            return mLibraryLoader;
        }

        /**
         * Sets whether QUIC protocol
         * is enabled. Defaults to disabled. If QUIC is enabled, then QUIC User Agent Id
         * containing application name and Cronet version is sent to the server.
         * @param value {@code true} to enable QUIC, {@code false} to disable.
         * @return the builder to facilitate chaining.
         */
        public Builder enableQuic(boolean value) {
            mQuicEnabled = value;
            return this;
        }

        /**
         * @hide only used by internal implementation.
         */
        public boolean quicEnabled() {
            return mQuicEnabled;
        }

        /**
         * Constructs default QUIC User Agent Id string including application name
         * and Cronet version. Returns empty string if QUIC is not enabled.
         *
         * @param context Android {@link Context} to get package name from.
         * @return QUIC User Agent ID string.
         * @hide only used by internal implementation.
         */
        // TODO(mef): remove |context| parameter when legacy ChromiumUrlRequestContext is removed.
        public String getDefaultQuicUserAgentId(Context context) {
            return mQuicEnabled ? UserAgent.getQuicUserAgentIdFrom(context) : "";
        }

        /**
         * Sets whether HTTP/2
         * protocol is enabled. Defaults to enabled.
         * @param value {@code true} to enable HTTP/2, {@code false} to disable.
         * @return the builder to facilitate chaining.
         */
        public Builder enableHttp2(boolean value) {
            mHttp2Enabled = value;
            return this;
        }

        /**
         * @hide only used by internal implementation.
         */
        public boolean http2Enabled() {
            return mHttp2Enabled;
        }

        /**
         * Sets whether
         *
         * SDCH compression is enabled. Defaults to disabled.
         * @param value {@code true} to enable SDCH, {@code false} to disable.
         * @return the builder to facilitate chaining.
         */
        public Builder enableSDCH(boolean value) {
            mSdchEnabled = value;
            return this;
        }

        /**
         * @hide only used by internal implementation.
         */
        public boolean sdchEnabled() {
            return mSdchEnabled;
        }

        /**
         * Enables
         * Data
         * Reduction Proxy. Defaults to disabled.
         * @param key key to use when authenticating with the proxy.
         * @return the builder to facilitate chaining.
         */
        public Builder enableDataReductionProxy(String key) {
            mDataReductionProxyKey = key;
            return this;
        }

        /**
         * @hide only used by internal implementation.
         */
        public String dataReductionProxyKey() {
            return mDataReductionProxyKey;
        }

        /**
         * Overrides
         *
         * Data Reduction Proxy configuration parameters with a primary
         * proxy name, fallback proxy name, and a secure proxy check URL. Proxies
         * are specified as [scheme://]host[:port]. Used for testing.
         * @param primaryProxy the primary data reduction proxy to use.
         * @param fallbackProxy a fallback data reduction proxy to use.
         * @param secureProxyCheckUrl a URL to fetch to determine if using a secure
         * proxy is allowed.
         * @return the builder to facilitate chaining.
         * @hide as it's a prototype.
         */
        public Builder setDataReductionProxyOptions(
                String primaryProxy, String fallbackProxy, String secureProxyCheckUrl) {
            if (primaryProxy.isEmpty() || fallbackProxy.isEmpty()
                    || secureProxyCheckUrl.isEmpty()) {
                throw new IllegalArgumentException(
                        "Primary and fallback proxies and check url must be set");
            }
            mDataReductionProxyPrimaryProxy = primaryProxy;
            mDataReductionProxyFallbackProxy = fallbackProxy;
            mDataReductionProxySecureProxyCheckUrl = secureProxyCheckUrl;
            return this;
        }

        /**
         * @hide only used by internal implementation.
         */
        public String dataReductionProxyPrimaryProxy() {
            return mDataReductionProxyPrimaryProxy;
        }

        /**
         * @hide only used by internal implementation.
         */
        public String dataReductionProxyFallbackProxy() {
            return mDataReductionProxyFallbackProxy;
        }

        /**
         * @hide only used by internal implementation.
         */
        public String dataReductionProxySecureProxyCheckUrl() {
            return mDataReductionProxySecureProxyCheckUrl;
        }

        /** @hide */
        @IntDef({
                HTTP_CACHE_DISABLED, HTTP_CACHE_IN_MEMORY, HTTP_CACHE_DISK_NO_HTTP, HTTP_CACHE_DISK,
        })
        @Retention(RetentionPolicy.SOURCE)
        public @interface HttpCacheSetting {}

        /**
         * Setting to disable HTTP cache. Some data may still be temporarily stored in memory.
         * Passed to {@link #enableHttpCache}.
         */
        public static final int HTTP_CACHE_DISABLED = 0;

        /**
         * Setting to enable in-memory HTTP cache, including HTTP data.
         * Passed to {@link #enableHttpCache}.
         */
        public static final int HTTP_CACHE_IN_MEMORY = 1;

        /**
         * Setting to enable on-disk cache, excluding HTTP data.
         * {@link #setStoragePath} must be called prior to passing this constant to
         * {@link #enableHttpCache}.
         */
        public static final int HTTP_CACHE_DISK_NO_HTTP = 2;

        /**
         * Setting to enable on-disk cache, including HTTP data.
         * {@link #setStoragePath} must be called prior to passing this constant to
         * {@link #enableHttpCache}.
         */
        public static final int HTTP_CACHE_DISK = 3;

        /**
         * Enables or disables caching of HTTP data and other information like QUIC
         * server information.
         * @param cacheMode control location and type of cached data. Must be one of
         *         {@link #HTTP_CACHE_DISABLED HTTP_CACHE_*}.
         * @param maxSize maximum size in bytes used to cache data (advisory and maybe
         * exceeded at times).
         * @return the builder to facilitate chaining.
         */
        public Builder enableHttpCache(@HttpCacheSetting int cacheMode, long maxSize) {
            if (cacheMode == HTTP_CACHE_DISK || cacheMode == HTTP_CACHE_DISK_NO_HTTP) {
                if (storagePath() == null) {
                    throw new IllegalArgumentException("Storage path must be set");
                }
            } else {
                if (storagePath() != null) {
                    throw new IllegalArgumentException("Storage path must not be set");
                }
            }
            mDisableCache =
                    (cacheMode == HTTP_CACHE_DISABLED || cacheMode == HTTP_CACHE_DISK_NO_HTTP);
            mHttpCacheMaxSize = maxSize;

            switch (cacheMode) {
                case HTTP_CACHE_DISABLED:
                    mHttpCacheMode = HttpCacheType.DISABLED;
                    break;
                case HTTP_CACHE_DISK_NO_HTTP:
                case HTTP_CACHE_DISK:
                    mHttpCacheMode = HttpCacheType.DISK;
                    break;
                case HTTP_CACHE_IN_MEMORY:
                    mHttpCacheMode = HttpCacheType.MEMORY;
                    break;
                default:
                    throw new IllegalArgumentException("Unknown cache mode");
            }
            return this;
        }

        /**
         * @hide only used by internal implementation.
         */
        public boolean cacheDisabled() {
            return mDisableCache;
        }

        /**
         * @hide only used by internal implementation.
         */
        public long httpCacheMaxSize() {
            return mHttpCacheMaxSize;
        }

        /**
         * @hide only used by internal implementation.
         */
        public int httpCacheMode() {
            return mHttpCacheMode;
        }

        /**
         * Adds hint that {@code host} supports QUIC.
         * Note that {@link #enableHttpCache enableHttpCache}
         * ({@link #HTTP_CACHE_DISK}) is needed to take advantage of 0-RTT
         * connection establishment between sessions.
         *
         * @param host hostname of the server that supports QUIC.
         * @param port host of the server that supports QUIC.
         * @param alternatePort alternate port to use for QUIC.
         * @return the builder to facilitate chaining.
         */
        public Builder addQuicHint(String host, int port, int alternatePort) {
            if (host.contains("/")) {
                throw new IllegalArgumentException("Illegal QUIC Hint Host: " + host);
            }
            mQuicHints.add(new QuicHint(host, port, alternatePort));
            return this;
        }

        /**
         * @hide only used by internal implementation.
         */
        public List<QuicHint> quicHints() {
            return mQuicHints;
        }

        /**
         *

         * Pins a set of public keys for a given host. By pinning a set of public keys,
         * {@code pinsSha256}, communication with {@code hostName} is required to
         * authenticate with a certificate with a public key from the set of pinned ones.
         * An app can pin the public key of the root certificate, any of the intermediate
         * certificates or the end-entry certificate. Authentication will fail and secure
         * communication will not be established if none of the public keys is present in the
         * host's certificate chain, even if the host attempts to authenticate with a
         * certificate allowed by the device's trusted store of certificates.
         *

         *

         * Calling this method multiple times with the same host name overrides the previously
         * set pins for the host.
         *

         *

         * More information about the public key pinning can be found in
         * RFC 7469.
         *

         *
         * @param hostName name of the host to which the public keys should be pinned. A host that
         *                 consists only of digits and the dot character is treated as invalid.
         * @param pinsSha256 a set of pins. Each pin is the SHA-256 cryptographic
         *                   hash of the DER-encoded ASN.1 representation of the Subject Public
         *                   Key Info (SPKI) of the host's X.509 certificate. Use
         *                   {@link java.security.cert.Certificate#getPublicKey()
         *                   Certificate.getPublicKey()} and
         *                   {@link java.security.Key#getEncoded() Key.getEncoded()}
         *                   to obtain DER-encoded ASN.1 representation of the SPKI.
         *                   Although, the method does not mandate the presence of the backup pin
         *                   that can be used if the control of the primary private key has been
         *                   lost, it is highly recommended to supply one.
         * @param includeSubdomains indicates whether the pinning policy should be applied to
         *                          subdomains of {@code hostName}.
         * @param expirationDate specifies the expiration date for the pins.
         * @return the builder to facilitate chaining.
         * @throws NullPointerException if any of the input parameters are {@code null}.
         * @throws IllegalArgumentException if the given host name is invalid or {@code pinsSha256}
         *                                  contains a byte array that does not represent a valid
         *                                  SHA-256 hash.
         */
        public Builder addPublicKeyPins(String hostName, Set<byte[]> pinsSha256,
                boolean includeSubdomains, Date expirationDate) {
            if (hostName == null) {
                throw new NullPointerException("The hostname cannot be null");
            }
            if (pinsSha256 == null) {
                throw new NullPointerException("The set of SHA256 pins cannot be null");
            }
            if (expirationDate == null) {
                throw new NullPointerException("The pin expiration date cannot be null");
            }
            String idnHostName = validateHostNameForPinningAndConvert(hostName);
            // Convert the pin to BASE64 encoding. The hash set will eliminate duplications.
            Set<byte[]> hashes = new HashSet<>(pinsSha256.size());
            for (byte[] pinSha256 : pinsSha256) {
                if (pinSha256 == null || pinSha256.length != 32) {
                    throw new IllegalArgumentException("Public key pin is invalid");
                }
                hashes.add(pinSha256);
            }
            // Add new element to PKP list.
            mPkps.add(new Pkp(idnHostName, hashes.toArray(new byte[hashes.size()][]),
                    includeSubdomains, expirationDate));
            return this;
        }

        /**
         * Returns list of public key pins.
         * @return list of public key pins.
         * @hide only used by internal implementation.
         */
        public List<Pkp> publicKeyPins() {
            return mPkps;
        }

        /**
         * Enables or disables public key pinning bypass for local trust anchors. Disabling the
         * bypass for local trust anchors is highly discouraged since it may prohibit the app
         * from communicating with the pinned hosts. E.g., a user may want to send all traffic
         * through an SSL enabled proxy by changing the device proxy settings and adding the
         * proxy certificate to the list of local trust anchor. Disabling the bypass will most
         * likly prevent the app from sending any traffic to the pinned hosts. For more
         * information see 'How does key pinning interact with local proxies and filters?' at
         * https://www.chromium.org/Home/chromium-security/security-faq
         *
         * @param value {@code true} to enable the bypass, {@code false} to disable.
         * @return the builder to facilitate chaining.
         */
        public Builder enablePublicKeyPinningBypassForLocalTrustAnchors(boolean value) {
            mPublicKeyPinningBypassForLocalTrustAnchorsEnabled = value;
            return this;
        }

        /**
         * @hide only used by internal implementation.
         */
        public boolean publicKeyPinningBypassForLocalTrustAnchorsEnabled() {
            return mPublicKeyPinningBypassForLocalTrustAnchorsEnabled;
        }

        /**
         * Checks whether a given string represents a valid host name for PKP and converts it
         * to ASCII Compatible Encoding representation according to RFC 1122, RFC 1123 and
         * RFC 3490. This method is more restrictive than required by RFC 7469. Thus, a host
         * that contains digits and the dot character only is considered invalid.
         *
         * Note: Currently Cronet doesn't have native implementation of host name validation that
         *       can be used. There is code that parses a provided URL but doesn't ensure its
         *       correctness. The implementation relies on {@code getaddrinfo} function.
         *
         * @param hostName host name to check and convert.
         * @return true if the string is a valid host name.
         * @throws IllegalArgumentException if the the given string does not represent a valid
         *                                  hostname.
         */
        private static String validateHostNameForPinningAndConvert(String hostName)
                throws IllegalArgumentException {
            if (INVALID_PKP_HOST_NAME.matcher(hostName).matches()) {
                throw new IllegalArgumentException("Hostname " + hostName + " is illegal."
                        + " A hostname should not consist of digits and/or dots only.");
            }
            // Workaround for crash, see crbug.com/634914
            if (hostName.length() > 255) {
                throw new IllegalArgumentException("Hostname " + hostName + " is too long."
                        + " The name of the host does not comply with RFC 1122 and RFC 1123.");
            }
            try {
                return IDN.toASCII(hostName, IDN.USE_STD3_ASCII_RULES);
            } catch (IllegalArgumentException ex) {
                throw new IllegalArgumentException("Hostname " + hostName + " is illegal."
                        + " The name of the host does not comply with RFC 1122 and RFC 1123.");
            }
        }

        /**
         * Sets experimental options to be used in Cronet.
         *
         * @param options JSON formatted experimental options.
         * @return the builder to facilitate chaining.
         */
        public Builder setExperimentalOptions(String options) {
            mExperimentalOptions = options;
            return this;
        }

        /**
         * @hide only used by internal implementation.
         */
        public String experimentalOptions() {
            return mExperimentalOptions;
        }

        /**
         * Sets a native MockCertVerifier for testing. See
         * {@code MockCertVerifier.createMockCertVerifier} for a method that
         * can be used to create a MockCertVerifier.
         * @param mockCertVerifier pointer to native MockCertVerifier.
         * @return the builder to facilitate chaining.
         * @hide
         */
        @VisibleForTesting
        public Builder setMockCertVerifierForTesting(long mockCertVerifier) {
            mMockCertVerifier = mockCertVerifier;
            return this;
        }

        /**
         * @hide only used by internal implementation.
         */
        public long mockCertVerifier() {
            return mMockCertVerifier;
        }

        /**
         * Enables the network quality estimator, which collects and reports
         * measurements of round trip time (RTT) and downstream throughput at
         * various layers of the network stack. After enabling the estimator,
         * listeners of RTT and throughput can be added with
         * {@link #addRttListener} and {@link #addThroughputListener} and
         * removed with {@link #removeRttListener} and
         * {@link #removeThroughputListener}. The estimator uses memory and CPU
         * only when enabled.
         * @param value {@code true} to enable network quality estimator,
         *            {@code false} to disable.
         * @hide as it's a prototype.
         * @return the builder to facilitate chaining.
         */
        public Builder enableNetworkQualityEstimator(boolean value) {
            mNetworkQualityEstimatorEnabled = value;
            return this;
        }

        /**
         * @return true if the network quality estimator has been enabled for
         * this builder.
         * @hide as it's a prototype and only used by internal implementation.
         */
        public boolean networkQualityEstimatorEnabled() {
            return mNetworkQualityEstimatorEnabled;
        }

        /**
         * Initializes CachingCertVerifier's cache with certVerifierData which has
         * the results of certificate verification.
         * @param certVerifierData a serialized representation of certificate
         *        verification results.
         * @return the builder to facilitate chaining.
         */
        public Builder setCertVerifierData(String certVerifierData) {
            mCertVerifierData = certVerifierData;
            return this;
        }

        /**
         * @hide only used by internal implementation.
         */
        public String certVerifierData() {
            return mCertVerifierData;
        }

        /**
         * Returns {@link Context} for builder.
         *
         * @return {@link Context} for builder.
         * @hide only used by internal implementation.
         */
        public Context getContext() {
            return mContext;
        }

        /**
         * Build a {@link CronetEngine} using this builder's configuration.
         * @return constructed {@link CronetEngine}.
         */
        public CronetEngine build() {
            if (getUserAgent() == null) {
                setUserAgent(getDefaultUserAgent());
            }
            CronetEngine cronetEngine = null;
            if (!legacyMode()) {
                cronetEngine = createCronetEngine(this);
            }
            if (cronetEngine == null) {
                cronetEngine = new JavaCronetEngine(getUserAgent());
            }
            Log.i(TAG, "Using network stack: " + cronetEngine.getVersionString());
            // Clear MOCK_CERT_VERIFIER reference if there is any, since
            // the ownership has been transferred to the engine.
            mMockCertVerifier = 0;
            return cronetEngine;
        }
    }

    private static final String TAG = "UrlRequestFactory";
    private static final String CRONET_URL_REQUEST_CONTEXT =
            "org.chromium.net.impl.CronetUrlRequestContext";

    /**
     * Creates a {@link UrlRequest} object. All callbacks will
     * be called on {@code executor}'s thread. {@code executor} must not run
     * tasks on the current thread to prevent blocking networking operations
     * and causing exceptions during shutdown. Request is given medium priority,
     * see {@link UrlRequest.Builder#REQUEST_PRIORITY_MEDIUM}. To specify other
     * priorities see {@link #createRequest(String, UrlRequest.Callback,
     * Executor, int priority)}.
     *
     * @param url {@link URL} for the request.
     * @param callback callback object that gets invoked on different events.
     * @param executor {@link Executor} on which all callbacks will be invoked.
     * @return new request.
     * @deprecated Use {@link UrlRequest.Builder#build}.
     * @hide
     */
    @Deprecated
    @SuppressLint("WrongConstant") // TODO(jbudorick): Remove this after rolling to the N SDK.
    public final UrlRequest createRequest(
            String url, UrlRequest.Callback callback, Executor executor) {
        return createRequest(url, callback, executor, UrlRequest.Builder.REQUEST_PRIORITY_MEDIUM);
    }

    /**
     * Creates a {@link UrlRequest} object. All callbacks will
     * be called on {@code executor}'s thread. {@code executor} must not run
     * tasks on the current thread to prevent blocking networking operations
     * and causing exceptions during shutdown.
     *
     * @param url {@link URL} for the request.
     * @param callback callback object that gets invoked on different events.
     * @param executor {@link Executor} on which all callbacks will be invoked.
     * @param priority priority of the request which should be one of the
     *         {@link UrlRequest.Builder#REQUEST_PRIORITY_IDLE REQUEST_PRIORITY_*}
     *         values.
     * @return new request.
     * @deprecated Use {@link UrlRequest.Builder#build}.
     * @hide
     */
    @Deprecated
    public final UrlRequest createRequest(String url, UrlRequest.Callback callback,
            Executor executor, @UrlRequest.Builder.RequestPriority int priority) {
        return createRequest(
                url, callback, executor, priority, Collections.emptyList(), false, false);
    }

    /**
     * Creates a {@link UrlRequest} object. All callbacks will
     * be called on {@code executor}'s thread. {@code executor} must not run
     * tasks on the current thread to prevent blocking networking operations
     * and causing exceptions during shutdown.
     *
     * @param url {@link URL} for the request.
     * @param callback callback object that gets invoked on different events.
     * @param executor {@link Executor} on which all callbacks will be invoked.
     * @param priority priority of the request which should be one of the
     *         {@link UrlRequest.Builder#REQUEST_PRIORITY_IDLE REQUEST_PRIORITY_*}
     *         values.
     * @param requestAnnotations Objects to pass on to {@link RequestFinishedInfo.Listener}.
     * @param disableCache disables cache for the request.
     *         If context is not set up to use cache this param has no effect.
     * @param disableConnectionMigration disables connection migration for this
     *         request if it is enabled for the session.
     * @return new request.
     * @deprecated Use {@link UrlRequest.Builder#build}.
     * @hide as it references hidden RequestFinishedInfo.Listener
     */
    @Deprecated
    protected abstract UrlRequest createRequest(String url, UrlRequest.Callback callback,
            Executor executor, int priority, Collection<Object> requestAnnotations,
            boolean disableCache, boolean disableConnectionMigration);

    /**
     * Creates a {@link BidirectionalStream} object. {@code callback} methods will
     * be invoked on {@code executor}. {@code executor} must not run
     * tasks on the current thread to prevent blocking networking operations
     * and causing exceptions during shutdown.
     *
     * @param url the URL for the stream
     * @param callback the object whose methods get invoked upon different events
     * @param executor the {@link Executor} on which all callbacks will be called
     * @param httpMethod the HTTP method to use for the stream
     * @param requestHeaders the list of request headers
     * @param priority priority of the stream which should be one of the
     *         {@link BidirectionalStream.Builder#STREAM_PRIORITY_IDLE STREAM_PRIORITY_*}
     *         values.
     * @param disableAutoFlush whether auto flush should be disabled
     * @param delayRequestHeadersUntilFirstFlush whether to delay sending request
     *         headers until flush() is called, and try to combine them
     *         with the next data frame.
     * @return a new stream.
     * @hide only used by internal implementation.
     */
    public abstract BidirectionalStream createBidirectionalStream(String url,
            BidirectionalStream.Callback callback, Executor executor, String httpMethod,
            List<Map.Entry<String, String>> requestHeaders,
            @BidirectionalStream.Builder.StreamPriority int priority, boolean disableAutoFlush,
            boolean delayRequestHeadersUntilFirstFlush);

    /**
     * @return {@code true} if the engine is enabled.
     * @hide only used by internal implementation.
     */
    public abstract boolean isEnabled();

    /**
     * @return a human-readable version string of the engine.
     */
    public abstract String getVersionString();

    /**
     * Shuts down the {@link CronetEngine} if there are no active requests,
     * otherwise throws an exception.
     *
     * Cannot be called on network thread - the thread Cronet calls into
     * Executor on (which is different from the thread the Executor invokes
     * callbacks on). May block until all the {@code CronetEngine}'s
     * resources have been cleaned up.
     */
    public abstract void shutdown();

    /**
     * Starts NetLog logging to a file. The NetLog will contain events emitted
     * by all live CronetEngines. The NetLog is useful for debugging.
     * The file can be viewed using a Chrome browser navigated to
     * chrome://net-internals/#import
     * @param fileName the complete file path. It must not be empty. If the file
     *            exists, it is truncated before starting. If actively logging,
     *            this method is ignored.
     * @param logAll {@code true} to include basic events, user cookies,
     *            credentials and all transferred bytes in the log.
     *            {@code false} to just include basic events.
     */
    public abstract void startNetLogToFile(String fileName, boolean logAll);

    /**
     * Stops NetLog logging and flushes file to disk. If a logging session is
     * not in progress, this call is ignored.
     */
    public abstract void stopNetLog();

    /**
     * Returns serialized representation of certificate verifier's cache
     * which contains the list of hosts/certificates and the certificate
     * verification results. May block until data is received from the network
     * thread (will timeout after the specified timeout). In case of timeout, it
     * returns the previous saved value.
     *
     * @param timeout in milliseconds. If timeout is 0, it will use default value.
     * @return serialized representation of certificate verification results
     *         data.
     */
    public abstract String getCertVerifierData(long timeout);

    /**
     * Returns differences in metrics collected by Cronet since the last call to
     * {@link #getGlobalMetricsDeltas}.
     *

     * Cronet collects these metrics globally. This means deltas returned by
     * {@code getGlobalMetricsDeltas()} will include measurements of requests
     * processed by other {@link CronetEngine} instances. Since this function
     * returns differences in metrics collected since the last call, and these
     * metrics are collected globally, a call to any {@code CronetEngine}
     * instance's {@code getGlobalMetricsDeltas()} method will affect the deltas
     * returned by any other {@code CronetEngine} instance's
     * {@code getGlobalMetricsDeltas()}.
     *

     * Cronet starts collecting these metrics after the first call to
     * {@code getGlobalMetricsDeltras()}, so the first call returns no
     * useful data as no metrics have yet been collected.
     *
     * @return differences in metrics collected by Cronet, since the last call
     *         to {@code getGlobalMetricsDeltas()}, serialized as a
     *         protobuf
     *         .
     */
    public abstract byte[] getGlobalMetricsDeltas();

    /**
     * Configures the network quality estimator for testing. This must be called
     * before round trip time and throughput listeners are added, and after the
     * network quality estimator has been enabled.
     * @param useLocalHostRequests include requests to localhost in estimates.
     * @param useSmallerResponses include small responses in throughput
     * estimates.
     * @hide as it's a prototype.
     */
    public abstract void configureNetworkQualityEstimatorForTesting(
            boolean useLocalHostRequests, boolean useSmallerResponses);

    /**
     * Registers a listener that gets called whenever the network quality
     * estimator witnesses a sample round trip time. This must be called
     * after {@link #enableNetworkQualityEstimator}, and with throw an
     * exception otherwise. Round trip times may be recorded at various layers
     * of the network stack, including TCP, QUIC, and at the URL request layer.
     * The listener is called on the {@link java.util.concurrent.Executor} that
     * is passed to {@link #enableNetworkQualityEstimator}.
     * @param listener the listener of round trip times.
     * @hide as it's a prototype.
     */
    public abstract void addRttListener(NetworkQualityRttListener listener);

    /**
     * Removes a listener of round trip times if previously registered with
     * {@link #addRttListener}. This should be called after a
     * {@link NetworkQualityRttListener} is added in order to stop receiving
     * observations.
     * @param listener the listener of round trip times.
     * @hide as it's a prototype.
     */
    public abstract void removeRttListener(NetworkQualityRttListener listener);

    /**
     * Registers a listener that gets called whenever the network quality
     * estimator witnesses a sample throughput measurement. This must be called
     * after {@link #enableNetworkQualityEstimator}. Throughput observations
     * are computed by measuring bytes read over the active network interface
     * at times when at least one URL response is being received. The listener
     * is called on the {@link java.util.concurrent.Executor} that is passed to
     * {@link #enableNetworkQualityEstimator}.
     * @param listener the listener of throughput.
     * @hide as it's a prototype.
     */
    public abstract void addThroughputListener(NetworkQualityThroughputListener listener);

    /**
     * Removes a listener of throughput. This should be called after a
     * {@link NetworkQualityThroughputListener} is added with
     * {@link #addThroughputListener} in order to stop receiving observations.
     * @param listener the listener of throughput.
     * @hide as it's a prototype.
     */
    public abstract void removeThroughputListener(NetworkQualityThroughputListener listener);

    /**
     * Establishes a new connection to the resource specified by the {@link URL} {@code url}.
     *

     * Note: Cronet's {@link java.net.HttpURLConnection} implementation is subject to certain
     * limitations, see {@link #createURLStreamHandlerFactory} for details.
     *
     * @param url URL of resource to connect to.
     * @return an {@link java.net.HttpURLConnection} instance implemented by this CronetEngine.
     * @throws IOException if an error occurs while opening the connection.
     */
    public abstract URLConnection openConnection(URL url) throws IOException;

    /**
     * Establishes a new connection to the resource specified by the {@link URL} {@code url}
     * using the given proxy.
     *

     * Note: Cronet's {@link java.net.HttpURLConnection} implementation is subject to certain
     * limitations, see {@link #createURLStreamHandlerFactory} for details.
     *
     * @param url URL of resource to connect to.
     * @param proxy proxy to use when establishing connection.
     * @return an {@link java.net.HttpURLConnection} instance implemented by this CronetEngine.
     * @throws IOException if an error occurs while opening the connection.
     * @hide TODO(pauljensen): Expose once implemented, http://crbug.com/418111
     */
    public abstract URLConnection openConnection(URL url, Proxy proxy) throws IOException;

    /**
     * Creates a {@link URLStreamHandlerFactory} to handle HTTP and HTTPS
     * traffic. An instance of this class can be installed via
     * {@link URL#setURLStreamHandlerFactory} thus using this CronetEngine by default for
     * all requests created via {@link URL#openConnection}.
     *

     * Cronet does not use certain HTTP features provided via the system:
     *

     *
the HTTP cache installed via
     *     {@link HttpResponseCache#install(java.io.File, long) HttpResponseCache.install()}

     *
the HTTP authentication method installed via
     *     {@link java.net.Authenticator#setDefault}

     *
the HTTP cookie storage installed via {@link java.net.CookieHandler#setDefault}

     *

     *

     * While Cronet supports and encourages requests using the HTTPS protocol,
     * Cronet does not provide support for the
     * {@link HttpsURLConnection} API. This lack of support also
     * includes not using certain HTTPS features provided via the system:
     *

     *
the HTTPS hostname verifier installed via {@link
     *   HttpsURLConnection#setDefaultHostnameVerifier(javax.net.ssl.HostnameVerifier)
     *     HttpsURLConnection.setDefaultHostnameVerifier()}

     *
the HTTPS socket factory installed via {@link
     *   HttpsURLConnection#setDefaultSSLSocketFactory(javax.net.ssl.SSLSocketFactory)
     *     HttpsURLConnection.setDefaultSSLSocketFactory()}

     *

     *
     * @return an {@link URLStreamHandlerFactory} instance implemented by this
     *         CronetEngine.
     */
    public abstract URLStreamHandlerFactory createURLStreamHandlerFactory();

    private static CronetEngine createCronetEngine(Builder builder) {
        CronetEngine cronetEngine = null;
        try {
            Class<? extends CronetEngine> engineClass =
                    builder.getContext()
                            .getClassLoader()
                            .loadClass(CRONET_URL_REQUEST_CONTEXT)
                            .asSubclass(CronetEngine.class);
            Constructor<? extends CronetEngine> constructor =
                    engineClass.getConstructor(Builder.class);
            CronetEngine possibleEngine = constructor.newInstance(builder);
            if (possibleEngine.isEnabled()) {
                cronetEngine = possibleEngine;
            }
        } catch (ClassNotFoundException e) {
            // Leave as null.
        } catch (Exception e) {
            throw new IllegalStateException("Cannot instantiate: " + CRONET_URL_REQUEST_CONTEXT, e);
        }
        return cronetEngine;
    }

    /**
     * Registers a listener that gets called after the end of each request with the request info.
     *
     *
This must be called after {@link #enableNetworkQualityEstimator} and will throw an
     * exception otherwise.
     *
     *
The listener is called on the {@link java.util.concurrent.Executor} that
     * is passed to {@link #enableNetworkQualityEstimator}.
     *
     * @param listener the listener for finished requests.
     *
     * @hide as it's a prototype.
     */
    public abstract void addRequestFinishedListener(RequestFinishedInfo.Listener listener);

    /**
     * Removes a finished request listener.
     *
     * @param listener the listener to remove.
     *
     * @hide it's a prototype.
     */
    public abstract void removeRequestFinishedListener(RequestFinishedInfo.Listener listener);
}


text:
import os

from generator.generator import generate  # must be first import
from rogerthat.rpc.calls import client_mapping, mapping

generate(os.path.splitext(os.path.basename(__file__))[0], mapping, client_mapping)

redpajama_set_name: RedPajamaGithub


text:
package com.hs.mail.imap.processor;

//import static org.mockito.Mockito.*;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.RETURNS_MOCKS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.Arrays;

import com.hs.mail.imap.mailbox.MailboxManager;
import com.hs.mail.imap.message.request.CloseRequest;
import com.hs.mail.imap.message.responder.Responder;

public class CloseProcessorTest extends AbstractImapProcessorTest {

    private static final String COMMAND = "CLOSE";

	Responder responder;
	CloseProcessor processor = new MockCloseProcessor();

	protected void setUp() throws Exception {
		super.setUp();
		responder = mock(Responder.class);
	}

	public void testReadOnlyClose() throws Exception {
		expectGetSelectedMailbox();
		when(selectedMailbox.isReadOnly()).thenReturn(true);

		CloseRequest message = new CloseRequest(TAG, COMMAND);
		processor.doProcess(session, message, responder);

		verify(mailboxManager, never()).expunge(anyLong());
		verify(session, times(1)).deselect();
		verify(responder, times(1)).okCompleted(message);
	}

	public void testReadWriteClose() throws Exception {
		expectGetSelectedMailbox();
		when(selectedMailbox.isReadOnly()).thenReturn(false);
		when(mailboxManager.getEventDispatcher()).thenAnswer(RETURNS_MOCKS);
		when(mailboxManager.expunge(eq(1L))).thenReturn(
				Arrays.asList(new Long[] { 147L }));

		CloseRequest message = new CloseRequest(TAG, COMMAND);
		processor.doProcess(session, message, responder);

		verify(mailboxManager, times(1)).expunge(eq(1L));
		verify(mailboxManager, times(1)).deleteMessage(eq(147L));
		verify(session, times(1)).deselect();
		verify(responder, times(1)).okCompleted(message);
	}

    private void expectGetSelectedMailbox() throws Exception {
		when(session.getSelectedMailbox()).thenReturn(selectedMailbox);
		when(selectedMailbox.getMailboxID()).thenReturn(1L);
    }

    static class MockCloseProcessor extends CloseProcessor {
    	protected MailboxManager getMailboxManager() {
    		return mailboxManager;
    	}
    }

}


text:
<resources>
    <string name="app_name">Tirkx Player</string>

    <string name="title_section1">ปักหมุด</string>
    <string name="title_section2">ฉายจบแล้ว</string>
    <string name="title_section3">เกี่ยวกับ</string>
    <string name="title_section4">มาใหม่</string>

    <string name="navigation_drawer_open">Open navigation drawer</string>
    <string name="navigation_drawer_close">Close navigation drawer</string>

    <string name="action_example">Example action</string>

    <string name="action_settings">Settings</string>
    <string name="search">ค้นหา</string>
    <string name="search_anime">ค้นหารายชื่ออนิเมะ</string>
    <string name="credit">พัฒนาโดย pureexe</string>
    <string name="connection_problem">การเชื่อมต่อมีปัญหา</string>
    <string name="file_not_found">ไม่พบไฟล์ที่ท่านต้องการ</string>
    <string name="preload_sqlite_fetchfail">การดึงข้อมูลจาก SQLite ล้มเหลว กรุณาลบแอปออกและติดตั้งใหม่</string>
    <string name="file_anime_not_found">อนิเมะเรื่องนี้ไม่มีไฟล์ใดๆอยู่เลย</string>
</resources>


text:
package com.bxf.hradmin.common.exception;

/**
 * HRHeadCountException
 *
 * @since 2016-06-05
 * @author Bo-Xuan Fan
 */
public class HRHeadCountException extends HRException {

    /** serialVersionUID */
    private static final long serialVersionUID = -5281582581282798461L;

    public HRHeadCountException() {
        super();
    }

    public HRHeadCountException(String message, Throwable cause) {
        super(message, cause);
    }

    public HRHeadCountException(String message) {
        super(message);
    }

    public HRHeadCountException(Throwable cause) {
        super(cause);
    }
}


text:
DEFINE_int32(max_keyevents, 100000,
             "test at most |max_keyevents| key sequences");
DEFINE_string(server_path, "", "specify server path");
DEFINE_int32(key_duration, 10, "key duration (msec)");
DEFINE_bool(test_renderer, false, "test renderer");
DEFINE_bool(test_testsendkey, true, "test TestSendKey");

DECLARE_bool(logtostderr);

int main(int argc, char **argv) {
  mozc::InitMozc(argv[0], &argc, &argv, false);

  FLAGS_logtostderr = true;

  mozc::client::Client client;
  if (!FLAGS_server_path.empty()) {
    client.set_server_program(FLAGS_server_path);
  }

  CHECK(client.IsValidRunLevel()) << "IsValidRunLevel failed";
  CHECK(client.EnsureSession()) << "EnsureSession failed";
  CHECK(client.NoOperation()) << "Server is not respoinding";

  std::unique_ptr<mozc::renderer::RendererClient> renderer_client;
  mozc::commands::RendererCommand renderer_command;

  if (FLAGS_test_renderer) {
#if defined(OS_WIN) || defined(OS_MACOSX)
#ifdef OS_WIN
    renderer_command.mutable_application_info()->set_process_id
        (::GetCurrentProcessId());
    renderer_command.mutable_application_info()->set_thread_id
        (::GetCurrentThreadId());
#endif  // OS_WIN
    renderer_command.mutable_preedit_rectangle()->set_left(10);
    renderer_command.mutable_preedit_rectangle()->set_top(10);
    renderer_command.mutable_preedit_rectangle()->set_right(200);
    renderer_command.mutable_preedit_rectangle()->set_bottom(30);
#else
    LOG(FATAL) << "test_renderer is only supported on Windows and Mac";
#endif  // OS_WIN || OS_MACOSX
    renderer_client.reset(new mozc::renderer::RendererClient);
    CHECK(renderer_client->Activate());
  }

  vector<mozc::commands::KeyEvent> keys;
  mozc::commands::Output output;
  int32 keyevents_size = 0;

  // TODO(taku):
  // Stop the test if server is crashed.
  // Currently, we cannot detect the server crash out of
  // client library, as client automatically re-lahches the server.

  while (true) {
    mozc::session::RandomKeyEventsGenerator::GenerateSequence(&keys);
    CHECK(client.NoOperation()) << "Server is not responding";
    for (size_t i = 0; i < keys.size(); ++i) {
      mozc::Util::Sleep(FLAGS_key_duration);
      keyevents_size++;
      if (keyevents_size % 100 == 0) {
        std::cout << keyevents_size << " key events finished" << std::endl;
      }
      if (FLAGS_max_keyevents < keyevents_size) {
        std::cout << "key events reached to " << FLAGS_max_keyevents
                  << std::endl;
        return 0;
      }
      if (FLAGS_test_testsendkey) {
        VLOG(2) << "Sending to Server: " << keys[i].DebugString();
        client.TestSendKey(keys[i], &output);
        VLOG(2) << "Output of TestSendKey: " << output.DebugString();
        mozc::Util::Sleep(10);
      }

      VLOG(2) << "Sending to Server: " << keys[i].DebugString();
      client.SendKey(keys[i], &output);
      VLOG(2) << "Output of SendKey: " << output.DebugString();

      if (renderer_client.get() != NULL) {
        renderer_command.set_type(mozc::commands::RendererCommand::UPDATE);
        renderer_command.set_visible(output.has_candidates());
        renderer_command.mutable_output()->CopyFrom(output);
        VLOG(2) << "Sending to Renderer: " << renderer_command.DebugString();
        renderer_client->ExecCommand(renderer_command);
      }
    }
  }

  return 0;
}


text:
Online discussion forum

The website is now live on Amazon AWS and you can view it on [Soapbox](http://ec2-54-175-128-205.compute-1.amazonaws.com/soapbox/)

Test credentials for login are:

**username**: sipps7

**password**: okiedokie

**It is so easy to use that it's hard to explain.**

We made it really, really simple for people to ask any question and get answers from real people with first-hand experience.

**You already know how this works.**

Choose from the topics of your interest to create a feed of information tuned to your interests. Create a thread to share knowledge.


text:
package db

type scannable interface {
	Scan(destinations ...interface{}) error
}


text:
package com.cisco.axl.api._8;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlValue;

/**
 *
Java class for XAnalogPort complex type.
 *
 *
The following schema fragment specifies the expected content contained within this class.
 *
 *

 * <complexType name="XAnalogPort">
 *   <complexContent>
 *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       <sequence minOccurs="0">
 *         <element name="portNumber" type="{http://www.cisco.com/AXL/API/8.0}XInteger"/>
 *         <element name="attendantDn" type="{http://www.cisco.com/AXL/API/8.0}String255" minOccurs="0"/>
 *         <element name="unattendedPort" type="{http://www.cisco.com/AXL/API/8.0}boolean" minOccurs="0"/>
 *         <element name="callerIdDn" type="{http://www.cisco.com/AXL/API/8.0}String255" minOccurs="0"/>
 *         <element name="callerIdEnable" type="{http://www.cisco.com/AXL/API/8.0}boolean"/>
 *         <element name="callingPartySelection" type="{http://www.cisco.com/AXL/API/8.0}XCallingPartySelection" minOccurs="0"/>
 *         <element name="digitSending" type="{http://www.cisco.com/AXL/API/8.0}XDigitSending" minOccurs="0"/>
 *         <element name="expectedDigits" type="{http://www.cisco.com/AXL/API/8.0}XInteger"/>
 *         <element name="sigDigits">
 *           <complexType>
 *             <simpleContent>
 *               <extension base="<http://www.cisco.com/AXL/API/8.0>XInteger">
 *                 <attribute name="enable" type="{http://www.w3.org/2001/XMLSchema}boolean" />
 *               </extension>
 *             </simpleContent>
 *           </complexType>
 *         </element>
 *         <element name="lines" minOccurs="0">
 *           <complexType>
 *             <complexContent>
 *               <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *                 <choice>
 *                   <element name="line" type="{http://www.cisco.com/AXL/API/8.0}XPhoneLine"/>
 *                   <element name="lineIdentifier" type="{http://www.cisco.com/AXL/API/8.0}XNumplanIdentifier"/>
 *                 </choice>
 *               </restriction>
 *             </complexContent>
 *           </complexType>
 *         </element>
 *         <element name="prefixDn" type="{http://www.cisco.com/AXL/API/8.0}String255" minOccurs="0"/>
 *         <element name="presentationBit" type="{http://www.cisco.com/AXL/API/8.0}XPresentationBit" minOccurs="0"/>
 *         <element name="silenceSuppressionThreshold" type="{http://www.cisco.com/AXL/API/8.0}XSilenceSuppressionThreshold" minOccurs="0"/>
 *         <element name="smdiPortNumber" type="{http://www.cisco.com/AXL/API/8.0}XInteger"/>
 *         <element name="startDialProtocol" type="{http://www.cisco.com/AXL/API/8.0}XStartDialProtocol" minOccurs="0"/>
 *         <element name="trunk" type="{http://www.cisco.com/AXL/API/8.0}XTrunk" minOccurs="0"/>
 *         <element name="trunkDirection" type="{http://www.cisco.com/AXL/API/8.0}XTrunkDirection"/>
 *         <element name="trunkLevel" type="{http://www.cisco.com/AXL/API/8.0}XTrunkLevel" minOccurs="0"/>
 *         <element name="trunkPadRx" type="{http://www.cisco.com/AXL/API/8.0}XTrunkPad" minOccurs="0"/>
 *         <element name="trunkPadTx" type="{http://www.cisco.com/AXL/API/8.0}XTrunkPad" minOccurs="0"/>
 *         <element name="vendorConfig" type="{http://www.cisco.com/AXL/API/8.0}XVendorConfig" minOccurs="0"/>
 *         <element name="timer1" type="{http://www.cisco.com/AXL/API/8.0}XInteger"/>
 *         <element name="timer2" type="{http://www.cisco.com/AXL/API/8.0}XInteger"/>
 *         <element name="timer3" type="{http://www.cisco.com/AXL/API/8.0}XInteger"/>
 *         <element name="timer4" type="{http://www.cisco.com/AXL/API/8.0}XInteger"/>
 *         <element name="timer5" type="{http://www.cisco.com/AXL/API/8.0}XInteger"/>
 *         <element name="timer6" type="{http://www.cisco.com/AXL/API/8.0}XInteger"/>
 *       </sequence>
 *     </restriction>
 *   </complexContent>
 * </complexType>
 *

 *
 *
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "XAnalogPort", propOrder = {
    "portNumber",
    "attendantDn",
    "unattendedPort",
    "callerIdDn",
    "callerIdEnable",
    "callingPartySelection",
    "digitSending",
    "expectedDigits",
    "sigDigits",
    "lines",
    "prefixDn",
    "presentationBit",
    "silenceSuppressionThreshold",
    "smdiPortNumber",
    "startDialProtocol",
    "trunk",
    "trunkDirection",
    "trunkLevel",
    "trunkPadRx",
    "trunkPadTx",
    "vendorConfig",
    "timer1",
    "timer2",
    "timer3",
    "timer4",
    "timer5",
    "timer6"
})
public class XAnalogPort {

    protected String portNumber;
    protected String attendantDn;
    @XmlElementRef(name = "unattendedPort", type = JAXBElement.class)
    protected JAXBElement<String> unattendedPort;
    @XmlElementRef(name = "callerIdDn", type = JAXBElement.class)
    protected JAXBElement<String> callerIdDn;
    protected String callerIdEnable;
    protected String callingPartySelection;
    @XmlElement(defaultValue = "DTMF")
    protected String digitSending;
    protected String expectedDigits;
    protected XAnalogPort.SigDigits sigDigits;
    protected XAnalogPort.Lines lines;
    @XmlElementRef(name = "prefixDn", type = JAXBElement.class)
    protected JAXBElement<String> prefixDn;
    protected String presentationBit;
    protected String silenceSuppressionThreshold;
    @XmlElement(defaultValue = "0")
    protected String smdiPortNumber;
    @XmlElement(defaultValue = "Not Set")
    protected String startDialProtocol;
    protected String trunk;
    protected String trunkDirection;
    protected String trunkLevel;
    protected String trunkPadRx;
    protected String trunkPadTx;
    @XmlElementRef(name = "vendorConfig", type = JAXBElement.class)
    protected JAXBElement<XVendorConfig> vendorConfig;
    protected String timer1;
    protected String timer2;
    protected String timer3;
    protected String timer4;
    protected String timer5;
    protected String timer6;

    /**
     * Gets the value of the portNumber property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getPortNumber() {
        return portNumber;
    }

    /**
     * Sets the value of the portNumber property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setPortNumber(String value) {
        this.portNumber = value;
    }

    /**
     * Gets the value of the attendantDn property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getAttendantDn() {
        return attendantDn;
    }

    /**
     * Sets the value of the attendantDn property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setAttendantDn(String value) {
        this.attendantDn = value;
    }

    /**
     * Gets the value of the unattendedPort property.
     *
     * @return
     *     possible object is
     *     {@link JAXBElement }{@code <}{@link String }{@code >}
     *
     */
    public JAXBElement<String> getUnattendedPort() {
        return unattendedPort;
    }

    /**
     * Sets the value of the unattendedPort property.
     *
     * @param value
     *     allowed object is
     *     {@link JAXBElement }{@code <}{@link String }{@code >}
     *
     */
    public void setUnattendedPort(JAXBElement<String> value) {
        this.unattendedPort = ((JAXBElement<String> ) value);
    }

    /**
     * Gets the value of the callerIdDn property.
     *
     * @return
     *     possible object is
     *     {@link JAXBElement }{@code <}{@link String }{@code >}
     *
     */
    public JAXBElement<String> getCallerIdDn() {
        return callerIdDn;
    }

    /**
     * Sets the value of the callerIdDn property.
     *
     * @param value
     *     allowed object is
     *     {@link JAXBElement }{@code <}{@link String }{@code >}
     *
     */
    public void setCallerIdDn(JAXBElement<String> value) {
        this.callerIdDn = ((JAXBElement<String> ) value);
    }

    /**
     * Gets the value of the callerIdEnable property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getCallerIdEnable() {
        return callerIdEnable;
    }

    /**
     * Sets the value of the callerIdEnable property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setCallerIdEnable(String value) {
        this.callerIdEnable = value;
    }

    /**
     * Gets the value of the callingPartySelection property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getCallingPartySelection() {
        return callingPartySelection;
    }

    /**
     * Sets the value of the callingPartySelection property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setCallingPartySelection(String value) {
        this.callingPartySelection = value;
    }

    /**
     * Gets the value of the digitSending property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getDigitSending() {
        return digitSending;
    }

    /**
     * Sets the value of the digitSending property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setDigitSending(String value) {
        this.digitSending = value;
    }

    /**
     * Gets the value of the expectedDigits property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getExpectedDigits() {
        return expectedDigits;
    }

    /**
     * Sets the value of the expectedDigits property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setExpectedDigits(String value) {
        this.expectedDigits = value;
    }

    /**
     * Gets the value of the sigDigits property.
     *
     * @return
     *     possible object is
     *     {@link XAnalogPort.SigDigits }
     *
     */
    public XAnalogPort.SigDigits getSigDigits() {
        return sigDigits;
    }

    /**
     * Sets the value of the sigDigits property.
     *
     * @param value
     *     allowed object is
     *     {@link XAnalogPort.SigDigits }
     *
     */
    public void setSigDigits(XAnalogPort.SigDigits value) {
        this.sigDigits = value;
    }

    /**
     * Gets the value of the lines property.
     *
     * @return
     *     possible object is
     *     {@link XAnalogPort.Lines }
     *
     */
    public XAnalogPort.Lines getLines() {
        return lines;
    }

    /**
     * Sets the value of the lines property.
     *
     * @param value
     *     allowed object is
     *     {@link XAnalogPort.Lines }
     *
     */
    public void setLines(XAnalogPort.Lines value) {
        this.lines = value;
    }

    /**
     * Gets the value of the prefixDn property.
     *
     * @return
     *     possible object is
     *     {@link JAXBElement }{@code <}{@link String }{@code >}
     *
     */
    public JAXBElement<String> getPrefixDn() {
        return prefixDn;
    }

    /**
     * Sets the value of the prefixDn property.
     *
     * @param value
     *     allowed object is
     *     {@link JAXBElement }{@code <}{@link String }{@code >}
     *
     */
    public void setPrefixDn(JAXBElement<String> value) {
        this.prefixDn = ((JAXBElement<String> ) value);
    }

    /**
     * Gets the value of the presentationBit property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getPresentationBit() {
        return presentationBit;
    }

    /**
     * Sets the value of the presentationBit property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setPresentationBit(String value) {
        this.presentationBit = value;
    }

    /**
     * Gets the value of the silenceSuppressionThreshold property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getSilenceSuppressionThreshold() {
        return silenceSuppressionThreshold;
    }

    /**
     * Sets the value of the silenceSuppressionThreshold property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setSilenceSuppressionThreshold(String value) {
        this.silenceSuppressionThreshold = value;
    }

    /**
     * Gets the value of the smdiPortNumber property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getSmdiPortNumber() {
        return smdiPortNumber;
    }

    /**
     * Sets the value of the smdiPortNumber property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setSmdiPortNumber(String value) {
        this.smdiPortNumber = value;
    }

    /**
     * Gets the value of the startDialProtocol property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getStartDialProtocol() {
        return startDialProtocol;
    }

    /**
     * Sets the value of the startDialProtocol property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setStartDialProtocol(String value) {
        this.startDialProtocol = value;
    }

    /**
     * Gets the value of the trunk property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getTrunk() {
        return trunk;
    }

    /**
     * Sets the value of the trunk property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setTrunk(String value) {
        this.trunk = value;
    }

    /**
     * Gets the value of the trunkDirection property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getTrunkDirection() {
        return trunkDirection;
    }

    /**
     * Sets the value of the trunkDirection property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setTrunkDirection(String value) {
        this.trunkDirection = value;
    }

    /**
     * Gets the value of the trunkLevel property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getTrunkLevel() {
        return trunkLevel;
    }

    /**
     * Sets the value of the trunkLevel property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setTrunkLevel(String value) {
        this.trunkLevel = value;
    }

    /**
     * Gets the value of the trunkPadRx property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getTrunkPadRx() {
        return trunkPadRx;
    }

    /**
     * Sets the value of the trunkPadRx property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setTrunkPadRx(String value) {
        this.trunkPadRx = value;
    }

    /**
     * Gets the value of the trunkPadTx property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getTrunkPadTx() {
        return trunkPadTx;
    }

    /**
     * Sets the value of the trunkPadTx property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setTrunkPadTx(String value) {
        this.trunkPadTx = value;
    }

    /**
     * Gets the value of the vendorConfig property.
     *
     * @return
     *     possible object is
     *     {@link JAXBElement }{@code <}{@link XVendorConfig }{@code >}
     *
     */
    public JAXBElement<XVendorConfig> getVendorConfig() {
        return vendorConfig;
    }

    /**
     * Sets the value of the vendorConfig property.
     *
     * @param value
     *     allowed object is
     *     {@link JAXBElement }{@code <}{@link XVendorConfig }{@code >}
     *
     */
    public void setVendorConfig(JAXBElement<XVendorConfig> value) {
        this.vendorConfig = ((JAXBElement<XVendorConfig> ) value);
    }

    /**
     * Gets the value of the timer1 property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getTimer1() {
        return timer1;
    }

    /**
     * Sets the value of the timer1 property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setTimer1(String value) {
        this.timer1 = value;
    }

    /**
     * Gets the value of the timer2 property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getTimer2() {
        return timer2;
    }

    /**
     * Sets the value of the timer2 property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setTimer2(String value) {
        this.timer2 = value;
    }

    /**
     * Gets the value of the timer3 property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getTimer3() {
        return timer3;
    }

    /**
     * Sets the value of the timer3 property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setTimer3(String value) {
        this.timer3 = value;
    }

    /**
     * Gets the value of the timer4 property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getTimer4() {
        return timer4;
    }

    /**
     * Sets the value of the timer4 property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setTimer4(String value) {
        this.timer4 = value;
    }

    /**
     * Gets the value of the timer5 property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getTimer5() {
        return timer5;
    }

    /**
     * Sets the value of the timer5 property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setTimer5(String value) {
        this.timer5 = value;
    }

    /**
     * Gets the value of the timer6 property.
     *
     * @return
     *     possible object is
     *     {@link String }
     *
     */
    public String getTimer6() {
        return timer6;
    }

    /**
     * Sets the value of the timer6 property.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     *
     */
    public void setTimer6(String value) {
        this.timer6 = value;
    }

    /**
     *
Java class for anonymous complex type.
     *
     *
The following schema fragment specifies the expected content contained within this class.
     *
     *

     * <complexType>
     *   <complexContent>
     *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
     *       <choice>
     *         <element name="line" type="{http://www.cisco.com/AXL/API/8.0}XPhoneLine"/>
     *         <element name="lineIdentifier" type="{http://www.cisco.com/AXL/API/8.0}XNumplanIdentifier"/>
     *       </choice>
     *     </restriction>
     *   </complexContent>
     * </complexType>
     *

     *
     *
     */
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "line",
        "lineIdentifier"
    })
    public static class Lines {

        protected XPhoneLine line;
        protected XNumplanIdentifier lineIdentifier;

        /**
         * Gets the value of the line property.
         *
         * @return
         *     possible object is
         *     {@link XPhoneLine }
         *
         */
        public XPhoneLine getLine() {
            return line;
        }

        /**
         * Sets the value of the line property.
         *
         * @param value
         *     allowed object is
         *     {@link XPhoneLine }
         *
         */
        public void setLine(XPhoneLine value) {
            this.line = value;
        }

        /**
         * Gets the value of the lineIdentifier property.
         *
         * @return
         *     possible object is
         *     {@link XNumplanIdentifier }
         *
         */
        public XNumplanIdentifier getLineIdentifier() {
            return lineIdentifier;
        }

        /**
         * Sets the value of the lineIdentifier property.
         *
         * @param value
         *     allowed object is
         *     {@link XNumplanIdentifier }
         *
         */
        public void setLineIdentifier(XNumplanIdentifier value) {
            this.lineIdentifier = value;
        }

    }

    /**
     *
Java class for anonymous complex type.
     *
     *
The following schema fragment specifies the expected content contained within this class.
     *
     *

     * <complexType>
     *   <simpleContent>
     *     <extension base="<http://www.cisco.com/AXL/API/8.0>XInteger">
     *       <attribute name="enable" type="{http://www.w3.org/2001/XMLSchema}boolean" />
     *     </extension>
     *   </simpleContent>
     * </complexType>
     *

     *
     *
     */
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "value"
    })
    public static class SigDigits {

        @XmlValue
        protected String value;
        @XmlAttribute
        protected Boolean enable;

        /**
         * Gets the value of the value property.
         *
         * @return
         *     possible object is
         *     {@link String }
         *
         */
        public String getValue() {
            return value;
        }

        /**
         * Sets the value of the value property.
         *
         * @param value
         *     allowed object is
         *     {@link String }
         *
         */
        public void setValue(String value) {
            this.value = value;
        }

        /**
         * Gets the value of the enable property.
         *
         * @return
         *     possible object is
         *     {@link Boolean }
         *
         */
        public Boolean isEnable() {
            return enable;
        }

        /**
         * Sets the value of the enable property.
         *
         * @param value
         *     allowed object is
         *     {@link Boolean }
         *
         */
        public void setEnable(Boolean value) {
            this.enable = value;
        }

    }

}


text:
<?php

namespace Perfumer\Framework\View;

use Perfumer\Framework\Controller\Exception\ExitActionException;

trait StatusViewControllerHelpers
{
    /**
     * @return bool
     */
    protected function getStatus()
    {
        return $this->getView()->getStatus();
    }

    /**
     * @param bool $status
     */
    protected function setStatus($status)
    {
        $this->getView()->setStatus($status);
    }

    /**
     * @param bool $status
     * @throws ExitActionException
     */
    protected function setStatusAndExit($status)
    {
        $this->getView()->setStatus($status);

        throw new ExitActionException();
    }

    /**
     * @return string
     */
    protected function getStatusCode()
    {
        return $this->getView()->getStatusCode();
    }

    /**
     * @param string $status_code
     */
    protected function setStatusCode($status_code)
    {
        $this->getView()->setStatusCode($status_code);
    }

    /**
     * @param string $status_code
     * @throws ExitActionException
     */
    protected function setStatusCodeAndExit($status_code)
    {
        $this->getView()->setStatusCode($status_code);

        throw new ExitActionException();
    }

    /**
     * @return string
     */
    protected function getMessage()
    {
        return $this->getView()->getMessage();
    }

    /**
     * @param string $message
     */
    protected function setErrorMessage($message)
    {
        $this->getView()->setErrorMessage($message);
    }

    /**
     * @param string $message
     * @throws ExitActionException
     */
    protected function setErrorMessageAndExit($message)
    {
        $this->getView()->setErrorMessage($message);

        throw new ExitActionException;
    }

    /**
     * @param string $message
     */
    protected function setSuccessMessage($message)
    {
        $this->getView()->setSuccessMessage($message);
    }

    /**
     * @param string $message
     * @throws ExitActionException
     */
    protected function setSuccessMessageAndExit($message)
    {
        $this->getView()->setSuccessMessage($message);

        throw new ExitActionException;
    }

    /**
     * @return bool
     */
    protected function hasMessage()
    {
        return $this->getView()->hasMessage();
    }

    /**
     * @return array
     */
    protected function getErrors()
    {
        return $this->getView()->getErrors();
    }

    /**
     * @param string $key
     * @return mixed
     */
    protected function getError($key)
    {
        return $this->getView()->getError($key);
    }

    /**
     * @param array $errors
     */
    protected function addErrors($errors)
    {
        $this->getView()->addErrors($errors);
    }

    /**
     * @param array $errors
     * @throws ExitActionException
     */
    protected function addErrorsAndExit($errors)
    {
        $this->getView()->addErrors($errors);

        throw new ExitActionException;
    }

    /**
     * @param string $key
     * @param mixed $value
     */
    protected function addError($key, $value)
    {
        $this->getView()->addError($key, $value);
    }

    /**
     * @param string $key
     * @param mixed $value
     * @throws ExitActionException
     */
    protected function addErrorAndExit($key, $value)
    {
        $this->getView()->addError($key, $value);

        throw new ExitActionException;
    }

    /**
     * @return bool
     */
    protected function hasErrors()
    {
        return $this->getView()->hasErrors();
    }

    /**
     * @param string $key
     * @return bool
     */
    protected function hasError($key)
    {
        return $this->getView()->hasError($key);
    }

    /**
     * @return mixed
     */
    protected function getContent()
    {
        return $this->getView()->getContent();
    }

    /**
     * @param mixed $content
     */
    protected function setContent($content)
    {
        $this->getView()->setContent($content);
    }

    /**
     * @param mixed $content
     * @throws ExitActionException
     */
    protected function setContentAndExit($content)
    {
        $this->getView()->setContent($content);

        throw new ExitActionException();
    }

    /**
     * @return bool mixed
     */
    protected function hasContent()
    {
        return $this->getView()->hasContent();
    }
}


text:
def test_crohme_get_parser_test():
    # First party modules
    from hwrt.datasets import crohme_eval

    crohme_eval.get_parser()

def test_expressmatch_get_writemath_username_test():
    # First party modules
    from hwrt.datasets import expressmatch

    path = "/home/moose/Downloads/expressmatch-time-datasetV0.2/65_Nina.inkml"
    expressmatch.get_writemath_username(path)

def test_inkml_normalize_symbol_name_test():
    # First party modules
    from hwrt.datasets import inkml

    assert inkml.normalize_symbol_name("A") == "A"

def test_mathbrush_mathbrush_formula_fix_test():
    # First party modules
    from hwrt.datasets import mathbrush

    assert mathbrush.mathbrush_formula_fix("lparen") == "("

def test_mfrdb_strip_end_test():
    # First party modules
    from hwrt.datasets import mfrdb

    assert mfrdb.strip_end("asdf", "df") == "as"

def test_mfrdb_eval_less_than_test():
    # First party modules
    from hwrt import utils

    utils.less_than([1, 2, 3], 2)


text:
skcraft-mobile-backend
===========

SKCraft Mobile GCM backend.

#### License
skcraft-mobile-backend is licensed under the MIT License.


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using SQLite.Net.Expressions;
using SQLite.Net.Helpers;

namespace SQLite.Net.Translation
{
	internal class RedundantSubqueryRemover : DbExpressionVisitor
	{
		private RedundantSubqueryRemover(){}

		internal static Expression Remove(Expression expression)
		{
			expression = new RedundantSubqueryRemover().Visit(expression);
			expression = SubqueryMerger.Merge(expression);
			return expression;
		}

		protected override Expression VisitSelect(SelectExpression select)
		{
			select = (SelectExpression)base.VisitSelect(select);

			// first remove all purely redundant subqueries
			List<SelectExpression> redundant = RedundantSubqueryGatherer.Gather(select.From);
			if (redundant != null)
			{
				select = SubqueryRemover.Remove(select, redundant);
			}

			return select;
		}

		protected override Expression VisitProjection(ProjectionExpression proj)
		{
			proj = (ProjectionExpression)base.VisitProjection(proj);
			if (proj.Source is SelectExpression select && select.From is QueryExpression)
			{
				List<SelectExpression> redundant = RedundantSubqueryGatherer.Gather(proj.Source);
				if (redundant != null)
				{
					proj = SubqueryRemover.Remove(proj, redundant);
				}
			}
			return proj;
		}

		private static bool ProjectionIsSimple(SelectExpression select)
		{
			return select.Columns.All(c => c.Expression is ColumnExpression colExpr && colExpr.Name == c.Name);
		}

		private static bool IsColumnProjection(SelectExpression select)
		{
			return !select.Columns.Any(cd => cd.Expression.NodeType != (ExpressionType)DbExpressionType.Column &&
											 cd.Expression.NodeType != ExpressionType.Constant);
		}

		private static bool IsNameMapProjection(SelectExpression select)
		{
			if (select.From is SelectExpression fromSelect && select.Columns.Count == fromSelect.Columns.Count)
			{
				// test that all columns in 'select' are refering to columns in the same position
				// in 'fromSelect'.
				return select.Columns.Zip(
					fromSelect.Columns,
					(col, fCol) => col.Expression is ColumnExpression && ((ColumnExpression)col.Expression).Name == fCol.Name
				)
				.All(equal => equal);
			}

			if (select.From is RawQueryExpression)
			{
				return IsColumnProjection(select);
			}
			return false;
		}

		private class RedundantSubqueryGatherer : DbExpressionVisitor
		{
			private List<SelectExpression> _redundant;

			private RedundantSubqueryGatherer() { }

			internal static List<SelectExpression> Gather(Expression source)
			{
				RedundantSubqueryGatherer gatherer = new RedundantSubqueryGatherer();
				gatherer.Visit(source);
				return gatherer._redundant;
			}

			private static bool IsRedudantSubquery(SelectExpression select)
			{
				return select.From is AliasedExpression
				       && (ProjectionIsSimple(select) || IsNameMapProjection(select))
					   && !select.IsDistinct
				       && select.Where == null
					   && select.Limit == null
					   && select.Offset == null
					   && select.Having == null
				       && (select.GroupBy == null || select.GroupBy.Count == 0)
				       && (select.OrderBy == null || select.OrderBy.Count == 0);
			}

			protected override Expression VisitSelect(SelectExpression select)
			{
				if (IsRedudantSubquery(select))
				{
					if (_redundant == null)
					{
						_redundant = new List<SelectExpression>();
					}
					_redundant.Add(select);
				}
				return select;
			}

			protected override Expression VisitSubquery(SubQueryExpression subquery)
			{
				// don't gather inside scalar & exists
				return subquery;
			}
		}

		private class SubqueryMerger : DbExpressionVisitor
		{
			private bool _isTopLevel = true;

			private SubqueryMerger(){}

			internal static Expression Merge(Expression expression)
			{
				return new SubqueryMerger().Visit(expression);
			}

			protected override Expression VisitSelect(SelectExpression select)
			{
				bool wasTopLevel = _isTopLevel;
				_isTopLevel = false;

				select = (SelectExpression)base.VisitSelect(select);

				// next attempt to merge subqueries that would have been removed by the above
				// logic except for the existence of a where clause
				while (CanMergeWithFrom(select, wasTopLevel))
				{
					SelectExpression fromSelect = GetLeftMostSelect(select.From);

					// remove the redundant subquery
					select = SubqueryRemover.Remove(select, fromSelect);

					// merge where expressions
					Expression where;
					Expression having;
					if (fromSelect.GroupBy != null && fromSelect.GroupBy.Count > 0)
					{
						where = fromSelect.Where;
						having = select.Where;
						if (fromSelect.Having != null)
						{
							having = having != null ? Expression.AndAlso(fromSelect.Having, having) : fromSelect.Having;
						}
					}
					else
					{
						where = select.Where;
						if (fromSelect.Where != null)
						{
							where = where != null ? Expression.AndAlso(fromSelect.Where, where) : fromSelect.Where;
						}
						having = null;
					}

					var orderBy = select.OrderBy != null && select.OrderBy.Count > 0 ? select.OrderBy : fromSelect.OrderBy;
					var groupBy = select.GroupBy != null && select.GroupBy.Count > 0 ? select.GroupBy : fromSelect.GroupBy;
					Expression offset = select.Offset;
					if (fromSelect.Offset != null)
					{
						offset = offset == null ? fromSelect.Offset : Expression.Add(fromSelect.Offset, offset);
					}
					Expression limit = select.Limit ?? fromSelect.Limit;
					if (fromSelect.Limit != null)
					{
						limit = limit == null ? fromSelect.Limit :
							Expression.Call(typeof(Math), nameof(Math.Min), null, fromSelect.Limit, limit);
					}
					bool isDistinct = select.IsDistinct | fromSelect.IsDistinct;

					if (where != select.Where
					    || orderBy != select.OrderBy
					    || groupBy != select.GroupBy
						|| having != select.Having
					    || isDistinct != select.IsDistinct
					    || offset != select.Offset
					    || limit != select.Limit)
					{
						select = new SelectExpression(
							select.Alias, select.Columns, select.From, where, groupBy, having, orderBy, offset, limit, isDistinct
						);
					}
				}

				return select;
			}

			private static SelectExpression GetLeftMostSelect(Expression source)
			{
				if (source is SelectExpression select) return select;
				if (source is JoinExpression join) return GetLeftMostSelect(join.Left);
				return null;
			}

			private static bool CanMergeWithFrom(SelectExpression select, bool isTopLevel)
			{
				SelectExpression fromSelect = GetLeftMostSelect(select.From);
				if (fromSelect == null) return false;
				//if (!IsColumnProjection(fromSelect)) return false;

				bool selHasNameMapProjection = IsNameMapProjection(select);
				bool selHasOrderBy = select.OrderBy != null && select.OrderBy.Count > 0;
				bool selHasGroupBy = select.GroupBy != null && select.GroupBy.Count > 0;
				bool selHasAggregates = AggregateChecker.HasAggregates(select);
				bool selHasJoin = select.From is JoinExpression;
				bool frmHasOrderBy = fromSelect.OrderBy != null && fromSelect.OrderBy.Count > 0;
				bool frmHasGroupBy = fromSelect.GroupBy != null && fromSelect.GroupBy.Count > 0;
				bool frmHasAggregates = AggregateChecker.HasAggregates(fromSelect);

				// both cannot have orderby
				if (selHasOrderBy && frmHasOrderBy) return false;
				// both cannot have groupby
				if (selHasGroupBy && frmHasGroupBy) return false;
				// cannot move forward order-by if outer has group-by
				if (frmHasOrderBy && (selHasGroupBy || selHasAggregates || select.IsDistinct)) return false;
				// cannot move forward a limit or an offset if outer has distinct
				if (fromSelect.Limit != null && fromSelect.Offset != null && (select.IsDistinct || selHasAggregates || selHasGroupBy || selHasJoin)) return false;
				// cannot move forward a distinct if outer has groupby or a different projection
				if (fromSelect.IsDistinct && (!selHasNameMapProjection || selHasGroupBy || selHasAggregates || (selHasOrderBy && !isTopLevel) || selHasJoin))
					return false;
				if (frmHasAggregates && (select.IsDistinct || selHasAggregates || selHasGroupBy || selHasJoin)) return false;

				return true;
			}
		}
	}
}


text:
import { GanttColumnHeadersOverlayDirective } from './gantt-column-headers-overlay.directive';

describe('GanttColumnHeadersOverlayDirective', () => {
  it('should create an instance', () => {
    const directive = new GanttColumnHeadersOverlayDirective(null);
    expect(directive).toBeTruthy();
  });
});