package org.apache.synapse.endpoints;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.clustering.Member;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.synapse.MessageContext;
import org.apache.synapse.SynapseConstants;
import org.apache.synapse.SynapseException;
import org.apache.synapse.core.SynapseEnvironment;
import org.apache.synapse.core.axis2.Axis2MessageContext;
import org.apache.synapse.mediators.Value;
import org.apache.synapse.mediators.eip.EIPConstants;
import org.apache.synapse.util.MessageHelper;

/**
 * <p>
 * A Recipient List endpoint can contain multiple child endpoints or member elements.
 * It routes cloned copies of messages to each child recipient. This will assume that
 * all immediate child endpoints are identical in state (state is replicated) or state
 * is not maintained at those endpoints.
 * </p>
 */
public class RecipientListEndpoint extends AbstractEndpoint {

    private static final Log log = LogFactory.getLog(RecipientListEndpoint.class);

    private static final String DELIMITER = ",";

    /**
     * The list of members to which the message is delivered to
     */
    private List<Member> members;

    private Map<String, Endpoint> dynamicEndpointPool;

    private Value dynamicEndpointSet;

    public final static int DEFAULT_MAX_POOL = 20;

    /**
     * Should this recipient list fail over;
     */
    private boolean failover;

    private int currentPool;

    private SynapseEnvironment env = null;

    public RecipientListEndpoint(int poolSize) {
        dynamicEndpointPool = Collections.synchronizedMap(new DynamicEndpointPool<String, Endpoint>(poolSize));
        this.currentPool = poolSize;
    }

    public RecipientListEndpoint() {
        this.currentPool = DEFAULT_MAX_POOL;
    }

    @Override
    public void init(SynapseEnvironment synapseEnvironment) {
        if (!initialized) {
            super.init(synapseEnvironment);
        }
        this.env = synapseEnvironment;
    }

    @Override
    public void destroy() {
        super.destroy();
    }

    @Override
    public void send(MessageContext synCtx) {
        if (log.isDebugEnabled()) {
            log.debug("Sending using Recipient List " + toString());
        }
        List<Endpoint> children = getChildren();
        // Service child endpoints
        if (children != null && !children.isEmpty()) {
            sendToEndpointList(synCtx, children);
        } else if (members != null && !members.isEmpty()) {
            // Service member elements if specified
            sendToApplicationMembers(synCtx);
        } else if (dynamicEndpointSet != null) {
            sendToDynamicMembers(synCtx);
        } else {
            String msg = "No child endpoints nor members available";
            log.error(msg);
            throw new SynapseException(msg);
        }
    }

    private void sendToEndpointList(MessageContext synCtx, List<Endpoint> children) {
        int i = 0;
        boolean foundEndpoint = false;
        for (Endpoint childEndpoint : children) {
            if (childEndpoint.readyToSend()) {
                foundEndpoint = true;
                MessageContext newCtx;

// Used when aggregating responses
                newCtx.setProperty(EIPConstants.MESSAGE_SEQUENCE, String.valueOf(i++) + EIPConstants.MESSAGE_SEQUENCE_DELEMITER + children.size());
                // evaluate the endpoint properties
                evaluateProperties(newCtx);
                newCtx.pushFaultHandler(this);
                childEndpoint.send(newCtx);
            }
        }
        if (!foundEndpoint) {
            String msg = "Recipient List endpoint : " + (getName() != null ? getName() : SynapseConstants.ANONYMOUS_ENDPOINT) + " - no ready child endpoints";
            log.warn(msg);
            informFailure(synCtx, SynapseConstants.ENDPOINT_FO_NONE_READY, msg);
        }
    }

    private void sendToDynamicMembers(MessageContext synCtx) {
        String dynamicUrlStr = dynamicEndpointSet.evaluateValue(synCtx);
        String[] dynamicUrlSet = dynamicUrlStr.split(DELIMITER);
        if (dynamicUrlSet.length == 0) {
            log.warn("No recipients were derived from the expression : " + dynamicEndpointSet.toString());
            return;
        }
        List<Endpoint> children = new ArrayList<Endpoint>();
        for (String url : dynamicUrlSet) {
            url = StringUtils.deleteWhitespace(url);
            if (StringUtils.isNotEmpty(url)) {
                // get an Endpoint from the pool
                Endpoint epFromPool = dynamicEndpointPool.get(url);
                if (epFromPool == null) {
                    AddressEndpoint endpoint = new AddressEndpoint();
                    endpoint.setEnableMBeanStats(false);
                    endpoint.setName("DYNAMIC_RECIPIENT_LIST_EP_" + UUID.randomUUID());
                    EndpointDefinition definition = new EndpointDefinition();
                    definition.setReplicationDisabled(true);
                    definition.setAddress(url);
                    endpoint.setDefinition(definition);
                    endpoint.init(env);
                    // finally add the newly created endpoint to the Pool
                    dynamicEndpointPool.put(url, endpoint);
                    children.add(endpoint);
                } else {
                    // do nothing endpoint is already in the pool
                    children.add(epFromPool);
                }
            }
        }
        if (children.size() > 0) {
            sendToEndpointList(synCtx, children);
        } else {
            if (log.isDebugEnabled()) {
                log.debug("Halted sending messages to recipients. No recipient found !!! : " + dynamicUrlStr);
            }
        }
    }

    /**
     *
Iterates the members list, creates Address Endpoints
     *  from each member element and routes cloned copies of the message
     *  to each Address Endpoint.

     *  @param synCtx - The Original Message received by Synapse
     */
    private void sendToApplicationMembers(MessageContext synCtx) {
        int i = 0;
        boolean foundEndpoint = false;
        for (Member member : members) {
            org.apache.axis2.context.MessageContext axis2MsgCtx = ((Axis2MessageContext) synCtx).getAxis2MessageContext();
            String transport = axis2MsgCtx.getTransportIn().getName();
            // If the transport is not HTTP nor HTTPS
            if (!transport.equals("http") && !transport.equals("https")) {
                // Skip member.
                log.error("Cannot deliver for non-HTTP/S transport " + transport);
                continue;
            }
            MessageContext newCtx;
            try {
                newCtx = MessageHelper.cloneMessageContext(synCtx);
            } catch (AxisFault e) {
                handleException("Error cloning the message context", e);
                return;
            }
            // Used when aggregating responses
            newCtx.setProperty(EIPConstants.MESSAGE_SEQUENCE, String.valueOf(i++) + EIPConstants.MESSAGE_SEQUENCE_DELEMITER + members.size());
            // evaluate the endpoint properties
            evaluateProperties(newCtx);
            // URL rewrite
            String address = newCtx.getTo().getAddress();
            if (address.contains(":")) {
                try {
                    address = new URL(address).getPath();
                } catch (MalformedURLException e) {
                    String msg = "URL " + address + " is malformed";
                    log.error(msg, e);
                    throw new SynapseException(msg, e);
                }
            }
            EndpointReference epr = new EndpointReference(transport + "://" + member.getHostName() + ":" + ("http".equals(transport) ? member.getHttpPort() : member.getHttpsPort()) + address);
            newCtx.setTo(epr);
            newCtx.pushFaultHandler(this);
            AddressEndpoint endpoint = new AddressEndpoint();
            EndpointDefinition definition = new EndpointDefinition();
            endpoint.setDefinition(definition);
            endpoint.init(newCtx.getEnvironment());
            if (endpoint.readyToSend()) {
                foundEndpoint = true;
                endpoint.send(newCtx);
            }
        }
        if (!foundEndpoint) {
            String msg = "Recipient List endpoint : " + (getName() != null ? getName() : SynapseConstants.ANONYMOUS_ENDPOINT) + " - no ready child members";
            log.warn(msg);
            informFailure(synCtx, SynapseConstants.ENDPOINT_FO_NONE_READY, msg);
        }
    }

    @Override
    public boolean readyToSend() {
        for (Endpoint endpoint : getChildren()) {
            if (endpoint.readyToSend()) {
                if (log.isDebugEnabled()) {
                    log.debug("Recipient List " + this.toString() + " has at least one endpoint at ready state");
                }
                return true;
            }
        }
        return false;
    }

    public void onChildEndpointFail(Endpoint endpoint, MessageContext synMessageContext) {
        // we just log the failed recipient here
        logOnChildEndpointFail(endpoint, synMessageContext);
        String msg = "";
        if (log.isDebugEnabled()) {
            msg = "Recipient List endpoint : " + (getName() != null ? getName() : SynapseConstants.ANONYMOUS_ENDPOINT) + " - one of the recipients encounterd an error while sending the message ";
            log.debug(msg);
        }
        informFailure(synMessageContext, SynapseConstants.ENDPOINT_FO_NONE_READY, msg);
    }

    public List<Member> getMembers() {
        return members;
    }

    public void setMembers(List<Member> members) {
        this.members = members;
    }

    public Value getDynamicEndpointSet() {
        return dynamicEndpointSet;
    }

    public void setDynamicEndpointSet(Value dynamicEndpointSet) {
        this.dynamicEndpointSet = dynamicEndpointSet;
    }

    public int getCurrentPoolSize() {
        return currentPool;
    }

    public boolean isFailover() {
        return failover;
    }

    public void setFailover(boolean failover) {
        this.failover = failover;
    }

    /**
     * create a simple LRU cached Endpoint pool for dynamic endpoints
     */
    private static class DynamicEndpointPool<String, Endpoint> extends LinkedHashMap<String, Endpoint> {

        private final int maxPoolSize;

        public DynamicEndpointPool(final int max) {
            super(max + 1, 1.0f, true);
            this.maxPoolSize = max;
        }

        @Override
        protected boolean removeEldestEntry(final Map.Entry<String, Endpoint> eldest) {
            return super.size() > maxPoolSize;
        }
    }
}


try {
            System.out.println("tryLock(2, TimeUnit.SECONDS): " + captured);
        } finally {
            if (captured)
                lock.unlock();
        }

package concurrency;

/* Added by Eclipse.py */
// Locks in the concurrent library allow you
// to give up on trying to acquire a lock.
import java.util.concurrent.*;
import java.util.concurrent.locks.*;

public class AttemptLocking {

    private ReentrantLock lock = new ReentrantLock();

    public void untimed() {
        boolean captured = lock.tryLock();
        try {
            System.out.println("tryLock(): " + captured);
        } finally {
            if (captured)
                lock.unlock();
        }
    }

    public void timed() {
        boolean captured = false;
        try {
            captured = lock.tryLock(2, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

    }

    public static void main(String[] args) {
        final AttemptLocking al = new AttemptLocking();
        // True -- lock is available
        al.untimed();
        // True -- lock is available
        al.timed();
        // Now create a separate task to grab the lock:
        new Thread() {

            {
                setDaemon(true);
            }

            public void run() {
                al.lock.lock();
                System.out.println("acquired");
            }
        }.start();
        // Give the 2nd task a chance
        Thread.yield();
        // False -- lock grabbed by task
        al.untimed();
        // False -- lock grabbed by task
        al.timed();
    }
}


public BigInteger getPositiveValue() {
        return new BigInteger(1, bytes);
    }

package org.apache.geronimo.crypto.asn1;

import java.io.IOException;
import java.math.BigInteger;

public class DERInteger extends DERObject {

    byte[] bytes;

    /**
     * return an integer from the passed in object
     *
     * @exception IllegalArgumentException if the object cannot be converted.
     */
    public static DERInteger getInstance(Object obj) {
        if (obj == null || obj instanceof DERInteger) {
            return (DERInteger) obj;
        }
        if (obj instanceof ASN1OctetString) {
            return new DERInteger(((ASN1OctetString) obj).getOctets());
        }
        if (obj instanceof ASN1TaggedObject) {
            return getInstance(((ASN1TaggedObject) obj).getObject());
        }
        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
    }

    /**
     * return an Integer from a tagged object.
     *
     * @param obj the tagged object holding the object we want
     * @param explicit true if the object is meant to be explicitly
     *              tagged false otherwise.
     * @exception IllegalArgumentException if the tagged object cannot
     *               be converted.
     */
    public static DERInteger getInstance(ASN1TaggedObject obj, boolean explicit) {
        return getInstance(obj.getObject());
    }

    public DERInteger(int value) {
        bytes = BigInteger.valueOf(value).toByteArray();
    }

    public DERInteger(BigInteger value) {
        bytes = value.toByteArray();
    }

    public DERInteger(byte[] bytes) {
        this.bytes = bytes;
    }

    public BigInteger getValue() {
        return new BigInteger(bytes);
    }

    /**
     * in some cases positive values get crammed into a space,
     * that's not quite big enough...
     */

    void encode(DEROutputStream out) throws IOException {
        out.writeEncoded(INTEGER, bytes);
    }

    public int hashCode() {
        int value = 0;
        for (int i = 0; i != bytes.length; i++) {
            value ^= (bytes[i] & 0xff) << (i % 4);
        }
        return value;
    }

    public boolean equals(Object o) {
        if (o == null || !(o instanceof DERInteger)) {
            return false;
        }
        DERInteger other = (DERInteger) o;
        if (bytes.length != other.bytes.length) {
            return false;
        }
        for (int i = 0; i != bytes.length; i++) {
            if (bytes[i] != other.bytes[i]) {
                return false;
            }
        }
        return true;
    }
}


for (int i = 0; i != bytes.length; i++) {
            if (bytes[i] != other.bytes[i]) {
                return false;
            }
        }

package org.apache.geronimo.crypto.asn1;

import java.io.IOException;
import java.math.BigInteger;

public class DERInteger extends DERObject {

    byte[] bytes;

    /**
     * return an integer from the passed in object
     *
     * @exception IllegalArgumentException if the object cannot be converted.
     */
    public static DERInteger getInstance(Object obj) {
        if (obj == null || obj instanceof DERInteger) {
            return (DERInteger) obj;
        }
        if (obj instanceof ASN1OctetString) {
            return new DERInteger(((ASN1OctetString) obj).getOctets());
        }
        if (obj instanceof ASN1TaggedObject) {
            return getInstance(((ASN1TaggedObject) obj).getObject());
        }
        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
    }

    /**
     * return an Integer from a tagged object.
     *
     * @param obj the tagged object holding the object we want
     * @param explicit true if the object is meant to be explicitly
     *              tagged false otherwise.
     * @exception IllegalArgumentException if the tagged object cannot
     *               be converted.
     */
    public static DERInteger getInstance(ASN1TaggedObject obj, boolean explicit) {
        return getInstance(obj.getObject());
    }

    public DERInteger(int value) {
        bytes = BigInteger.valueOf(value).toByteArray();
    }

    public DERInteger(BigInteger value) {
        bytes = value.toByteArray();
    }

    public DERInteger(byte[] bytes) {
        this.bytes = bytes;
    }

    public BigInteger getValue() {
        return new BigInteger(bytes);
    }

    /**
     * in some cases positive values get crammed into a space,
     * that's not quite big enough...
     */
    public BigInteger getPositiveValue() {
        return new BigInteger(1, bytes);
    }

    void encode(DEROutputStream out) throws IOException {
        out.writeEncoded(INTEGER, bytes);
    }

    public int hashCode() {
        int value = 0;
        for (int i = 0; i != bytes.length; i++) {
            value ^= (bytes[i] & 0xff) << (i % 4);
        }
        return value;
    }

    public boolean equals(Object o) {
        if (o == null || !(o instanceof DERInteger)) {
            return false;
        }
        DERInteger other = (DERInteger) o;
        if (bytes.length != other.bytes.length) {
            return false;
        }


public Object[][] getContents() {
        return contents;
    }

/**
 * ***************************************************************************
 *  Product: Adempiere ERP & CRM Smart Business Solution                       *
 *  For the text or an alternative of this public license, you may reach us    *
 *  ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA        *
 *  or via example@nnthink.com or http://example.com           *
 * ***************************************************************************
 */
package org.compiere.apps;

import java.util.ListResourceBundle;

/**
 *  Norwegian Base Resource Bundle Translation
 *
 * 	@author 	Olaf Slazak L\ufffdken
 * 	@version 	$Id: ALoginRes_no.java,v 1.2 2006/07/30 00:51:27 jjanke Exp $
 */
public final class ALoginRes_no extends ListResourceBundle {

    // TODO Run native2ascii to convert to plain ASCII !!
    /**
     * Translation Content
     */
    static final Object[][] contents = new String[][] { { "Connection", "Forbindelse" }, { "Defaults", "Vanlige" }, { "Login", "iDempiere Loginn" }, { "File", "Fil" }, { "Exit", "Avslutt" }, { "Help", "Hjelp" }, { "About", "Om" }, { "Host", "Maskin" }, { "Database", "Database" }, { "User", "Bruker ID" }, { "EMail", "E-post" }, { "EnterUser", "Skriv  Applikasjon Bruker ID" }, { "Password", "Passord" }, { "EnterPassword", "Skriv Applikasjon Passordet" }, { "Language", "Spr\u00e5k" }, { "SelectLanguage", "Velg spr\u00e5k" }, { "Role", "Rolle" }, { "Client", "Klient" }, { "Organization", "Organisasjon" }, { "Date", "Dato" }, { "Warehouse", "Varehus" }, { "Printer", "Skriver" }, { "Connected", "Oppkoblett" }, { "NotConnected", "Ikke Oppkoblet" }, { "DatabaseNotFound", "Database ikke funnet" }, { "UserPwdError", "Bruker passer ikke til passordet" }, { "RoleNotFound", "Role not found/complete" }, { "Authorized", "Autorisert" }, { "Ok", "Ok" }, { "Cancel", "Avbryt" }, { "VersionConflict", "Versions Konflikt:" }, { "VersionInfo", "Server <> Klient" }, { "PleaseUpgrade", "Vennligst kj\u00f8r oppdaterings programet" } };

    /**
     *  Get Contents
     *  @return context
     */


Set<? extends CharSequence> getAllTypeNames();

package gw.lang.reflect;

import gw.config.IService;
import gw.fs.IFile;
import gw.fs.IResource;
import gw.lang.gosuc.ICustomParser;
import gw.lang.gosuc.IGosuc;
import gw.lang.parser.ISymbolTable;
import gw.lang.parser.ITypeUsesMap;
import gw.lang.parser.TypeVarToTypeMap;
import gw.lang.parser.exceptions.ParseResultsException;
import gw.lang.parser.expressions.ITypeLiteralExpression;
import gw.lang.reflect.gs.IGosuClassLoader;
import gw.lang.reflect.java.IJavaClassInfo;
import gw.lang.reflect.java.IJavaType;
import gw.lang.reflect.module.IExecutionEnvironment;
import gw.lang.reflect.module.IModule;
import gw.lang.reflect.module.IProject;
import java.util.List;
import java.util.Set;

public interface ITypeSystem extends IService {

    /**
     * Gets the intrinsic type for a given class.

     *

     * Note: you should use this method only if you do not have an
     * Object of class javaClass to get the type from. If you
     * do have such an object, use {@link #getFromObject} instead.
     *
     * @param javaClass the Class to convert to an intrinsic type
     *
     * @return the IType that corresponds to that class
     *
     * @see #getFromObject(Object)
     */
    IType get(Class<?> javaClass);

    /**
     * Gets the intrinsic type for a given class info object.

     *
     * @param javaClassInfo the Class info object to convert to an intrinsic type
     *
     * @return the IType that corresponds to that class
     */
    IType get(IJavaClassInfo javaClassInfo);

    /**
     * Returns the intrinsic type for the given Object.
     *
     * @param object the object to get an IType for
     *
     * @return the IType for the object
     *
     * @see #get(Class)
     */
    IType getFromObject(Object object);

    IType getByRelativeName(String relativeName) throws ClassNotFoundException;

    /**
     * Gets an intrinsic type based on a relative name.  This could either be the name of an entity,
     * like "User", the name of a typekey, like "SystemPermission", or a class name, like
     * "java.lang.String" (relative and fully qualified class names are the same as far as this factory
     * is concerned).  Names can have [] appended to them to create arrays, and multi-dimensional arrays
     * are supported.
     *
     * @param relativeName the relative name of the type
     * @param typeUses     the map of used types to use when resolving
     *
     * @return the corresponding IType
     *
     * @throws ClassNotFoundException if the specified name doesn't correspond to any type
     */
    IType getByRelativeName(String relativeName, ITypeUsesMap typeUses) throws ClassNotFoundException;

    /**
     * Gets an intrinsic type based on a fully-qualified name.  This could either be the name of an entity,
     * like "entity.User", the name of a typekey, like "typekey.SystemPermission", or a class name, like
     * "java.lang.String".  Names can have [] appended to them to create arrays, and multi-dimensional arrays
     * are supported.
     *
     * @param fullyQualifiedName the fully qualified name of the type
     *
     * @return the corresponding IType
     *
     * @throws RuntimeException if the specified name doesn't correspond to any type
     */
    IType getByFullName(String fullyQualifiedName);

    /**
     * Gets a type based on a fully-qualified name.  This could either be the name of an entity,
     * like "entity.User", the name of a typekey, like "typekey.SystemPermission", or a class name, like
     * "java.lang.String".  Names can have [] appended to them to create arrays, and multi-dimensional arrays
     * are supported.
     *
     * This method behaves the same as getByFullName execept instead of throwing it returns null.
     *
     * @param fullyQualifiedName the fully qualified name of the type
     *
     * @return the corresponding IType or null if the type does not exist
     */
    IType getByFullNameIfValid(String fullyQualifiedName);

    IType getByFullNameIfValidNoJava(String fullyQualifiedName);

    void refresh(ITypeRef typeRef);

    void refresh(boolean bRefreshCaches);

    void refresh(IModule module);

    /**
     * @return true if any types were refreshed for this file
     */
    void refreshed(IResource file, String typeName, RefreshKind refreshKind);

    void shutdown();

    String[] getTypesForFile(IModule module, IFile file);

    int getRefreshChecksum();

    int getSingleRefreshChecksum();

    /**
     * Converts a String name of a type into an IType.
     *
     * @throws IllegalArgumentException if the type string doesn't correspond to any known IType
     */
    IType parseType(String typeString) throws IllegalArgumentException;

    IType parseType(String typeString, ITypeUsesMap typeUsesMap) throws IllegalArgumentException;

    IType parseType(String typeString, TypeVarToTypeMap actualParamByVarName);

    IType parseType(String typeString, TypeVarToTypeMap actualParamByVarName, ITypeUsesMap typeUsesMap);

    ITypeLiteralExpression parseTypeExpression(String typeString, TypeVarToTypeMap actualParamByVarName, ITypeUsesMap typeUsesMap) throws ParseResultsException;

    IType getComponentType(IType valueType);

    INamespaceType getNamespace(String strFqNamespace);

    /**
     * Returns all type names in the system for all type loaders.
     * @return all type names in the system.
     */

    ITypeVariableType getOrCreateTypeVariableType(String strName, IType boundingType, IType enclosingType);

    IFunctionType getOrCreateFunctionType(IMethodInfo mi);

    IFunctionType getOrCreateFunctionType(String strFunctionName, IType retType, IType[] paramTypes);

    TypeVarToTypeMap mapTypeByVarName(IType ownersType, IType declaringType, boolean bKeepTypeVars);

    IType getActualType(IType type, TypeVarToTypeMap actualParamByVarName, boolean bKeepTypeVars);

    void inferTypeVariableTypesFromGenParamTypeAndConcreteType(IType genParamType, IType argType, TypeVarToTypeMap map);

    IErrorType getErrorType();

    IErrorType getErrorType(String strErrantName);

    IErrorType getErrorType(ParseResultsException pe);

    IDefaultTypeLoader getDefaultTypeLoader();

    IType findParameterizedType(IType type, IType rhsType);

    void addTypeLoaderListenerAsWeakRef(ITypeLoaderListener listener);

    Set<String> getNamespacesFromTypeNames(Set<? extends CharSequence> allTypeNames, Set<String> namespaces);

    void pushTypeLoader(ITypeLoader loader);

    void pushTypeLoader(IModule module, ITypeLoader loader);

    void removeTypeLoader(Class<? extends ITypeLoader> loader);

    boolean areBeansEqual(Object o1, Object o2);

    void pushIncludeAll();

    void popIncludeAll();

    boolean isIncludeAll();

    IType getCurrentCompilingType();

    IType getCompilingType(String strName);

    void pushCompilingType(IType type);

    void popCompilingType();

    void pushSymTableCtx(ISymbolTable ctx);

    void popSymTableCtx();

    ISymbolTable getSymTableCtx();

    <T extends ITypeLoader> T getTypeLoader(Class<? extends T> loaderClass, IModule module);

    String getNameOfParams(IType[] paramTypes, boolean bRelative, boolean bWithEnclosingType);

    ISymbolTable getCompiledGosuClassSymbolTable();

    List<ITypeLoader> getAllTypeLoaders();

    IType getJavaType(Class javaClass);

    String getNameWithQualifiedTypeVariables(IType type);

    IType getDefaultParameterizedType(IType type);

    IType getDefaultParameterizedTypeWithTypeVars(IType type);

    boolean canCast(IType lhsType, IType rhsType);

    void removeTypeLoaderListener(ITypeLoaderListener listener);

    IJavaType getPrimitiveType(String name);

    IType getPrimitiveType(IType boxType);

    IType getBoxType(IType primitiveType);

    IExecutionEnvironment getExecutionEnvironment();

    IExecutionEnvironment getExecutionEnvironment(IProject project);

    IModule getCurrentModule();

    ITypeRef getOrCreateTypeReference(IType type);

    ITypeRef getTypeReference(IType type);

    IType getTypeFromObject(Object obj);

    boolean isExpandable(IType type);

    void clearErrorTypes();

    IType boundTypes(IType parameterType, List<IType> inferringTypes);

    IGosuClassLoader getGosuClassLoader();

    void dumpGosuClassLoader();

    IMetaType getDefaultType();

    boolean isSingleModuleMode();

    void addShutdownListener(TypeSystemShutdownListener listener);

    void pushModule(IModule gosuModule);

    void popModule(IModule gosuModule);

    IType replaceTypeVariableTypeParametersWithBoundingTypes(IType iType, IType type);

    IGosuc makeGosucCompiler(String gosucProjectFile, ICustomParser custParser);
}


/*
 * JasperReports - Free Java Reporting Library.
 * http://www.jaspersoft.com
 *
 * the following license terms apply:
 *
 * This program is part of JasperReports.
 *
 */
package net.sf.jasperreports.engine.util;

import java.security.ProtectionDomain;

/**
 * {@link ProtectionDomain ProtectionDomain} factory that is used by
 * {@link JRClassLoader JRClassLoader} to create per-instance protection domains.
 *
 * @author Lucian Chirita (example@nnthink.com)
 */
public interface ProtectionDomainFactory {

    /**
     * Return a protection domain to be used for a specific classloader.
     *
     * @param classloader the classloader
     * @return the protection domain to be used by the classloader
     */


private boolean isSetter(Element element) {
        return element.getSimpleName().toString().startsWith("set");
    }

package jdk.javadoc.internal.doclets.toolkit.builders;

import java.text.MessageFormat;
import java.util.*;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.ExecutableType;
import javax.lang.model.type.PrimitiveType;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.SimpleTypeVisitor9;
import com.sun.source.doctree.DocTree;
import com.sun.source.doctree.DocTree.Kind;
import jdk.javadoc.internal.doclets.toolkit.AnnotationTypeWriter;
import jdk.javadoc.internal.doclets.toolkit.ClassWriter;
import jdk.javadoc.internal.doclets.toolkit.Content;
import jdk.javadoc.internal.doclets.toolkit.MemberSummaryWriter;
import jdk.javadoc.internal.doclets.toolkit.WriterFactory;
import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
import jdk.javadoc.internal.doclets.toolkit.util.DocFinder;
import jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberMap;
import jdk.javadoc.internal.doclets.toolkit.CommentUtils;

/**
 * Builds the member summary.
 *
 *
This is NOT part of any supported API.
 *  If you write code that depends on this, you do so at your own risk.
 *  This code and its internal interfaces are subject to change or
 *  deletion without notice.
 *
 * @author Jamie Ho
 * @author Bhavesh Patel (Modified)
 */
public class MemberSummaryBuilder extends AbstractMemberBuilder {

    /**
     * The XML root for this builder.
     */
    public static final String NAME = "MemberSummary";

    /**
     * The member summary writers for the given class.
     */
    private final EnumMap<VisibleMemberMap.Kind, MemberSummaryWriter> memberSummaryWriters;

    /**
     * The type being documented.
     */
    private final TypeElement typeElement;

    /**
     * Construct a new MemberSummaryBuilder.
     *
     * @param classWriter   the writer for the class whose members are being
     *                      summarized.
     * @param context       the build context.
     */
    private MemberSummaryBuilder(Context context, TypeElement typeElement) {
        super(context);
        this.typeElement = typeElement;
        memberSummaryWriters = new EnumMap<>(VisibleMemberMap.Kind.class);
    }

    /**
     * Construct a new MemberSummaryBuilder.
     *
     * @param classWriter   the writer for the class whose members are being
     *                      summarized.
     * @param context       the build context.
     */
    public static MemberSummaryBuilder getInstance(ClassWriter classWriter, Context context) {
        MemberSummaryBuilder builder = new MemberSummaryBuilder(context, classWriter.getTypeElement());
        WriterFactory wf = context.configuration.getWriterFactory();
        for (VisibleMemberMap.Kind kind : VisibleMemberMap.Kind.values()) {
            MemberSummaryWriter msw = builder.getVisibleMemberMap(kind).noVisibleMembers() ? null : wf.getMemberSummaryWriter(classWriter, kind);
            builder.memberSummaryWriters.put(kind, msw);
        }
        return builder;
    }

    /**
     * Construct a new MemberSummaryBuilder.
     *
     * @param annotationTypeWriter the writer for the class whose members are
     *                             being summarized.
     * @param configuration the current configuration of the doclet.
     */
    public static MemberSummaryBuilder getInstance(AnnotationTypeWriter annotationTypeWriter, Context context) {
        MemberSummaryBuilder builder = new MemberSummaryBuilder(context, annotationTypeWriter.getAnnotationTypeElement());
        WriterFactory wf = context.configuration.getWriterFactory();
        for (VisibleMemberMap.Kind kind : VisibleMemberMap.Kind.values()) {
            MemberSummaryWriter msw = builder.getVisibleMemberMap(kind).noVisibleMembers() ? null : wf.getMemberSummaryWriter(annotationTypeWriter, kind);
            builder.memberSummaryWriters.put(kind, msw);
        }
        return builder;
    }

    @Override
    public String getName() {
        return NAME;
    }

    /**
     * Return the specified visible member map.
     *
     * @param kind the kind of visible member map to return.
     * @return the specified visible member map.
     * @throws ArrayIndexOutOfBoundsException when the type is invalid.
     * @see VisibleMemberMap
     */
    public VisibleMemberMap getVisibleMemberMap(VisibleMemberMap.Kind kind) {
        return configuration.getVisibleMemberMap(typeElement, kind);
    }

    /**
     * .
     *  Return the specified member summary writer.
     *
     *  @param kind the kind of member summary writer to return.
     *  @return the specified member summary writer.
     *  @throws ArrayIndexOutOfBoundsException when the type is invalid.
     *  @see VisibleMemberMap
     */
    public MemberSummaryWriter getMemberSummaryWriter(VisibleMemberMap.Kind kind) {
        return memberSummaryWriters.get(kind);
    }

    /**
     * Returns a list of methods that will be documented for the given class.
     * This information can be used for doclet specific documentation
     * generation.
     *
     * @param kind the kind of elements to return.
     * @return a list of methods that will be documented.
     * @see VisibleMemberMap
     */
    public SortedSet<Element> members(VisibleMemberMap.Kind kind) {
        TreeSet<Element> out = new TreeSet<>(comparator);
        out.addAll(getVisibleMemberMap(kind).getLeafMembers());
        return out;
    }

    /**
     * Return true it there are any members to summarize.
     *
     * @return true if there are any members to summarize.
     */
    @Override
    public boolean hasMembersToDocument() {
        if (utils.isAnnotationType(typeElement)) {
            return !utils.getAnnotationMethods(typeElement).isEmpty();
        }
        for (VisibleMemberMap.Kind kind : VisibleMemberMap.Kind.values()) {
            VisibleMemberMap members = getVisibleMemberMap(kind);
            if (!members.noVisibleMembers()) {
                return true;
            }
        }
        return false;
    }

    /**
     * Build the summary for the enum constants.
     *
     * @param node the XML element that specifies which components to document
     * @param memberSummaryTree the content tree to which the documentation will be added
     */
    public void buildEnumConstantsSummary(XMLNode node, Content memberSummaryTree) {
        MemberSummaryWriter writer = memberSummaryWriters.get(VisibleMemberMap.Kind.ENUM_CONSTANTS);
        VisibleMemberMap visibleMemberMap = getVisibleMemberMap(VisibleMemberMap.Kind.ENUM_CONSTANTS);
        addSummary(writer, visibleMemberMap, false, memberSummaryTree);
    }

    /**
     * Build the summary for fields.
     *
     * @param node the XML element that specifies which components to document
     * @param memberSummaryTree the content tree to which the documentation will be added
     */
    public void buildAnnotationTypeFieldsSummary(XMLNode node, Content memberSummaryTree) {
        MemberSummaryWriter writer = memberSummaryWriters.get(VisibleMemberMap.Kind.ANNOTATION_TYPE_FIELDS);
        VisibleMemberMap visibleMemberMap = getVisibleMemberMap(VisibleMemberMap.Kind.ANNOTATION_TYPE_FIELDS);
        addSummary(writer, visibleMemberMap, false, memberSummaryTree);
    }

    /**
     * Build the summary for the optional members.
     *
     * @param node the XML element that specifies which components to document
     * @param memberSummaryTree the content tree to which the documentation will be added
     */
    public void buildAnnotationTypeOptionalMemberSummary(XMLNode node, Content memberSummaryTree) {
        MemberSummaryWriter writer = memberSummaryWriters.get(VisibleMemberMap.Kind.ANNOTATION_TYPE_MEMBER_OPTIONAL);
        VisibleMemberMap visibleMemberMap = getVisibleMemberMap(VisibleMemberMap.Kind.ANNOTATION_TYPE_MEMBER_OPTIONAL);
        addSummary(writer, visibleMemberMap, false, memberSummaryTree);
    }

    /**
     * Build the summary for the optional members.
     *
     * @param node the XML element that specifies which components to document
     * @param memberSummaryTree the content tree to which the documentation will be added
     */
    public void buildAnnotationTypeRequiredMemberSummary(XMLNode node, Content memberSummaryTree) {
        MemberSummaryWriter writer = memberSummaryWriters.get(VisibleMemberMap.Kind.ANNOTATION_TYPE_MEMBER_REQUIRED);
        VisibleMemberMap visibleMemberMap = getVisibleMemberMap(VisibleMemberMap.Kind.ANNOTATION_TYPE_MEMBER_REQUIRED);
        addSummary(writer, visibleMemberMap, false, memberSummaryTree);
    }

    /**
     * Build the summary for the fields.
     *
     * @param node the XML element that specifies which components to document
     * @param memberSummaryTree the content tree to which the documentation will be added
     */
    public void buildFieldsSummary(XMLNode node, Content memberSummaryTree) {
        MemberSummaryWriter writer = memberSummaryWriters.get(VisibleMemberMap.Kind.FIELDS);
        VisibleMemberMap visibleMemberMap = getVisibleMemberMap(VisibleMemberMap.Kind.FIELDS);
        addSummary(writer, visibleMemberMap, true, memberSummaryTree);
    }

    /**
     * Build the summary for the fields.
     */
    public void buildPropertiesSummary(XMLNode node, Content memberSummaryTree) {
        MemberSummaryWriter writer = memberSummaryWriters.get(VisibleMemberMap.Kind.PROPERTIES);
        VisibleMemberMap visibleMemberMap = getVisibleMemberMap(VisibleMemberMap.Kind.PROPERTIES);
        addSummary(writer, visibleMemberMap, true, memberSummaryTree);
    }

    /**
     * Build the summary for the nested classes.
     *
     * @param node the XML element that specifies which components to document
     * @param memberSummaryTree the content tree to which the documentation will be added
     */
    public void buildNestedClassesSummary(XMLNode node, Content memberSummaryTree) {
        MemberSummaryWriter writer = memberSummaryWriters.get(VisibleMemberMap.Kind.INNER_CLASSES);
        VisibleMemberMap visibleMemberMap = getVisibleMemberMap(VisibleMemberMap.Kind.INNER_CLASSES);
        addSummary(writer, visibleMemberMap, true, memberSummaryTree);
    }

    /**
     * Build the method summary.
     *
     * @param node the XML element that specifies which components to document
     * @param memberSummaryTree the content tree to which the documentation will be added
     */
    public void buildMethodsSummary(XMLNode node, Content memberSummaryTree) {
        MemberSummaryWriter writer = memberSummaryWriters.get(VisibleMemberMap.Kind.METHODS);
        VisibleMemberMap visibleMemberMap = getVisibleMemberMap(VisibleMemberMap.Kind.METHODS);
        addSummary(writer, visibleMemberMap, true, memberSummaryTree);
    }

    /**
     * Build the constructor summary.
     *
     * @param node the XML element that specifies which components to document
     * @param memberSummaryTree the content tree to which the documentation will be added
     */
    public void buildConstructorsSummary(XMLNode node, Content memberSummaryTree) {
        MemberSummaryWriter writer = memberSummaryWriters.get(VisibleMemberMap.Kind.CONSTRUCTORS);
        VisibleMemberMap visibleMemberMap = getVisibleMemberMap(VisibleMemberMap.Kind.CONSTRUCTORS);
        addSummary(writer, visibleMemberMap, false, memberSummaryTree);
    }

    /**
     * Build the member summary for the given members.
     *
     * @param writer the summary writer to write the output.
     * @param visibleMemberMap the given members to summarize.
     * @param summaryTreeList list of content trees to which the documentation will be added
     */
    private void buildSummary(MemberSummaryWriter writer, VisibleMemberMap visibleMemberMap, LinkedList<Content> summaryTreeList) {
        SortedSet<Element> members = asSortedSet(visibleMemberMap.getLeafMembers());
        if (!members.isEmpty()) {
            List<Content> tableContents = new LinkedList<>();
            int counter = 0;
            for (Element member : members) {
                final Element property = visibleMemberMap.getPropertyMemberDoc(member);
                if (property != null) {
                    processProperty(visibleMemberMap, member, property);
                }
                List<? extends DocTree> firstSentenceTags = utils.getFirstSentenceTrees(member);
                if (utils.isExecutableElement(member) && firstSentenceTags.isEmpty()) {
                    // Inherit comments from overriden or implemented method if
                    DocFinder.Output inheritedDoc = DocFinder.search(configuration, new DocFinder.Input(utils, (ExecutableElement) member));
                    if (inheritedDoc.holder != null && !utils.getFirstSentenceTrees(inheritedDoc.holder).isEmpty()) {
                        // let the comment helper know of the overridden element
                        CommentHelper ch = utils.getCommentHelper(member);
                        ch.setOverrideElement(inheritedDoc.holder);
                        firstSentenceTags = utils.getFirstSentenceTrees(inheritedDoc.holder);
                    }
                }
                writer.addMemberSummary(typeElement, member, firstSentenceTags, tableContents, counter);
                counter++;
            }
            summaryTreeList.add(writer.getSummaryTableTree(typeElement, tableContents));
        }
    }

    /**
     * Process the property method, property setter and/or property getter
     * comment text so that it contains the documentation from
     * the property field. The method adds the leading sentence,
     * copied documentation including the defaultValue tag and
     * the see tags if the appropriate property getter and setter are
     * available.
     *
     * @param visibleMemberMap the members information.
     * @param member the member which is to be augmented.
     * @param property the original property documentation.
     */
    private void processProperty(VisibleMemberMap visibleMemberMap, Element member, Element property) {
        CommentUtils cmtutils = configuration.cmtUtils;
        final boolean isSetter = isSetter(member);
        final boolean isGetter = isGetter(member);
        List<DocTree> fullBody = new ArrayList<>();
        List<DocTree> blockTags = new ArrayList<>();
        if (isGetter || isSetter) {
            // add "[GS]ets the value of the property PROPERTY_NAME."
            if (isSetter) {
                String text = MessageFormat.format(configuration.getText("doclet.PropertySetterWithName"), utils.propertyName((ExecutableElement) member));
                fullBody.addAll(cmtutils.makeFirstSentenceTree(text));
            }
            if (isGetter) {
                String text = MessageFormat.format(configuration.getText("doclet.PropertyGetterWithName"), utils.propertyName((ExecutableElement) member));
                fullBody.addAll(cmtutils.makeFirstSentenceTree(text));
            }
            List<? extends DocTree> propertyTags = utils.getBlockTags(property, "propertyDescription");
            if (propertyTags.isEmpty()) {
                List<? extends DocTree> comment = utils.getFullBody(property);
                blockTags.addAll(cmtutils.makePropertyDescriptionTree(comment));
            }
        } else {
            fullBody.addAll(utils.getFullBody(property));
        }
        // copy certain tags
        List<? extends DocTree> tags = utils.getBlockTags(property, Kind.SINCE);
        blockTags.addAll(tags);
        List<? extends DocTree> bTags = utils.getBlockTags(property, Kind.UNKNOWN_BLOCK_TAG);
        CommentHelper ch = utils.getCommentHelper(property);
        for (DocTree dt : bTags) {
            String tagName = ch.getTagName(dt);
            if ("defaultValue".equals(tagName)) {
                blockTags.add(dt);
            }
        }
        // add @see tags
        if (!isGetter && !isSetter) {
            ExecutableElement getter = (ExecutableElement) visibleMemberMap.getGetterForProperty(member);
            ExecutableElement setter = (ExecutableElement) visibleMemberMap.getSetterForProperty(member);
            if (null != getter) {
                StringBuilder sb = new StringBuilder("#");
                sb.append(utils.getSimpleName(getter)).append("()");
                blockTags.add(cmtutils.makeSeeTree(sb.toString(), getter));
            }
            if (null != setter) {
                VariableElement param = setter.getParameters().get(0);
                StringBuilder sb = new StringBuilder("#");
                sb.append(utils.getSimpleName(setter));
                if (!utils.isTypeVariable(param.asType())) {
                    sb.append("(").append(utils.getTypeSignature(param.asType(), false, true)).append(")");
                }
                blockTags.add(cmtutils.makeSeeTree(sb.toString(), setter));
            }
        }
        cmtutils.setDocCommentTree(member, fullBody, blockTags, utils);
    }

    /**
     * Test whether the method is a getter.
     * @param element property method documentation. Needs to be either property
     * method, property getter, or property setter.
     * @return true if the given documentation belongs to a getter.
     */
    private boolean isGetter(Element element) {
        final String pedName = element.getSimpleName().toString();
        return pedName.startsWith("get") || pedName.startsWith("is");
    }

    /**
     * Test whether the method is a setter.
     * @param element property method documentation. Needs to be either property
     * method, property getter, or property setter.
     * @return true if the given documentation belongs to a setter.
     */

    /**
     * Build the inherited member summary for the given methods.
     *
     * @param writer the writer for this member summary.
     * @param visibleMemberMap the map for the members to document.
     * @param summaryTreeList list of content trees to which the documentation will be added
     */
    private void buildInheritedSummary(MemberSummaryWriter writer, VisibleMemberMap visibleMemberMap, LinkedList<Content> summaryTreeList) {
        for (TypeElement inhclass : visibleMemberMap.getVisibleClasses()) {
            if (!(utils.isPublic(inhclass) || utils.isLinkable(inhclass))) {
                continue;
            }
            if (inhclass == typeElement) {
                continue;
            }
            SortedSet<Element> inhmembers = asSortedSet(visibleMemberMap.getMembers(inhclass));
            if (!inhmembers.isEmpty()) {
                Content inheritedTree = writer.getInheritedSummaryHeader(inhclass);
                Content linksTree = writer.getInheritedSummaryLinksTree();
                for (Element member : inhmembers) {
                    TypeElement t = inhclass;
                    if (utils.isPackagePrivate(inhclass) && !utils.isLinkable(inhclass)) {
                        t = typeElement;
                    }
                    writer.addInheritedMemberSummary(t, member, inhmembers.first() == member, inhmembers.last() == member, linksTree);
                }
                inheritedTree.addContent(linksTree);
                summaryTreeList.add(writer.getMemberTree(inheritedTree));
            }
        }
    }

    /**
     * Add the summary for the documentation.
     *
     * @param writer the writer for this member summary.
     * @param visibleMemberMap the map for the members to document.
     * @param showInheritedSummary true if inherited summary should be documented
     * @param memberSummaryTree the content tree to which the documentation will be added
     */
    private void addSummary(MemberSummaryWriter writer, VisibleMemberMap visibleMemberMap, boolean showInheritedSummary, Content memberSummaryTree) {
        LinkedList<Content> summaryTreeList = new LinkedList<>();
        buildSummary(writer, visibleMemberMap, summaryTreeList);
        if (showInheritedSummary)
            buildInheritedSummary(writer, visibleMemberMap, summaryTreeList);
        if (!summaryTreeList.isEmpty()) {
            Content memberTree = writer.getMemberSummaryHeader(typeElement, memberSummaryTree);
            summaryTreeList.stream().forEach(memberTree::addContent);
            writer.addMemberTree(memberSummaryTree, memberTree);
        }
    }
}


public boolean waitForAcquireQuietly() {
        boolean success = false;
        try {
            success = Utils.ioResult(acquireFuture);
        } catch (DLInterruptedException ie) {
            Thread.currentThread().interrupt();
        } catch (LockTimeoutException lte) {
            logger.debug("Timeout on lock acquiring", lte);
        } catch (IOException e) {
            logger.error("Caught exception waiting for lock acquired", e);
        }
        return success;
    }

package org.apache.distributedlog.lock;

import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import org.apache.bookkeeper.common.concurrent.FutureUtils;
import org.apache.bookkeeper.common.util.OrderedScheduler;
import org.apache.distributedlog.exceptions.DLInterruptedException;
import org.apache.distributedlog.util.Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Lock waiter represents the attempt that application tries to lock.
 */
public class LockWaiter {

    private static final Logger logger = LoggerFactory.getLogger(LockWaiter.class);

    private final String lockId;

    private final String currentOwner;

    private final CompletableFuture<Boolean> acquireFuture;

    public LockWaiter(String lockId, String currentOwner, CompletableFuture<Boolean> acquireFuture) {
        this.lockId = lockId;
        this.currentOwner = currentOwner;
        this.acquireFuture = acquireFuture;
    }

    /**
     * Return the lock id of the waiter.
     *
     * @return lock id of the waiter
     */
    public String getId() {
        return lockId;
    }

    /**
     * Return the owner that observed when waiter is waiting.
     *
     * @return the owner that observed when waiter is waiting
     */
    public String getCurrentOwner() {
        return currentOwner;
    }

    /**
     * Return the future representing the waiting result.
     *
     * <p>If the future is interrupted
     * (e.g. {@link FutureUtils#within(CompletableFuture, long, TimeUnit, Throwable, OrderedScheduler, Object)}),
     * the waiter will automatically clean up its waiting state.
     *
     * @return the future representing the acquire result.
     */
    public CompletableFuture<Boolean> getAcquireFuture() {
        return acquireFuture;
    }

    /**
     * Wait for the acquire result.
     *
     * @return true if acquired successfully, otherwise false.
     */


try {
            success = Utils.ioResult(acquireFuture);
        } catch (DLInterruptedException ie) {
            Thread.currentThread().interrupt();
        } catch (LockTimeoutException lte) {
            logger.debug("Timeout on lock acquiring", lte);
        } catch (IOException e) {
            logger.error("Caught exception waiting for lock acquired", e);
        }

package org.apache.distributedlog.lock;

import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import org.apache.bookkeeper.common.concurrent.FutureUtils;
import org.apache.bookkeeper.common.util.OrderedScheduler;
import org.apache.distributedlog.exceptions.DLInterruptedException;
import org.apache.distributedlog.util.Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Lock waiter represents the attempt that application tries to lock.
 */
public class LockWaiter {

    private static final Logger logger = LoggerFactory.getLogger(LockWaiter.class);

    private final String lockId;

    private final String currentOwner;

    private final CompletableFuture<Boolean> acquireFuture;

    public LockWaiter(String lockId, String currentOwner, CompletableFuture<Boolean> acquireFuture) {
        this.lockId = lockId;
        this.currentOwner = currentOwner;
        this.acquireFuture = acquireFuture;
    }

    /**
     * Return the lock id of the waiter.
     *
     * @return lock id of the waiter
     */
    public String getId() {
        return lockId;
    }

    /**
     * Return the owner that observed when waiter is waiting.
     *
     * @return the owner that observed when waiter is waiting
     */
    public String getCurrentOwner() {
        return currentOwner;
    }

    /**
     * Return the future representing the waiting result.
     *
     * <p>If the future is interrupted
     * (e.g. {@link FutureUtils#within(CompletableFuture, long, TimeUnit, Throwable, OrderedScheduler, Object)}),
     * the waiter will automatically clean up its waiting state.
     *
     * @return the future representing the acquire result.
     */
    public CompletableFuture<Boolean> getAcquireFuture() {
        return acquireFuture;
    }

    /**
     * Wait for the acquire result.
     *
     * @return true if acquired successfully, otherwise false.
     */
    public boolean waitForAcquireQuietly() {
        boolean success = false;


protected void exchangeNodes(Node i, Node j, Node p, Node jP) {
        replace(p, i, j);
        replace(jP, j, i);
    }

/*
* File Exchange.java
*
*
* This file is part of BEAST2.
*
*/
/*
 * ExchangeOperator.java
 *
 *
 * This file is part of BEAST.
 *
 */
package beast.evolution.operators;

import beast.core.Description;
import beast.core.Input;
import beast.evolution.tree.Node;
import beast.evolution.tree.Tree;
import beast.util.Randomizer;

/*
 * KNOWN BUGS: WIDE operator cannot be used on trees with 4 or less tips!
 */
@Description("Implements branch exchange operations. There is a NARROW and WIDE variety. " + "The narrow exchange is very similar to a rooted-beast.tree nearest-neighbour " + "interchange but with the restriction that node height must remain consistent.")
public class Exchange extends TreeOperator {

    final public Input<Boolean> isNarrowInput = new Input<>("isNarrow", "if true (default) a narrow exchange is performed, otherwise a wide exchange", true);

    @Override
    public void initAndValidate() {
    }

    /**
     * override this for proposals,
     *
     * @return log of Hastings Ratio, or Double.NEGATIVE_INFINITY if proposal should not be accepted *
     */
    @Override
    public double proposal() {
        final Tree tree = treeInput.get(this);
        double logHastingsRatio = 0;
        if (isNarrowInput.get()) {
            logHastingsRatio = narrow(tree);
        } else {
            logHastingsRatio = wide(tree);
        }
        return logHastingsRatio;
    }

    private int isg(final Node n) {
        return (n.getLeft().isLeaf() && n.getRight().isLeaf()) ? 0 : 1;
    }

    private int sisg(final Node n) {
        return n.isLeaf() ? 0 : isg(n);
    }

    /**
     * WARNING: Assumes strictly bifurcating beast.tree.
     */
    public double narrow(final Tree tree) {
        final int internalNodes = tree.getInternalNodeCount();
        if (internalNodes <= 1) {
            return Double.NEGATIVE_INFINITY;
        }
        Node grandParent = tree.getNode(internalNodes + 1 + Randomizer.nextInt(internalNodes));
        while (grandParent.getLeft().isLeaf() && grandParent.getRight().isLeaf()) {
            grandParent = tree.getNode(internalNodes + 1 + Randomizer.nextInt(internalNodes));
        }
        Node parentIndex = grandParent.getLeft();
        Node uncle = grandParent.getRight();
        if (parentIndex.getHeight() < uncle.getHeight()) {
            parentIndex = grandParent.getRight();
            uncle = grandParent.getLeft();
        }
        if (parentIndex.isLeaf()) {
            // tree with dated tips
            return Double.NEGATIVE_INFINITY;
        }
        int validGP = 0;
        {
            for (int i = internalNodes + 1; i < 1 + 2 * internalNodes; ++i) {
                validGP += isg(tree.getNode(i));
            }
        }
        final int c2 = sisg(parentIndex) + sisg(uncle);
        final Node i = (Randomizer.nextBoolean() ? parentIndex.getLeft() : parentIndex.getRight());
        exchangeNodes(i, uncle, parentIndex, grandParent);
        final int validGPafter = validGP - c2 + sisg(parentIndex) + sisg(uncle);
        return Math.log((float) validGP / validGPafter);
    }

    /**
     * WARNING: Assumes strictly bifurcating beast.tree.
     * @param tree
     */
    public double wide(final Tree tree) {
        final int nodeCount = tree.getNodeCount();
        Node i = tree.getRoot();
        while (i.isRoot()) {
            i = tree.getNode(Randomizer.nextInt(nodeCount));
        }
        Node j = i;
        while (j.getNr() == i.getNr() || j.isRoot()) {
            j = tree.getNode(Randomizer.nextInt(nodeCount));
        }
        final Node p = i.getParent();
        final Node jP = j.getParent();
        if ((p != jP) && (i != jP) && (j != p) && (j.getHeight() < p.getHeight()) && (i.getHeight() < jP.getHeight())) {
            exchangeNodes(i, j, p, jP);
            // All the nodes on the path from i/j to the common ancestor of i/j parents had a topology change,
            // so they need to be marked FILTHY.
            if (markCladesInput.get()) {
                Node iup = p;
                Node jup = jP;
                while (iup != jup) {
                    if (iup.getHeight() < jup.getHeight()) {
                        assert !iup.isRoot();
                        iup = iup.getParent();
                        iup.makeDirty(Tree.IS_FILTHY);
                    } else {
                        assert !jup.isRoot();
                        jup = jup.getParent();
                        jup.makeDirty(Tree.IS_FILTHY);
                    }
                }
            }
            return 0;
        }
        // Randomly selected nodes i and j are not valid candidates for a wide exchange.
        // reject instead of counting (like we do for narrow).
        return Double.NEGATIVE_INFINITY;
    }

    /* exchange sub-trees whose root are i and j */


for (int i = internalNodes + 1; i < 1 + 2 * internalNodes; ++i) {
                validGP += isg(tree.getNode(i));
            }

/*
* File Exchange.java
*
*
* This file is part of BEAST2.
*
*/
/*
 * ExchangeOperator.java
 *
 *
 * This file is part of BEAST.
 *
 */
package beast.evolution.operators;

import beast.core.Description;
import beast.core.Input;
import beast.evolution.tree.Node;
import beast.evolution.tree.Tree;
import beast.util.Randomizer;

/*
 * KNOWN BUGS: WIDE operator cannot be used on trees with 4 or less tips!
 */
@Description("Implements branch exchange operations. There is a NARROW and WIDE variety. " + "The narrow exchange is very similar to a rooted-beast.tree nearest-neighbour " + "interchange but with the restriction that node height must remain consistent.")
public class Exchange extends TreeOperator {

    final public Input<Boolean> isNarrowInput = new Input<>("isNarrow", "if true (default) a narrow exchange is performed, otherwise a wide exchange", true);

    @Override
    public void initAndValidate() {
    }

    /**
     * override this for proposals,
     *
     * @return log of Hastings Ratio, or Double.NEGATIVE_INFINITY if proposal should not be accepted *
     */
    @Override
    public double proposal() {
        final Tree tree = treeInput.get(this);
        double logHastingsRatio = 0;
        if (isNarrowInput.get()) {
            logHastingsRatio = narrow(tree);
        } else {
            logHastingsRatio = wide(tree);
        }
        return logHastingsRatio;
    }

    private int isg(final Node n) {
        return (n.getLeft().isLeaf() && n.getRight().isLeaf()) ? 0 : 1;
    }

    private int sisg(final Node n) {
        return n.isLeaf() ? 0 : isg(n);
    }

    /**
     * WARNING: Assumes strictly bifurcating beast.tree.
     */
    public double narrow(final Tree tree) {
        final int internalNodes = tree.getInternalNodeCount();
        if (internalNodes <= 1) {
            return Double.NEGATIVE_INFINITY;
        }
        Node grandParent = tree.getNode(internalNodes + 1 + Randomizer.nextInt(internalNodes));
        while (grandParent.getLeft().isLeaf() && grandParent.getRight().isLeaf()) {
            grandParent = tree.getNode(internalNodes + 1 + Randomizer.nextInt(internalNodes));
        }
        Node parentIndex = grandParent.getLeft();
        Node uncle = grandParent.getRight();
        if (parentIndex.getHeight() < uncle.getHeight()) {
            parentIndex = grandParent.getRight();
            uncle = grandParent.getLeft();
        }
        if (parentIndex.isLeaf()) {
            // tree with dated tips
            return Double.NEGATIVE_INFINITY;
        }
        int validGP = 0;
        {

        }
        final int c2 = sisg(parentIndex) + sisg(uncle);
        final Node i = (Randomizer.nextBoolean() ? parentIndex.getLeft() : parentIndex.getRight());
        exchangeNodes(i, uncle, parentIndex, grandParent);
        final int validGPafter = validGP - c2 + sisg(parentIndex) + sisg(uncle);
        return Math.log((float) validGP / validGPafter);
    }

    /**
     * WARNING: Assumes strictly bifurcating beast.tree.
     * @param tree
     */
    public double wide(final Tree tree) {
        final int nodeCount = tree.getNodeCount();
        Node i = tree.getRoot();
        while (i.isRoot()) {
            i = tree.getNode(Randomizer.nextInt(nodeCount));
        }
        Node j = i;
        while (j.getNr() == i.getNr() || j.isRoot()) {
            j = tree.getNode(Randomizer.nextInt(nodeCount));
        }
        final Node p = i.getParent();
        final Node jP = j.getParent();
        if ((p != jP) && (i != jP) && (j != p) && (j.getHeight() < p.getHeight()) && (i.getHeight() < jP.getHeight())) {
            exchangeNodes(i, j, p, jP);
            // All the nodes on the path from i/j to the common ancestor of i/j parents had a topology change,
            // so they need to be marked FILTHY.
            if (markCladesInput.get()) {
                Node iup = p;
                Node jup = jP;
                while (iup != jup) {
                    if (iup.getHeight() < jup.getHeight()) {
                        assert !iup.isRoot();
                        iup = iup.getParent();
                        iup.makeDirty(Tree.IS_FILTHY);
                    } else {
                        assert !jup.isRoot();
                        jup = jup.getParent();
                        jup.makeDirty(Tree.IS_FILTHY);
                    }
                }
            }
            return 0;
        }
        // Randomly selected nodes i and j are not valid candidates for a wide exchange.
        // reject instead of counting (like we do for narrow).
        return Double.NEGATIVE_INFINITY;
    }

    /* exchange sub-trees whose root are i and j */
    protected void exchangeNodes(Node i, Node j, Node p, Node jP) {
        replace(p, i, j);
        replace(jP, j, i);
    }
}


while (j.getNr() == i.getNr() || j.isRoot()) {
            j = tree.getNode(Randomizer.nextInt(nodeCount));
        }

/*
* File Exchange.java
*
*
* This file is part of BEAST2.
*
*/
/*
 * ExchangeOperator.java
 *
 *
 * This file is part of BEAST.
 *
 */
package beast.evolution.operators;

import beast.core.Description;
import beast.core.Input;
import beast.evolution.tree.Node;
import beast.evolution.tree.Tree;
import beast.util.Randomizer;

/*
 * KNOWN BUGS: WIDE operator cannot be used on trees with 4 or less tips!
 */
@Description("Implements branch exchange operations. There is a NARROW and WIDE variety. " + "The narrow exchange is very similar to a rooted-beast.tree nearest-neighbour " + "interchange but with the restriction that node height must remain consistent.")
public class Exchange extends TreeOperator {

    final public Input<Boolean> isNarrowInput = new Input<>("isNarrow", "if true (default) a narrow exchange is performed, otherwise a wide exchange", true);

    @Override
    public void initAndValidate() {
    }

    /**
     * override this for proposals,
     *
     * @return log of Hastings Ratio, or Double.NEGATIVE_INFINITY if proposal should not be accepted *
     */
    @Override
    public double proposal() {
        final Tree tree = treeInput.get(this);
        double logHastingsRatio = 0;
        if (isNarrowInput.get()) {
            logHastingsRatio = narrow(tree);
        } else {
            logHastingsRatio = wide(tree);
        }
        return logHastingsRatio;
    }

    private int isg(final Node n) {
        return (n.getLeft().isLeaf() && n.getRight().isLeaf()) ? 0 : 1;
    }

    private int sisg(final Node n) {
        return n.isLeaf() ? 0 : isg(n);
    }

    /**
     * WARNING: Assumes strictly bifurcating beast.tree.
     */
    public double narrow(final Tree tree) {
        final int internalNodes = tree.getInternalNodeCount();
        if (internalNodes <= 1) {
            return Double.NEGATIVE_INFINITY;
        }
        Node grandParent = tree.getNode(internalNodes + 1 + Randomizer.nextInt(internalNodes));
        while (grandParent.getLeft().isLeaf() && grandParent.getRight().isLeaf()) {
            grandParent = tree.getNode(internalNodes + 1 + Randomizer.nextInt(internalNodes));
        }
        Node parentIndex = grandParent.getLeft();
        Node uncle = grandParent.getRight();
        if (parentIndex.getHeight() < uncle.getHeight()) {
            parentIndex = grandParent.getRight();
            uncle = grandParent.getLeft();
        }
        if (parentIndex.isLeaf()) {
            // tree with dated tips
            return Double.NEGATIVE_INFINITY;
        }
        int validGP = 0;
        {
            for (int i = internalNodes + 1; i < 1 + 2 * internalNodes; ++i) {
                validGP += isg(tree.getNode(i));
            }
        }
        final int c2 = sisg(parentIndex) + sisg(uncle);
        final Node i = (Randomizer.nextBoolean() ? parentIndex.getLeft() : parentIndex.getRight());
        exchangeNodes(i, uncle, parentIndex, grandParent);
        final int validGPafter = validGP - c2 + sisg(parentIndex) + sisg(uncle);
        return Math.log((float) validGP / validGPafter);
    }

    /**
     * WARNING: Assumes strictly bifurcating beast.tree.
     * @param tree
     */
    public double wide(final Tree tree) {
        final int nodeCount = tree.getNodeCount();
        Node i = tree.getRoot();
        while (i.isRoot()) {
            i = tree.getNode(Randomizer.nextInt(nodeCount));
        }
        Node j = i;

        final Node p = i.getParent();
        final Node jP = j.getParent();
        if ((p != jP) && (i != jP) && (j != p) && (j.getHeight() < p.getHeight()) && (i.getHeight() < jP.getHeight())) {
            exchangeNodes(i, j, p, jP);
            // All the nodes on the path from i/j to the common ancestor of i/j parents had a topology change,
            // so they need to be marked FILTHY.
            if (markCladesInput.get()) {
                Node iup = p;
                Node jup = jP;
                while (iup != jup) {
                    if (iup.getHeight() < jup.getHeight()) {
                        assert !iup.isRoot();
                        iup = iup.getParent();
                        iup.makeDirty(Tree.IS_FILTHY);
                    } else {
                        assert !jup.isRoot();
                        jup = jup.getParent();
                        jup.makeDirty(Tree.IS_FILTHY);
                    }
                }
            }
            return 0;
        }
        // Randomly selected nodes i and j are not valid candidates for a wide exchange.
        // reject instead of counting (like we do for narrow).
        return Double.NEGATIVE_INFINITY;
    }

    /* exchange sub-trees whose root are i and j */
    protected void exchangeNodes(Node i, Node j, Node p, Node jP) {
        replace(p, i, j);
        replace(jP, j, i);
    }
}


try {
            if (data == null) {
                return null;
            }
            return Serializer.serialize(data, kryo);
        } catch (Exception e) {
            System.out.println(e);
            return null;
        }

package org.apache.example.learn2.producer;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.serializers.CompatibleFieldSerializer;
import com.esotericsoftware.kryo.util.DefaultInstantiatorStrategy;
import org.apache.kafka.common.serialization.Serializer;
import org.objenesis.strategy.StdInstantiatorStrategy;
import java.io.ByteArrayOutputStream;
import java.util.Map;

public class KryoSerializer implements Serializer {

    private Kryo kryo;

    @Override
    public void configure(Map configs, boolean isKey) {
        this.kryo = Serializer.getKryo();
    }

    @Override
    public byte[] serialize(String topic, Object data) {

    }

    @Override
    public void close() {
    }

    private static class Serializer {

        private static byte[] serialize(Object object, Kryo kryo) {
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            Output output = new Output(1024, 102400);
            output.setOutputStream(outputStream);
            kryo.writeClassAndObject(output, object);
            output.close();
            return outputStream.toByteArray();
        }

        private static Kryo getKryo() {
            Kryo kryo = new Kryo();
            DefaultInstantiatorStrategy defaultInstantiatorStrategy = new DefaultInstantiatorStrategy(new StdInstantiatorStrategy());
            kryo.setInstantiatorStrategy(defaultInstantiatorStrategy);
            kryo.setReferences(false);
            kryo.setRegistrationRequired(false);
            kryo.setDefaultSerializer(CompatibleFieldSerializer.class);
            return kryo;
        }
    }
}


for (int i = 0; i < 3; i++) {
            store(new Item());
        }

package com.db4o.db4ounit.common.querying;

import com.db4o.*;
import db4ounit.*;
import db4ounit.extensions.*;

public class QueryingForAllObjectsTestCase extends AbstractDb4oTestCase {

    public static class Item {
    }

    @Override
    protected void store() throws Exception {

    }

    public void testConstrainObjectClass() {
        ObjectSet<Object> objectSet = db().query(Object.class);
        Assert.areEqual(3, objectSet.size());
    }

    public void testConstrainByNewObject() {
        ObjectSet<Object> objectSet = db().queryByExample(new Object());
        Assert.areEqual(3, objectSet.size());
    }
}


for (int i = 0; i < uiTabs.size(); i++) {
            Tab tab = uiTabs.get(i);
            int[] ii = { i };
            tab.setOnSelectionChanged(event -> {
                if (tab.isSelected()) {
                    tabs.get(ii[0]).onTabOpened();
                }
            });
        }

package gearth.ui;

import gearth.protocol.connection.proxy.ProxyProviderFactory;
import gearth.protocol.connection.proxy.SocksConfiguration;
import gearth.ui.logger.loggerdisplays.PacketLoggerFactory;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import gearth.protocol.HConnection;
import gearth.ui.connection.ConnectionController;
import gearth.ui.extensions.ExtensionsController;
import gearth.ui.info.InfoController;
import gearth.ui.injection.InjectionController;
import gearth.ui.logger.LoggerController;
import gearth.ui.scheduler.SchedulerController;
import gearth.ui.extra.ExtraController;
import gearth.ui.tools.ToolsController;
import java.util.ArrayList;
import java.util.List;

public class GEarthController {

    public Tab tab_Logger;

    public TabPane tabBar;

    private Stage stage = null;

    private volatile HConnection hConnection;

    private volatile int initcount = 0;

    public ConnectionController connectionController;

    public InjectionController injectionController;

    public LoggerController loggerController;

    public ToolsController toolsController;

    public SchedulerController schedulerController;

    public ExtraController extraController;

    public InfoController infoController;

    public ExtensionsController extensionsController;

    private List<SubForm> tabs = null;

    public Pane mover;

    public GEarthController() {
        SocksConfiguration temporary_socks = new SocksConfiguration() {

            public boolean useSocks() {
                return false;
            }

            public int getSocksPort() {
                return 0;
            }

            public String getSocksHost() {
                return null;
            }

            public boolean onlyUseIfNeeded() {
                return true;
            }
        };
        ProxyProviderFactory.setSocksConfig(temporary_socks);
        hConnection = new HConnection();
    }

    public void initialize() {
        tabs = new ArrayList<>();
        // must be ordered correctly
        tabs.add(connectionController);
        tabs.add(injectionController);
        tabs.add(loggerController);
        tabs.add(toolsController);
        tabs.add(schedulerController);
        tabs.add(extensionsController);
        tabs.add(extraController);
        tabs.add(infoController);
        synchronized (this) {
            trySetController();
        }
        List<Tab> uiTabs = tabBar.getTabs();

        if (PacketLoggerFactory.usesUIlogger()) {
            tabBar.getTabs().remove(tab_Logger);
        }
    }

    public void setStage(Stage stage) {
        this.stage = stage;
        synchronized (this) {
            trySetController();
        }
    }

    private void trySetController() {
        if (++initcount == 2) {
            GEarthController self = this;
            extensionsController.setParentController(self);
            tabs.forEach(subForm -> {
                if (subForm != extensionsController)
                    subForm.setParentController(self);
            });
        }
    }

    public Stage getStage() {
        return stage;
    }

    HConnection getHConnection() {
        return hConnection;
    }

    void writeToLog(javafx.scene.paint.Color color, String text) {
        loggerController.miniLogText(color, text);
    }

    public void exit() {
        tabs.forEach(SubForm::exit);
        hConnection.abort();
    }
}


try {
            inputStream = metaStateHandle.openInputStream();
            cancelStreamRegistry.registerCloseable(inputStream);
            DataInputView in = new DataInputViewStreamWrapper(inputStream);
            return readMetaData(in);
        } finally {
            if (cancelStreamRegistry.unregisterCloseable(inputStream)) {
                inputStream.close();
            }
        }

package org.apache.flink.contrib.streaming.state.restore;

import org.apache.flink.api.common.typeutils.TypeSerializer;
import org.apache.flink.api.common.typeutils.TypeSerializerSchemaCompatibility;
import org.apache.flink.contrib.streaming.state.RocksDBIncrementalCheckpointUtils;
import org.apache.flink.contrib.streaming.state.RocksDBKeyedStateBackend.RocksDbKvStateInfo;
import org.apache.flink.contrib.streaming.state.RocksDBNativeMetricOptions;
import org.apache.flink.contrib.streaming.state.RocksDBOperationUtils;
import org.apache.flink.contrib.streaming.state.RocksDBStateDownloader;
import org.apache.flink.contrib.streaming.state.RocksDBWriteBatchWrapper;
import org.apache.flink.contrib.streaming.state.RocksIteratorWrapper;
import org.apache.flink.contrib.streaming.state.ttl.RocksDbTtlCompactFiltersManager;
import org.apache.flink.core.fs.CloseableRegistry;
import org.apache.flink.core.memory.DataInputView;
import org.apache.flink.core.memory.DataInputViewStreamWrapper;
import org.apache.flink.metrics.MetricGroup;
import org.apache.flink.runtime.state.BackendBuildingException;
import org.apache.flink.runtime.state.CompositeKeySerializationUtils;
import org.apache.flink.runtime.state.DirectoryStateHandle;
import org.apache.flink.runtime.state.IncrementalKeyedStateHandle;
import org.apache.flink.runtime.state.IncrementalLocalKeyedStateHandle;
import org.apache.flink.runtime.state.IncrementalRemoteKeyedStateHandle;
import org.apache.flink.runtime.state.KeyGroupRange;
import org.apache.flink.runtime.state.KeyedBackendSerializationProxy;
import org.apache.flink.runtime.state.KeyedStateHandle;
import org.apache.flink.runtime.state.RegisteredStateMetaInfoBase;
import org.apache.flink.runtime.state.StateHandleID;
import org.apache.flink.runtime.state.StateSerializerProvider;
import org.apache.flink.runtime.state.StreamStateHandle;
import org.apache.flink.runtime.state.metainfo.StateMetaInfoSnapshot;
import org.apache.flink.util.FileUtils;
import org.apache.flink.util.IOUtils;
import org.apache.flink.util.StateMigrationException;
import org.rocksdb.ColumnFamilyDescriptor;
import org.rocksdb.ColumnFamilyHandle;
import org.rocksdb.ColumnFamilyOptions;
import org.rocksdb.DBOptions;
import org.rocksdb.ReadOptions;
import org.rocksdb.RocksDB;
import org.rocksdb.RocksDBException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.UUID;
import java.util.function.Function;
import static org.apache.flink.runtime.state.StateUtil.unexpectedStateHandleException;

/**
 * Encapsulates the process of restoring a RocksDB instance from an incremental snapshot.
 */
public class RocksDBIncrementalRestoreOperation<K> implements RocksDBRestoreOperation {

    private static final Logger logger = LoggerFactory.getLogger(RocksDBIncrementalRestoreOperation.class);

    private final String operatorIdentifier;

    private final SortedMap<Long, Set<StateHandleID>> restoredSstFiles;

    private final RocksDBHandle rocksHandle;

    private final Collection<KeyedStateHandle> restoreStateHandles;

    private final CloseableRegistry cancelStreamRegistry;

    private final KeyGroupRange keyGroupRange;

    private final File instanceBasePath;

    private final int numberOfTransferringThreads;

    private final int keyGroupPrefixBytes;

    private final StateSerializerProvider<K> keySerializerProvider;

    private final ClassLoader userCodeClassLoader;

    private long lastCompletedCheckpointId;

    private UUID backendUID;

    private final long writeBatchSize;

    private boolean isKeySerializerCompatibilityChecked;

    public RocksDBIncrementalRestoreOperation(String operatorIdentifier, KeyGroupRange keyGroupRange, int keyGroupPrefixBytes, int numberOfTransferringThreads, CloseableRegistry cancelStreamRegistry, ClassLoader userCodeClassLoader, Map<String, RocksDbKvStateInfo> kvStateInformation, StateSerializerProvider<K> keySerializerProvider, File instanceBasePath, File instanceRocksDBPath, DBOptions dbOptions, Function<String, ColumnFamilyOptions> columnFamilyOptionsFactory, RocksDBNativeMetricOptions nativeMetricOptions, MetricGroup metricGroup, @Nonnull Collection<KeyedStateHandle> restoreStateHandles, @Nonnull RocksDbTtlCompactFiltersManager ttlCompactFiltersManager, @Nonnegative long writeBatchSize, Long writeBufferManagerCapacity) {
        this.rocksHandle = new RocksDBHandle(kvStateInformation, instanceRocksDBPath, dbOptions, columnFamilyOptionsFactory, nativeMetricOptions, metricGroup, ttlCompactFiltersManager, writeBufferManagerCapacity);
        this.operatorIdentifier = operatorIdentifier;
        this.restoredSstFiles = new TreeMap<>();
        this.lastCompletedCheckpointId = -1L;
        this.backendUID = UUID.randomUUID();
        this.writeBatchSize = writeBatchSize;
        this.restoreStateHandles = restoreStateHandles;
        this.cancelStreamRegistry = cancelStreamRegistry;
        this.keyGroupRange = keyGroupRange;
        this.instanceBasePath = instanceBasePath;
        this.numberOfTransferringThreads = numberOfTransferringThreads;
        this.keyGroupPrefixBytes = keyGroupPrefixBytes;
        this.keySerializerProvider = keySerializerProvider;
        this.userCodeClassLoader = userCodeClassLoader;
    }

    /**
     * Root method that branches for different implementations of {@link KeyedStateHandle}.
     */
    @Override
    public RocksDBRestoreResult restore() throws Exception {
        if (restoreStateHandles == null || restoreStateHandles.isEmpty()) {
            return null;
        }
        final KeyedStateHandle theFirstStateHandle = restoreStateHandles.iterator().next();
        boolean isRescaling = (restoreStateHandles.size() > 1 || !Objects.equals(theFirstStateHandle.getKeyGroupRange(), keyGroupRange));
        if (isRescaling) {
            restoreWithRescaling(restoreStateHandles);
        } else {
            restoreWithoutRescaling(theFirstStateHandle);
        }
        return new RocksDBRestoreResult(this.rocksHandle.getDb(), this.rocksHandle.getDefaultColumnFamilyHandle(), this.rocksHandle.getNativeMetricMonitor(), lastCompletedCheckpointId, backendUID, restoredSstFiles);
    }

    /**
     * Recovery from a single remote incremental state without rescaling.
     */
    @SuppressWarnings("unchecked")
    private void restoreWithoutRescaling(KeyedStateHandle keyedStateHandle) throws Exception {
        logger.info("Starting to restore from state handle: {} without rescaling.", keyedStateHandle);
        if (keyedStateHandle instanceof IncrementalRemoteKeyedStateHandle) {
            IncrementalRemoteKeyedStateHandle incrementalRemoteKeyedStateHandle = (IncrementalRemoteKeyedStateHandle) keyedStateHandle;
            restorePreviousIncrementalFilesStatus(incrementalRemoteKeyedStateHandle);
            restoreFromRemoteState(incrementalRemoteKeyedStateHandle);
        } else if (keyedStateHandle instanceof IncrementalLocalKeyedStateHandle) {
            IncrementalLocalKeyedStateHandle incrementalLocalKeyedStateHandle = (IncrementalLocalKeyedStateHandle) keyedStateHandle;
            restorePreviousIncrementalFilesStatus(incrementalLocalKeyedStateHandle);
            restoreFromLocalState(incrementalLocalKeyedStateHandle);
        } else {
            throw unexpectedStateHandleException(new Class[] { IncrementalRemoteKeyedStateHandle.class, IncrementalLocalKeyedStateHandle.class }, keyedStateHandle.getClass());
        }
        logger.info("Finished restoring from state handle: {} without rescaling.", keyedStateHandle);
    }

    private void restorePreviousIncrementalFilesStatus(IncrementalKeyedStateHandle localKeyedStateHandle) {
        backendUID = localKeyedStateHandle.getBackendIdentifier();
        restoredSstFiles.put(localKeyedStateHandle.getCheckpointId(), localKeyedStateHandle.getSharedStateHandleIDs());
        lastCompletedCheckpointId = localKeyedStateHandle.getCheckpointId();
    }

    private void restoreFromRemoteState(IncrementalRemoteKeyedStateHandle stateHandle) throws Exception {
        // used as restore source for IncrementalRemoteKeyedStateHandle
        final Path tmpRestoreInstancePath = instanceBasePath.getAbsoluteFile().toPath().resolve(UUID.randomUUID().toString());
        try {
            restoreFromLocalState(transferRemoteStateToLocalDirectory(tmpRestoreInstancePath, stateHandle));
        } finally {
            cleanUpPathQuietly(tmpRestoreInstancePath);
        }
    }

    private void restoreFromLocalState(IncrementalLocalKeyedStateHandle localKeyedStateHandle) throws Exception {
        KeyedBackendSerializationProxy<K> serializationProxy = readMetaData(localKeyedStateHandle.getMetaDataState());
        List<StateMetaInfoSnapshot> stateMetaInfoSnapshots = serializationProxy.getStateMetaInfoSnapshots();
        Path restoreSourcePath = localKeyedStateHandle.getDirectoryStateHandle().getDirectory();
        logger.debug("Restoring keyed backend uid in operator {} from incremental snapshot to {}.", operatorIdentifier, backendUID);
        this.rocksHandle.openDB(createlumnFamilyDescriptors(stateMetaInfoSnapshots, true), stateMetaInfoSnapshots, restoreSourcePath);
    }

    private IncrementalLocalKeyedStateHandle transferRemoteStateToLocalDirectory(Path temporaryRestoreInstancePath, IncrementalRemoteKeyedStateHandle restoreStateHandle) throws Exception {
        try (RocksDBStateDownloader rocksDBStateDownloader = new RocksDBStateDownloader(numberOfTransferringThreads)) {
            rocksDBStateDownloader.transferAllStateDataToDirectory(restoreStateHandle, temporaryRestoreInstancePath, cancelStreamRegistry);
        }
        // since we transferred all remote state to a local directory, we can use the same code as
        // local recovery.
        return new IncrementalLocalKeyedStateHandle(restoreStateHandle.getBackendIdentifier(), restoreStateHandle.getCheckpointId(), new DirectoryStateHandle(temporaryRestoreInstancePath), restoreStateHandle.getKeyGroupRange(), restoreStateHandle.getMetaStateHandle(), restoreStateHandle.getSharedState().keySet());
    }

    private void cleanUpPathQuietly(@Nonnull Path path) {
        try {
            FileUtils.deleteDirectory(path.toFile());
        } catch (IOException ex) {
            logger.warn("Failed to clean up path " + path, ex);
        }
    }

    /**
     * Recovery from multi incremental states with rescaling. For rescaling, this method creates a
     * temporary RocksDB instance for a key-groups shard. All contents from the temporary instance
     * are copied into the real restore instance and then the temporary instance is discarded.
     */
    private void restoreWithRescaling(Collection<KeyedStateHandle> restoreStateHandles) throws Exception {
        // Prepare for restore with rescaling
        KeyedStateHandle initialHandle = RocksDBIncrementalCheckpointUtils.chooseTheBestStateHandleForInitial(restoreStateHandles, keyGroupRange);
        // Init base DB instance
        if (initialHandle != null) {
            restoreStateHandles.remove(initialHandle);
            initDBWithRescaling(initialHandle);
        } else {
            this.rocksHandle.openDB();
        }
        // Transfer remaining key-groups from temporary instance into base DB
        byte[] startKeyGroupPrefixBytes = new byte[keyGroupPrefixBytes];
        CompositeKeySerializationUtils.serializeKeyGroup(keyGroupRange.getStartKeyGroup(), startKeyGroupPrefixBytes);
        byte[] stopKeyGroupPrefixBytes = new byte[keyGroupPrefixBytes];
        CompositeKeySerializationUtils.serializeKeyGroup(keyGroupRange.getEndKeyGroup() + 1, stopKeyGroupPrefixBytes);
        for (KeyedStateHandle rawStateHandle : restoreStateHandles) {
            if (!(rawStateHandle instanceof IncrementalRemoteKeyedStateHandle)) {
                throw unexpectedStateHandleException(IncrementalRemoteKeyedStateHandle.class, rawStateHandle.getClass());
            }
            logger.info("Starting to restore from state handle: {} with rescaling.", rawStateHandle);
            Path temporaryRestoreInstancePath = instanceBasePath.getAbsoluteFile().toPath().resolve(UUID.randomUUID().toString());
            try (RestoredDBInstance tmpRestoreDBInfo = restoreDBInstanceFromStateHandle((IncrementalRemoteKeyedStateHandle) rawStateHandle, temporaryRestoreInstancePath);
                RocksDBWriteBatchWrapper writeBatchWrapper = new RocksDBWriteBatchWrapper(this.rocksHandle.getDb(), writeBatchSize)) {
                List<ColumnFamilyDescriptor> tmpColumnFamilyDescriptors = tmpRestoreDBInfo.columnFamilyDescriptors;
                List<ColumnFamilyHandle> tmpColumnFamilyHandles = tmpRestoreDBInfo.columnFamilyHandles;
                // iterating only the requested descriptors automatically skips the default column
                // family handle
                for (int i = 0; i < tmpColumnFamilyDescriptors.size(); ++i) {
                    ColumnFamilyHandle tmpColumnFamilyHandle = tmpColumnFamilyHandles.get(i);
                    ColumnFamilyHandle targetColumnFamilyHandle = this.rocksHandle.getOrRegisterStateColumnFamilyHandle(null, tmpRestoreDBInfo.stateMetaInfoSnapshots.get(i)).columnFamilyHandle;
                    try (RocksIteratorWrapper iterator = RocksDBOperationUtils.getRocksIterator(tmpRestoreDBInfo.db, tmpColumnFamilyHandle, tmpRestoreDBInfo.readOptions)) {
                        iterator.seek(startKeyGroupPrefixBytes);
                        while (iterator.isValid()) {
                            if (RocksDBIncrementalCheckpointUtils.beforeThePrefixBytes(iterator.key(), stopKeyGroupPrefixBytes)) {
                                writeBatchWrapper.put(targetColumnFamilyHandle, iterator.key(), iterator.value());
                            } else {
                                // Since the iterator will visit the record according to the sorted
                                // we can just break here.
                                break;
                            }
                            iterator.next();
                        }
                    }
                    // releases native iterator resources
                }
                logger.info("Finished restoring from state handle: {} with rescaling.", rawStateHandle);
            } finally {
                cleanUpPathQuietly(temporaryRestoreInstancePath);
            }
        }
    }

    private void initDBWithRescaling(KeyedStateHandle initialHandle) throws Exception {
        assert (initialHandle instanceof IncrementalRemoteKeyedStateHandle);
        // 1. Restore base DB from selected initial handle
        restoreFromRemoteState((IncrementalRemoteKeyedStateHandle) initialHandle);
        // 2. Clip the base DB instance
        try {
            RocksDBIncrementalCheckpointUtils.clipDBWithKeyGroupRange(this.rocksHandle.getDb(), this.rocksHandle.getColumnFamilyHandles(), keyGroupRange, initialHandle.getKeyGroupRange(), keyGroupPrefixBytes, writeBatchSize);
        } catch (RocksDBException e) {
            String errMsg = "Failed to clip DB after initialization.";
            logger.error(errMsg, e);
            throw new BackendBuildingException(errMsg, e);
        }
    }

    /**
     * Entity to hold the temporary RocksDB instance created for restore.
     */
    private static class RestoredDBInstance implements AutoCloseable {

        @Nonnull
        private final RocksDB db;

        @Nonnull
        private final ColumnFamilyHandle defaultColumnFamilyHandle;

        @Nonnull
        private final List<ColumnFamilyHandle> columnFamilyHandles;

        @Nonnull
        private final List<ColumnFamilyDescriptor> columnFamilyDescriptors;

        @Nonnull
        private final List<StateMetaInfoSnapshot> stateMetaInfoSnapshots;

        private final ReadOptions readOptions;

        private RestoredDBInstance(@Nonnull RocksDB db, @Nonnull List<ColumnFamilyHandle> columnFamilyHandles, @Nonnull List<ColumnFamilyDescriptor> columnFamilyDescriptors, @Nonnull List<StateMetaInfoSnapshot> stateMetaInfoSnapshots) {
            this.db = db;
            this.defaultColumnFamilyHandle = columnFamilyHandles.remove(0);
            this.columnFamilyHandles = columnFamilyHandles;
            this.columnFamilyDescriptors = columnFamilyDescriptors;
            this.stateMetaInfoSnapshots = stateMetaInfoSnapshots;
            this.readOptions = new ReadOptions();
        }

        @Override
        public void close() {
            List<ColumnFamilyOptions> columnFamilyOptions = new ArrayList<>(columnFamilyDescriptors.size() + 1);
            columnFamilyDescriptors.forEach((cfd) -> columnFamilyOptions.add(cfd.getOptions()));
            RocksDBOperationUtils.addColumnFamilyOptionsToCloseLater(columnFamilyOptions, defaultColumnFamilyHandle);
            IOUtils.closeQuietly(defaultColumnFamilyHandle);
            IOUtils.closeAllQuietly(columnFamilyHandles);
            IOUtils.closeQuietly(db);
            IOUtils.closeAllQuietly(columnFamilyOptions);
            IOUtils.closeQuietly(readOptions);
        }
    }

    private RestoredDBInstance restoreDBInstanceFromStateHandle(IncrementalRemoteKeyedStateHandle restoreStateHandle, Path temporaryRestoreInstancePath) throws Exception {
        try (RocksDBStateDownloader rocksDBStateDownloader = new RocksDBStateDownloader(numberOfTransferringThreads)) {
            rocksDBStateDownloader.transferAllStateDataToDirectory(restoreStateHandle, temporaryRestoreInstancePath, cancelStreamRegistry);
        }
        KeyedBackendSerializationProxy<K> serializationProxy = readMetaData(restoreStateHandle.getMetaStateHandle());
        // read meta data
        List<StateMetaInfoSnapshot> stateMetaInfoSnapshots = serializationProxy.getStateMetaInfoSnapshots();
        List<ColumnFamilyDescriptor> columnFamilyDescriptors = createlumnFamilyDescriptors(stateMetaInfoSnapshots, false);
        List<ColumnFamilyHandle> columnFamilyHandles = new ArrayList<>(stateMetaInfoSnapshots.size() + 1);
        RocksDB restoreDb = RocksDBOperationUtils.openDB(temporaryRestoreInstancePath.toString(), columnFamilyDescriptors, columnFamilyHandles, RocksDBOperationUtils.createColumnFamilyOptions(this.rocksHandle.getColumnFamilyOptionsFactory(), "default"), this.rocksHandle.getDbOptions());
        return new RestoredDBInstance(restoreDb, columnFamilyHandles, columnFamilyDescriptors, stateMetaInfoSnapshots);
    }

    /**
     * This method recreates and registers all {@link ColumnFamilyDescriptor} from Flink's state
     * meta data snapshot.
     */
    private List<ColumnFamilyDescriptor> createlumnFamilyDescriptors(List<StateMetaInfoSnapshot> stateMetaInfoSnapshots, boolean registerTtlCompactFilter) {
        List<ColumnFamilyDescriptor> columnFamilyDescriptors = new ArrayList<>(stateMetaInfoSnapshots.size());
        for (StateMetaInfoSnapshot stateMetaInfoSnapshot : stateMetaInfoSnapshots) {
            RegisteredStateMetaInfoBase metaInfoBase = RegisteredStateMetaInfoBase.fromMetaInfoSnapshot(stateMetaInfoSnapshot);
            ColumnFamilyDescriptor columnFamilyDescriptor = RocksDBOperationUtils.createColumnFamilyDescriptor(metaInfoBase, this.rocksHandle.getColumnFamilyOptionsFactory(), registerTtlCompactFilter ? this.rocksHandle.getTtlCompactFiltersManager() : null, this.rocksHandle.getWriteBufferManagerCapacity());
            columnFamilyDescriptors.add(columnFamilyDescriptor);
        }
        return columnFamilyDescriptors;
    }

    /**
     * Reads Flink's state meta data file from the state handle.
     */
    private KeyedBackendSerializationProxy<K> readMetaData(StreamStateHandle metaStateHandle) throws Exception {
        InputStream inputStream = null;

    }

    KeyedBackendSerializationProxy<K> readMetaData(DataInputView dataInputView) throws IOException, StateMigrationException {
        // isSerializerPresenceRequired flag is set to false, since for the RocksDB state backend,
        // deserialization of state happens lazily during runtime; we depend on the fact
        // that the new serializer for states could be compatible, and therefore the restore can
        // without old serializers required to be present.
        KeyedBackendSerializationProxy<K> serializationProxy = new KeyedBackendSerializationProxy<>(userCodeClassLoader);
        serializationProxy.read(dataInputView);
        if (!isKeySerializerCompatibilityChecked) {
            // fetch current serializer now because if it is incompatible, we can't access
            // it anymore to improve the error message
            TypeSerializer<K> currentSerializer = keySerializerProvider.currentSchemaSerializer();
            // check for key serializer compatibility; this also reconfigures the
            // key serializer to be compatible, if it is required and is possible
            TypeSerializerSchemaCompatibility<K> keySerializerSchemaCompat = keySerializerProvider.setPreviousSerializerSnapshotForRestoredState(serializationProxy.getKeySerializerSnapshot());
            if (keySerializerSchemaCompat.isCompatibleAfterMigration() || keySerializerSchemaCompat.isIncompatible()) {
                throw new StateMigrationException("The new key serializer (" + currentSerializer + ") must be compatible with the previous key serializer (" + keySerializerProvider.previousSchemaSerializer() + ").");
            }
            isKeySerializerCompatibilityChecked = true;
        }
        return serializationProxy;
    }

    @Override
    public void close() throws Exception {
        this.rocksHandle.close();
    }
}