switch(listener.getValue()) {
                    case TRIGGER_ME:
                        listener.setValue(ListenerState.TRIGGERED);
                        listener.getKey().onStartedRequest();
                        listenerTriggered = true;
                        break;
                    case UNSET:
                        listener.setValue(ListenerState.SET);
                        break;
                    default:
                        break;
                }

package fr.pcreations.labs.RESTDroid.core;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import java.util.UUID;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import fr.pcreations.labs.RESTDroid.core.RequestListeners.OnFailedRequestListener;
import fr.pcreations.labs.RESTDroid.core.RequestListeners.OnFinishedRequestListener;
import fr.pcreations.labs.RESTDroid.core.RequestListeners.OnStartedRequestListener;
import fr.pcreations.labs.RESTDroid.core.RequestListeners.OnSucceededRequestListener;

/**
 * <b>Holder class for all request stuff. Provides some listener to handle specific logic in Activity when request starts, succeed or failed</b>
 *
 * @author Pierre Criulanscy
 *
 * @param <T>
 * 		The {@link ResourceRepresentation} class that request deals with
 *
 * @version 0.7.2
 */
public class RESTRequest<T extends Resource> implements Serializable {

    private static final long serialVersionUID = -3975518541858101876L;

    /**
     * ID of the request. Should be unique
     *
     * @see RESTRequest#getID()
     */
    private UUID mID;

    /**
     * The particular {@link HTTPVerb} for this request
     *
     * @see RESTRequest#getVerb()
     * @see RESTRequest#setVerb(HTTPVerb)
     */
    private HTTPVerb mVerb;

    /**
     * Url for this request
     *
     * @see RESTRequest#getUrl()
     * @see RESTRequest#setUrl(String)
     */
    private String mUrl;

    /**
     * Request result code
     *
     * @see RESTRequest#getResultCode()
     * @see RESTRequest#setResultCode(int)
     */
    private int mResultCode;

    /**
     * Boolean to know if request is pending
     *
     * @see RESTRequest#isPending()
     * @see RESTRequest#setPending(boolean)
     *
     * @since 0.6.0
     */
    private boolean mPending;

    /**
     * The server response
     *
     * @see RESTRequest#getResultStream()
     * @see RESTRequest#setResultStream(InputStream)
     *
     * @since 0.7.1
     */
    private transient ByteArrayOutputStream mByteArrayResultStream;

    /**
     * Defines extra parameters for request
     */
    private Bundle mExtraParams;

    /**
     * List of {@link SerializableHeader} for this request
     *
     * @see RESTRequest#getHeaders()
     * @see RESTRequest#addHeader(SerializableHeader)
     * @see RESTRequest#addHeader(String, String)
     */
    private List<SerializableHeader> mHeaders;

    /**
     * Instance of {@link ResourceRepresentation} attached to this request
     *
     * @see RESTRequest#getResourceRepresentation()
     * @see RESTRequest#setResourceRepresentation(ResourceRepresentation)
     */
    private T mResource;

    /**
     * The Class object of {@link ResourceRepresentation} attached to this request. Useful when {@link RESTRequest#mResource} is null
     *
     * @see RESTRequest#getResourceClass()
     */
    private Class<T> mResourceClass;

    /**
     *  Instance of {@link RequestListeners}
     *
     *  @see RESTRequest#setRequestListeners(Activity, Class)
     *  @see RESTRequest#getRequestListeners()
     *
     *  @since 0.7.1
     */
    private transient RequestListeners mRequestListeners;

    private Class<? extends FailBehavior> mFailBehaviorClass;

    private long mExpirationTime;

    /**
     * Constructor
     *
     * @param id
     * 		Unique ID of the request
     *
     * @param clazz
     * 		The Class object of the {@link ResourceRepresentation} attached to this request
     */
    public RESTRequest(UUID id, Class<T> clazz) {
        mID = id;
        mResourceClass = clazz;
        mPending = false;
        mHeaders = new ArrayList<SerializableHeader>();
    }

    /**
     * Constructor
     *
     * @param verb
     * @param id
     * @param url
     * @param extraParams
     */
    public RESTRequest(HTTPVerb verb, UUID id, String url, Bundle extraParams) {
        super();
        mVerb = verb;
        mID = id;
        mUrl = url;
        mPending = false;
        mExtraParams = extraParams;
        mHeaders = new ArrayList<SerializableHeader>();
    }

    /**
     * Pauses the listeners by setting their state to {@link ListenerState#UNSET}
     *
     * @see RESTRequest#resumeListeners()
     * @see RequestListeners
     */
    public void pauseListeners() {
        if (mRequestListeners != null) {
            for (Entry<OnStartedRequestListener, ListenerState> listener : mRequestListeners.getOnStartedRequestListeners().entrySet()) {
                listener.setValue(ListenerState.UNSET);
            }
            for (Entry<OnFailedRequestListener, ListenerState> listener : mRequestListeners.getOnFailedRequestListeners().entrySet()) {
                listener.setValue(ListenerState.UNSET);
            }
            for (Entry<OnSucceededRequestListener, ListenerState> listener : mRequestListeners.getOnSucceedRequestListeners().entrySet()) {
                listener.setValue(ListenerState.UNSET);
            }
        }
    }

    /**
     * Resumes the listeners. If listener state is set to {@link ListenerState#UNSET}, state is updated to {@link ListenerState#SET}. If the state is {@link ListenerState#TRIGGER_ME} the listener is triggered and is state updated to {@link ListenerState#TRIGGERED}
     *
     * @return
     * 		True if listener(s) was triggered, false otherwise
     *
     * @see RESTRequest#pauseListeners()
     * @see RequestListeners
     */
    public boolean resumeListeners() {
        boolean listenerTriggered = false;
        if (mRequestListeners != null) {
            for (Entry<OnStartedRequestListener, ListenerState> listener : mRequestListeners.getOnStartedRequestListeners().entrySet()) {

            }
            for (Entry<OnFailedRequestListener, ListenerState> listener : mRequestListeners.getOnFailedRequestListeners().entrySet()) {
                switch(listener.getValue()) {
                    case TRIGGER_ME:
                        listener.setValue(ListenerState.TRIGGERED);
                        listener.getKey().onFailedRequest(mResultCode);
                        listenerTriggered = true;
                        break;
                    case UNSET:
                        listener.setValue(ListenerState.SET);
                        break;
                    default:
                        break;
                }
            }
            for (Entry<OnSucceededRequestListener, ListenerState> listener : mRequestListeners.getOnSucceedRequestListeners().entrySet()) {
                switch(listener.getValue()) {
                    case TRIGGER_ME:
                        listener.setValue(ListenerState.TRIGGERED);
                        listener.getKey().onSucceededRequest(mResultCode);
                        listenerTriggered = true;
                        break;
                    case UNSET:
                        listener.setValue(ListenerState.SET);
                        break;
                    default:
                        break;
                }
            }
        }
        return listenerTriggered;
    }

    /**
     * Getter for the unique ID of the request
     *
     * @return
     * 		The unique ID of the request
     *
     * @see RESTRequest#mID
     */
    public UUID getID() {
        return mID;
    }

    /**
     * Getter for request's list of {@link SerializableHeader}
     *
     * @return
     * 		All the {@link SerializableHeader} of the request
     *
     * @see RESTRequest#mHeaders
     * @see RESTRequest#addHeader(SerializableHeader)
     * @see RESTRequest#addHeader(String, String)
     * @see SerializableHeader
     */
    public List<SerializableHeader> getHeaders() {
        return mHeaders;
    }

    /**
     * Triggers {@link OnStartedRequestListener} if state is set to {@link ListenerState#SET} and updates state to {@link ListenerState#TRIGGERED}. If the listener is unset, state is updated to {@link ListenerState#TRIGGER_ME}
     *
     * @return
     * 		True if a listener was triggered, false otherwise
     *
     * @see RequestListeners#mOnStartedRequestListeners
     */
    public boolean triggerOnStartedRequestListeners() {
        boolean listenerFired = false;
        if (mRequestListeners != null) {
            for (Entry<OnStartedRequestListener, ListenerState> listener : mRequestListeners.getOnStartedRequestListeners().entrySet()) {
                switch(listener.getValue()) {
                    case SET:
                        listener.setValue(ListenerState.TRIGGERED);
                        listenerFired = true;
                        listener.getKey().onStartedRequest();
                        break;
                    case UNSET:
                        listener.setValue(ListenerState.TRIGGER_ME);
                        break;
                    default:
                        Log.e("CAN'T TRIGGER STARTED REQUEST LISTENER", listener.getValue().toString());
                }
            }
        }
        return listenerFired;
    }

    /**
     * Triggers {@link OnFinishedRequestListener} if state is set to {@link ListenerState#SET} and updates state to {@link ListenerState#TRIGGERED}. If the listener is unset, state is updated to {@link ListenerState#TRIGGER_ME}
     *
     * @return
     * 		True if a listener was triggered, false otherwise
     *
     * @see RequestListeners#mOnSucceededRequestListeners
     */
    public boolean triggerOnSucceededRequestListeners() {
        boolean listenerFired = false;
        if (mRequestListeners != null) {
            for (Entry<OnSucceededRequestListener, ListenerState> listener : mRequestListeners.getOnSucceedRequestListeners().entrySet()) {
                switch(listener.getValue()) {
                    case SET:
                        listener.setValue(ListenerState.TRIGGERED);
                        listenerFired = true;
                        listener.getKey().onSucceededRequest(mResultCode);
                        break;
                    case UNSET:
                        listener.setValue(ListenerState.TRIGGER_ME);
                        break;
                    default:
                        break;
                }
            }
        }
        return listenerFired;
    }

    /**
     * Triggers {@link OnFailedRequestListener} if state is set to {@link ListenerState#SET} and updates state to {@link ListenerState#TRIGGERED}. If the listener is unset, state is updated to {@link ListenerState#TRIGGER_ME}
     *
     * @return
     * 		True if a listener was triggered, false otherwise
     *
     * @see RequestListeners#mOnFailedRequestListeners
     */
    public boolean triggerOnFailedRequestListeners() {
        boolean listenerFired = false;
        if (mRequestListeners != null) {
            for (Entry<OnFailedRequestListener, ListenerState> listener : mRequestListeners.getOnFailedRequestListeners().entrySet()) {
                switch(listener.getValue()) {
                    case SET:
                        listener.setValue(ListenerState.TRIGGERED);
                        listenerFired = true;
                        listener.getKey().onFailedRequest(mResultCode);
                        break;
                    case UNSET:
                        listener.setValue(ListenerState.TRIGGER_ME);
                        break;
                    default:
                        break;
                }
            }
        }
        return listenerFired;
    }

    /**
     * Triggers {@link OnFinishedRequestListener} if state is set to {@link ListenerState#SET} and updates state to {@link ListenerState#TRIGGERED}. If the listener is unset, state is updated to {@link ListenerState#TRIGGER_ME}
     *
     * @return
     * 		True if a listener was triggered, false otherwise
     *
     * @see RequestListeners#mOnFinishedRequestListeners
     */
    public boolean triggerOnFinishedRequestListeners() {
        boolean listenerFired = false;
        if (mRequestListeners != null) {
            for (Entry<OnFinishedRequestListener, ListenerState> listener : mRequestListeners.getOnFinishedRequestListeners().entrySet()) {
                switch(listener.getValue()) {
                    case SET:
                        listener.setValue(ListenerState.TRIGGERED);
                        listenerFired = true;
                        listener.getKey().onFinishedRequest(mResultCode);
                        break;
                    case UNSET:
                        listener.setValue(ListenerState.TRIGGER_ME);
                        break;
                    default:
                        break;
                }
            }
        }
        return listenerFired;
    }

    /**
     * Getter for url
     *
     * @return
     * 		The {@link RESTRequest}'s url
     *
     * @see RESTRequest#mUrl
     * @see RESTRequest#setUrl(String)
     */
    public String getUrl() {
        return mUrl;
    }

    /**
     * Setter for url
     *
     * @param url
     * 		The {@link RESTRequest}'s url
     *
     * @see RESTRequest#mUrl
     * @see RESTRequest#getUrl()
     */
    public void setUrl(String url) {
        this.mUrl = url;
    }

    /**
     * Getter for {@link RESTRequest#mResultCode}
     *
     * @return
     * 		The request result code
     *
     * @see RESTRequest#mResultCode
     * @see RESTRequest#setResultCode(int)
     */
    public int getResultCode() {
        return mResultCode;
    }

    /**
     * Set the request's result code
     *
     * @param resultCode
     * 		The result code to set
     *
     * @see RESTRequest#mResultCode
     * @see RESTRequest#getResultCode()
     */
    public void setResultCode(int resultCode) {
        mResultCode = resultCode;
    }

    /**
     * Getter for {@link RESTRequest#mPending}
     *
     * @return
     * 		True if the request is pending, false otherwise
     *
     * @see RESTRequest#mPending
     * @see RESTRequest#setPending(boolean)
     *
     * @since 0.6.0
     */
    public boolean isPending() {
        return mPending;
    }

    /**
     * Setter for {@link RESTRequest#mPending}
     *
     * @param pending
     * 		The pending state
     *
     * @see RESTRequest#mPending
     * @see RESTRequest#isPending()
     *
     * @since 0.6.0
     */
    public void setPending(boolean pending) {
        mPending = pending;
    }

    /**
     * Getter for {@link RESTRequest#mByteArrayResultStream}. Returns a new InputStream each time
     *
     * @return
     * 		The server's result stream
     *
     * @see RESTRequest#mByteArrayResultStream
     * @see RESTRequest#setResultStream(InputStream)
     *
     * @since 0.7.1
     */
    public InputStream getResultStream() {
        if (null == mByteArrayResultStream)
            return null;
        InputStream is = new ByteArrayInputStream(mByteArrayResultStream.toByteArray());
        return is;
    }

    /**
     * Setter for {@link RESTRequest#mByteArrayResultStream}
     *
     * @param mResultStream
     * 		The server's result stream
     * @throws IOException
     *
     * @see RESTRequest#mByteArrayResultStream
     * @see RESTRequest#getResultStream()
     *
     * @since 0.7.1
     */
    public void setResultStream(InputStream mResultStream) throws IOException {
        if (null != mResultStream) {
            mByteArrayResultStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            while ((len = mResultStream.read(buffer)) > -1) {
                mByteArrayResultStream.write(buffer, 0, len);
            }
            mByteArrayResultStream.flush();
        }
    }

    /**
     * Getter for {@link HTTPVerb}
     *
     * @return
     * 		The {@link RESTRequest}'s {@link HTTPVerb}
     *
     * @see HTTPVerb
     * @see RESTRequest#mVerb
     * @see RESTRequest#setVerb(HTTPVerb)
     */
    public HTTPVerb getVerb() {
        return mVerb;
    }

    /**
     * Setter for {@link HTTPVerb}
     *
     * @param mVerb
     * 		The {@link RESTRequest}'s {@link HTTPVerb}
     *
     * @see HTTPVerb
     * @see RESTRequest#mVerb
     * @see RESTRequest#getVerb()
     */
    public void setVerb(HTTPVerb mVerb) {
        this.mVerb = mVerb;
    }

    /**
     * Getter for {@link ResourceRepresentation}
     *
     * @return
     * 		The {@link RESTRequest}'s {@link ResourceRepresentation}
     *
     * @see ResourceRepresentation
     * @see RESTRequest#mResource
     * @see RESTRequest#setResourceRepresentation(ResourceRepresentation)
     */
    public T getResource() {
        return mResource;
    }

    /**
     * Getter for Class object of {@link RESTRequest}'s {@link ResourceRepresentation}
     *
     * @return
     * 		Class object of {@link RESTRequest}'s {@link ResourceRepresentation}
     *
     * @see ResourceRepresentation
     * @see RESTRequest#mResourceClass
     */
    public Class<T> getResourceClass() {
        return mResourceClass;
    }

    /**
     * Setter for {@link ResourceRepresentation}
     *
     * @param mResourceRepresentation
     * 		Instance of {@link ResourceRepresentation}
     *
     * @see ResourceRepresentation
     * @see RESTRequest#mResource
     * @see RESTRequest#getResourceRepresentation()
     */
    @SuppressWarnings("unchecked")
    public void setResource(Resource mResourceRepresentation) {
        this.mResource = (T) mResourceRepresentation;
    }

    /**
     * Getter for extra parameters
     *
     * @return
     * 		{@link RESTRequest}'s extra	parameters
     *
     * @see RESTRequest#mExtraParams
     * @see RESTRequest#setExtraParams(Bundle)
     */
    public Bundle getExtraParams() {
        return mExtraParams;
    }

    /**
     * Setter for extra parameters
     *
     * @param extraParams
     * 		Extra parameters to store in {@link RESTRequest}
     *
     * @see RESTRequest#mExtraParams
     */
    public void setExtraParams(Bundle extraParams) {
        mExtraParams = extraParams;
    }

    /**
     * Getter for {@link RESTRequest#mRequestListeners}
     *
     * @return
     * 		{@link RESTRequest#mRequestListeners}
     *
     * @see RESTRequest#mRequestListeners
     * @see RequestListeners
     * @see RESTRequest#setRequestListeners(Activity, Class)
     *
     * @since 0.7.1
     */
    public RequestListeners getRequestListeners() {
        return mRequestListeners;
    }

    /**
     * Setter for {@link RESTRequest#mRequestListeners}. Dynamically instanciate new instance of the specified {@link RequestListeners} class.
     *
     * @param a
     * 		Context activity where the {@link RequestListeners} inner class is defined
     * @param clazz
     * 		{@link RESTRequest} Class object holding by this {@link RequestListeners} class
     *
     * @since 0.7.1
     */
    public <L> void setRequestListeners(Activity a, Class<L> clazz) {
        try {
            Constructor<L> ctor = clazz.getConstructor(a.getClass());
            mRequestListeners = (RequestListeners) ctor.newInstance(a);
            mRequestListeners.setRequest(this);
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * Add {@link SerializableHeader} to {@link RESTRequest}
     *
     * @param h
     * 		Instance of {@link SerializableHeader}
     *
     * @see SerializableHeader
     * @see RESTRequest#mHeaders
     * @see RESTRequest#getHeaders()
     * @see RESTRequest#addHeader(String, String)
     */
    public void addHeader(SerializableHeader h) {
        mHeaders.add(h);
    }

    /**
     * Add {@link SerializableHeader} from name and value
     *
     * @param name
     * 		Header's name
     *
     * @param value
     * 		Header's value
     *
     * @see SerializableHeader
     * @see RESTRequest#mHeaders
     * @see RESTRequest#getHeaders()
     * @see RESTRequest#addHeader(SerializableHeader)
     */
    public void addHeader(String name, String value) {
        mHeaders.add(new SerializableHeader(name, value));
    }

    public void setExpirationTime(long expirationTime) {
        mExpirationTime = expirationTime;
    }

    public long getExpirationTime() {
        return mExpirationTime;
    }

    public Class<? extends FailBehavior> getFailBehaviorClass() {
        return mFailBehaviorClass;
    }

    public void setFailBehaviorClass(Class<? extends FailBehavior> failBehaviorClass) {
        this.mFailBehaviorClass = failBehaviorClass;
    }

    public String toString() {
        String str = "";
        str += null != mID ? "Request[id] = " + mID.toString() : "Request[id] = null";
        str += null != mVerb ? "[verb] = " + mVerb.name() : "[verb] = null";
        str += null != mUrl ? "[url] = " + mUrl : "[url] = null";
        str += null != mResource ? mResource.toString() : "[ResourceRepresentation] = null";
        return str;
    }
}


while ((len = mResultStream.read(buffer)) > -1) {
                mByteArrayResultStream.write(buffer, 0, len);
            }

package fr.pcreations.labs.RESTDroid.core;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import java.util.UUID;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import fr.pcreations.labs.RESTDroid.core.RequestListeners.OnFailedRequestListener;
import fr.pcreations.labs.RESTDroid.core.RequestListeners.OnFinishedRequestListener;
import fr.pcreations.labs.RESTDroid.core.RequestListeners.OnStartedRequestListener;
import fr.pcreations.labs.RESTDroid.core.RequestListeners.OnSucceededRequestListener;

/**
 * <b>Holder class for all request stuff. Provides some listener to handle specific logic in Activity when request starts, succeed or failed</b>
 *
 * @author Pierre Criulanscy
 *
 * @param <T>
 * 		The {@link ResourceRepresentation} class that request deals with
 *
 * @version 0.7.2
 */
public class RESTRequest<T extends Resource> implements Serializable {

    private static final long serialVersionUID = -3975518541858101876L;

    /**
     * ID of the request. Should be unique
     *
     * @see RESTRequest#getID()
     */
    private UUID mID;

    /**
     * The particular {@link HTTPVerb} for this request
     *
     * @see RESTRequest#getVerb()
     * @see RESTRequest#setVerb(HTTPVerb)
     */
    private HTTPVerb mVerb;

    /**
     * Url for this request
     *
     * @see RESTRequest#getUrl()
     * @see RESTRequest#setUrl(String)
     */
    private String mUrl;

    /**
     * Request result code
     *
     * @see RESTRequest#getResultCode()
     * @see RESTRequest#setResultCode(int)
     */
    private int mResultCode;

    /**
     * Boolean to know if request is pending
     *
     * @see RESTRequest#isPending()
     * @see RESTRequest#setPending(boolean)
     *
     * @since 0.6.0
     */
    private boolean mPending;

    /**
     * The server response
     *
     * @see RESTRequest#getResultStream()
     * @see RESTRequest#setResultStream(InputStream)
     *
     * @since 0.7.1
     */
    private transient ByteArrayOutputStream mByteArrayResultStream;

    /**
     * Defines extra parameters for request
     */
    private Bundle mExtraParams;

    /**
     * List of {@link SerializableHeader} for this request
     *
     * @see RESTRequest#getHeaders()
     * @see RESTRequest#addHeader(SerializableHeader)
     * @see RESTRequest#addHeader(String, String)
     */
    private List<SerializableHeader> mHeaders;

    /**
     * Instance of {@link ResourceRepresentation} attached to this request
     *
     * @see RESTRequest#getResourceRepresentation()
     * @see RESTRequest#setResourceRepresentation(ResourceRepresentation)
     */
    private T mResource;

    /**
     * The Class object of {@link ResourceRepresentation} attached to this request. Useful when {@link RESTRequest#mResource} is null
     *
     * @see RESTRequest#getResourceClass()
     */
    private Class<T> mResourceClass;

    /**
     *  Instance of {@link RequestListeners}
     *
     *  @see RESTRequest#setRequestListeners(Activity, Class)
     *  @see RESTRequest#getRequestListeners()
     *
     *  @since 0.7.1
     */
    private transient RequestListeners mRequestListeners;

    private Class<? extends FailBehavior> mFailBehaviorClass;

    private long mExpirationTime;

    /**
     * Constructor
     *
     * @param id
     * 		Unique ID of the request
     *
     * @param clazz
     * 		The Class object of the {@link ResourceRepresentation} attached to this request
     */
    public RESTRequest(UUID id, Class<T> clazz) {
        mID = id;
        mResourceClass = clazz;
        mPending = false;
        mHeaders = new ArrayList<SerializableHeader>();
    }

    /**
     * Constructor
     *
     * @param verb
     * @param id
     * @param url
     * @param extraParams
     */
    public RESTRequest(HTTPVerb verb, UUID id, String url, Bundle extraParams) {
        super();
        mVerb = verb;
        mID = id;
        mUrl = url;
        mPending = false;
        mExtraParams = extraParams;
        mHeaders = new ArrayList<SerializableHeader>();
    }

    /**
     * Pauses the listeners by setting their state to {@link ListenerState#UNSET}
     *
     * @see RESTRequest#resumeListeners()
     * @see RequestListeners
     */
    public void pauseListeners() {
        if (mRequestListeners != null) {
            for (Entry<OnStartedRequestListener, ListenerState> listener : mRequestListeners.getOnStartedRequestListeners().entrySet()) {
                listener.setValue(ListenerState.UNSET);
            }
            for (Entry<OnFailedRequestListener, ListenerState> listener : mRequestListeners.getOnFailedRequestListeners().entrySet()) {
                listener.setValue(ListenerState.UNSET);
            }
            for (Entry<OnSucceededRequestListener, ListenerState> listener : mRequestListeners.getOnSucceedRequestListeners().entrySet()) {
                listener.setValue(ListenerState.UNSET);
            }
        }
    }

    /**
     * Resumes the listeners. If listener state is set to {@link ListenerState#UNSET}, state is updated to {@link ListenerState#SET}. If the state is {@link ListenerState#TRIGGER_ME} the listener is triggered and is state updated to {@link ListenerState#TRIGGERED}
     *
     * @return
     * 		True if listener(s) was triggered, false otherwise
     *
     * @see RESTRequest#pauseListeners()
     * @see RequestListeners
     */
    public boolean resumeListeners() {
        boolean listenerTriggered = false;
        if (mRequestListeners != null) {
            for (Entry<OnStartedRequestListener, ListenerState> listener : mRequestListeners.getOnStartedRequestListeners().entrySet()) {
                switch(listener.getValue()) {
                    case TRIGGER_ME:
                        listener.setValue(ListenerState.TRIGGERED);
                        listener.getKey().onStartedRequest();
                        listenerTriggered = true;
                        break;
                    case UNSET:
                        listener.setValue(ListenerState.SET);
                        break;
                    default:
                        break;
                }
            }
            for (Entry<OnFailedRequestListener, ListenerState> listener : mRequestListeners.getOnFailedRequestListeners().entrySet()) {
                switch(listener.getValue()) {
                    case TRIGGER_ME:
                        listener.setValue(ListenerState.TRIGGERED);
                        listener.getKey().onFailedRequest(mResultCode);
                        listenerTriggered = true;
                        break;
                    case UNSET:
                        listener.setValue(ListenerState.SET);
                        break;
                    default:
                        break;
                }
            }
            for (Entry<OnSucceededRequestListener, ListenerState> listener : mRequestListeners.getOnSucceedRequestListeners().entrySet()) {
                switch(listener.getValue()) {
                    case TRIGGER_ME:
                        listener.setValue(ListenerState.TRIGGERED);
                        listener.getKey().onSucceededRequest(mResultCode);
                        listenerTriggered = true;
                        break;
                    case UNSET:
                        listener.setValue(ListenerState.SET);
                        break;
                    default:
                        break;
                }
            }
        }
        return listenerTriggered;
    }

    /**
     * Getter for the unique ID of the request
     *
     * @return
     * 		The unique ID of the request
     *
     * @see RESTRequest#mID
     */
    public UUID getID() {
        return mID;
    }

    /**
     * Getter for request's list of {@link SerializableHeader}
     *
     * @return
     * 		All the {@link SerializableHeader} of the request
     *
     * @see RESTRequest#mHeaders
     * @see RESTRequest#addHeader(SerializableHeader)
     * @see RESTRequest#addHeader(String, String)
     * @see SerializableHeader
     */
    public List<SerializableHeader> getHeaders() {
        return mHeaders;
    }

    /**
     * Triggers {@link OnStartedRequestListener} if state is set to {@link ListenerState#SET} and updates state to {@link ListenerState#TRIGGERED}. If the listener is unset, state is updated to {@link ListenerState#TRIGGER_ME}
     *
     * @return
     * 		True if a listener was triggered, false otherwise
     *
     * @see RequestListeners#mOnStartedRequestListeners
     */
    public boolean triggerOnStartedRequestListeners() {
        boolean listenerFired = false;
        if (mRequestListeners != null) {
            for (Entry<OnStartedRequestListener, ListenerState> listener : mRequestListeners.getOnStartedRequestListeners().entrySet()) {
                switch(listener.getValue()) {
                    case SET:
                        listener.setValue(ListenerState.TRIGGERED);
                        listenerFired = true;
                        listener.getKey().onStartedRequest();
                        break;
                    case UNSET:
                        listener.setValue(ListenerState.TRIGGER_ME);
                        break;
                    default:
                        Log.e("CAN'T TRIGGER STARTED REQUEST LISTENER", listener.getValue().toString());
                }
            }
        }
        return listenerFired;
    }

    /**
     * Triggers {@link OnFinishedRequestListener} if state is set to {@link ListenerState#SET} and updates state to {@link ListenerState#TRIGGERED}. If the listener is unset, state is updated to {@link ListenerState#TRIGGER_ME}
     *
     * @return
     * 		True if a listener was triggered, false otherwise
     *
     * @see RequestListeners#mOnSucceededRequestListeners
     */
    public boolean triggerOnSucceededRequestListeners() {
        boolean listenerFired = false;
        if (mRequestListeners != null) {
            for (Entry<OnSucceededRequestListener, ListenerState> listener : mRequestListeners.getOnSucceedRequestListeners().entrySet()) {
                switch(listener.getValue()) {
                    case SET:
                        listener.setValue(ListenerState.TRIGGERED);
                        listenerFired = true;
                        listener.getKey().onSucceededRequest(mResultCode);
                        break;
                    case UNSET:
                        listener.setValue(ListenerState.TRIGGER_ME);
                        break;
                    default:
                        break;
                }
            }
        }
        return listenerFired;
    }

    /**
     * Triggers {@link OnFailedRequestListener} if state is set to {@link ListenerState#SET} and updates state to {@link ListenerState#TRIGGERED}. If the listener is unset, state is updated to {@link ListenerState#TRIGGER_ME}
     *
     * @return
     * 		True if a listener was triggered, false otherwise
     *
     * @see RequestListeners#mOnFailedRequestListeners
     */
    public boolean triggerOnFailedRequestListeners() {
        boolean listenerFired = false;
        if (mRequestListeners != null) {
            for (Entry<OnFailedRequestListener, ListenerState> listener : mRequestListeners.getOnFailedRequestListeners().entrySet()) {
                switch(listener.getValue()) {
                    case SET:
                        listener.setValue(ListenerState.TRIGGERED);
                        listenerFired = true;
                        listener.getKey().onFailedRequest(mResultCode);
                        break;
                    case UNSET:
                        listener.setValue(ListenerState.TRIGGER_ME);
                        break;
                    default:
                        break;
                }
            }
        }
        return listenerFired;
    }

    /**
     * Triggers {@link OnFinishedRequestListener} if state is set to {@link ListenerState#SET} and updates state to {@link ListenerState#TRIGGERED}. If the listener is unset, state is updated to {@link ListenerState#TRIGGER_ME}
     *
     * @return
     * 		True if a listener was triggered, false otherwise
     *
     * @see RequestListeners#mOnFinishedRequestListeners
     */
    public boolean triggerOnFinishedRequestListeners() {
        boolean listenerFired = false;
        if (mRequestListeners != null) {
            for (Entry<OnFinishedRequestListener, ListenerState> listener : mRequestListeners.getOnFinishedRequestListeners().entrySet()) {
                switch(listener.getValue()) {
                    case SET:
                        listener.setValue(ListenerState.TRIGGERED);
                        listenerFired = true;
                        listener.getKey().onFinishedRequest(mResultCode);
                        break;
                    case UNSET:
                        listener.setValue(ListenerState.TRIGGER_ME);
                        break;
                    default:
                        break;
                }
            }
        }
        return listenerFired;
    }

    /**
     * Getter for url
     *
     * @return
     * 		The {@link RESTRequest}'s url
     *
     * @see RESTRequest#mUrl
     * @see RESTRequest#setUrl(String)
     */
    public String getUrl() {
        return mUrl;
    }

    /**
     * Setter for url
     *
     * @param url
     * 		The {@link RESTRequest}'s url
     *
     * @see RESTRequest#mUrl
     * @see RESTRequest#getUrl()
     */
    public void setUrl(String url) {
        this.mUrl = url;
    }

    /**
     * Getter for {@link RESTRequest#mResultCode}
     *
     * @return
     * 		The request result code
     *
     * @see RESTRequest#mResultCode
     * @see RESTRequest#setResultCode(int)
     */
    public int getResultCode() {
        return mResultCode;
    }

    /**
     * Set the request's result code
     *
     * @param resultCode
     * 		The result code to set
     *
     * @see RESTRequest#mResultCode
     * @see RESTRequest#getResultCode()
     */
    public void setResultCode(int resultCode) {
        mResultCode = resultCode;
    }

    /**
     * Getter for {@link RESTRequest#mPending}
     *
     * @return
     * 		True if the request is pending, false otherwise
     *
     * @see RESTRequest#mPending
     * @see RESTRequest#setPending(boolean)
     *
     * @since 0.6.0
     */
    public boolean isPending() {
        return mPending;
    }

    /**
     * Setter for {@link RESTRequest#mPending}
     *
     * @param pending
     * 		The pending state
     *
     * @see RESTRequest#mPending
     * @see RESTRequest#isPending()
     *
     * @since 0.6.0
     */
    public void setPending(boolean pending) {
        mPending = pending;
    }

    /**
     * Getter for {@link RESTRequest#mByteArrayResultStream}. Returns a new InputStream each time
     *
     * @return
     * 		The server's result stream
     *
     * @see RESTRequest#mByteArrayResultStream
     * @see RESTRequest#setResultStream(InputStream)
     *
     * @since 0.7.1
     */
    public InputStream getResultStream() {
        if (null == mByteArrayResultStream)
            return null;
        InputStream is = new ByteArrayInputStream(mByteArrayResultStream.toByteArray());
        return is;
    }

    /**
     * Setter for {@link RESTRequest#mByteArrayResultStream}
     *
     * @param mResultStream
     * 		The server's result stream
     * @throws IOException
     *
     * @see RESTRequest#mByteArrayResultStream
     * @see RESTRequest#getResultStream()
     *
     * @since 0.7.1
     */
    public void setResultStream(InputStream mResultStream) throws IOException {
        if (null != mResultStream) {
            mByteArrayResultStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;

            mByteArrayResultStream.flush();
        }
    }

    /**
     * Getter for {@link HTTPVerb}
     *
     * @return
     * 		The {@link RESTRequest}'s {@link HTTPVerb}
     *
     * @see HTTPVerb
     * @see RESTRequest#mVerb
     * @see RESTRequest#setVerb(HTTPVerb)
     */
    public HTTPVerb getVerb() {
        return mVerb;
    }

    /**
     * Setter for {@link HTTPVerb}
     *
     * @param mVerb
     * 		The {@link RESTRequest}'s {@link HTTPVerb}
     *
     * @see HTTPVerb
     * @see RESTRequest#mVerb
     * @see RESTRequest#getVerb()
     */
    public void setVerb(HTTPVerb mVerb) {
        this.mVerb = mVerb;
    }

    /**
     * Getter for {@link ResourceRepresentation}
     *
     * @return
     * 		The {@link RESTRequest}'s {@link ResourceRepresentation}
     *
     * @see ResourceRepresentation
     * @see RESTRequest#mResource
     * @see RESTRequest#setResourceRepresentation(ResourceRepresentation)
     */
    public T getResource() {
        return mResource;
    }

    /**
     * Getter for Class object of {@link RESTRequest}'s {@link ResourceRepresentation}
     *
     * @return
     * 		Class object of {@link RESTRequest}'s {@link ResourceRepresentation}
     *
     * @see ResourceRepresentation
     * @see RESTRequest#mResourceClass
     */
    public Class<T> getResourceClass() {
        return mResourceClass;
    }

    /**
     * Setter for {@link ResourceRepresentation}
     *
     * @param mResourceRepresentation
     * 		Instance of {@link ResourceRepresentation}
     *
     * @see ResourceRepresentation
     * @see RESTRequest#mResource
     * @see RESTRequest#getResourceRepresentation()
     */
    @SuppressWarnings("unchecked")
    public void setResource(Resource mResourceRepresentation) {
        this.mResource = (T) mResourceRepresentation;
    }

    /**
     * Getter for extra parameters
     *
     * @return
     * 		{@link RESTRequest}'s extra	parameters
     *
     * @see RESTRequest#mExtraParams
     * @see RESTRequest#setExtraParams(Bundle)
     */
    public Bundle getExtraParams() {
        return mExtraParams;
    }

    /**
     * Setter for extra parameters
     *
     * @param extraParams
     * 		Extra parameters to store in {@link RESTRequest}
     *
     * @see RESTRequest#mExtraParams
     */
    public void setExtraParams(Bundle extraParams) {
        mExtraParams = extraParams;
    }

    /**
     * Getter for {@link RESTRequest#mRequestListeners}
     *
     * @return
     * 		{@link RESTRequest#mRequestListeners}
     *
     * @see RESTRequest#mRequestListeners
     * @see RequestListeners
     * @see RESTRequest#setRequestListeners(Activity, Class)
     *
     * @since 0.7.1
     */
    public RequestListeners getRequestListeners() {
        return mRequestListeners;
    }

    /**
     * Setter for {@link RESTRequest#mRequestListeners}. Dynamically instanciate new instance of the specified {@link RequestListeners} class.
     *
     * @param a
     * 		Context activity where the {@link RequestListeners} inner class is defined
     * @param clazz
     * 		{@link RESTRequest} Class object holding by this {@link RequestListeners} class
     *
     * @since 0.7.1
     */
    public <L> void setRequestListeners(Activity a, Class<L> clazz) {
        try {
            Constructor<L> ctor = clazz.getConstructor(a.getClass());
            mRequestListeners = (RequestListeners) ctor.newInstance(a);
            mRequestListeners.setRequest(this);
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * Add {@link SerializableHeader} to {@link RESTRequest}
     *
     * @param h
     * 		Instance of {@link SerializableHeader}
     *
     * @see SerializableHeader
     * @see RESTRequest#mHeaders
     * @see RESTRequest#getHeaders()
     * @see RESTRequest#addHeader(String, String)
     */
    public void addHeader(SerializableHeader h) {
        mHeaders.add(h);
    }

    /**
     * Add {@link SerializableHeader} from name and value
     *
     * @param name
     * 		Header's name
     *
     * @param value
     * 		Header's value
     *
     * @see SerializableHeader
     * @see RESTRequest#mHeaders
     * @see RESTRequest#getHeaders()
     * @see RESTRequest#addHeader(SerializableHeader)
     */
    public void addHeader(String name, String value) {
        mHeaders.add(new SerializableHeader(name, value));
    }

    public void setExpirationTime(long expirationTime) {
        mExpirationTime = expirationTime;
    }

    public long getExpirationTime() {
        return mExpirationTime;
    }

    public Class<? extends FailBehavior> getFailBehaviorClass() {
        return mFailBehaviorClass;
    }

    public void setFailBehaviorClass(Class<? extends FailBehavior> failBehaviorClass) {
        this.mFailBehaviorClass = failBehaviorClass;
    }

    public String toString() {
        String str = "";
        str += null != mID ? "Request[id] = " + mID.toString() : "Request[id] = null";
        str += null != mVerb ? "[verb] = " + mVerb.name() : "[verb] = null";
        str += null != mUrl ? "[url] = " + mUrl : "[url] = null";
        str += null != mResource ? mResource.toString() : "[ResourceRepresentation] = null";
        return str;
    }
}


for (type$ptr<Expr> /*P*/
        /*P*/
        I = LE.capture_init_begin(), /*P*/
        /*P*/
        E = LE.capture_init_end(); $noteq_ptr(I, E); I.$preInc()) {
            if ((I.$star() != null)) {
                this.Visit(I.$star());
            }
        }

/**
 * This file was converted to Java from the original LLVM source file. The original
 * source file follows the LLVM Release License, outlined below.
 *
 * ==============================================================================
 *
 * All rights reserved.
 *
 * Developed by:
 *
 *     LLVM Team
 *
 *     University of Illinois at Urbana-Champaign
 *
 *     http://llvm.org
 *
 * ==============================================================================
 * Copyrights and Licenses for Third Party Software Distributed with LLVM:
 * ==============================================================================
 *
 * The following pieces of software have additional or alternate copyrights,
 * licenses, and/or restrictions:
 *
 * Program             Directory
 * -------             ---------
 * Autoconf            llvm/autoconf
 *                     llvm/projects/ModuleMaker/autoconf
 * Google Test         llvm/utils/unittest/googletest
 * OpenBSD regex       llvm/lib/Support/{reg*, COPYRIGHT.regex}
 * pyyaml tests        llvm/test/YAMLParser/{*.data, LICENSE.TXT}
 * ARM contributions   llvm/lib/Target/ARM/LICENSE.TXT
 * md5 contributions   llvm/lib/Support/MD5.cpp llvm/include/llvm/Support/MD5.h
 */
package org.clang.ast;

import org.clank.support.*;
import org.clank.support.aliases.*;
import static org.clank.support.Native.*;

// / \brief Given a potentially-evaluated expression, this visitor visits all
// / of its potentially-evaluated subexpressions, recursively.
/*template <template <typename > class Ptr, typename ImplClass> TEMPLATE*/
@Converted(kind = Converted.Kind.AUTO, source = "${LLVM_SRC}/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h", line = 29, FQN = "clang::EvaluatedExprVisitorBase", NM = "_ZN5clang24EvaluatedExprVisitorBaseE", cmd = "jclank.sh -java-options=${SPUTNIK}/modules/org.clang.ast/llvmToClangType ${LLVM_SRC}/llvm/tools/clang/lib/Sema/SemaExpr.cpp -nm=_ZN5clang24EvaluatedExprVisitorBaseE")
public interface EvaluatedExprVisitorBase</*template <typename > TEMPLATE*/
Ptr, /*typename*/
ImplClass extends EvaluatedExprVisitorBase<?, ?>> extends StmtVisitorBaseVoid<Ptr, ImplClass> {

    // Fields container
    @Converted(kind = Converted.Kind.MANUAL_SEMANTIC)
    public static final class EvaluatedExprVisitorBase$Fields {

        public final ASTContext Context;

        public EvaluatedExprVisitorBase$Fields(final ASTContext Context) {
            this.Context = Context;
        }
    }

    public default EvaluatedExprVisitorBase$Fields $EvaluatedExprVisitorBase$Fields() {
        throw new UnsupportedOperationException("Why not implemented in derived? " + this.getClass() + ". Keep what was returned from $EvaluatedExprVisitorBase in your final field and just return it here.");
    }

    @Converted(kind = Converted.Kind.AUTO, source = "${LLVM_SRC}/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h", line = 37, FQN = "clang::EvaluatedExprVisitorBase::EvaluatedExprVisitorBase<Ptr, ImplClass>", NM = "_ZN5clang24EvaluatedExprVisitorBaseC1ERKNS_10ASTContextE", cmd = "jclank.sh -java-options=${SPUTNIK}/modules/org.clang.ast/llvmToClangType ${LLVM_SRC}/llvm/tools/clang/lib/Sema/SemaExpr.cpp -nm=_ZN5clang24EvaluatedExprVisitorBaseC1ERKNS_10ASTContextE")
    public default /*explicit*/
    EvaluatedExprVisitorBase$Fields $EvaluatedExprVisitorBase(final ASTContext Context) {
        // START JInit
        return new EvaluatedExprVisitorBase$Fields(Context);
        // END JInit
    }

    // Expressions that have no potentially-evaluated subexpressions (but may have
    @Converted(kind = Converted.Kind.AUTO, source = "${LLVM_SRC}/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h", line = 41, FQN = "clang::EvaluatedExprVisitorBase::VisitDeclRefExpr", NM = "_ZN5clang24EvaluatedExprVisitorBase16VisitDeclRefExprENT_INS_11DeclRefExprEE4typeE", cmd = "jclank.sh -java-options=${SPUTNIK}/modules/org.clang.ast/llvmToClangType ${LLVM_SRC}/llvm/tools/clang/lib/Sema/SemaExpr.cpp -nm=_ZN5clang24EvaluatedExprVisitorBase16VisitDeclRefExprENT_INS_11DeclRefExprEE4typeE")
    public default void VisitDeclRefExpr(DeclRefExpr /*P*/
    E) {
    }

    @Converted(kind = Converted.Kind.AUTO, source = "${LLVM_SRC}/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h", line = 42, FQN = "clang::EvaluatedExprVisitorBase::VisitOffsetOfExpr", NM = "_ZN5clang24EvaluatedExprVisitorBase17VisitOffsetOfExprENT_INS_12OffsetOfExprEE4typeE", cmd = "jclank.sh -java-options=${SPUTNIK}/modules/org.clang.ast/llvmToClangType ${LLVM_SRC}/llvm/tools/clang/lib/Sema/SemaExpr.cpp -nm=_ZN5clang24EvaluatedExprVisitorBase17VisitOffsetOfExprENT_INS_12OffsetOfExprEE4typeE")
    public default void VisitOffsetOfExpr(OffsetOfExpr /*P*/
    E) {
    }

    @Converted(kind = Converted.Kind.AUTO, source = "${LLVM_SRC}/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h", line = 43, FQN = "clang::EvaluatedExprVisitorBase::VisitUnaryExprOrTypeTraitExpr", NM = "_ZN5clang24EvaluatedExprVisitorBase29VisitUnaryExprOrTypeTraitExprENT_INS_24UnaryExprOrTypeTraitExprEE4typeE", cmd = "jclank.sh -java-options=${SPUTNIK}/modules/org.clang.ast/llvmToClangType ${LLVM_SRC}/llvm/tools/clang/lib/Sema/SemaExpr.cpp -nm=_ZN5clang24EvaluatedExprVisitorBase29VisitUnaryExprOrTypeTraitExprENT_INS_24UnaryExprOrTypeTraitExprEE4typeE")
    public default void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr /*P*/
    E) {
    }

    @Converted(kind = Converted.Kind.AUTO, source = "${LLVM_SRC}/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h", line = 44, FQN = "clang::EvaluatedExprVisitorBase::VisitExpressionTraitExpr", NM = "_ZN5clang24EvaluatedExprVisitorBase24VisitExpressionTraitExprENT_INS_19ExpressionTraitExprEE4typeE", cmd = "jclank.sh -java-options=${SPUTNIK}/modules/org.clang.ast/llvmToClangType ${LLVM_SRC}/llvm/tools/clang/lib/Sema/SemaExpr.cpp -nm=_ZN5clang24EvaluatedExprVisitorBase24VisitExpressionTraitExprENT_INS_19ExpressionTraitExprEE4typeE")
    public default void VisitExpressionTraitExpr(ExpressionTraitExpr /*P*/
    E) {
    }

    @Converted(kind = Converted.Kind.AUTO, source = "${LLVM_SRC}/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h", line = 45, FQN = "clang::EvaluatedExprVisitorBase::VisitBlockExpr", NM = "_ZN5clang24EvaluatedExprVisitorBase14VisitBlockExprENT_INS_9BlockExprEE4typeE", cmd = "jclank.sh -java-options=${SPUTNIK}/modules/org.clang.ast/llvmToClangType ${LLVM_SRC}/llvm/tools/clang/lib/Sema/SemaExpr.cpp -nm=_ZN5clang24EvaluatedExprVisitorBase14VisitBlockExprENT_INS_9BlockExprEE4typeE")
    public default void VisitBlockExpr(BlockExpr /*P*/
    E) {
    }

    @Converted(kind = Converted.Kind.AUTO, source = "${LLVM_SRC}/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h", line = 46, FQN = "clang::EvaluatedExprVisitorBase::VisitCXXUuidofExpr", NM = "_ZN5clang24EvaluatedExprVisitorBase18VisitCXXUuidofExprENT_INS_13CXXUuidofExprEE4typeE", cmd = "jclank.sh -java-options=${SPUTNIK}/modules/org.clang.ast/llvmToClangType ${LLVM_SRC}/llvm/tools/clang/lib/Sema/SemaExpr.cpp -nm=_ZN5clang24EvaluatedExprVisitorBase18VisitCXXUuidofExprENT_INS_13CXXUuidofExprEE4typeE")
    public default void VisitCXXUuidofExpr(CXXUuidofExpr /*P*/
    E) {
    }

    @Converted(kind = Converted.Kind.AUTO, source = "${LLVM_SRC}/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h", line = 47, FQN = "clang::EvaluatedExprVisitorBase::VisitCXXNoexceptExpr", NM = "_ZN5clang24EvaluatedExprVisitorBase20VisitCXXNoexceptExprENT_INS_15CXXNoexceptExprEE4typeE", cmd = "jclank.sh -java-options=${SPUTNIK}/modules/org.clang.ast/llvmToClangType ${LLVM_SRC}/llvm/tools/clang/lib/Sema/SemaExpr.cpp -nm=_ZN5clang24EvaluatedExprVisitorBase20VisitCXXNoexceptExprENT_INS_15CXXNoexceptExprEE4typeE")
    public default void VisitCXXNoexceptExpr(CXXNoexceptExpr /*P*/
    E) {
    }

    @Converted(kind = Converted.Kind.AUTO, source = "${LLVM_SRC}/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h", line = 49, FQN = "clang::EvaluatedExprVisitorBase::VisitMemberExpr", NM = "_ZN5clang24EvaluatedExprVisitorBase15VisitMemberExprENT_INS_10MemberExprEE4typeE", cmd = "jclank.sh -java-options=${SPUTNIK}/modules/org.clang.ast/llvmToClangType ${LLVM_SRC}/llvm/tools/clang/lib/Sema/SemaExpr.cpp -nm=_ZN5clang24EvaluatedExprVisitorBase15VisitMemberExprENT_INS_10MemberExprEE4typeE")
    public default void VisitMemberExpr(MemberExpr /*P*/
    E) {
        // Only the base matters.
        this.Visit(E.getBase());
        return;
    }

    @Converted(kind = Converted.Kind.AUTO, source = "${LLVM_SRC}/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h", line = 54, FQN = "clang::EvaluatedExprVisitorBase::VisitChooseExpr", NM = "_ZN5clang24EvaluatedExprVisitorBase15VisitChooseExprENT_INS_10ChooseExprEE4typeE", cmd = "jclank.sh -java-options=${SPUTNIK}/modules/org.clang.ast/llvmToClangType ${LLVM_SRC}/llvm/tools/clang/lib/Sema/SemaExpr.cpp -nm=_ZN5clang24EvaluatedExprVisitorBase15VisitChooseExprENT_INS_10ChooseExprEE4typeE")
    public default void VisitChooseExpr(ChooseExpr /*P*/
    E) {
        // Don't visit either child expression if the condition is dependent.
        if (E.getCond().isValueDependent()) {
            return;
        }
        // Only the selected subexpression matters; the other one is not evaluated.
        this.Visit(E.getChosenSubExpr());
        return;
    }

    @Converted(kind = Converted.Kind.AUTO, source = "${LLVM_SRC}/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h", line = 62, FQN = "clang::EvaluatedExprVisitorBase::VisitGenericSelectionExpr", NM = "_ZN5clang24EvaluatedExprVisitorBase25VisitGenericSelectionExprENT_INS_20GenericSelectionExprEE4typeE", cmd = "jclank.sh -java-options=${SPUTNIK}/modules/org.clang.ast/llvmToClangType ${LLVM_SRC}/llvm/tools/clang/lib/Sema/SemaExpr.cpp -nm=_ZN5clang24EvaluatedExprVisitorBase25VisitGenericSelectionExprENT_INS_20GenericSelectionExprEE4typeE")
    public default void VisitGenericSelectionExpr(GenericSelectionExpr /*P*/
    E) {
        // The controlling expression of a generic selection is not evaluated.
        // Don't visit either child expression if the condition is type-dependent.
        if (E.isResultDependent()) {
            return;
        }
        // Only the selected subexpression matters; the other subexpressions and the
        // controlling expression are not evaluated.
        this.Visit(E.getResultExpr());
        return;
    }

    @Converted(kind = Converted.Kind.AUTO, source = "${LLVM_SRC}/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h", line = 73, FQN = "clang::EvaluatedExprVisitorBase::VisitDesignatedInitExpr", NM = "_ZN5clang24EvaluatedExprVisitorBase23VisitDesignatedInitExprENT_INS_18DesignatedInitExprEE4typeE", cmd = "jclank.sh -java-options=${SPUTNIK}/modules/org.clang.ast/llvmToClangType ${LLVM_SRC}/llvm/tools/clang/lib/Sema/SemaExpr.cpp -nm=_ZN5clang24EvaluatedExprVisitorBase23VisitDesignatedInitExprENT_INS_18DesignatedInitExprEE4typeE")
    public default void VisitDesignatedInitExpr(DesignatedInitExpr /*P*/
    E) {
        // Only the actual initializer matters; the designators are all constant
        this.Visit(E.getInit());
        return;
    }

    @Converted(kind = Converted.Kind.AUTO, source = "${LLVM_SRC}/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h", line = 79, FQN = "clang::EvaluatedExprVisitorBase::VisitCXXTypeidExpr", NM = "_ZN5clang24EvaluatedExprVisitorBase18VisitCXXTypeidExprENT_INS_13CXXTypeidExprEE4typeE", cmd = "jclank.sh -java-options=${SPUTNIK}/modules/org.clang.ast/llvmToClangType ${LLVM_SRC}/llvm/tools/clang/lib/Sema/SemaExpr.cpp -nm=_ZN5clang24EvaluatedExprVisitorBase18VisitCXXTypeidExprENT_INS_13CXXTypeidExprEE4typeE")
    public default void VisitCXXTypeidExpr(CXXTypeidExpr /*P*/
    E) {
        if (E.isPotentiallyEvaluated()) {
            this.Visit(E.getExprOperand());
            return;
        }
    }

    @Converted(kind = Converted.Kind.AUTO, source = "${LLVM_SRC}/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h", line = 84, FQN = "clang::EvaluatedExprVisitorBase::VisitCallExpr", NM = "_ZN5clang24EvaluatedExprVisitorBase13VisitCallExprENT_INS_8CallExprEE4typeE", cmd = "jclank.sh -java-options=${SPUTNIK}/modules/org.clang.ast/llvmToClangType ${LLVM_SRC}/llvm/tools/clang/lib/Sema/SemaExpr.cpp -nm=_ZN5clang24EvaluatedExprVisitorBase13VisitCallExprENT_INS_8CallExprEE4typeE")
    public default void VisitCallExpr(CallExpr /*P*/
    CE) {
        if (!CE.isUnevaluatedBuiltinCall($EvaluatedExprVisitorBase$Fields().Context)) {
            ((ImplClass) /*P*/
            (this)).VisitExpr(CE);
            return;
        }
    }

    @Converted(kind = Converted.Kind.AUTO, source = "${LLVM_SRC}/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h", line = 89, FQN = "clang::EvaluatedExprVisitorBase::VisitLambdaExpr", NM = "_ZN5clang24EvaluatedExprVisitorBase15VisitLambdaExprENT_INS_10LambdaExprEE4typeE", cmd = "jclank.sh -java-options=${SPUTNIK}/modules/org.clang.ast/llvmToClangType ${LLVM_SRC}/llvm/tools/clang/lib/Sema/SemaExpr.cpp -nm=_ZN5clang24EvaluatedExprVisitorBase15VisitLambdaExprENT_INS_10LambdaExprEE4typeE")
    public default void VisitLambdaExpr(LambdaExpr /*P*/
    LE) {
        // Only visit the capture initializers, and not the body.

    }

    // / \brief The basis case walks all of the children of the statement or
    // / expression, assuming they are all potentially evaluated.
    @Converted(kind = Converted.Kind.AUTO, source = "${LLVM_SRC}/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h", line = 100, FQN = "clang::EvaluatedExprVisitorBase::VisitStmt", NM = "_ZN5clang24EvaluatedExprVisitorBase9VisitStmtENT_INS_4StmtEE4typeE", cmd = "jclank.sh -java-options=${SPUTNIK}/modules/org.clang.ast/llvmToClangType ${LLVM_SRC}/llvm/tools/clang/lib/Sema/SemaExpr.cpp -nm=_ZN5clang24EvaluatedExprVisitorBase9VisitStmtENT_INS_4StmtEE4typeE")
    public default void VisitStmt(Stmt /*P*/
    S) {
        for (Stmt /*P*/
        SubStmt : S.children()) {
            if (SubStmt != null) {
                this.Visit(SubStmt);
            }
        }
    }

    public default void $destroy$EvaluatedExprVisitor() {
    }
}


package edu.iu.dsc.tws.tset.graph;

import java.io.Serializable;
import java.util.Set;

/**
 * Graph used for modeling the TSet dependency structure
 */
public interface MutableGraph<T> extends Serializable {

    /**
     * Adds {@code node} if it is not already present.
     *
     *
Nodes must be unique, just as {@code Map} keys must be. They must also be non-null.
     *
     * @return {@code true} if the graph was modified as a result of this call
     */
    boolean addNode(T node);

    /**
     * Adds an edge connecting {@code nodeU} to {@code nodeV} if one is not already present.
     *
     *
If the graph is directed, the resultant edge will be directed; otherwise, it will be
     * undirected.
     *
     *
If {@code nodeU} and {@code nodeV} are not already present in this graph, this method will
     * silently {@link #addNode(Object) add} {@code nodeU} and {@code nodeV} to the graph.
     *
     * @return {@code true} if the graph was modified as a result of this call
     * @throws IllegalArgumentException if the introduction of the edge would violate {@link
     * #allowsSelfLoops()}
     */
    boolean putEdge(T orgin, T target);

    Set<T> nodes();

    /**
     * Removes {@code node} if it is present; all edges incident to {@code node} will also be removed.
     *
     * @return {@code true} if the graph was modified as a result of this call
     */
    boolean removeNode(T node);

    /**
     * Removes the edge connecting {@code nodeU} to {@code nodeV}, if it is present.
     *
     * @return {@code true} if the graph was modified as a result of this call
     */
    boolean removeEdge(T nodeU, T nodeV);

    /**
     * Returns all nodes in this graph adjacent to {@code node} which can be reached by traversing
     * {@code node}'s outgoing edges in the direction (if any) of the edge.
     *
     * @throws IllegalArgumentException if {@code node} is not an element of this graph
     */
    Set<T> successors(T node);

    /**
     * Returns all nodes in this graph adjacent to {@code node} which can be reached by traversing
     * {@code node}'s incoming edges against the direction (if any) of the edge.
     *
     * @throws IllegalArgumentException if {@code node} is not an element of this graph
     */
    Set<T> predecessors(T node);

    /**
     * Returns true if this graph allows self-loops (edges that connect a node to itself). Attempting
     * to add a self-loop to a graph that does not allow them will throw an {@link
     * IllegalArgumentException}.
     */
    default boolean allowsSelfLoops() {
        return false;
    }

    /**
     * Returns true if the edges in this graph are directed.
     */

    /**
     * returns the node which has the given Id or null if no such node exsists
     * @param id the id of the node to return
     */
    T getNodeById(String id);
}


SearchResult searchUser(String keyword, int selectPageNumber, int returnCount, User user) throws SearchException;

package com.edgenius.wiki.search.service;

import com.edgenius.core.model.User;

/**
 * @author Dapeng.Ni
 */
public interface UserSearchService {

    /**
     * @param keyword
     * @param selectPageNumber
     * @param user
     * @return
     */


package com.minecolonies.api.tileentities;

import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;

public abstract class AbstractTileEntityBarrel extends TileEntity implements ITickableTileEntity {

    /**
     * The number of items it needs to start composting
     */
    public static final int MAX_ITEMS = 64;

    public AbstractTileEntityBarrel(final TileEntityType<?> tileEntityTypeIn) {
        super(tileEntityTypeIn);
    }

    /**
     * Returns the number of items that the block contains
     *
     * @return the number of items
     */

    public abstract boolean isDone();

    public abstract boolean checkIfWorking();

    public abstract boolean addItem(ItemStack item);

    public abstract ItemStack retrieveCompost(double multiplier);
}


package lib.sound.sampled;

/**
 * A mixer is an audio device with one or more lines.  It need not be
 * designed for mixing audio signals.  A mixer that actually mixes audio
 * has multiple input (source) lines and at least one output (target) line.
 * The former are often instances of classes that implement
 * {@link SourceDataLine},
 * and the latter, {@link TargetDataLine}.  {@link Port}
 * objects, too, are either source lines or target lines.
 * A mixer can accept prerecorded, loopable sound as input, by having
 * some of its source lines be instances of objects that implement the
 * {@link Clip} interface.
 *

 * Through methods of the Line interface, which Mixer extends,
 * a mixer might provide a set of controls that are global to the mixer.  For example,
 * the mixer can have a master gain control.  These global controls are distinct
 * from the controls belonging to each of the mixer's individual lines.
 *

 * Some mixers, especially
 * those with internal digital mixing capabilities, may provide
 * additional capabilities by implementing the DataLine interface.
 *

 * A mixer can support synchronization of its lines.  When one line in
 * a synchronized group is started or stopped, the other lines in the group
 * automatically start or stop simultaneously with the explicitly affected one.
 *
 * @author Kara Kytle
 * @since 1.3
 */
public interface Mixer extends Line {

    /**
     * Obtains information about this mixer, including the product's name,
     * version, vendor, etc.
     *
     * @return a mixer info object that describes this mixer
     * @see Mixer.Info
     */
    Info getMixerInfo();

    /**
     * Obtains information about the set of source lines supported
     * by this mixer.
     * Some source lines may only be available when this mixer is open.
     *
     * @return array of Line.Info objects representing source lines
     * for this mixer.  If no source lines are supported,
     * an array of length 0 is returned.
     */

/**
     * Obtains information about the set of target lines supported
     * by this mixer.
     * Some target lines may only be available when this mixer is open.
     *
     * @return array of Line.Info objects representing target lines
     * for this mixer.  If no target lines are supported,
     * an array of length 0 is returned.
     */
    Line.Info[] getTargetLineInfo();

    /**
     * Obtains information about source lines of a particular type supported
     * by the mixer.
     * Some source lines may only be available when this mixer is open.
     *
     * @param info a Line.Info object describing lines about which information
     *             is queried
     * @return an array of Line.Info objects describing source lines matching
     * the type requested.  If no matching source lines are supported, an array of length 0
     * is returned.
     */
    Line.Info[] getSourceLineInfo(Line.Info info);

    /**
     * Obtains information about target lines of a particular type supported
     * by the mixer.
     * Some target lines may only be available when this mixer is open.
     *
     * @param info a Line.Info object describing lines about which information
     *             is queried
     * @return an array of Line.Info objects describing target lines matching
     * the type requested.  If no matching target lines are supported, an array of length 0
     * is returned.
     */
    Line.Info[] getTargetLineInfo(Line.Info info);

    /**
     * Indicates whether the mixer supports a line (or lines) that match
     * the specified Line.Info object.
     * Some lines may only be supported when this mixer is open.
     *
     * @param info describes the line for which support is queried
     * @return true if at least one matching line is
     * supported, false otherwise
     */
    boolean isLineSupported(Line.Info info);

    /**
     * Obtains a line that is available for use and that matches the description
     * in the specified Line.Info object.
     *

     *
If a DataLine is requested, and info
     * is an instance of DataLine.Info specifying at
     * least one fully qualified audio format, the last one
     * will be used as the default format of the returned
     * DataLine.
     *
     * @param info describes the desired line
     * @throws LineUnavailableException if a matching line
     *                                  is not available due to resource restrictions
     * @throws IllegalArgumentException if this mixer does
     *                                  not support any lines matching the description
     * @throws SecurityException        if a matching line
     *                                  is not available due to security restrictions
     */
    Line getLine(Line.Info info) throws LineUnavailableException;

    // $$fb 2002-04-12: fix for 4667258: behavior of Mixer.getMaxLines(Line.Info) method doesn't match the spec
    /**
     * Obtains the approximate maximum number of lines of the requested type that can be open
     * simultaneously on the mixer.
     *

     * Certain types of mixers do not have a hard bound and may allow opening more lines.
     * Since certain lines are a shared resource, a mixer may not be able to open the maximum
     * number of lines if another process has opened lines of this mixer.
     *

     * The requested type is any line that matches the description in
     * the provided Line.Info object.  For example, if the info
     * object represents a speaker
     * port, and the mixer supports exactly one speaker port, this method
     * should return 1.  If the info object represents a source data line
     * and the mixer supports the use of 32 source data lines simultaneously,
     * the return value should be 32.
     * If there is no limit, this function returns AudioSystem.NOT_SPECIFIED.
     *
     * @param info a Line.Info that describes the line for which
     *             the number of supported instances is queried
     * @return the maximum number of matching lines supported, or AudioSystem.NOT_SPECIFIED
     */
    int getMaxLines(Line.Info info);

    /**
     * Obtains the set of all source lines currently open to this mixer.
     *
     * @return the source lines currently open to the mixer.
     * If no source lines are currently open to this mixer,  an
     * array of length 0 is returned.
     * @throws SecurityException if the matching lines
     *                           are not available due to security restrictions
     */
    Line[] getSourceLines();

    /**
     * Obtains the set of all target lines currently open from this mixer.
     *
     * @return target lines currently open from the mixer.
     * If no target lines are currently open from this mixer, an
     * array of length 0 is returned.
     * @throws SecurityException if the matching lines
     *                           are not available due to security restrictions
     */
    Line[] getTargetLines();

    /**
     * Synchronizes two or more lines.  Any subsequent command that starts or stops
     * audio playback or capture for one of these lines will exert the
     * same effect on the other lines in the group, so that they start or stop playing or
     * capturing data simultaneously.
     *
     * @param lines        the lines that should be synchronized
     * @param maintainSync true if the synchronization
     *                     must be precisely maintained (i.e., the synchronization must be sample-accurate)
     *                     at all times during operation of the lines , or false
     *                     if precise synchronization is required only during start and stop operations
     * @throws IllegalArgumentException if the lines cannot be synchronized.
     *                                  This may occur if the lines are of different types or have different
     *                                  formats for which this mixer does not support synchronization, or if
     *                                  all lines specified do not belong to this mixer.
     */
    void synchronize(Line[] lines, boolean maintainSync);

    /**
     * Releases synchronization for the specified lines.  The array must
     * be identical to one for which synchronization has already been
     * established; otherwise an exception may be thrown.  However, null
     * may be specified, in which case all currently synchronized lines that belong
     * to this mixer are unsynchronized.
     *
     * @param lines the synchronized lines for which synchronization should be
     *              released, or null for all this mixer's synchronized lines
     * @throws IllegalArgumentException if the lines cannot be unsynchronized.
     *                                  This may occur if the argument specified does not exactly match a set
     *                                  of lines for which synchronization has already been established.
     */
    void unsynchronize(Line[] lines);

    /**
     * Reports whether this mixer supports synchronization of the specified set of lines.
     *
     * @param lines        the set of lines for which synchronization support is queried
     * @param maintainSync true if the synchronization
     *                     must be precisely maintained (i.e., the synchronization must be sample-accurate)
     *                     at all times during operation of the lines , or false
     *                     if precise synchronization is required only during start and stop operations
     * @return true if the lines can be synchronized, false
     * otherwise
     */
    boolean isSynchronizationSupported(Line[] lines, boolean maintainSync);

    /**
     * The Mixer.Info class represents information about an audio mixer,
     * including the product's name, version, and vendor, along with a textual
     * description.  This information may be retrieved through the
     * {@link Mixer#getMixerInfo() getMixerInfo}
     * method of the Mixer interface.
     *
     * @author Kara Kytle
     * @since 1.3
     */
    class Info {

        private String name;

        private String vendor;

        private String description;

        private String version;

        /**
         * Constructs a mixer's info object, passing it the given
         * textual information.
         *
         * @param name        the name of the mixer
         * @param vendor      the company who manufactures or creates the hardware
         *                    or software mixer
         * @param description descriptive text about the mixer
         * @param version     version information for the mixer
         */
        protected Info(String name, String vendor, String description, String version) {
            this.name = name;
            this.vendor = vendor;
            this.description = description;
            this.version = version;
        }

        /**
         * Indicates whether two info objects are equal, returning true if
         * they are identical.
         *
         * @param obj the reference object with which to compare this info
         *            object
         * @return true if this info object is the same as the
         * obj argument; false otherwise
         */
        public final boolean equals(Object obj) {
            return super.equals(obj);
        }

        /**
         * Finalizes the hashcode method.
         *
         * @return the hashcode for this object
         */
        public final int hashCode() {
            return super.hashCode();
        }

        /**
         * Obtains the name of the mixer.
         *
         * @return a string that names the mixer
         */
        public final String getName() {
            return name;
        }

        /**
         * Obtains the vendor of the mixer.
         *
         * @return a string that names the mixer's vendor
         */
        public final String getVendor() {
            return vendor;
        }

        /**
         * Obtains the description of the mixer.
         *
         * @return a textual description of the mixer
         */
        public final String getDescription() {
            return description;
        }

        /**
         * Obtains the version of the mixer.
         *
         * @return textual version information for the mixer
         */
        public final String getVersion() {
            return version;
        }

        /**
         * Provides a string representation of the mixer info.
         *
         * @return a string describing the info object
         */
        public final String toString() {
            return (name + ", version " + version);
        }
    }
}


public InetAddress getAddress() {
        return address;
    }

package java.net;

/**
 * This class represents a Network Interface address. In short it's an
 * IP address, a subnet mask and a broadcast address when the address is
 * an IPv4 one. An IP address and a network prefix length in the case
 * of IPv6 address.
 *
 * @see java.net.NetworkInterface
 * @since 1.6
 */
public class InterfaceAddress {

    private InetAddress address = null;

    private Inet4Address broadcast = null;

    private short maskLength = 0;

    /*
     * Package private constructor. Can't be built directly, instances are
     * obtained through the NetworkInterface class.
     */
    InterfaceAddress() {
    }

    /**
     * Returns an {@code InetAddress} for this address.
     *
     * @return the {@code InetAddress} for this address.
     */

/**
     * Returns an {@code InetAddress} for the broadcast address
     * for this InterfaceAddress.
     *

     * Only IPv4 networks have broadcast address therefore, in the case
     * of an IPv6 network, {@code null} will be returned.
     *
     * @return the {@code InetAddress} representing the broadcast
     *         address or {@code null} if there is no broadcast address.
     */
    public InetAddress getBroadcast() {
        return broadcast;
    }

    /**
     * Returns the network prefix length for this address. This is also known
     * as the subnet mask in the context of IPv4 addresses.
     * Typical IPv4 values would be 8 (255.0.0.0), 16 (255.255.0.0)
     * or 24 (255.255.255.0).

     * Typical IPv6 values would be 128 (::1/128) or 10 (fe80::203:baff:fe27:1243/10)
     *
     * @return a {@code short} representing the prefix length for the
     *         subnet of that address.
     */
    public short getNetworkPrefixLength() {
        return maskLength;
    }

    /**
     * Compares this object against the specified object.
     * The result is {@code true} if and only if the argument is
     * not {@code null} and it represents the same interface address as
     * this object.
     *

     * Two instances of {@code InterfaceAddress} represent the same
     * address if the InetAddress, the prefix length and the broadcast are
     * the same for both.
     *
     * @param   obj   the object to compare against.
     * @return  {@code true} if the objects are the same;
     *          {@code false} otherwise.
     * @see     java.net.InterfaceAddress#hashCode()
     */
    public boolean equals(Object obj) {
        if (!(obj instanceof InterfaceAddress)) {
            return false;
        }
        InterfaceAddress cmp = (InterfaceAddress) obj;
        if (!(address == null ? cmp.address == null : address.equals(cmp.address)))
            return false;
        if (!(broadcast == null ? cmp.broadcast == null : broadcast.equals(cmp.broadcast)))
            return false;
        if (maskLength != cmp.maskLength)
            return false;
        return true;
    }

    /**
     * Returns a hashcode for this Interface address.
     *
     * @return  a hash code value for this Interface address.
     */
    public int hashCode() {
        return address.hashCode() + ((broadcast != null) ? broadcast.hashCode() : 0) + maskLength;
    }

    /**
     * Converts this Interface address to a {@code String}. The
     * string returned is of the form: InetAddress / prefix length [ broadcast address ].
     *
     * @return  a string representation of this Interface address.
     */
    public String toString() {
        return address + "/" + maskLength + " [" + broadcast + "]";
    }
}


public static void checkEqualOperand(Expression expr) {
        if (expr instanceof ConstantExpression) {
            Object value = ((ConstantExpression) expr).getValue();
            if (value == null) {
                throw new RuntimeException("'" + expr + "' cannot be compared.");
            }
        }
    }

package org.apache.rocketmq.filter.expression;

import java.util.List;

/**
 * A filter performing a comparison of two objects
 * <p>
 * This class was taken from ActiveMQ org.apache.activemq.filter.ComparisonExpression,
 * but:
 * 1. Remove LIKE expression, and related methods;
 * 2. Extract a new method __compare which has int return value;
 * 3. When create between expression, check whether left value is less or equal than right value;
 * 4. For string type value(can not convert to number), only equal or unequal comparison are supported.
 * </p>
 */
public abstract class ComparisonExpression extends BinaryExpression implements BooleanExpression {

    public static final ThreadLocal<Boolean> CONVERT_STRING_EXPRESSIONS = new ThreadLocal<Boolean>();

    boolean convertStringExpressions = false;

    /**
     * @param left
     * @param right
     */
    public ComparisonExpression(Expression left, Expression right) {
        super(left, right);
        convertStringExpressions = CONVERT_STRING_EXPRESSIONS.get() != null;
    }

    public static BooleanExpression createBetween(Expression value, Expression left, Expression right) {
        // check
        if (left instanceof ConstantExpression && right instanceof ConstantExpression) {
            Object lv = ((ConstantExpression) left).getValue();
            Object rv = ((ConstantExpression) right).getValue();
            if (lv == null || rv == null) {
                throw new RuntimeException("Illegal values of between, values can not be null!");
            }
            if (lv instanceof Comparable && rv instanceof Comparable) {
                int ret = __compare((Comparable) rv, (Comparable) lv, true);
                if (ret < 0)
                    throw new RuntimeException(String.format("Illegal values of between, left value(%s) must less than or equal to right value(%s)", lv, rv));
            }
        }
        return LogicExpression.createAND(createGreaterThanEqual(value, left), createLessThanEqual(value, right));
    }

    public static BooleanExpression createNotBetween(Expression value, Expression left, Expression right) {
        return LogicExpression.createOR(createLessThan(value, left), createGreaterThan(value, right));
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static BooleanExpression createInFilter(Expression left, List elements) {
        if (!(left instanceof PropertyExpression)) {
            throw new RuntimeException("Expected a property for In expression, got: " + left);
        }
        return UnaryExpression.createInExpression((PropertyExpression) left, elements, false);
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static BooleanExpression createNotInFilter(Expression left, List elements) {
        if (!(left instanceof PropertyExpression)) {
            throw new RuntimeException("Expected a property for In expression, got: " + left);
        }
        return UnaryExpression.createInExpression((PropertyExpression) left, elements, true);
    }

    public static BooleanExpression createIsNull(Expression left) {
        return doCreateEqual(left, ConstantExpression.NULL);
    }

    public static BooleanExpression createIsNotNull(Expression left) {
        return UnaryExpression.createNOT(doCreateEqual(left, ConstantExpression.NULL));
    }

    public static BooleanExpression createNotEqual(Expression left, Expression right) {
        return UnaryExpression.createNOT(createEqual(left, right));
    }

    public static BooleanExpression createEqual(Expression left, Expression right) {
        checkEqualOperand(left);
        checkEqualOperand(right);
        checkEqualOperandCompatability(left, right);
        return doCreateEqual(left, right);
    }

    @SuppressWarnings({ "rawtypes" })
    private static BooleanExpression doCreateEqual(Expression left, Expression right) {
        return new ComparisonExpression(left, right) {

            public Object evaluate(EvaluationContext context) throws Exception {
                Object lv = left.evaluate(context);
                Object rv = right.evaluate(context);
                // If one of the values is null
                if (lv == null ^ rv == null) {
                    if (lv == null) {
                        return null;
                    }
                    return Boolean.FALSE;
                }
                if (lv == rv || lv.equals(rv)) {
                    return Boolean.TRUE;
                }
                if (lv instanceof Comparable && rv instanceof Comparable) {
                    return compare((Comparable) lv, (Comparable) rv);
                }
                return Boolean.FALSE;
            }

            protected boolean asBoolean(int answer) {
                return answer == 0;
            }

            public String getExpressionSymbol() {
                return "==";
            }
        };
    }

    public static BooleanExpression createGreaterThan(final Expression left, final Expression right) {
        checkLessThanOperand(left);
        checkLessThanOperand(right);
        return new ComparisonExpression(left, right) {

            protected boolean asBoolean(int answer) {
                return answer > 0;
            }

            public String getExpressionSymbol() {
                return ">";
            }
        };
    }

    public static BooleanExpression createGreaterThanEqual(final Expression left, final Expression right) {
        checkLessThanOperand(left);
        checkLessThanOperand(right);
        return new ComparisonExpression(left, right) {

            protected boolean asBoolean(int answer) {
                return answer >= 0;
            }

            public String getExpressionSymbol() {
                return ">=";
            }
        };
    }

    public static BooleanExpression createLessThan(final Expression left, final Expression right) {
        checkLessThanOperand(left);
        checkLessThanOperand(right);
        return new ComparisonExpression(left, right) {

            protected boolean asBoolean(int answer) {
                return answer < 0;
            }

            public String getExpressionSymbol() {
                return "<";
            }
        };
    }

    public static BooleanExpression createLessThanEqual(final Expression left, final Expression right) {
        checkLessThanOperand(left);
        checkLessThanOperand(right);
        return new ComparisonExpression(left, right) {

            protected boolean asBoolean(int answer) {
                return answer <= 0;
            }

            public String getExpressionSymbol() {
                return "<=";
            }
        };
    }

    /**
     * Only Numeric expressions can be used in >, >=, < or <= expressions.s
     */
    public static void checkLessThanOperand(Expression expr) {
        if (expr instanceof ConstantExpression) {
            Object value = ((ConstantExpression) expr).getValue();
            if (value instanceof Number) {
                return;
            }
            // Else it's boolean or a String..
            throw new RuntimeException("Value '" + expr + "' cannot be compared.");
        }
        if (expr instanceof BooleanExpression) {
            throw new RuntimeException("Value '" + expr + "' cannot be compared.");
        }
    }

    /**
     * Validates that the expression can be used in == or <> expression. Cannot
     * not be NULL TRUE or FALSE litterals.
     */

    /**
     * @param left
     * @param right
     */
    private static void checkEqualOperandCompatability(Expression left, Expression right) {
        if (left instanceof ConstantExpression && right instanceof ConstantExpression) {
            if (left instanceof BooleanExpression && !(right instanceof BooleanExpression)) {
                throw new RuntimeException("'" + left + "' cannot be compared with '" + right + "'");
            }
        }
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    public Object evaluate(EvaluationContext context) throws Exception {
        Comparable<Comparable> lv = (Comparable) left.evaluate(context);
        if (lv == null) {
            return null;
        }
        Comparable rv = (Comparable) right.evaluate(context);
        if (rv == null) {
            return null;
        }
        if (getExpressionSymbol().equals(">=") || getExpressionSymbol().equals(">") || getExpressionSymbol().equals("<") || getExpressionSymbol().equals("<=")) {
            Class<? extends Comparable> lc = lv.getClass();
            Class<? extends Comparable> rc = rv.getClass();
            if (lc == rc && lc == String.class) {
                // Compare String is illegal
                // first try to convert to double
                try {
                    Comparable lvC = Double.valueOf((String) (Comparable) lv);
                    Comparable rvC = Double.valueOf((String) rv);
                    return compare(lvC, rvC);
                } catch (Exception e) {
                    throw new RuntimeException("It's illegal to compare string by '>=', '>', '<', '<='. lv=" + lv + ", rv=" + rv, e);
                }
            }
        }
        return compare(lv, rv);
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    protected static int __compare(Comparable lv, Comparable rv, boolean convertStringExpressions) {
        Class<? extends Comparable> lc = lv.getClass();
        Class<? extends Comparable> rc = rv.getClass();
        // If the the objects are not of the same type,
        // try to convert up to allow the comparison.
        if (lc != rc) {
            try {
                if (lc == Boolean.class) {
                    if (convertStringExpressions && rc == String.class) {
                        lv = Boolean.valueOf((String) lv).booleanValue();
                    } else {
                        return -1;
                    }
                } else if (lc == Byte.class) {
                    if (rc == Short.class) {
                        lv = Short.valueOf(((Number) lv).shortValue());
                    } else if (rc == Integer.class) {
                        lv = Integer.valueOf(((Number) lv).intValue());
                    } else if (rc == Long.class) {
                        lv = Long.valueOf(((Number) lv).longValue());
                    } else if (rc == Float.class) {
                        lv = new Float(((Number) lv).floatValue());
                    } else if (rc == Double.class) {
                        lv = new Double(((Number) lv).doubleValue());
                    } else if (convertStringExpressions && rc == String.class) {
                        rv = Byte.valueOf((String) rv);
                    } else {
                        return -1;
                    }
                } else if (lc == Short.class) {
                    if (rc == Integer.class) {
                        lv = Integer.valueOf(((Number) lv).intValue());
                    } else if (rc == Long.class) {
                        lv = Long.valueOf(((Number) lv).longValue());
                    } else if (rc == Float.class) {
                        lv = new Float(((Number) lv).floatValue());
                    } else if (rc == Double.class) {
                        lv = new Double(((Number) lv).doubleValue());
                    } else if (convertStringExpressions && rc == String.class) {
                        rv = Short.valueOf((String) rv);
                    } else {
                        return -1;
                    }
                } else if (lc == Integer.class) {
                    if (rc == Long.class) {
                        lv = Long.valueOf(((Number) lv).longValue());
                    } else if (rc == Float.class) {
                        lv = new Float(((Number) lv).floatValue());
                    } else if (rc == Double.class) {
                        lv = new Double(((Number) lv).doubleValue());
                    } else if (convertStringExpressions && rc == String.class) {
                        rv = Integer.valueOf((String) rv);
                    } else {
                        return -1;
                    }
                } else if (lc == Long.class) {
                    if (rc == Integer.class) {
                        rv = Long.valueOf(((Number) rv).longValue());
                    } else if (rc == Float.class) {
                        lv = new Float(((Number) lv).floatValue());
                    } else if (rc == Double.class) {
                        lv = new Double(((Number) lv).doubleValue());
                    } else if (convertStringExpressions && rc == String.class) {
                        rv = Long.valueOf((String) rv);
                    } else {
                        return -1;
                    }
                } else if (lc == Float.class) {
                    if (rc == Integer.class) {
                        rv = new Float(((Number) rv).floatValue());
                    } else if (rc == Long.class) {
                        rv = new Float(((Number) rv).floatValue());
                    } else if (rc == Double.class) {
                        lv = new Double(((Number) lv).doubleValue());
                    } else if (convertStringExpressions && rc == String.class) {
                        rv = Float.valueOf((String) rv);
                    } else {
                        return -1;
                    }
                } else if (lc == Double.class) {
                    if (rc == Integer.class) {
                        rv = new Double(((Number) rv).doubleValue());
                    } else if (rc == Long.class) {
                        rv = new Double(((Number) rv).doubleValue());
                    } else if (rc == Float.class) {
                        rv = new Float(((Number) rv).doubleValue());
                    } else if (convertStringExpressions && rc == String.class) {
                        rv = Double.valueOf((String) rv);
                    } else {
                        return -1;
                    }
                } else if (convertStringExpressions && lc == String.class) {
                    if (rc == Boolean.class) {
                        lv = Boolean.valueOf((String) lv);
                    } else if (rc == Byte.class) {
                        lv = Byte.valueOf((String) lv);
                    } else if (rc == Short.class) {
                        lv = Short.valueOf((String) lv);
                    } else if (rc == Integer.class) {
                        lv = Integer.valueOf((String) lv);
                    } else if (rc == Long.class) {
                        lv = Long.valueOf((String) lv);
                    } else if (rc == Float.class) {
                        lv = Float.valueOf((String) lv);
                    } else if (rc == Double.class) {
                        lv = Double.valueOf((String) lv);
                    } else {
                        return -1;
                    }
                } else {
                    return -1;
                }
            } catch (NumberFormatException e) {
                throw new RuntimeException(e);
            }
        }
        return lv.compareTo(rv);
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    protected Boolean compare(Comparable lv, Comparable rv) {
        return asBoolean(__compare(lv, rv, convertStringExpressions)) ? Boolean.TRUE : Boolean.FALSE;
    }

    protected abstract boolean asBoolean(int answer);

    public boolean matches(EvaluationContext context) throws Exception {
        Object object = evaluate(context);
        return object != null && object == Boolean.TRUE;
    }
}