while (itr.hasNext()) {
            Entry<K, V> entry = itr.next();
            K k = entry.getKey();
            V v = entry.getValue();
            K conflict = inverse.delegate.putIfAbsent(v, k);
            if (conflict != null) {
                broken = entry;
                // We're definitely going to throw, but we'll try to keep the BiMap in an internally
                // consistent state by removing the bad entry.
                itr.remove();
            }
        }

package com.azure.cosmos.implementation.guava25.collect;

import static com.azure.cosmos.implementation.guava25.base.Preconditions.checkArgument;
import static com.azure.cosmos.implementation.guava25.base.Preconditions.checkState;
import static com.azure.cosmos.implementation.guava25.collect.CollectPreconditions.checkRemove;
import com.azure.cosmos.implementation.guava25.base.Objects;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;

/**
 * A general-purpose bimap implementation using any two backing {@code Map} instances.
 *
 * <p>Note that this class contains {@code equals()} calls that keep it from supporting {@code
 * IdentityHashMap} backing maps.
 *
 * @author Kevin Bourrillion
 * @author Mike Bostock
 */
abstract class AbstractBiMap<K, V> extends ForwardingMap<K, V> implements BiMap<K, V>, Serializable {

    private transient Map<K, V> delegate;

    transient AbstractBiMap<V, K> inverse;

    /**
     * Package-private constructor for creating a map-backed bimap.
     */
    AbstractBiMap(Map<K, V> forward, Map<V, K> backward) {
        setDelegates(forward, backward);
    }

    /**
     * Private constructor for inverse bimap.
     */
    private AbstractBiMap(Map<K, V> backward, AbstractBiMap<V, K> forward) {
        delegate = backward;
        inverse = forward;
    }

    @Override
    protected Map<K, V> delegate() {
        return delegate;
    }

    /**
     * Returns its input, or throws an exception if this is not a valid key.
     */
    K checkKey(K key) {
        return key;
    }

    /**
     * Returns its input, or throws an exception if this is not a valid value.
     */
    V checkValue(V value) {
        return value;
    }

    /**
     * Specifies the delegate maps going in each direction. Called by the constructor and by
     * subclasses during deserialization.
     */
    void setDelegates(Map<K, V> forward, Map<V, K> backward) {
        checkState(delegate == null);
        checkState(inverse == null);
        checkArgument(forward.isEmpty());
        checkArgument(backward.isEmpty());
        checkArgument(forward != backward);
        delegate = forward;
        inverse = makeInverse(backward);
    }

    AbstractBiMap<V, K> makeInverse(Map<V, K> backward) {
        return new Inverse<>(backward, this);
    }

    void setInverse(AbstractBiMap<V, K> inverse) {
        this.inverse = inverse;
    }

    // Query Operations (optimizations)
    @Override
    public boolean containsValue(Object value) {
        return inverse.containsKey(value);
    }

    // Modification Operations
    @Override
    public V put(K key, V value) {
        return putInBothMaps(key, value, false);
    }

    @Override
    public V forcePut(K key, V value) {
        return putInBothMaps(key, value, true);
    }

    private V putInBothMaps(K key, V value, boolean force) {
        checkKey(key);
        checkValue(value);
        boolean containedKey = containsKey(key);
        if (containedKey && Objects.equal(value, get(key))) {
            return value;
        }
        if (force) {
            inverse().remove(value);
        } else {
            checkArgument(!containsValue(value), "value already present: %s", value);
        }
        V oldValue = delegate.put(key, value);
        updateInverseMap(key, containedKey, oldValue, value);
        return oldValue;
    }

    private void updateInverseMap(K key, boolean containedKey, V oldValue, V newValue) {
        if (containedKey) {
            removeFromInverseMap(oldValue);
        }
        inverse.delegate.put(newValue, key);
    }

    @Override
    public V remove(Object key) {
        return containsKey(key) ? removeFromBothMaps(key) : null;
    }

    private V removeFromBothMaps(Object key) {
        V oldValue = delegate.remove(key);
        removeFromInverseMap(oldValue);
        return oldValue;
    }

    private void removeFromInverseMap(V oldValue) {
        inverse.delegate.remove(oldValue);
    }

    // Bulk Operations
    @Override
    public void putAll(Map<? extends K, ? extends V> map) {
        for (Entry<? extends K, ? extends V> entry : map.entrySet()) {
            put(entry.getKey(), entry.getValue());
        }
    }

    @Override
    public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
        this.delegate.replaceAll(function);
        inverse.delegate.clear();
        Entry<K, V> broken = null;
        Iterator<Entry<K, V>> itr = this.delegate.entrySet().iterator();

        if (broken != null) {
            throw new IllegalArgumentException("value already present: " + broken.getValue());
        }
    }

    @Override
    public void clear() {
        delegate.clear();
        inverse.delegate.clear();
    }

    // Views
    @Override
    public BiMap<V, K> inverse() {
        return inverse;
    }

    private transient Set<K> keySet;

    @Override
    public Set<K> keySet() {
        Set<K> result = keySet;
        return (result == null) ? keySet = new KeySet() : result;
    }

    private class KeySet extends ForwardingSet<K> {

        @Override
        protected Set<K> delegate() {
            return delegate.keySet();
        }

        @Override
        public void clear() {
            AbstractBiMap.this.clear();
        }

        @Override
        public boolean remove(Object key) {
            if (!contains(key)) {
                return false;
            }
            removeFromBothMaps(key);
            return true;
        }

        @Override
        public boolean removeAll(Collection<?> keysToRemove) {
            return standardRemoveAll(keysToRemove);
        }

        @Override
        public boolean retainAll(Collection<?> keysToRetain) {
            return standardRetainAll(keysToRetain);
        }

        @Override
        public Iterator<K> iterator() {
            return Maps.keyIterator(entrySet().iterator());
        }
    }

    private transient Set<V> valueSet;

    @Override
    public Set<V> values() {
        /*
     * We can almost reuse the inverse's keySet, except we have to fix the
     * iteration order so that it is consistent with the forward map.
     */
        Set<V> result = valueSet;
        return (result == null) ? valueSet = new ValueSet() : result;
    }

    private class ValueSet extends ForwardingSet<V> {

        final Set<V> valuesDelegate = inverse.keySet();

        @Override
        protected Set<V> delegate() {
            return valuesDelegate;
        }

        @Override
        public Iterator<V> iterator() {
            return Maps.valueIterator(entrySet().iterator());
        }

        @Override
        public Object[] toArray() {
            return standardToArray();
        }

        @Override
        public <T> T[] toArray(T[] array) {
            return standardToArray(array);
        }

        @Override
        public String toString() {
            return standardToString();
        }
    }

    private transient Set<Entry<K, V>> entrySet;

    @Override
    public Set<Entry<K, V>> entrySet() {
        Set<Entry<K, V>> result = entrySet;
        return (result == null) ? entrySet = new EntrySet() : result;
    }

    class BiMapEntry extends ForwardingMapEntry<K, V> {

        private final Entry<K, V> delegate;

        BiMapEntry(Entry<K, V> delegate) {
            this.delegate = delegate;
        }

        @Override
        protected Entry<K, V> delegate() {
            return delegate;
        }

        @Override
        public V setValue(V value) {
            checkValue(value);
            // Preconditions keep the map and inverse consistent.
            checkState(entrySet().contains(this), "entry no longer in map");
            // similar to putInBothMaps, but set via entry
            if (Objects.equal(value, getValue())) {
                return value;
            }
            checkArgument(!containsValue(value), "value already present: %s", value);
            V oldValue = delegate.setValue(value);
            checkState(Objects.equal(value, get(getKey())), "entry no longer in map");
            updateInverseMap(getKey(), true, oldValue, value);
            return oldValue;
        }
    }

    Iterator<Entry<K, V>> entrySetIterator() {
        final Iterator<Entry<K, V>> iterator = delegate.entrySet().iterator();
        return new Iterator<Entry<K, V>>() {

            Entry<K, V> entry;

            @Override
            public boolean hasNext() {
                return iterator.hasNext();
            }

            @Override
            public Entry<K, V> next() {
                entry = iterator.next();
                return new BiMapEntry(entry);
            }

            @Override
            public void remove() {
                checkRemove(entry != null);
                V value = entry.getValue();
                iterator.remove();
                removeFromInverseMap(value);
                entry = null;
            }
        };
    }

    private class EntrySet extends ForwardingSet<Entry<K, V>> {

        final Set<Entry<K, V>> esDelegate = delegate.entrySet();

        @Override
        protected Set<Entry<K, V>> delegate() {
            return esDelegate;
        }

        @Override
        public void clear() {
            AbstractBiMap.this.clear();
        }

        @Override
        public boolean remove(Object object) {
            if (!esDelegate.contains(object)) {
                return false;
            }
            // safe because esDelegate.contains(object).
            Entry<?, ?> entry = (Entry<?, ?>) object;
            inverse.delegate.remove(entry.getValue());
            /*
       * Remove the mapping in inverse before removing from esDelegate because
       * if entry is part of esDelegate, entry might be invalidated after the
       * mapping is removed from esDelegate.
       */
            esDelegate.remove(entry);
            return true;
        }

        @Override
        public Iterator<Entry<K, V>> iterator() {
            return entrySetIterator();
        }

        // See java.util.Collections.CheckedEntrySet for details on attacks.
        @Override
        public Object[] toArray() {
            return standardToArray();
        }

        @Override
        public <T> T[] toArray(T[] array) {
            return standardToArray(array);
        }

        @Override
        public boolean contains(Object o) {
            return Maps.containsEntryImpl(delegate(), o);
        }

        @Override
        public boolean containsAll(Collection<?> c) {
            return standardContainsAll(c);
        }

        @Override
        public boolean removeAll(Collection<?> c) {
            return standardRemoveAll(c);
        }

        @Override
        public boolean retainAll(Collection<?> c) {
            return standardRetainAll(c);
        }
    }

    /**
     * The inverse of any other {@code AbstractBiMap} subclass.
     */
    static class Inverse<K, V> extends AbstractBiMap<K, V> {

        Inverse(Map<K, V> backward, AbstractBiMap<V, K> forward) {
            super(backward, forward);
        }

        /*
     * Serialization stores the forward bimap, the inverse of this inverse.
     * Deserialization calls inverse() on the forward bimap and returns that
     * inverse.
     *
     * If a bimap and its inverse are serialized together, the deserialized
     * instances have inverse() methods that return the other.
     */
        @Override
        K checkKey(K key) {
            return inverse.checkValue(key);
        }

        @Override
        V checkValue(V value) {
            return inverse.checkKey(value);
        }

        /**
         * @serialData the forward bimap
         */
        private void writeObject(ObjectOutputStream stream) throws IOException {
            stream.defaultWriteObject();
            stream.writeObject(inverse());
        }

        // reading data stored by writeObject
        @SuppressWarnings({ "unchecked", "rawtypes" })
        private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
            stream.defaultReadObject();
            setInverse((AbstractBiMap<V, K>) stream.readObject());
        }

        Object readResolve() {
            return inverse().inverse();
        }

        private static final long serialVersionUID = 0;
    }

    private static final long serialVersionUID = 0;
}


@Override
    public void generateWSDL(MessageContext msgContext) throws AxisFault {
        invoke(msgContext);
    }

/*
 * GovWay - A customizable API Gateway
 * https://govway.org
 *
 *
 *
 */
package org.openspcoop2.ValidazioneContenutiWS.utilities;

import org.apache.axis.AxisFault;
import org.apache.axis.MessageContext;
import org.apache.axis.handlers.BasicHandler;

/**
 * @author Poli Andrea (example@nnthink.com)
 * @author $Author$
 * @version $Rev$, $Date$
 */
public class IntegrationReaderUscitaHandler extends BasicHandler {

    private static final long serialVersionUID = 1L;

    /**
     * Metodo contenente la definizione di un handler per il servizio axis   'RicezioneContenutiApplicativi' e 'Gop'.
     *
     * @param msgContext contiene il contesto di Axis.
     */
    @Override
    public void invoke(MessageContext msgContext) throws AxisFault {
        // Elimina eventuale id se rimasto!
        IntegrationInfoRepository.clear();
    }

    /**
     * Metodo necessario per la definizione dell'handler.
     *
     * @param msgContext contiene il contesto di Axis.
     */


package com.google.cloud.bigquery.connector.common;

import java.net.URI;
import java.util.Optional;

/**
 * Config interface to provide proxy parameters. The concrete class implementing this interface
 * should implement methods to provide ProxyUri, ProxyUserName and ProxyPassword.
 */
public interface BigQueryProxyConfig {

    /**
     * The Uniform Resource Identifier ({@link URI URI}) of the proxy sever. This is an Optional field
     * so can be empty.
     *
     * @return java.util.Optional<URI>
     */

    /**
     * The userName used to connect to the proxy. This is an Optional field so can be empty.
     *
     * @return java.util.Optional<String>
     */
    Optional<String> getProxyUsername();

    /**
     * The password used to connect to the proxy. This is an Optional field so can be empty.
     *
     * @return java.util.Optional<String>
     */
    Optional<String> getProxyPassword();
}


void sendTxtMail(String[] toMails, String subject, String text);

package org.gourd.hu.notice.mail;

/**
 * @author gourd.hu
 */
public interface GourdMailService {

    /**
     * 发送包含简单文本的邮件
     *
     * @param toMails 接收者
     * @param subject 主题
     * @param text    内容
     */

    /**
     * 发送包含HTML文本的邮件
     *
     * @param toMails  接收者
     * @param subject  主题
     * @param htmlText html格式内容
     */
    void sendHtmlMail(String[] toMails, String subject, String htmlText);

    void sendImageMail(String[] toMails, String subject, String htmlImageText);

    void sendAttachmentMail(String[] toMails, String subject, String htmlAttachText);

    void sendTemplateMail(String[] toMails, String subject);
}


package com.google.code.hs4j.network.core;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteOrder;

/**
 * Abstract connection
 *
 * @author dennis
 */
public interface Session {

    public enum SessionStatus {

        NULL,
        READING,
        WRITING,
        IDLE,
        INITIALIZE,
        CLOSING,
        CLOSED
    }

    /**
     * Start session
     */
    public void start();

    /**
     * Write a message,if you don't care when the message is written
     *
     * @param packet
     */
    public void write(Object packet);

    /**
     * Check if session is closed
     *
     * @return
     */
    public boolean isClosed();

    /**
     * Close session
     */
    public void close();

    /**
     * Return the remote end's InetSocketAddress
     *
     * @return
     */
    public InetSocketAddress getRemoteSocketAddress();

    public InetAddress getLocalAddress();

    /**
     * Return true if using blocking write
     *
     * @return
     */
    public boolean isUseBlockingWrite();

    /**
     * Set if using blocking write
     *
     * @param useBlockingWrite
     */
    public void setUseBlockingWrite(boolean useBlockingWrite);

    /**
     * Return true if using blocking read
     *
     * @return
     */
    public boolean isUseBlockingRead();

    public void setUseBlockingRead(boolean useBlockingRead);

    /**
     * Flush the write queue,this method may be no effect if OP_WRITE is
     * running.
     */
    public void flush();

    /**
     * Return true if session is expired,session is expired beacause you set the
     * sessionTimeout,if since session's last operation form now is over this
     * vlaue,isExpired return true,and Handler.onExpired() will be invoked.
     *
     * @return
     */

    /**
     * Check if session is idle
     *
     * @return
     */
    public boolean isIdle();

    /**
     * Return current encoder
     *
     * @return
     */
    public CodecFactory.Encoder getEncoder();

    /**
     * Set encoder
     *
     * @param encoder
     */
    public void setEncoder(CodecFactory.Encoder encoder);

    /**
     * Return current decoder
     *
     * @return
     */
    public CodecFactory.Decoder getDecoder();

    public void setDecoder(CodecFactory.Decoder decoder);

    /**
     * Return true if allow handling read and write concurrently,default is
     * true.
     *
     * @return
     */
    public boolean isHandleReadWriteConcurrently();

    public void setHandleReadWriteConcurrently(boolean handleReadWriteConcurrently);

    /**
     * Return the session read buffer's byte order,big end or little end.
     *
     * @return
     */
    public ByteOrder getReadBufferByteOrder();

    public void setReadBufferByteOrder(ByteOrder readBufferByteOrder);

    /**
     * Set a attribute attched with this session
     *
     * @param key
     * @param value
     */
    public void setAttribute(String key, Object value);

    /**
     * Remove attribute
     *
     * @param key
     */
    public void removeAttribute(String key);

    /**
     * Return attribute associated with key
     *
     * @param key
     * @return
     */
    public Object getAttribute(String key);

    /**
     * Clear attributes
     */
    public void clearAttributes();

    /**
     * Return the bytes in write queue,there bytes is in memory.Use this method
     * to controll writing speed.
     *
     * @return
     */
    public long getScheduleWritenBytes();

    /**
     * Return last operation timestamp,operation include read,write,idle
     *
     * @return
     */
    public long getLastOperationTimeStamp();

    /**
     * return true if it is a loopback connection
     *
     * @return
     */
    public boolean isLoopbackConnection();

    public long getSessionIdleTimeout();

    public void setSessionIdleTimeout(long sessionIdleTimeout);

    public long getSessionTimeout();

    public void setSessionTimeout(long sessionTimeout);

    public Object setAttributeIfAbsent(String key, Object value);

    public Handler getHandler();
}


public abstract boolean coversSubscription(Subscription sub);

/**
 *    This file is part of OpenIoT.
 *
 *     Contact: OpenIoT mailto: example@nnthink.com
 */
package org.openiot.cupus.artefact;

import java.io.Serializable;
import org.openiot.cupus.common.UniqueObject;

/**
 * @author Aleksandar
 */
public abstract class Announcement extends UniqueObject implements Serializable {

    private static final long serialVersionUID = 1L;

    protected long validity;

    protected long startTime;

    public Announcement(long validity, long startTime) {
        super();
        this.validity = validity;
        this.startTime = startTime;
    }

    public long getValidity() {
        return validity;
    }

    public long getStartTime() {
        return startTime;
    }

    /**
     * Checks if validity is bigger than current time in millis or if it is -1.
     * If either of those is true then true is returned, else the publication is
     * invalid.
     */
    public boolean isValid() {
        return (validity >= System.currentTimeMillis()) || (validity == -1);
    }

    /**
     * Returns whether this announcement covers specified subscripion sub.<br>
     * Announcement A covers subscription B if A.equals(B) or (Type of A covers
     * Type of B and properties of A cover properties of B). Properties of A
     * cover properties of B only if B contains all properties of A.
     *
     * @param sub
     *            Subccription to compare to.
     *
     * @return True if this announcement covers specified sub, else false.
     */


public String[] getEnableableProtocols(SSLContext context);

package org.apache.tomcat.util.net;

import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSessionContext;
import javax.net.ssl.TrustManager;

public interface SSLUtil {

    public SSLContext createSSLContext() throws Exception;

    public KeyManager[] getKeyManagers() throws Exception;

    public TrustManager[] getTrustManagers() throws Exception;

    public void configureSessionContext(SSLSessionContext sslSessionContext);

    /**
     * Determines the SSL cipher suites that can be enabled, based on the
     * configuration of the endpoint and the ciphers supported by the SSL
     * implementation.
     *
     * @param context An initialized context to obtain the supported ciphers from.
     *
     * @return Array of SSL cipher suites that may be enabled (which may be
     *         empty if none of the specified ciphers are supported), or
     *         the defaults for the underlying SSL implementation if
     *         the endpoint configuration does not specify any ciphers.
     */
    public String[] getEnableableCiphers(SSLContext context);

    /**
     * Determines the SSL protocol variants that can be enabled, based on the
     * configuration of the endpoint and the ciphers supported by the SSL
     * implementation.
     *
     * @param context An initialized context to obtain the supported protocols from.
     *
     * @return Array of SSL protocol variants that may be enabled (which may be
     *         empty if none of the specified protocols are supported), or
     *         the defaults for the underlying SSL implementation if
     *         the endpoint configuration does not specify any protocols.
     */


D create(String tagName, Map<String, String> attributes);

package org.waveprotocol.wave.model.document;

import java.util.Map;

/**
 * A factory for creating a document by specifying its only
 * immutable component, the document element. (Though the attributes of
 * the document element of course can change later).
 *
 * @param <D> document type produced by this builder
 */
public interface DocumentFactory<D> {

    /**
     * Creates a document, with a specified document element.
     *
     * @param tagName     tag name for the document element
     * @param attributes  attributes for the document element
     * @return new document.
     */


public String getStringValue() {
        return String.valueOf(object);
    }

/*
 * eXist-db Open Source Native XML Database
 *
 * example@nnthink.com
 * http://www.exist-db.org
 *
 */
package org.exist.xquery.value;

import com.ibm.icu.text.Collator;
import org.exist.xquery.Constants.Comparison;
import org.exist.xquery.ErrorCodes;
import org.exist.xquery.XPathException;

/**
 * Represents a reference to an arbitrary Java object which is treated as an
 * atomic value.
 *
 * @author wolf
 */
public class JavaObjectValue extends AtomicValue {

    private final Object object;

    public JavaObjectValue(Object object) {
        this.object = object;
    }

    /* (non-Javadoc)
     * @see org.exist.xquery.value.AtomicValue#getType()
     */
    public int getType() {
        return Type.JAVA_OBJECT;
    }

    public Object getObject() {
        return object;
    }

    /* (non-Javadoc)
     * @see org.exist.xquery.value.Sequence#getStringValue()
     */

    /* (non-Javadoc)
     * @see org.exist.xquery.value.Sequence#convertTo(int)
     */
    public AtomicValue convertTo(int requiredType) throws XPathException {
        if (requiredType == Type.JAVA_OBJECT) {
            return this;
        }
        throw new XPathException(ErrorCodes.FORG0001, "cannot convert Java object to " + Type.getTypeName(requiredType));
    }

    public boolean effectiveBooleanValue() throws XPathException {
        throw new XPathException("Called effectiveBooleanValue() on JavaObjectValue");
    }

    @Override
    public boolean compareTo(Collator collator, Comparison operator, AtomicValue other) throws XPathException {
        throw new XPathException("cannot compare Java object to " + Type.getTypeName(other.getType()));
    }

    /* (non-Javadoc)
     * @see org.exist.xquery.value.AtomicValue#compareTo(org.exist.xquery.value.AtomicValue)
     */
    public int compareTo(Collator collator, AtomicValue other) throws XPathException {
        throw new XPathException("cannot compare Java object to " + Type.getTypeName(other.getType()));
    }

    /* (non-Javadoc)
     * @see org.exist.xquery.value.AtomicValue#max(org.exist.xquery.value.AtomicValue)
     */
    public AtomicValue max(Collator collator, AtomicValue other) throws XPathException {
        throw new XPathException("Invalid argument to aggregate function: cannot compare Java objects");
    }

    public AtomicValue min(Collator collator, AtomicValue other) throws XPathException {
        throw new XPathException("Invalid argument to aggregate function: cannot compare Java objects");
    }

    /* (non-Javadoc)
     * @see org.exist.xquery.value.Item#conversionPreference(java.lang.Class)
     */
    public int conversionPreference(Class<?> javaClass) {
        if (javaClass.isAssignableFrom(object.getClass())) {
            return 0;
        }
        return Integer.MAX_VALUE;
    }

    /* (non-Javadoc)
     * @see org.exist.xquery.value.Item#toJavaObject(java.lang.Class)
     */
    @Override
    public <T> T toJavaObject(final Class<T> target) throws XPathException {
        if (target.isAssignableFrom(object.getClass())) {
            return (T) object;
        } else if (target == Object.class) {
            return (T) object;
        }
        throw new XPathException("cannot convert value of type " + Type.getTypeName(getType()) + " to Java object of type " + target.getName());
    }
}


public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (obj instanceof DateTick && super.equals(obj)) {
            DateTick dt = (DateTick) obj;
            if (!ObjectUtilities.equal(this.date, dt.date)) {
                return false;
            }
            return true;
        }
        return false;
    }

/* ===========================================================
 * JFreeChart : a free chart library for the Java(tm) platform
 * ===========================================================
 *
 *
 * Project Info:  http://example.com
 *
 *
 * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
 * in the United States and other countries.]
 *
 * -------------
 * DateTick.java
 * -------------
 *
 * Original Author:  David Gilbert (for Object Refinery Limited);
 * Contributor(s):   -;
 *
 * Changes
 * -------
 * 07-Nov-2003 : Version 1 (DG);
 * 13-May-2004 : Added equals() method (DG);
 * 20-Jun-2007 : Removed JCommon dependencies (DG);
 *
 */
package org.jfree.chart.axis;

import java.util.Date;
import org.jfree.chart.text.TextAnchor;
import org.jfree.chart.util.ObjectUtilities;

/**
 * A tick used by the {@link DateAxis} class.
 */
public class DateTick extends ValueTick {

    /**
     * The date.
     */
    private Date date;

    /**
     * Creates a new date tick.
     *
     * @param date  the date.
     * @param label  the label.
     * @param textAnchor  the part of the label that is aligned to the anchor
     *                    point.
     * @param rotationAnchor  defines the rotation point relative to the text.
     * @param angle  the rotation angle (in radians).
     */
    public DateTick(Date date, String label, TextAnchor textAnchor, TextAnchor rotationAnchor, double angle) {
        super(date.getTime(), label, textAnchor, rotationAnchor, angle);
        this.date = date;
    }

    /**
     * Returns the date.
     *
     * @return The date.
     */
    public Date getDate() {
        return this.date;
    }

    /**
     * Tests this tick for equality with an arbitrary object.
     *
     * @param obj  the object to test (null permitted).
     *
     * @return A boolean.
     */

    /**
     * Returns a hash code for this object.
     *
     * @return A hash code.
     */
    public int hashCode() {
        return this.date.hashCode();
    }
}


@Override
    public String getMystromFriendlyName(String itemName) {
        MyStromEcoPowerBindingConfig config = (MyStromEcoPowerBindingConfig) bindingConfigs.get(itemName);
        return config != null ? config.mystromFriendlyName : null;
    }

package org.openhab.binding.mystromecopower.internal;

import org.openhab.binding.mystromecopower.MyStromEcoPowerBindingProvider;
import org.openhab.core.binding.BindingConfig;
import org.openhab.core.items.Item;
import org.openhab.core.library.items.NumberItem;
import org.openhab.core.library.items.StringItem;
import org.openhab.core.library.items.SwitchItem;
import org.openhab.model.item.binding.AbstractGenericBindingProvider;
import org.openhab.model.item.binding.BindingConfigParseException;

/**
 * This class is responsible for parsing the binding configuration.
 *
 * @author Jordens Christophe
 * @since 1.8.0
 */
/**
 * @author Christophe
 */
public class MyStromEcoPowerGenericBindingProvider extends AbstractGenericBindingProvider implements MyStromEcoPowerBindingProvider {

    @Override
    public String getBindingType() {
        return "mystromecopower";
    }

    @Override
    public void validateItemType(Item item, String bindingConfig) throws BindingConfigParseException {
        if (!(item instanceof SwitchItem || item instanceof NumberItem || item instanceof StringItem)) {
            throw new BindingConfigParseException("item '" + item.getName() + "' is of type '" + item.getClass().getSimpleName() + "', only Switch, Number or String is allowed - please check your *.items configuration");
        }
    }

    @Override
    public void processBindingConfiguration(String context, Item item, String bindingConfig) throws BindingConfigParseException {
        super.processBindingConfiguration(context, item, bindingConfig);
        MyStromEcoPowerBindingConfig config = new MyStromEcoPowerBindingConfig();
        // parse bindingconfig here ...
        config.mystromFriendlyName = bindingConfig;
        config.isSwitch = item instanceof SwitchItem;
        config.isNumberItem = item instanceof NumberItem;
        config.isStringItem = item instanceof StringItem;
        addBindingConfig(item, config);
    }

    /*
     * (non-Javadoc)
     *
     * @see org.openhab.binding.mystromecopower.MyStromEcoPowerBindingProvider#
     * getMystromFriendlyName(java.lang.String)
     */

    @Override
    public Boolean getIsSwitch(String itemName) {
        MyStromEcoPowerBindingConfig config = (MyStromEcoPowerBindingConfig) bindingConfigs.get(itemName);
        return config != null ? config.isSwitch : false;
    }

    @Override
    public Boolean getIsNumberItem(String itemName) {
        MyStromEcoPowerBindingConfig config = (MyStromEcoPowerBindingConfig) bindingConfigs.get(itemName);
        return config != null ? config.isNumberItem : false;
    }

    @Override
    public Boolean getIsStringItem(String itemName) {
        MyStromEcoPowerBindingConfig config = (MyStromEcoPowerBindingConfig) bindingConfigs.get(itemName);
        return config != null ? config.isStringItem : false;
    }

    /**
     * This class is responsible to transport configuration data.
     *
     * @author Jordens Christophe
     * @since 1.7.0-SNAPSHOT
     */
    class MyStromEcoPowerBindingConfig implements BindingConfig {

        /**
         * The name of the device on the mystrom server.
         */
        public String mystromFriendlyName;

        /**
         * Indicates if the openhab item is a switch item.
         */
        public Boolean isSwitch = false;

        /**
         * Indicates if the openhab item is a number item.
         */
        public Boolean isNumberItem = false;

        /**
         * Indicates if the openhab item is a string item.
         */
        public Boolean isStringItem = false;
    }
}


public static ResourceBundle getStringsResourceBundleForObject(Object obj) {
        String fullClassName = obj.getClass().getName();
        String packageClassName = obj.getClass().getPackage().getName();
        String shortClassName = fullClassName.substring(packageClassName.length() + 1);
        return ResourceBundle.getBundle(ResourceBundleConstant.GENERIC_STRINGS.replaceFirst("%", shortClassName), Locale.getDefault());
    }

/*
 Violet - A program for editing UML diagrams.

 */
package com.horstmann.violet.framework.injection.resources;

import java.util.Locale;
import java.util.ResourceBundle;

public class ResourceBundleUtils {

    /**
     * @param obj that we need to look for resource
     * @return the corresponding resource bundle. Ex : ClassDiagramGraph.class -> ClassDiagramGraphStrings.properties
     */


package javax.faces.component;

import javax.faces.convert.Converter;
import javax.el.ValueExpression;

/**
 *
ValueHolder is an
 * interface that may be implemented by any concrete {@link UIComponent}
 * that wishes to support a local value, as well as access data in the
 * model tier via a value expression, and support conversion
 * between String and the model tier data's native data type.
 */
public interface ValueHolder {

    /**
     *
Return the local value of this {@link UIComponent} (if any),
     * without evaluating any associated {@link ValueExpression}.

     *
     * @return the local value.
     */

/**
     *
Gets the value of this {@link UIComponent}.  If validation
     * failed, as indicated by
     * {@link javax.faces.context.FacesContext#isValidationFailed}
     * returning true, always return the local value.
     * Otherwise, first, consult the local value property of this
     * component.  If non-null return it.  If
     * null, see if we have a {@link ValueExpression} for
     * the value property.  If so, return the result of
     * evaluating the property, otherwise return null.
     * Note that because the specification for {@link
     * UIComponent#setValueBinding} requires a call through to {@link
     * UIComponent#setValueExpression}, legacy tags will continue to
     * work.

     *
     * @return the value.
     */
    public Object getValue();

    /**
     *
Set the value of this {@link UIComponent} (if any).

     *
     * @param value The new local value
     */
    public void setValue(Object value);

    /**
     *
Return the {@link Converter} (if any)
     * that is registered for this {@link UIComponent}.

     *
     * @return the converter.
     */
    public Converter getConverter();

    /**
     *
Set the {@link Converter} (if any) that is registered for this
     * {@link UIComponent}.

     *
     * @param converter New {@link Converter} (or null)
     */
    public void setConverter(Converter converter);
}


public static float noise1(float x) {
        int bx0, bx1;
        float rx0, rx1, sx, t, u, v;
        if (start) {
            start = false;
            init();
        }
        t = x + N;
        bx0 = ((int) t) & BM;
        bx1 = (bx0 + 1) & BM;
        rx0 = t - (int) t;
        rx1 = rx0 - 1.0f;
        sx = sCurve(rx0);
        u = rx0 * g1[p[bx0]];
        v = rx1 * g1[p[bx1]];
        return 2.3f * lerp(sx, u, v);
    }

package com.jhlabs.math;

import java.util.*;

/**
 * Perlin Noise functions
 */
public class Noise implements Function1D, Function2D, Function3D {

    private static Random randomGenerator = new Random();

    public float evaluate(float x) {
        return noise1(x);
    }

    public float evaluate(float x, float y) {
        return noise2(x, y);
    }

    public float evaluate(float x, float y, float z) {
        return noise3(x, y, z);
    }

    /**
     * Compute turbulence using Perlin noise.
     * @param x the x value
     * @param y the y value
     * @param octaves number of octaves of turbulence
     * @return turbulence value at (x,y)
     */
    public static float turbulence2(float x, float y, float octaves) {
        float t = 0.0f;
        for (float f = 1.0f; f <= octaves; f *= 2) t += Math.abs(noise2(f * x, f * y)) / f;
        return t;
    }

    /**
     * Compute turbulence using Perlin noise.
     * @param x the x value
     * @param y the y value
     * @param octaves number of octaves of turbulence
     * @return turbulence value at (x,y)
     */
    public static float turbulence3(float x, float y, float z, float octaves) {
        float t = 0.0f;
        for (float f = 1.0f; f <= octaves; f *= 2) t += Math.abs(noise3(f * x, f * y, f * z)) / f;
        return t;
    }

    private final static int B = 0x100;

    private final static int BM = 0xff;

    private final static int N = 0x1000;

    static int[] p = new int[B + B + 2];

    static float[][] g3 = new float[B + B + 2][3];

    static float[][] g2 = new float[B + B + 2][2];

    static float[] g1 = new float[B + B + 2];

    static boolean start = true;

    private static float sCurve(float t) {
        return t * t * (3.0f - 2.0f * t);
    }

    /**
     * Compute 1-dimensional Perlin noise.
     * @param x the x value
     * @return noise value at x in the range -1..1
     */

    /**
     * Compute 2-dimensional Perlin noise.
     * @param x the x coordinate
     * @param y the y coordinate
     * @return noise value at (x,y)
     */
    public static float noise2(float x, float y) {
        int bx0, bx1, by0, by1, b00, b10, b01, b11;
        float rx0, rx1, ry0, ry1, q[], sx, sy, a, b, t, u, v;
        int i, j;
        if (start) {
            start = false;
            init();
        }
        t = x + N;
        bx0 = ((int) t) & BM;
        bx1 = (bx0 + 1) & BM;
        rx0 = t - (int) t;
        rx1 = rx0 - 1.0f;
        t = y + N;
        by0 = ((int) t) & BM;
        by1 = (by0 + 1) & BM;
        ry0 = t - (int) t;
        ry1 = ry0 - 1.0f;
        i = p[bx0];
        j = p[bx1];
        b00 = p[i + by0];
        b10 = p[j + by0];
        b01 = p[i + by1];
        b11 = p[j + by1];
        sx = sCurve(rx0);
        sy = sCurve(ry0);
        q = g2[b00];
        u = rx0 * q[0] + ry0 * q[1];
        q = g2[b10];
        v = rx1 * q[0] + ry0 * q[1];
        a = lerp(sx, u, v);
        q = g2[b01];
        u = rx0 * q[0] + ry1 * q[1];
        q = g2[b11];
        v = rx1 * q[0] + ry1 * q[1];
        b = lerp(sx, u, v);
        return 1.5f * lerp(sy, a, b);
    }

    /**
     * Compute 3-dimensional Perlin noise.
     * @param x the x coordinate
     * @param y the y coordinate
     * @param y the y coordinate
     * @return noise value at (x,y,z)
     */
    public static float noise3(float x, float y, float z) {
        int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
        float rx0, rx1, ry0, ry1, rz0, rz1, q[], sy, sz, a, b, c, d, t, u, v;
        int i, j;
        if (start) {
            start = false;
            init();
        }
        t = x + N;
        bx0 = ((int) t) & BM;
        bx1 = (bx0 + 1) & BM;
        rx0 = t - (int) t;
        rx1 = rx0 - 1.0f;
        t = y + N;
        by0 = ((int) t) & BM;
        by1 = (by0 + 1) & BM;
        ry0 = t - (int) t;
        ry1 = ry0 - 1.0f;
        t = z + N;
        bz0 = ((int) t) & BM;
        bz1 = (bz0 + 1) & BM;
        rz0 = t - (int) t;
        rz1 = rz0 - 1.0f;
        i = p[bx0];
        j = p[bx1];
        b00 = p[i + by0];
        b10 = p[j + by0];
        b01 = p[i + by1];
        b11 = p[j + by1];
        t = sCurve(rx0);
        sy = sCurve(ry0);
        sz = sCurve(rz0);
        q = g3[b00 + bz0];
        u = rx0 * q[0] + ry0 * q[1] + rz0 * q[2];
        q = g3[b10 + bz0];
        v = rx1 * q[0] + ry0 * q[1] + rz0 * q[2];
        a = lerp(t, u, v);
        q = g3[b01 + bz0];
        u = rx0 * q[0] + ry1 * q[1] + rz0 * q[2];
        q = g3[b11 + bz0];
        v = rx1 * q[0] + ry1 * q[1] + rz0 * q[2];
        b = lerp(t, u, v);
        c = lerp(sy, a, b);
        q = g3[b00 + bz1];
        u = rx0 * q[0] + ry0 * q[1] + rz1 * q[2];
        q = g3[b10 + bz1];
        v = rx1 * q[0] + ry0 * q[1] + rz1 * q[2];
        a = lerp(t, u, v);
        q = g3[b01 + bz1];
        u = rx0 * q[0] + ry1 * q[1] + rz1 * q[2];
        q = g3[b11 + bz1];
        v = rx1 * q[0] + ry1 * q[1] + rz1 * q[2];
        b = lerp(t, u, v);
        d = lerp(sy, a, b);
        return 1.5f * lerp(sz, c, d);
    }

    public static float lerp(float t, float a, float b) {
        return a + t * (b - a);
    }

    private static void normalize2(float[] v) {
        float s = (float) Math.sqrt(v[0] * v[0] + v[1] * v[1]);
        v[0] = v[0] / s;
        v[1] = v[1] / s;
    }

    static void normalize3(float[] v) {
        float s = (float) Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
        v[0] = v[0] / s;
        v[1] = v[1] / s;
        v[2] = v[2] / s;
    }

    private static int random() {
        return randomGenerator.nextInt() & 0x7fffffff;
    }

    private static void init() {
        int i, j, k;
        for (i = 0; i < B; i++) {
            p[i] = i;
            g1[i] = (float) ((random() % (B + B)) - B) / B;
            for (j = 0; j < 2; j++) g2[i][j] = (float) ((random() % (B + B)) - B) / B;
            normalize2(g2[i]);
            for (j = 0; j < 3; j++) g3[i][j] = (float) ((random() % (B + B)) - B) / B;
            normalize3(g3[i]);
        }
        for (i = B - 1; i >= 0; i--) {
            k = p[i];
            p[i] = p[j = random() % B];
            p[j] = k;
        }
        for (i = 0; i < B + 2; i++) {
            p[B + i] = p[i];
            g1[B + i] = g1[i];
            for (j = 0; j < 2; j++) g2[B + i][j] = g2[i][j];
            for (j = 0; j < 3; j++) g3[B + i][j] = g3[i][j];
        }
    }

    /**
     * Returns the minimum and maximum of a number of random values
     * of the given function. This is useful for making some stab at
     * normalising the function.
     */
    public static float[] findRange(Function1D f, float[] minmax) {
        if (minmax == null)
            minmax = new float[2];
        float min = 0, max = 0;
        // Some random numbers here...
        for (float x = -100; x < 100; x += 1.27139) {
            float n = f.evaluate(x);
            min = Math.min(min, n);
            max = Math.max(max, n);
        }
        minmax[0] = min;
        minmax[1] = max;
        return minmax;
    }

    /**
     * Returns the minimum and maximum of a number of random values
     * of the given function. This is useful for making some stab at
     * normalising the function.
     */
    public static float[] findRange(Function2D f, float[] minmax) {
        if (minmax == null)
            minmax = new float[2];
        float min = 0, max = 0;
        // Some random numbers here...
        for (float y = -100; y < 100; y += 10.35173) {
            for (float x = -100; x < 100; x += 10.77139) {
                float n = f.evaluate(x, y);
                min = Math.min(min, n);
                max = Math.max(max, n);
            }
        }
        minmax[0] = min;
        minmax[1] = max;
        return minmax;
    }
}


public void setRequestId(String RequestId) {
        this.RequestId = RequestId;
    }

package com.tencentcloudapi.tdmq.v20200217.models;

import com.tencentcloudapi.common.AbstractModel;
import com.google.gson.annotations.SerializedName;
import com.google.gson.annotations.Expose;
import java.util.HashMap;

public class ClearCmqSubscriptionFilterTagsResponse extends AbstractModel {

    /**
     * 唯一请求 ID，每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
     */
    @SerializedName("RequestId")
    @Expose
    private String RequestId;

    /**
     * Get 唯一请求 ID，每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
     * @return RequestId 唯一请求 ID，每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
     */
    public String getRequestId() {
        return this.RequestId;
    }

    /**
     * Set 唯一请求 ID，每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
     * @param RequestId 唯一请求 ID，每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
     */

    public ClearCmqSubscriptionFilterTagsResponse() {
    }

    /**
     * NOTE: Any ambiguous key set via .set("AnyKey", "value") will be a shallow copy,
     *       and any explicit key, i.e Foo, set via .setFoo("value") will be a deep copy.
     */
    public ClearCmqSubscriptionFilterTagsResponse(ClearCmqSubscriptionFilterTagsResponse source) {
        if (source.RequestId != null) {
            this.RequestId = new String(source.RequestId);
        }
    }

    /**
     * Internal implementation, normal users should not use it.
     */
    public void toMap(HashMap<String, String> map, String prefix) {
        this.setParamSimple(map, prefix + "RequestId", this.RequestId);
    }
}


public WeaveViolationType getType() {
        return type;
    }

package com.newrelic.weave.violation;

import org.objectweb.asm.commons.Method;
import com.google.common.base.MoreObjects;

/**
 * A violation of the weave API. Used to validate @Weave classes against original classes.
 */
public class WeaveViolation {

    private final WeaveViolationType type;

    private String clazz;

    private String field;

    private Method method;

    /**
     * Create a class-level violation with the specified type and class.
     * @param type violation type
     * @param clazz weave class name
     */
    public WeaveViolation(WeaveViolationType type, String clazz) {
        this.type = type;
        this.clazz = clazz;
    }

    /**
     * Create a field-level violation with the specified type, class, and field.
     * @param type violation type
     * @param clazz weave class name
     * @param field weave field name
     */
    public WeaveViolation(WeaveViolationType type, String clazz, String field) {
        this(type, clazz);
        this.field = field;
    }

    /**
     * Create a method-level violation with the specified type, class, and field.
     * @param type violation type
     * @param clazz weave class name
     * @param method weave method
     */
    public WeaveViolation(WeaveViolationType type, String clazz, Method method) {
        this(type, clazz);
        this.method = method;
    }

    /**
     * The type of violation.
     * @return type of violation
     */

/**
     * The weave class name that caused the violation.
     * @return weave class name
     */
    public String getClazz() {
        return clazz;
    }

    /**
     * The weave field name that caused the violation, or null if not applicable.
     * @return weave field name, or null if not applicable
     */
    public String getField() {
        return field;
    }

    /**
     * The weave method that caused the violation, or null if not applicable.
     * @return weave method, or null if not applicable
     */
    public Method getMethod() {
        return method;
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this).omitNullValues().add("type", type).add("clazz", clazz).add("field", field).add("method", method).toString();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        WeaveViolation violation = (WeaveViolation) o;
        if (type != violation.type) {
            return false;
        }
        if (clazz != null ? !clazz.equals(violation.clazz) : violation.clazz != null) {
            return false;
        }
        if (field != null ? !field.equals(violation.field) : violation.field != null) {
            return false;
        }
        return !(method != null ? !method.equals(violation.method) : violation.method != null);
    }

    @Override
    public int hashCode() {
        int result = type.hashCode();
        result = 31 * result + (clazz != null ? clazz.hashCode() : 0);
        result = 31 * result + (field != null ? field.hashCode() : 0);
        result = 31 * result + (method != null ? method.hashCode() : 0);
        return result;
    }
}


while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode node = queue.remove();
                if (node.left != null) {
                    queue.add(node.left);
                }
                if (node.right != null) {
                    queue.add(node.right);
                }
                if (i == size - 1) {
                    list.add(node.val);
                }
            }
        }

package com.leetcode.medium;

import com.leetcode.base.TreeNode;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class RightSideView {

    // 二叉树的层序遍历问题 遍历每一层的时候 把最右的节点记录下来
    public List<Integer> rightSideView(TreeNode root) {
        if (root == null) {
            return new ArrayList<>();
        }
        List<Integer> list = new ArrayList<>();
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);


public float getNodeBoost(NodeState state) {
        IndexingRule rule = getApplicableIndexingRule(state);
        if (rule != null) {
            return rule.getNodeBoost();
        }
        return DEFAULT_BOOST;
    }

package org.apache.jackrabbit.core.query.lucene;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Properties;
import javax.jcr.NamespaceException;
import javax.jcr.RepositoryException;
import org.apache.commons.collections.iterators.AbstractIteratorDecorator;
import org.apache.jackrabbit.core.HierarchyManager;
import org.apache.jackrabbit.core.HierarchyManagerImpl;
import org.apache.jackrabbit.core.id.PropertyId;
import org.apache.jackrabbit.core.nodetype.EffectiveNodeType;
import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
import org.apache.jackrabbit.core.nodetype.NodeTypeRegistryListener;
import org.apache.jackrabbit.core.nodetype.xml.AdditionalNamespaceResolver;
import org.apache.jackrabbit.core.query.QueryHandlerContext;
import org.apache.jackrabbit.core.state.ChildNodeEntry;
import org.apache.jackrabbit.core.state.ItemStateException;
import org.apache.jackrabbit.core.state.ItemStateManager;
import org.apache.jackrabbit.core.state.NodeState;
import org.apache.jackrabbit.core.state.PropertyState;
import org.apache.jackrabbit.core.value.InternalValue;
import org.apache.jackrabbit.spi.Name;
import org.apache.jackrabbit.spi.Path;
import org.apache.jackrabbit.spi.PathFactory;
import org.apache.jackrabbit.spi.QNodeTypeDefinition;
import org.apache.jackrabbit.spi.QPropertyDefinition;
import org.apache.jackrabbit.spi.commons.conversion.IllegalNameException;
import org.apache.jackrabbit.spi.commons.conversion.MalformedPathException;
import org.apache.jackrabbit.spi.commons.conversion.NameResolver;
import org.apache.jackrabbit.spi.commons.conversion.ParsingNameResolver;
import org.apache.jackrabbit.spi.commons.name.NameFactoryImpl;
import org.apache.jackrabbit.spi.commons.name.PathFactoryImpl;
import org.apache.jackrabbit.spi.commons.name.Pattern;
import org.apache.jackrabbit.spi.commons.namespace.NamespaceResolver;
import org.apache.jackrabbit.util.ISO9075;
import org.apache.lucene.analysis.Analyzer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Attr;
import org.w3c.dom.CharacterData;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * IndexingConfigurationImpl implements a concrete indexing
 * configuration.
 */
public class IndexingConfigurationImpl implements IndexingConfiguration, NodeTypeRegistryListener {

    /**
     * The logger instance for this class
     */
    private static final Logger log = LoggerFactory.getLogger(IndexingConfigurationImpl.class);

    /**
     * The path factory instance.
     */
    private static final PathFactory PATH_FACTORY = PathFactoryImpl.getInstance();

    /**
     * An Iterator over an empty list of node states.
     */
    private static final Iterator<NodeState> EMPTY_NODESTATE_ITERATOR;

    static {
        Collection<NodeState> empty = Collections.emptyList();
        EMPTY_NODESTATE_ITERATOR = empty.iterator();
    }

    /**
     * The indexing configuration.
     */
    private Element configuration;

    /**
     * A namespace resolver for parsing QNames in the configuration.
     */
    private NameResolver resolver;

    /**
     * The item state manager to retrieve additional item states.
     */
    private ItemStateManager ism;

    /**
     * A hierarchy resolver for the item state manager.
     */
    private HierarchyManager hmgr;

    /**
     * The node type registry.
     */
    private NodeTypeRegistry ntReg;

    /**
     * The {@link IndexingRule}s inside this configuration.
     */
    private Map<Name, List<IndexingRule>> configElements = new HashMap<Name, List<IndexingRule>>();

    /**
     * The indexing aggregates inside this configuration.
     */
    private AggregateRule[] aggregateRules;

    /**
     * The configured analyzers for indexing properties.
     */
    private Map<String, Analyzer> analyzers = new HashMap<String, Analyzer>();

    public void init(Element config, QueryHandlerContext context, NamespaceMappings nsMappings) throws Exception {
        configuration = config;
        ism = context.getItemStateManager();
        hmgr = new HierarchyManagerImpl(context.getRootId(), ism);
        NamespaceResolver nsResolver = new AdditionalNamespaceResolver(getNamespaces(config));
        resolver = new ParsingNameResolver(NameFactoryImpl.getInstance(), nsResolver);
        ntReg = context.getNodeTypeRegistry();
        ntReg.addListener(this);
        refreshIndexRules();
        List<AggregateRule> idxAggregates = new ArrayList<AggregateRule>();
        NodeList indexingConfigs = config.getChildNodes();
        for (int i = 0; i < indexingConfigs.getLength(); i++) {
            Node configNode = indexingConfigs.item(i);
            if (configNode.getNodeName().equals("aggregate")) {
                idxAggregates.add(new AggregateRuleImpl(configNode, resolver, ism, hmgr));
            } else if (configNode.getNodeName().equals("analyzers")) {
                NodeList childNodes = configNode.getChildNodes();
                for (int j = 0; j < childNodes.getLength(); j++) {
                    Node analyzerNode = childNodes.item(j);
                    if (analyzerNode.getNodeName().equals("analyzer")) {
                        Analyzer analyzer = JackrabbitAnalyzer.getAnalyzerInstance(analyzerNode.getAttributes().getNamedItem("class").getNodeValue());
                        NodeList propertyChildNodes = analyzerNode.getChildNodes();
                        for (int k = 0; k < propertyChildNodes.getLength(); k++) {
                            Node propertyNode = propertyChildNodes.item(k);
                            if (propertyNode.getNodeName().equals("property")) {
                                // get property name
                                Name propName = resolver.getQName(getTextContent(propertyNode));
                                String fieldName = nsMappings.translateName(propName);
                                // set analyzer for the fulltext property fieldname
                                int idx = fieldName.indexOf(':');
                                fieldName = fieldName.substring(0, idx + 1) + FieldNames.FULLTEXT_PREFIX + fieldName.substring(idx + 1);
                                Object prevAnalyzer = analyzers.put(fieldName, analyzer);
                                if (prevAnalyzer != null) {
                                    log.warn("Property " + propName.getLocalName() + " has been configured for multiple analyzers. " + " Last configured analyzer is used");
                                }
                            }
                        }
                    }
                }
            }
        }
        if (idxAggregates.isEmpty()) {
            aggregateRules = null;
        } else {
            aggregateRules = idxAggregates.toArray(new AggregateRule[idxAggregates.size()]);
        }
    }

    /**
     * Returns the configured indexing aggregate rules or null if
     * none exist.
     *
     * @return the configured rules or null if none exist.
     */
    public AggregateRule[] getAggregateRules() {
        return aggregateRules;
    }

    /**
     * Returns true if the property with the given name is fulltext
     * indexed according to this configuration.
     *
     * @param state        the node state.
     * @param propertyName the name of a property.
     * @return true if the property is fulltext indexed;
     *         false otherwise.
     */
    public boolean isIndexed(NodeState state, Name propertyName) {
        IndexingRule rule = getApplicableIndexingRule(state);
        if (rule != null) {
            return rule.isIndexed(state, propertyName);
        }
        // none of the configs matches -> index property
        return true;
    }

    /**
     * Returns the boost value for the given property name. If there is no
     * configuration entry for the property name the {@link #DEFAULT_BOOST} is
     * returned.
     *
     * @param state        the node state.
     * @param propertyName the name of a property.
     * @return the boost value for the property.
     */
    public float getPropertyBoost(NodeState state, Name propertyName) {
        IndexingRule rule = getApplicableIndexingRule(state);
        if (rule != null) {
            return rule.getBoost(propertyName);
        }
        return DEFAULT_BOOST;
    }

    /**
     * Returns the boost for the node scope fulltext index field.
     *
     * @param state the node state.
     * @return the boost for the node scope fulltext index field.
     */

/**
     * Returns true if the property with the given name should be
     * included in the node scope fulltext index. If there is not configuration
     * entry for that propery false is returned.
     *
     * @param state the node state.
     * @param propertyName the name of a property.
     * @return true if the property should be included in the node
     *         scope fulltext index.
     */
    public boolean isIncludedInNodeScopeIndex(NodeState state, Name propertyName) {
        IndexingRule rule = getApplicableIndexingRule(state);
        if (rule != null) {
            return rule.isIncludedInNodeScopeIndex(propertyName);
        }
        // none of the config elements matched -> default is to include
        return true;
    }

    /**
     * Returns true if the content of the property with the given
     * name should show up in an excerpt. If there is no configuration entry for
     * that property true is returned.
     *
     * @param state the node state.
     * @param propertyName the name of a property.
     * @return true if the content of the property should be
     *         included in an excerpt; false otherwise.
     */
    public boolean useInExcerpt(NodeState state, Name propertyName) {
        IndexingRule rule = getApplicableIndexingRule(state);
        if (rule != null) {
            return rule.useInExcerpt(propertyName);
        }
        // none of the config elements matched -> default is to include
        return true;
    }

    /**
     * Returns the analyzer configured for the property with this fieldName
     * (the string representation ,JCR-style name, of the given Name
     * prefixed with FieldNames.FULLTEXT_PREFIX)),
     * and null if none is configured, or the configured analyzer
     * cannot be found. If null is returned, the default Analyzer
     * is used.
     *
     * @param fieldName the string representation ,JCR-style name, of the given Name
     * prefixed with FieldNames.FULLTEXT_PREFIX))
     * @return the analyzer to use for indexing this property
     */
    public Analyzer getPropertyAnalyzer(String fieldName) {
        if (analyzers.containsKey(fieldName)) {
            return analyzers.get(fieldName);
        }
        return null;
    }

    public void nodeTypeRegistered(Name ntName) {
        try {
            refreshIndexRules();
        } catch (Exception e) {
            log.warn("Unable to refresh index rules", e);
        }
    }

    public void nodeTypeReRegistered(Name ntName) {
        // not interested
    }

    public void nodeTypesUnregistered(Collection<Name> names) {
        // not interested
    }

    /**
     * Refreshes the index rules in {@link #configElements} based on the current
     * node types available in the node type registry.
     *
     * @throws Exception if an error occurs while refreshing the rules.
     */
    private void refreshIndexRules() throws Exception {
        Map<Name, List<IndexingRule>> nt2rules = new HashMap<Name, List<IndexingRule>>();
        Name[] ntNames = ntReg.getRegisteredNodeTypes();
        NodeList indexingConfigs = configuration.getChildNodes();
        for (int i = 0; i < indexingConfigs.getLength(); i++) {
            Node configNode = indexingConfigs.item(i);
            if (configNode.getNodeName().equals("index-rule")) {
                IndexingRule element = new IndexingRule(configNode);
                // register under node type and all its sub types
                log.debug("Found rule '{}' for NodeType '{}'", element, element.getNodeTypeName());
                for (Name ntName : ntNames) {
                    if (ntReg.getEffectiveNodeType(ntName).includesNodeType(element.getNodeTypeName())) {
                        List<IndexingRule> perNtConfig = nt2rules.get(ntName);
                        if (perNtConfig == null) {
                            perNtConfig = new ArrayList<IndexingRule>();
                            nt2rules.put(ntName, perNtConfig);
                        }
                        log.debug("Registering it for name '{}'", ntName);
                        perNtConfig.add(new IndexingRule(element, ntReg.getNodeTypeDef(ntName), ntReg.getEffectiveNodeType(ntName)));
                    }
                }
            }
        }
        configElements = nt2rules;
    }

    /**
     * Returns the first indexing rule that applies to the given node
     * state.
     *
     * @param state a node state.
     * @return the indexing rule or null if none applies.
     */
    private IndexingRule getApplicableIndexingRule(NodeState state) {
        List<IndexingRule> rules = null;
        List<IndexingRule> r = configElements.get(state.getNodeTypeName());
        if (r != null) {
            rules = new ArrayList<IndexingRule>();
            rules.addAll(r);
        }
        for (Name name : state.getMixinTypeNames()) {
            r = configElements.get(name);
            if (r != null) {
                if (rules == null) {
                    rules = new ArrayList<IndexingRule>();
                }
                rules.addAll(r);
            }
        }
        IndexingRule matchingNodeTypeRule = null;
        if (rules != null) {
            for (IndexingRule rule : rules) {
                if (rule.appliesToNodeType(state)) {
                    if (!rule.containsCondition() && matchingNodeTypeRule == null) {
                        matchingNodeTypeRule = rule;
                    } else if (rule.appliesToCondition(state)) {
                        return rule;
                    }
                }
            }
        }
        return matchingNodeTypeRule;
    }

    /**
     * Returns the namespaces declared on the node.
     *
     * @param node a DOM node.
     * @return the namespaces
     */
    private Properties getNamespaces(Node node) {
        Properties namespaces = new Properties();
        NamedNodeMap attributes = node.getAttributes();
        for (int i = 0; i < attributes.getLength(); i++) {
            Attr attribute = (Attr) attributes.item(i);
            if (attribute.getName().startsWith("xmlns:")) {
                namespaces.setProperty(attribute.getName().substring(6), attribute.getValue());
            }
        }
        return namespaces;
    }

    /**
     * Creates property configurations defined in the config.
     *
     * @param config the fulltext indexing configuration.
     * @param propConfigs will be filled with exact Name to
     *                    PropertyConfig mappings.
     * @param namePatterns will be filled with NamePatterns.
     * @throws IllegalNameException   if the node type name contains illegal
     *                                characters.
     * @throws NamespaceException if the node type contains an unknown
     *                                prefix.
     */
    private void createPropertyConfigs(Node config, Map<Name, PropertyConfig> propConfigs, List<NamePattern> namePatterns) throws IllegalNameException, NamespaceException {
        NodeList childNodes = config.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++) {
            Node n = childNodes.item(i);
            if (n.getNodeName().equals("property")) {
                NamedNodeMap attributes = n.getAttributes();
                // get boost value
                float boost = 1.0f;
                Node boostAttr = attributes.getNamedItem("boost");
                if (boostAttr != null) {
                    try {
                        boost = Float.parseFloat(boostAttr.getNodeValue());
                    } catch (NumberFormatException e) {
                    }
                }
                // get nodeScopeIndex flag
                boolean nodeScopeIndex = true;
                Node nsIndex = attributes.getNamedItem("nodeScopeIndex");
                if (nsIndex != null) {
                    nodeScopeIndex = Boolean.valueOf(nsIndex.getNodeValue());
                }
                // get isRegexp flag
                boolean isRegexp = false;
                Node regexp = attributes.getNamedItem("isRegexp");
                if (regexp != null) {
                    isRegexp = Boolean.valueOf(regexp.getNodeValue());
                }
                // get useInExcerpt flag
                boolean useInExcerpt = true;
                Node excerpt = attributes.getNamedItem("useInExcerpt");
                if (excerpt != null) {
                    useInExcerpt = Boolean.valueOf(excerpt.getNodeValue());
                }
                PropertyConfig pc = new PropertyConfig(boost, nodeScopeIndex, useInExcerpt);
                if (isRegexp) {
                    namePatterns.add(new NamePattern(getTextContent(n), pc, resolver));
                } else {
                    Name propName = resolver.getQName(getTextContent(n));
                    propConfigs.put(propName, pc);
                }
            }
        }
    }

    /**
     * Gets the condition expression from the configuration.
     *
     * @param config the config node.
     * @return the condition expression or null if there is no
     *         condition set on the config.
     * @throws MalformedPathException if the condition string is malformed.
     * @throws IllegalNameException   if a name contains illegal characters.
     * @throws NamespaceException if a name contains an unknown prefix.
     */
    private PathExpression getCondition(Node config) throws MalformedPathException, IllegalNameException, NamespaceException {
        Node conditionAttr = config.getAttributes().getNamedItem("condition");
        if (conditionAttr == null) {
            return null;
        }
        String conditionString = conditionAttr.getNodeValue();
        int idx;
        int axis;
        Name elementTest = null;
        Name nameTest = null;
        Name propertyName;
        String propertyValue;
        // parse axis
        if (conditionString.startsWith("ancestor::")) {
            axis = PathExpression.ANCESTOR;
            idx = "ancestor::".length();
        } else if (conditionString.startsWith("parent::")) {
            axis = PathExpression.PARENT;
            idx = "parent::".length();
        } else if (conditionString.startsWith("@")) {
            axis = PathExpression.SELF;
            idx = "@".length();
        } else {
            axis = PathExpression.CHILD;
            idx = 0;
        }
        try {
            if (conditionString.startsWith("element(", idx)) {
                int colon = conditionString.indexOf(',', idx + "element(".length());
                String name = conditionString.substring(idx + "element(".length(), colon).trim();
                if (!name.equals("*")) {
                    nameTest = resolver.getQName(ISO9075.decode(name));
                }
                idx = conditionString.indexOf(")/@", colon);
                String type = conditionString.substring(colon + 1, idx).trim();
                elementTest = resolver.getQName(ISO9075.decode(type));
                idx += ")/@".length();
            } else {
                if (axis == PathExpression.ANCESTOR || axis == PathExpression.CHILD || axis == PathExpression.PARENT) {
                    // simple name test
                    String name = conditionString.substring(idx, conditionString.indexOf('/', idx));
                    if (!name.equals("*")) {
                        nameTest = resolver.getQName(ISO9075.decode(name));
                    }
                    idx += name.length() + "/@".length();
                }
            }
            // parse property name
            int eq = conditionString.indexOf('=', idx);
            String name = conditionString.substring(idx, eq).trim();
            propertyName = resolver.getQName(ISO9075.decode(name));
            // parse string value
            int quote = conditionString.indexOf('\'', eq) + 1;
            propertyValue = conditionString.substring(quote, conditionString.indexOf('\'', quote));
        } catch (IndexOutOfBoundsException e) {
            throw new MalformedPathException(conditionString);
        }
        return new PathExpression(axis, elementTest, nameTest, propertyName, propertyValue);
    }

    /**
     * @param node a node.
     * @return the text content of the node.
     */
    private static String getTextContent(Node node) {
        StringBuffer content = new StringBuffer();
        NodeList nodes = node.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            Node n = nodes.item(i);
            if (n.getNodeType() == Node.TEXT_NODE) {
                content.append(((CharacterData) n).getData());
            }
        }
        return content.toString();
    }

    /**
     * A property name pattern.
     */
    private static final class NamePattern {

        /**
         * The pattern to match.
         */
        private final Pattern pattern;

        /**
         * The associated configuration.
         */
        private final PropertyConfig config;

        /**
         * Creates a new name pattern.
         *
         * @param pattern the pattern as read from the configuration file.
         * @param config the associated configuration.
         * @param resolver a namespace resolver for parsing name from the
         *                 configuration.
         * @throws IllegalNameException if the prefix of the name pattern is
         *                              illegal.
         * @throws NamespaceException if the prefix of the name pattern cannot
         *                            be resolved.
         */
        private NamePattern(String pattern, PropertyConfig config, NameResolver resolver) throws IllegalNameException, NamespaceException {
            String uri = Name.NS_DEFAULT_URI;
            String localPattern = pattern;
            int idx = pattern.indexOf(':');
            if (idx != -1) {
                String prefix = pattern.substring(0, idx);
                if (prefix.equals(".*")) {
                    // match all namespaces
                    uri = prefix;
                } else {
                    // match only single namespace
                    // use a dummy local name to get namespace uri
                    uri = resolver.getQName(prefix + ":a").getNamespaceURI();
                }
                localPattern = pattern.substring(idx + 1);
            }
            this.pattern = Pattern.name(uri, localPattern);
            this.config = config;
        }

        /**
         * @param path the path to match.
         * @return true if path matches this name
         *         pattern; false otherwise.
         */
        boolean matches(Path path) {
            return pattern.match(path).isFullMatch();
        }

        /**
         * @return the property configuration for this name pattern.
         */
        PropertyConfig getConfig() {
            return config;
        }
    }

    private class IndexingRule {

        /**
         * The node type of this fulltext indexing rule.
         */
        private final Name nodeTypeName;

        /**
         * Indicates if nodetype is a mixin
         */
        private boolean mixinNodeType = false;

        /**
         * The effective node type of this fulltext indexing rule.
         */
        private EffectiveNodeType effectiveNodeType;

        /**
         * Map of {@link PropertyConfig}. Key=Name of property.
         */
        private final Map<Name, PropertyConfig> propConfigs;

        /**
         * List of {@link NamePattern}s.
         */
        private final List<NamePattern> namePatterns;

        /**
         * An expression based on a relative path.
         */
        private final PathExpression condition;

        /**
         * The boost value for this config element.
         */
        private final float boost;

        /**
         * Creates a new indexing rule base on an existing one, but for a
         * different node type name.
         *
         * @param original the existing rule.
         * @param nodeTypeDef the node type definition for the rule.
         * @param effectiveNodeType the EffectiveNodeType of the rule
         */
        IndexingRule(IndexingRule original, QNodeTypeDefinition nodeTypeDef, EffectiveNodeType effectiveNodeType) {
            this.nodeTypeName = nodeTypeDef.getName();
            this.mixinNodeType = nodeTypeDef.isMixin();
            this.effectiveNodeType = effectiveNodeType;
            this.propConfigs = original.propConfigs;
            this.namePatterns = original.namePatterns;
            this.condition = original.condition;
            this.boost = original.boost;
        }

        /**
         * @param config the configuration for this rule.
         * @throws MalformedPathException if the condition expression is malformed.
         * @throws IllegalNameException   if a name contains illegal characters.
         * @throws NamespaceException if a name contains an unknown prefix.
         */
        IndexingRule(Node config) throws MalformedPathException, IllegalNameException, NamespaceException {
            this.nodeTypeName = getNodeTypeName(config);
            this.condition = getCondition(config);
            this.boost = getNodeBoost(config);
            this.propConfigs = new HashMap<Name, PropertyConfig>();
            this.namePatterns = new ArrayList<NamePattern>();
            createPropertyConfigs(config, propConfigs, namePatterns);
        }

        /**
         * Returns the name of the node type where this rule applies to.
         *
         * @return name of the node type.
         */
        public Name getNodeTypeName() {
            return nodeTypeName;
        }

        /**
         * @return the value for the node boost.
         */
        public float getNodeBoost() {
            return boost;
        }

        /**
         * Returns true if the property with the given name is
         * indexed according to this rule.
         *
         * @param state        the node state.
         * @param propertyName the name of a property.
         * @return true if the property is indexed;
         *         false otherwise.
         */
        public boolean isIndexed(NodeState state, Name propertyName) {
            if (mixinNodeType && effectiveNodeType != null) {
                QPropertyDefinition[] allPropDefs = effectiveNodeType.getAllPropDefs();
                for (QPropertyDefinition propertyDefinition : allPropDefs) {
                    if (propertyDefinition.getName().equals(propertyName)) {
                        return getConfig(propertyName) != null;
                    }
                }
                return true;
            } else {
                return getConfig(propertyName) != null;
            }
        }

        /**
         * Returns the boost value for the given property name. If there is no
         * configuration entry for the property name the default boost value is
         * returned.
         *
         * @param propertyName the name of a property.
         * @return the boost value for the property.
         */
        public float getBoost(Name propertyName) {
            PropertyConfig config = getConfig(propertyName);
            if (config != null) {
                return config.boost;
            } else {
                return DEFAULT_BOOST;
            }
        }

        /**
         * Returns true if the property with the given name should
         * be included in the node scope fulltext index. If there is no
         * configuration entry for that propery false is returned.
         *
         * @param propertyName the name of a property.
         * @return true if the property should be included in the
         *         node scope fulltext index.
         */
        public boolean isIncludedInNodeScopeIndex(Name propertyName) {
            PropertyConfig config = getConfig(propertyName);
            return config != null && config.nodeScopeIndex;
        }

        /**
         * Returns true if the content of the property with the
         * given name should show up in an excerpt. If there is no configuration
         * entry for that property true is returned.
         *
         * @param propertyName the name of a property.
         * @return true if the content of the property should be
         *         included in an excerpt; false otherwise.
         */
        public boolean useInExcerpt(Name propertyName) {
            PropertyConfig config = getConfig(propertyName);
            return config == null || config.useInExcerpt;
        }

        /**
         * Returns true if the nodetype of this rule
         * applies to the given node state.
         *
         * @param state the state to check.
         * @return true the rule applies to the given node;
         *         false otherwise.
         */
        public boolean appliesToNodeType(NodeState state) {
            if (state.getMixinTypeNames().contains(nodeTypeName)) {
                return true;
            }
            if (!nodeTypeName.equals(state.getNodeTypeName())) {
                return false;
            }
            return true;
        }

        /**
         * Returns true if the condition of this rule
         * applies to the given node state.
         *
         * @param state the state to check.
         * @return true the rule applies to the given node;
         *         false otherwise.
         */
        public boolean appliesToCondition(NodeState state) {
            return condition != null && condition.evaluate(state);
        }

        /**
         * Returns true this rule contains a condition.
         *
         * @return true the rule contains a condition;
         *         false otherwise.
         */
        public boolean containsCondition() {
            return condition != null;
        }

        /**
         * @param propertyName name of a property.
         * @return the property configuration or null if this
         *         indexing rule does not contain a configuration for the given
         *         property.
         */
        private PropertyConfig getConfig(Name propertyName) {
            PropertyConfig config = propConfigs.get(propertyName);
            if (config != null) {
                return config;
            } else if (namePatterns.size() > 0) {
                Path path = PATH_FACTORY.create(propertyName);
                // check patterns
                for (NamePattern np : namePatterns) {
                    if (np.matches(path)) {
                        return np.getConfig();
                    }
                }
            }
            return null;
        }

        /**
         * Reads the node type of the root node of the indexing rule.
         *
         * @param config the configuration.
         * @return the name of the node type.
         * @throws IllegalNameException   if the node type name contains illegal
         *                                characters.
         * @throws NamespaceException if the node type contains an unknown
         *                                prefix.
         */
        private Name getNodeTypeName(Node config) throws IllegalNameException, NamespaceException {
            String ntString = config.getAttributes().getNamedItem("nodeType").getNodeValue();
            return resolver.getQName(ntString);
        }

        /**
         * Returns the node boost from the config.
         *
         * @param config the configuration.
         * @return the configured node boost or the default boost if none is
         *         configured.
         */
        private float getNodeBoost(Node config) {
            Node boost = config.getAttributes().getNamedItem("boost");
            if (boost != null) {
                try {
                    return Float.parseFloat(boost.getNodeValue());
                } catch (NumberFormatException e) {
                }
            }
            return DEFAULT_BOOST;
        }
    }

    /**
     * Simple class that holds boost and nodeScopeIndex flag.
     */
    private static class PropertyConfig {

        /**
         * The boost value for a property.
         */
        final float boost;

        /**
         * Flag that indicates whether a property is included in the node
         * scope fulltext index of its parent.
         */
        final boolean nodeScopeIndex;

        /**
         * Flag that indicates whether the content of a property should be used
         * to create an excerpt.
         */
        final boolean useInExcerpt;

        PropertyConfig(float boost, boolean nodeScopeIndex, boolean useInExcerpt) {
            this.boost = boost;
            this.nodeScopeIndex = nodeScopeIndex;
            this.useInExcerpt = useInExcerpt;
        }
    }

    private class PathExpression {

        static final int SELF = 0;

        static final int CHILD = 1;

        static final int ANCESTOR = 2;

        static final int PARENT = 3;

        private final int axis;

        private final Name elementTest;

        private final Name nameTest;

        private final Name propertyName;

        private final String propertyValue;

        PathExpression(int axis, Name elementTest, Name nameTest, Name propertyName, String propertyValue) {
            this.axis = axis;
            this.elementTest = elementTest;
            this.nameTest = nameTest;
            this.propertyName = propertyName;
            this.propertyValue = propertyValue;
        }

        /**
         * Evaluates this expression and returns true if the
         * condition matches using state as the context node
         * state.
         *
         * @param context the context from where the expression should be
         *                evaluated.
         * @return expression result.
         */
        boolean evaluate(final NodeState context) {
            // get iterator along specified axis
            Iterator<NodeState> nodeStates;
            if (axis == SELF) {
                nodeStates = Collections.singletonList(context).iterator();
            } else if (axis == CHILD) {
                nodeStates = (Iterator<NodeState>) new AbstractIteratorDecorator(context.getChildNodeEntries().iterator()) {

                    public Object next() {
                        ChildNodeEntry cne = (ChildNodeEntry) super.next();
                        try {
                            return ism.getItemState(cne.getId());
                        } catch (ItemStateException e) {
                            NoSuchElementException nsee = new NoSuchElementException("No node with id " + cne.getId() + " found in child axis");
                            nsee.initCause(e);
                            throw nsee;
                        }
                    }
                };
            } else if (axis == ANCESTOR) {
                try {
                    nodeStates = new Iterator<NodeState>() {

                        private NodeState next = context.getParentId() == null ? null : (NodeState) ism.getItemState(context.getParentId());

                        public void remove() {
                            throw new UnsupportedOperationException();
                        }

                        public boolean hasNext() {
                            return next != null;
                        }

                        public NodeState next() {
                            NodeState tmp = next;
                            try {
                                if (next.getParentId() != null) {
                                    next = (NodeState) ism.getItemState(next.getParentId());
                                } else {
                                    next = null;
                                }
                            } catch (ItemStateException e) {
                                next = null;
                            }
                            return tmp;
                        }
                    };
                } catch (ItemStateException e) {
                    nodeStates = EMPTY_NODESTATE_ITERATOR;
                }
            } else if (axis == PARENT) {
                try {
                    if (context.getParentId() != null) {
                        NodeState state = (NodeState) ism.getItemState(context.getParentId());
                        nodeStates = Collections.singletonList(state).iterator();
                    } else {
                        nodeStates = EMPTY_NODESTATE_ITERATOR;
                    }
                } catch (ItemStateException e) {
                    nodeStates = EMPTY_NODESTATE_ITERATOR;
                }
            } else {
                // unsupported axis
                nodeStates = EMPTY_NODESTATE_ITERATOR;
            }
            // check node type, name and property value for each
            while (nodeStates.hasNext()) {
                try {
                    NodeState current = nodeStates.next();
                    if (elementTest != null && !current.getNodeTypeName().equals(elementTest)) {
                        continue;
                    }
                    if (nameTest != null && !hmgr.getName(current.getNodeId()).equals(nameTest)) {
                        continue;
                    }
                    if (!current.hasPropertyName(propertyName)) {
                        continue;
                    }
                    PropertyId propId = new PropertyId(current.getNodeId(), propertyName);
                    PropertyState propState = (PropertyState) ism.getItemState(propId);
                    InternalValue[] values = propState.getValues();
                    for (InternalValue value : values) {
                        if (value.toString().equals(propertyValue)) {
                            return true;
                        }
                    }
                } catch (RepositoryException e) {
                    // move on to next one
                } catch (ItemStateException e) {
                    // move on to next one
                }
            }
            return false;
        }
    }
}


public static Vector2DFormat getVector2DFormat() {
        return getVector2DFormat(Locale.getDefault());
    }

/*
 * This is not the original file distributed by the Apache Software Foundation
 * It has been modified by the Hipparchus project
 */
package org.hipparchus.geometry.euclidean.twod;

import java.text.FieldPosition;
import java.text.NumberFormat;
import java.text.ParsePosition;
import java.util.Locale;
import org.hipparchus.exception.LocalizedCoreFormats;
import org.hipparchus.exception.MathIllegalStateException;
import org.hipparchus.geometry.Vector;
import org.hipparchus.geometry.VectorFormat;
import org.hipparchus.util.CompositeFormat;

/**
 * Formats a 2D vector in components list format "{x; y}".
 *
The prefix and suffix "{" and "}" and the separator "; " can be replaced by
 * any user-defined strings. The number format for components can be configured.

 *
White space is ignored at parse time, even if it is in the prefix, suffix
 * or separator specifications. So even if the default separator does include a space
 * character that is used at format time, both input string "{1;1}" and
 * " { 1 ; 1 } " will be parsed without error and the same vector will be
 * returned. In the second case, however, the parse position after parsing will be
 * just after the closing curly brace, i.e. just before the trailing space.

 *
Note: using "," as a separator may interfere with the grouping separator
 * of the default {@link NumberFormat} for the current locale. Thus it is advised
 * to use a {@link NumberFormat} instance with disabled grouping in such a case.

 */
public class Vector2DFormat extends VectorFormat<Euclidean2D> {

    /**
     * Create an instance with default settings.
     *
The instance uses the default prefix, suffix and separator:
     * "{", "}", and "; " and the default number format for components.

     */
    public Vector2DFormat() {
        super(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR, CompositeFormat.getDefaultNumberFormat());
    }

    /**
     * Create an instance with a custom number format for components.
     * @param format the custom format for components.
     */
    public Vector2DFormat(final NumberFormat format) {
        super(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR, format);
    }

    /**
     * Create an instance with custom prefix, suffix and separator.
     * @param prefix prefix to use instead of the default "{"
     * @param suffix suffix to use instead of the default "}"
     * @param separator separator to use instead of the default "; "
     */
    public Vector2DFormat(final String prefix, final String suffix, final String separator) {
        super(prefix, suffix, separator, CompositeFormat.getDefaultNumberFormat());
    }

    /**
     * Create an instance with custom prefix, suffix, separator and format
     * for components.
     * @param prefix prefix to use instead of the default "{"
     * @param suffix suffix to use instead of the default "}"
     * @param separator separator to use instead of the default "; "
     * @param format the custom format for components.
     */
    public Vector2DFormat(final String prefix, final String suffix, final String separator, final NumberFormat format) {
        super(prefix, suffix, separator, format);
    }

    /**
     * Returns the default 2D vector format for the current locale.
     * @return the default 2D vector format.
     * @since 1.4
     */

    /**
     * Returns the default 2D vector format for the given locale.
     * @param locale the specific locale used by the format.
     * @return the 2D vector format specific to the given locale.
     * @since 1.4
     */
    public static Vector2DFormat getVector2DFormat(final Locale locale) {
        return new Vector2DFormat(CompositeFormat.getDefaultNumberFormat(locale));
    }

    @Override
    public StringBuffer format(final Vector<Euclidean2D> vector, final StringBuffer toAppendTo, final FieldPosition pos) {
        final Vector2D p2 = (Vector2D) vector;
        return format(toAppendTo, pos, p2.getX(), p2.getY());
    }

    @Override
    public Vector2D parse(final String source) throws MathIllegalStateException {
        ParsePosition parsePosition = new ParsePosition(0);
        Vector2D result = parse(source, parsePosition);
        if (parsePosition.getIndex() == 0) {
            throw new MathIllegalStateException(LocalizedCoreFormats.CANNOT_PARSE_AS_TYPE, source, parsePosition.getErrorIndex(), Vector2D.class);
        }
        return result;
    }

    @Override
    public Vector2D parse(final String source, final ParsePosition pos) {
        final double[] coordinates = parseCoordinates(2, source, pos);
        if (coordinates == null) {
            return null;
        }
        return new Vector2D(coordinates[0], coordinates[1]);
    }
}