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);
                }

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.
     */
    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.");
            }
        }
    }

    /**
     * @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

            }
        }
        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;
    }
}


try {
            int size = batchHistoryDao.delete(args);
            if (1 == size) {
                return RetMsgFactory.getRetMsg(SysStatus.SUCCESS_CODE, "success", null);
            }
            return RetMsgFactory.getRetMsg(SysStatus.ERROR_CODE, "删除批次历史信息失败，请联系管理员", null);
        } catch (Exception e) {
            return RetMsgFactory.getRetMsg(SysStatus.EXCEPTION_ERROR_CODE, e.getMessage(), null);
        }

package com.asofdate.batch.service.impl;

import com.asofdate.batch.dao.BatchHistoryDao;
import com.asofdate.batch.dto.BatchHistoryDto;
import com.asofdate.batch.entity.BatchHistoryEntity;
import com.asofdate.batch.service.BatchHistoryService;
import com.asofdate.utils.RetMsg;
import com.asofdate.utils.SysStatus;
import com.asofdate.utils.factory.RetMsgFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by hzwy23 on 2017/6/16.
 */
@Service
public class BatchHistoryServiceImpl implements BatchHistoryService {

    @Autowired
    private BatchHistoryDao batchHistoryDao;

    @Override
    public List<BatchHistoryEntity> findAll(String domainId) {
        return batchHistoryDao.findAll(domainId);
    }

    @Override
    public RetMsg delete(List<BatchHistoryDto> list) {
        List<BatchHistoryEntity> args = new ArrayList<>();
        for (BatchHistoryDto m : list) {
            BatchHistoryEntity entity = new BatchHistoryEntity();
            entity.setSid(m.getSid());
            args.add(entity);
        }


switch(type) {
            case REAL_TIME_THREAD:
                ret = IOExecutorInstanceHolder.getInstance();
                break;
            case SERIAL_THREAD:
                ret = IOExecutorInstanceHolder.getInstance();
                break;
            default:
                ret = IOExecutorInstanceHolder.getInstance();
                break;
        }

package com.geek.thread.executor;

import android.util.Log;
import com.geek.thread.ThreadPoolConst;
import com.geek.thread.ThreadPoolParams;
import com.geek.thread.ThreadType;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Created by aotuman on 2017/11/23.
 */
public class ExecutorFactory {

    private static AtomicBoolean mIsRunning = new AtomicBoolean(true);

    public static BaseExecutor getExecutor(ThreadType type) {
        if (!mIsRunning.get()) {
            return null;
        }
        BaseExecutor ret = null;

        return ret;
    }

    private static class IOExecutorInstanceHolder {

        private static final IOExecutor mExecutor = new IOExecutor(getIOExecutorParams());

        public static IOExecutor getInstance() {
            return mExecutor;
        }

        private static ThreadPoolParams getIOExecutorParams() {
            ThreadPoolParams params = new ThreadPoolParams();
            params.corePoolSize = ThreadPoolConst.IO_CORE_POOL_SIZE;
            params.keepAliveTimeSec = ThreadPoolConst.IO_KEEP_ALIVE_TIME;
            params.maxPoolSize = ThreadPoolConst.IO_MAXIMUM_POOL_SIZE;
            params.poolQueueSize = ThreadPoolConst.IO_POOL_QUEUE_SIZE;
            return params;
        }
    }

    public static void shutdownAll() {
        try {
            mIsRunning.set(false);
            IOExecutorInstanceHolder.getInstance().shutdown();
        } catch (Throwable e) {
            Log.e("ExecutorFactory", e.getMessage());
        }
    }
}


try {
            mIsRunning.set(false);
            IOExecutorInstanceHolder.getInstance().shutdown();
        } catch (Throwable e) {
            Log.e("ExecutorFactory", e.getMessage());
        }

package com.geek.thread.executor;

import android.util.Log;
import com.geek.thread.ThreadPoolConst;
import com.geek.thread.ThreadPoolParams;
import com.geek.thread.ThreadType;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Created by aotuman on 2017/11/23.
 */
public class ExecutorFactory {

    private static AtomicBoolean mIsRunning = new AtomicBoolean(true);

    public static BaseExecutor getExecutor(ThreadType type) {
        if (!mIsRunning.get()) {
            return null;
        }
        BaseExecutor ret = null;
        switch(type) {
            case REAL_TIME_THREAD:
                ret = IOExecutorInstanceHolder.getInstance();
                break;
            case SERIAL_THREAD:
                ret = IOExecutorInstanceHolder.getInstance();
                break;
            default:
                ret = IOExecutorInstanceHolder.getInstance();
                break;
        }
        return ret;
    }

    private static class IOExecutorInstanceHolder {

        private static final IOExecutor mExecutor = new IOExecutor(getIOExecutorParams());

        public static IOExecutor getInstance() {
            return mExecutor;
        }

        private static ThreadPoolParams getIOExecutorParams() {
            ThreadPoolParams params = new ThreadPoolParams();
            params.corePoolSize = ThreadPoolConst.IO_CORE_POOL_SIZE;
            params.keepAliveTimeSec = ThreadPoolConst.IO_KEEP_ALIVE_TIME;
            params.maxPoolSize = ThreadPoolConst.IO_MAXIMUM_POOL_SIZE;
            params.poolQueueSize = ThreadPoolConst.IO_POOL_QUEUE_SIZE;
            return params;
        }
    }

    public static void shutdownAll() {


public static void main(String[] args) {
        URLClient theTests = new URLClient();
        Status s = theTests.run(args, new PrintWriter(System.out), new PrintWriter(System.err));
        s.exit();
    }

package com.sun.ts.tests.servlet.api.jakarta_servlet.scinitializer.addlistener;

import java.io.PrintWriter;
import com.sun.javatest.Status;
import com.sun.ts.tests.servlet.common.client.AbstractUrlClient;

public class URLClient extends AbstractUrlClient {

    /**
     * Entry point for different-VM execution. It should delegate to method
     * run(String[], PrintWriter, PrintWriter), and this method should not contain
     * any test configuration.
     */

    /**
     * Entry point for same-VM execution. In different-VM execution, the main
     * method delegates to this method.
     */
    public Status run(String[] args, PrintWriter out, PrintWriter err) {
        setContextRoot("/servlet_sci_addlistener_web");
        setServletName("TestServlet");
        return super.run(args, out, err);
    }

    /* Run test */
    /*
   * @testName: addListenerTest
   *
   * @assertion_ids: Servlet:JAVADOC:673.12;
   *
   * @test_Strategy: Create a ServletContextInitializer, in which, Add a
   * ServletContextListener instance using ServletContext.addListener; in the
   * ServletContextListener call ServletContext.addListener(Class) Verify that
   * UnsupportedOperationException is thrown.
   */
    public void addListenerTest() throws Fault {
        TEST_PROPS.setProperty(APITEST, "addListenerTest");
        invoke();
    }
}


package org.openstack4j.api.storage;

import java.util.Map;
import org.openstack4j.common.RestService;
import org.openstack4j.model.storage.object.SwiftAccount;

/**
 * The Object Storage Account based services
 *
 * @author Jeremy Unruh
 */
public interface ObjectStorageAccountService extends RestService {

    /**
     * Gets the {@link SwiftAccount}.
     *
     * @return The {@link SwiftAccount} object.
     */
    SwiftAccount get();

    /**
     * Creates or updates the {@link SwiftAccount} metadata.
     *
     * @param metadata the metadata to create or update.
     * @return true if the metadata was created or updated successfully,
     *         false if not
     */
    boolean updateMetadata(Map<String, String> metadata);

    /**
     * Deletes the {@link SwiftAccount} metadata.
     *
     * @param metadata the metadata to delete.
     * @return true if the metadata was deleted successfully,
     *         false if not
     */
    boolean deleteMetadata(Map<String, String> metadata);

    /**
     * Replaces the temporary URL key for the {@link SwiftAccount}
     *
     * @param temporaryUrlKey the temporary URL key
     * @return true if the update was successful
     */


public <T extends Consumer<? super E>> T distinct(T target, Equalator<? super E> equalator);

package one.microstream.collections.types;

import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Predicate;
import one.microstream.X;
import one.microstream.collections.interfaces.CapacityCarrying;
import one.microstream.collections.interfaces.ExtendedCollection;
import one.microstream.collections.old.OldCollection;
import one.microstream.equality.Equalator;
import one.microstream.functional.ToArrayAggregator;
import one.microstream.typing.Copyable;

/**
 * @param <E> type of contained elements
 */
public interface XGettingCollection<E> extends XIterable<E>, XJoinable<E>, ExtendedCollection<E>, Iterable<E>, CapacityCarrying, Copyable {

    /**
     * Gets one element from the collection. If the collection is not ordered {@link XGettingSequence}, then it is
     * undefined which element is returned. If the collection is ordered, the element at index 0 is returned.
     *
     * @return the first / any element.
     */
    public E get();

    @Override
    public Iterator<E> iterator();

    /**
     * Returns an array containing all of the elements in this collection.
     *
     *
The returned array will be "safe" in that no references to it are
     * maintained by this list.  (In other words, this method must allocate
     * a new array).  The caller is thus free to modify the returned array.
     *
     *
This method acts as bridge between MicroStream-based collections
     * and Java-native-based APIs.
     *
     * @return an array containing all of the elements in this collection
     */
    public default Object[] toArray() {
        return this.iterate(new ToArrayAggregator<>(new Object[X.checkArrayRange(this.size())])).yield();
    }

    /**
     * Returns a typed array containing all of the elements in this collection.
     *
     *
The returned array will be "safe" in that no references to it are
     * maintained by this list.  (In other words, this method must allocate
     * a new array).  The caller is thus free to modify the returned array.
     *
     *
This method acts as bridge between MicroStream-based collections
     * and Java-native-based APIs.
     *
     * @return a typed array containing all of the elements in this collection
     */
    public default E[] toArray(final Class<E> type) {
        return this.iterate(new ToArrayAggregator<>(X.Array(type, X.checkArrayRange(this.size())))).yield();
    }

    // stolen from Streams API. However. A) ambiguous for compiler and B) inferior to just keeping and passing a type.
    public OldCollection<E> old();

    @Override
    public boolean hasVolatileElements();

    @Override
    public long size();

    public default int intSize() {
        return X.checkArrayRange(this.size());
    }

    public Equalator<? super E> equality();

    /**
     * @return {@code true} if the passed collection is of the same type as this collection and
     * {@code this.equalsContent(list, equalator)} yields {@code true}
     * @param equalator is used to check the equality of the collections
     * @param samples is the collection which is checked for equality
     */
    public boolean equals(XGettingCollection<? extends E> samples, Equalator<? super E> equalator);

    /**
     * Returns {@code true} if all elements of this list and the passed list are sequentially equal as defined
     * by the passed equalator.
     *

     * Note that for colletion types that don't have a defined order of elements, this method is hardly usable
     * (as is {@link #equals(Object)} for them as defined in {@link Collection}). The core problem of comparing
     * collections that have no defined order is that they aren't really reliably comparable to any other collection.
     *
     * @param equalator the equalator to use to determine the equality of each element
     * @param samples is the collection which is checked for equality
     * @return {@code true} if this list is equal to the passed list, {@code false} otherwise
     */
    public boolean equalsContent(XGettingCollection<? extends E> samples, Equalator<? super E> equalator);

    /**
     * Provides an instance of an immutable collection type with equal behavior and data as this instance.
     *

     * If this instance already is of an immutable collection type, it returns itself.
     *
     * @return an immutable copy of this collection instance.
     */
    public XImmutableCollection<E> immure();

    /**
     * Creates a view of this collection and returns it. It is a read-only collection,
     * which wraps around this collection and only allows read methods.
     *

     * A view is different from immutable collection ({@link XGettingCollection#immure()})
     * in the way, that changes in this collection are still affecting the view.
     * The immutable collection on the other hand has no reference to this collection
     * and changes therefore do not affect the immutable collection.
     * @return new read-only collection to view this collection
     */
    public XGettingCollection<E> view();

    /**
     * Creates a true copy of this collection which references the same elements as this collection does
     * at the time the method is called. The elements themselves are NOT copied (no deep copying).

     * The type of the returned set is the same as of this list if possible.
     *
     * @return a copy of this list
     */
    @Override
    public XGettingCollection<E> copy();

    public boolean nullContained();

    /**
     * Special version of contains() that guarantees to use identity comparison (" == ") when searching for the
     * given element regardless of the collection's internal logic.

     * This method has the same behavior as {@link #containsSearched(Predicate)} with a {@link Predicate} implementation
     * that checks for object identity. The only difference is a performance and usability advantage
     * @param element the element to be searched in the collection by identity.
     * @return whether this collection contains exactly the given element.
     */
    public boolean containsId(E element);

    /**
     * Checks if the given element is contained in the collection.

     * In contrast to the {@link XGettingCollection#containsId(Object)} method, this method
     * uses the internal {@link Equalator} defined by the collection itself.
     * @param element to be searched in the collection
     * @return Whether this collection contains the given element as specified by the {@link Equalator}.
     */
    public boolean contains(E element);

    public boolean containsSearched(Predicate<? super E> predicate);

    /**
     * @param elements to be searched in the collection.
     * @return Whether this collection contains all given elements as specified by the {@link Equalator}.
     */
    public default boolean containsAll(final XGettingCollection<? extends E> elements) {
        return elements.applies(this::contains);
    }

    /**
     * Tests each element of the collection on the given predicate.

     *
     * @param predicate that's tested on each element.
     * @return If all elements test successfully, true is returned.
     * Otherwise (if at least one test has failed), false is returned.
     */
    public boolean applies(Predicate<? super E> predicate);

    /**
     * Count how many times this element matches another element in the collection
     * using the {@link Equalator}.
     * @param element to count
     * @return Amount of matches
     */
    public long count(E element);

    /**
     * Count how many matches are found using the given predicate on each element of the collection.
     * @param predicate defines which elements are counted and which are not
     * @return Amount of matches
     */
    public long countBy(Predicate<? super E> predicate);

    /**
     * Returns the first contained element matching the passed predicate.
     * @param predicate defines which element is searched
     * @return Matching element
     */
    public E search(Predicate<? super E> predicate);

    /**
     * Returns the first contained element matching the passed sample as defined by the collection's equality logic
     * or null, if no fitting element is contained.
     * (For collections using referential equality, this method is basically just a variation of
     * {@link #contains(Object)} with a different return type. For collections with data-dependant equality,
     * the returned element might be the same as the passed one or a data-wise equal one, depending on the content
     * of the collection)
     *
     * @param sample to seek in the collection
     * @return the first contained element matching the passed sample
     */
    public E seek(E sample);

    public E max(Comparator<? super E> comparator);

    public E min(Comparator<? super E> comparator);

    /**
     * Calls {@link Consumer#accept(Object)} on the target {@link Consumer} for all the unique/distinct
     * elements of this collection. This means the elements are not equal to each other.

     * Uniqueness is defined by the collections internal {@link Equalator}.
     *

     * Since all MicroStream Collections implement the {@link Consumer} interface,
     * new collections can be used as target.
     *

     * Example:

     *
     * BulkList<Integer> collection1 = BulkList.New(1,2,2,3);

     * BulkList<Integer> distinctCollection = collection1.distinct(BulkList.New());
     *

     * Results in distinctCollection containing 1, 2 and 3.
     *
     * @param target on which the {@link Consumer#accept(Object)} is called for every distinct element of this collection.
     * @return Given target
     */
    public <T extends Consumer<? super E>> T distinct(T target);

    /**
     * Calls {@link Consumer#accept(Object)} on the target {@link Consumer} for all the unique/distinct
     * elements of this collection. This means the elements are not equal to each other.

     * Uniqueness is defined by the given {@link Equalator}.
     *

     * Since all MicroStream Collections implement the {@link Consumer} interface,
     * new collections can be used as target.
     *

     * Example:

     *
     * BulkList<Integer> collection1 = BulkList.New(1,2,2,3);

     * BulkList<Integer> distinctCollection = collection1.distinct(BulkList.New(), Equalator.identity());
     *

     * Results in distinctCollection containing 1, 2 and 3.
     *
     * @param target on which the {@link Consumer#accept(Object)} is called for every distinct element of this collection.
     * @param equalator defines what distinct means (which elements are equal to one another)
     * @return Given target
     */

/**
     * Calls {@link Consumer#accept(Object)} on the target {@link Consumer} for all the elements of this collection.
     *

     * Since all MicroStream Collections implement the {@link Consumer} interface,
     * new collections can be used as target.
     *

     * Example:

     *
     * BulkList<Integer> collection1 = BulkList.New(1,2,3);

     * BulkList<Integer> copiedCollection = collection1.copyTo(BulkList.New());
     *

     * Results in copiedCollection containing 1, 2 and 3.
     *
     * @param target on which the {@link Consumer#accept(Object)} is called for all elements of this collection.
     * @return Given target
     */
    public <T extends Consumer<? super E>> T copyTo(T target);

    /**
     * Calls {@link Consumer#accept(Object)} on the target {@link Consumer} for all the elements of this collection
     * which test {@code true} on the given predicate.
     *

     * Since all MicroStream Collections implement the {@link Consumer} interface,
     * new collections can be used as target.
     *

     * Example:

     *
     * BulkList<Integer> collection1 = BulkList.New(1,2,3);

     * BulkList<Integer> filteredCollection = collection1.filterTo(BulkList.New(), e-> e % 2 == 0);
     *

     * Results in filteredCollection containing 2.
     *
     * @param target on which the {@link Consumer#accept(Object)} is called for elements that test {@code true}.
     * @param predicate on which to test all elements.
     * @return Given target
     */
    public <T extends Consumer<? super E>> T filterTo(T target, Predicate<? super E> predicate);

    /**
     * Calls {@link Consumer#accept(Object)} on the target {@link Consumer} for all the elements of this collection.
     * And calls it for all elements of the other collection, that are not already in this collection
     * (defined by the given {@link Equalator})

     * Therefore it effectively creates a mathematical union between the two collections.
     *

     * Since all MicroStream Collections implement the {@link Consumer} interface,
     * new collections can be used as target.
     *

     * Example:

     *
     * BulkList<Integer> collection1 = BulkList.New(1,2,3);

     * BulkList<Integer> collection2 = BulkList.New(2,3,4);

     * BulkList<Integer> union = collection1.union(collection2, Equalator.identity(), BulkList.New());
     *

     * Results in union containing 1, 2, 3 and 4.
     * @param other collection to build a union with.
     * @param equalator which is used for the equal-tests.
     * @param target on which the {@link Consumer#accept(Object)} is called for all unified elements.
     * @return Given target
     */
    public <T extends Consumer<? super E>> T union(XGettingCollection<? extends E> other, Equalator<? super E> equalator, T target);

    /**
     * Tests equality between each element of the two lists and calls {@link Consumer#accept(Object)} on the target {@link Consumer} for the
     * equal elements.

     * Therefore it effectively creates a mathematical intersection between the two collections.
     *

     * Since all MicroStream Collections implement the {@link Consumer} interface,
     * new collections can be used as target.
     *

     * Example:

     *
     * BulkList<Integer> collection1 = BulkList.New(1,2,3);

     * BulkList<Integer> collection2 = BulkList.New(2,3,4);

     * BulkList<Integer> intersection = collection1.intersect(collection2, Equalator.identity(), BulkList.New());
     *

     * Results in intersection containing 2 and 3.
     * @param other collection to intersect with.
     * @param equalator which is used for the equal-tests.
     * @param target on which the {@link Consumer#accept(Object)} is called for equal elements.
     * @return Given target
     */
    public <T extends Consumer<? super E>> T intersect(XGettingCollection<? extends E> other, Equalator<? super E> equalator, T target);

    /**
     * Calls {@link Consumer#accept(Object)} on the target {@link Consumer} for each
     * element of this collection that is not contained in the other collection (through the given equalator).
     *

     * Since all MicroStream Collections implement the {@link Consumer} interface,
     * new collections can be used as target.
     *

     * Example:

     *
     * BulkList<Integer> collection1 = BulkList.New(1,2,3);

     * BulkList<Integer> collection2 = BulkList.New(2,3,4);

     * BulkList<Integer> exceptCollection = collection1.except(collection2, Equalator.identity(), BulkList.New());
     *

     * Results in exceptCollection containing 1.
     * @param <T> type of the target
     * @param other collection whose elements are excluded from the target.
     * @param equalator which is used for the equal-tests.
     * @param target on which the {@link Consumer#accept(Object)} is called for elements not contained in the other collection.
     * @return Given target
     */
    public <T extends Consumer<? super E>> T except(XGettingCollection<? extends E> other, Equalator<? super E> equalator, T target);

    @Override
    public default  A join(final BiConsumer<? super E, ? super A> joiner, final A aggregate) {
        this.iterate(e -> joiner.accept(e, aggregate));
        return aggregate;
    }

    // (10.06.2014 TM)FIXME: remove old equality from interface / move to "Old" interfaces
    /**
     * Performs an equality comparison according to the specification in {@link Collection}.
     *

     * Note that it is this interface's author opinion that the whole concept of equals() in standard Java, especially
     * in the collection implementations, is flawed.

     * The reason is because all different kinds of comparison types that actually depend on the situation
     * have to be mixed up in a harcoded fashion in one method, from identity comparison over
     * data indentity comparison to content comparison.

     * In order to get the right behavior in every situation, one has to distinct between different types of equality

     *

     * This means several things:

     * 1.) You can't just say for example an ArrayList is the "same" as a LinkedList just because they contain the
     * same content.

     * There are different implementations for a good reason, so you have to distinct them when comparing.
     * There are simple code examples which create massive misbehavior that will catastrophically ruin the runtime
     * behavior of a programm due to this error in Java / JDK / Sun / whatever.

     * 2.) You can't always determine equality of two collections by determining equality of each element as
     * {@link Collection} defines it.
     *

     * As a conclusion: don't use this method!

     * Be clear what type of comparison you really need, then use one of the following methods
     * and proper comparators:

     * {@link #equals(XGettingCollection, Equalator)}

     * {@link #equalsContent(XGettingCollection, Equalator)}

     *

     * {@inheritDoc}
     *
     * @param o
     */
    @Override
    @Deprecated
    public boolean equals(Object o);

    @Override
    @Deprecated
    public int hashCode();

    public interface Creator<E> extends XFactory<E> {

        @Override
        public XGettingCollection<E> newInstance();
    }
}


protected abstract S decorate(S instance, Map<String, ?> attributes);

package org.ops4j.peaberry.util;

import java.util.Map;
import org.ops4j.peaberry.Import;
import org.ops4j.peaberry.builders.ImportDecorator;

/**
 * Skeletal implementation to simplify development of {@link ImportDecorator}s.
 * <p>
 * Developers only have to extend this class and provide an implementation of
 * the {@link #decorate(Object, Map)} method, which takes the original service
 * instance and associated attribute map, and returns a decorated instance.
 *
 * @author example@nnthink.com (Stuart McCulloch)
 */
public abstract class AbstractDecorator<S> implements ImportDecorator<S> {

    public final <T extends S> Import<T> decorate(final Import<T> service) {
        return new DelegatingImport<T>(service) {

            @Override
            @SuppressWarnings("unchecked")
            public T get() {
                return (T) decorate(service.get(), service.attributes());
            }
        };
    }

    /**
     * Decorate the current service instance.
     *
     * @param instance service instance
     * @param attributes service attributes
     * @return decorated service instance
     */


@Override
    public boolean isInitialized() {
        return true;
    }

package org.apache.metron.profiler.client.stellar;

import static org.apache.metron.profiler.client.stellar.ProfilerClientConfig.PROFILER_COLUMN_FAMILY;
import static org.apache.metron.profiler.client.stellar.ProfilerClientConfig.PROFILER_HBASE_TABLE;
import static org.apache.metron.profiler.client.stellar.ProfilerClientConfig.PROFILER_HBASE_TABLE_PROVIDER;
import static org.apache.metron.profiler.client.stellar.ProfilerClientConfig.PROFILER_PERIOD;
import static org.apache.metron.profiler.client.stellar.ProfilerClientConfig.PROFILER_PERIOD_UNITS;
import static org.apache.metron.profiler.client.stellar.ProfilerClientConfig.PROFILER_SALT_DIVISOR;
import static org.apache.metron.profiler.client.stellar.Util.getArg;
import static org.apache.metron.profiler.client.stellar.Util.getEffectiveConfig;
import static org.apache.metron.profiler.client.stellar.Util.getPeriodDurationInMillis;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.metron.hbase.HTableProvider;
import org.apache.metron.hbase.TableProvider;
import org.apache.metron.profiler.ProfileMeasurement;
import org.apache.metron.profiler.ProfilePeriod;
import org.apache.metron.profiler.client.HBaseProfilerClient;
import org.apache.metron.profiler.client.ProfilerClient;
import org.apache.metron.profiler.hbase.ColumnBuilder;
import org.apache.metron.profiler.hbase.RowKeyBuilder;
import org.apache.metron.profiler.hbase.SaltyRowKeyBuilder;
import org.apache.metron.profiler.hbase.ValueOnlyColumnBuilder;
import org.apache.metron.stellar.dsl.Context;
import org.apache.metron.stellar.dsl.ParseException;
import org.apache.metron.stellar.dsl.Stellar;
import org.apache.metron.stellar.dsl.StellarFunction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A Stellar function that can retrieve data contained within a Profile.
 *
 *  PROFILE_GET
 *
 * Retrieve all values for 'entity1' from 'profile1' over the past 4 hours.
 *
 *   PROFILE_GET('profile1', 'entity1', 4, 'HOURS')
 *
 * Retrieve all values for 'entity1' from 'profile1' over the past 2 days.
 *
 *   PROFILE_GET('profile1', 'entity1', 2, 'DAYS')
 *
 * Retrieve all values for 'entity1' from 'profile1' that occurred on 'weekdays' over the past month.
 *
 *   PROFILE_GET('profile1', 'entity1', 1, 'MONTHS', ['weekdays'])
 *
 * Retrieve all values for 'entity1' from 'profile1' over the past 2 days, with no 'groupBy',
 * and overriding the usual global client configuration parameters for window duration.
 *
 *   PROFILE_GET('profile1', 'entity1', 2, 'DAYS', [], {'profiler.client.period.duration' : '2', 'profiler.client.period.duration.units' : 'MINUTES'})
 *
 * Retrieve all values for 'entity1' from 'profile1' that occurred on 'weekdays' over the past month,
 * overriding the usual global client configuration parameters for window duration.
 *
 *   PROFILE_GET('profile1', 'entity1', 1, 'MONTHS', ['weekdays'], {'profiler.client.period.duration' : '2', 'profiler.client.period.duration.units' : 'MINUTES'})
 */
@Stellar(namespace = "PROFILE", name = "GET", description = "Retrieves a series of values from a stored profile.", params = { "profile - The name of the profile.", "entity - The name of the entity.", "periods - The list of profile periods to fetch. Use PROFILE_WINDOW or PROFILE_FIXED.", "groups - Optional - The groups to retrieve. Must correspond to the 'groupBy' " + "list used during profile creation. Defaults to an empty list, meaning no groups.", "config_overrides - Optional - Map (in curly braces) of name:value pairs, each overriding the global config parameter " + "of the same name. Default is the empty Map, meaning no overrides." }, returns = "The selected profile measurements.")
public class GetProfile implements StellarFunction {

    /**
     * Cached client that can retrieve profile values.
     */
    private ProfilerClient client;

    /**
     * Cached value of config map actually used to construct the previously cached client.
     */
    private Map<String, Object> cachedConfigMap = new HashMap<String, Object>(6);

    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

    /**
     * Initialization.  No longer need to do anything in initialization,
     * as all setup is done lazily and cached.
     */
    @Override
    public void initialize(Context context) {
    }

    /**
     * Is the function initialized?
     */

    /**
     * Apply the function.
     * @param args The function arguments.
     * @param context
     */
    @Override
    public Object apply(List<Object> args, Context context) throws ParseException {
        String profile = getArg(0, String.class, args);
        String entity = getArg(1, String.class, args);
        Optional<List<ProfilePeriod>> periods = Optional.ofNullable(getArg(2, List.class, args));
        // Optional arguments
        @SuppressWarnings("unchecked")
        List<Object> groups = null;
        Map configOverridesMap = null;
        if (args.size() < 4) {
            // no optional args, so default 'groups' and configOverridesMap remains null.
            groups = new ArrayList<>(0);
        } else if (args.get(3) instanceof List) {
            // correct extensible usage
            groups = getArg(3, List.class, args);
            if (args.size() >= 5) {
                configOverridesMap = getArg(4, Map.class, args);
                if (configOverridesMap.isEmpty())
                    configOverridesMap = null;
            }
        } else {
            // Deprecated "varargs" style usage for groups_list
            // configOverridesMap cannot be specified so it remains null.
            groups = getGroupsArg(3, args);
        }
        Map<String, Object> effectiveConfig = getEffectiveConfig(context, configOverridesMap);
        Object defaultValue = null;
        // lazily create new profiler client if needed
        if (client == null || !cachedConfigMap.equals(effectiveConfig)) {
            RowKeyBuilder rowKeyBuilder = getRowKeyBuilder(effectiveConfig);
            ColumnBuilder columnBuilder = getColumnBuilder(effectiveConfig);
            long periodDuration = getPeriodDurationInMillis(effectiveConfig);
            String tableName = PROFILER_HBASE_TABLE.get(effectiveConfig, String.class);
            Configuration hbaseConfig = HBaseConfiguration.create();
            client = new HBaseProfilerClient(getTableProvider(effectiveConfig), rowKeyBuilder, columnBuilder, periodDuration, tableName, hbaseConfig);
            cachedConfigMap = effectiveConfig;
        }
        if (cachedConfigMap != null) {
            defaultValue = ProfilerClientConfig.PROFILER_DEFAULT_VALUE.get(cachedConfigMap);
        }
        List<ProfileMeasurement> measurements = client.fetch(Object.class, profile, entity, groups, periods.orElse(new ArrayList<>(0)), Optional.ofNullable(defaultValue));
        // return only the value of each profile measurement
        List<Object> values = new ArrayList<>();
        for (ProfileMeasurement m : measurements) {
            values.add(m.getProfileValue());
        }
        return values;
    }

    /**
     * Get the groups defined by the user.
     *
     * The user can specify 0 or more groups.  All arguments from the specified position
     * on are assumed to be groups.  If there is no argument in the specified position,
     * then it is assumed the user did not specify any groups.
     *
     * @param startIndex The starting index of groups within the function argument list.
     * @param args The function arguments.
     * @return The groups.
     */
    private List<Object> getGroupsArg(int startIndex, List<Object> args) {
        List<Object> groups = new ArrayList<>();
        for (int i = startIndex; i < args.size(); i++) {
            String group = getArg(i, String.class, args);
            groups.add(group);
        }
        return groups;
    }

    /**
     * Creates the ColumnBuilder to use in accessing the profile data.
     * @param global The global configuration.
     */
    private ColumnBuilder getColumnBuilder(Map<String, Object> global) {
        ColumnBuilder columnBuilder;
        String columnFamily = PROFILER_COLUMN_FAMILY.get(global, String.class);
        columnBuilder = new ValueOnlyColumnBuilder(columnFamily);
        return columnBuilder;
    }

    /**
     * Creates the ColumnBuilder to use in accessing the profile data.
     * @param global The global configuration.
     */
    private RowKeyBuilder getRowKeyBuilder(Map<String, Object> global) {
        // how long is the profile period?
        long duration = PROFILER_PERIOD.get(global, Long.class);
        LOG.debug("profiler client: {}={}", PROFILER_PERIOD, duration);
        // which units are used to define the profile period?
        String configuredUnits = PROFILER_PERIOD_UNITS.get(global, String.class);
        TimeUnit units = TimeUnit.valueOf(configuredUnits);
        LOG.debug("profiler client: {}={}", PROFILER_PERIOD_UNITS, units);
        // what is the salt divisor?
        Integer saltDivisor = PROFILER_SALT_DIVISOR.get(global, Integer.class);
        LOG.debug("profiler client: {}={}", PROFILER_SALT_DIVISOR, saltDivisor);
        return new SaltyRowKeyBuilder(saltDivisor, duration, units);
    }

    /**
     * Create the TableProvider to use when accessing HBase.
     * @param global The global configuration.
     */
    private TableProvider getTableProvider(Map<String, Object> global) {
        String clazzName = PROFILER_HBASE_TABLE_PROVIDER.get(global, String.class);
        TableProvider provider;
        try {
            @SuppressWarnings("unchecked")
            Class<? extends TableProvider> clazz = (Class<? extends TableProvider>) Class.forName(clazzName);
            provider = clazz.getConstructor().newInstance();
        } catch (Exception e) {
            provider = new HTableProvider();
        }
        return provider;
    }
}


for (int i = startIndex; i < args.size(); i++) {
            String group = getArg(i, String.class, args);
            groups.add(group);
        }

package org.apache.metron.profiler.client.stellar;

import static org.apache.metron.profiler.client.stellar.ProfilerClientConfig.PROFILER_COLUMN_FAMILY;
import static org.apache.metron.profiler.client.stellar.ProfilerClientConfig.PROFILER_HBASE_TABLE;
import static org.apache.metron.profiler.client.stellar.ProfilerClientConfig.PROFILER_HBASE_TABLE_PROVIDER;
import static org.apache.metron.profiler.client.stellar.ProfilerClientConfig.PROFILER_PERIOD;
import static org.apache.metron.profiler.client.stellar.ProfilerClientConfig.PROFILER_PERIOD_UNITS;
import static org.apache.metron.profiler.client.stellar.ProfilerClientConfig.PROFILER_SALT_DIVISOR;
import static org.apache.metron.profiler.client.stellar.Util.getArg;
import static org.apache.metron.profiler.client.stellar.Util.getEffectiveConfig;
import static org.apache.metron.profiler.client.stellar.Util.getPeriodDurationInMillis;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.metron.hbase.HTableProvider;
import org.apache.metron.hbase.TableProvider;
import org.apache.metron.profiler.ProfileMeasurement;
import org.apache.metron.profiler.ProfilePeriod;
import org.apache.metron.profiler.client.HBaseProfilerClient;
import org.apache.metron.profiler.client.ProfilerClient;
import org.apache.metron.profiler.hbase.ColumnBuilder;
import org.apache.metron.profiler.hbase.RowKeyBuilder;
import org.apache.metron.profiler.hbase.SaltyRowKeyBuilder;
import org.apache.metron.profiler.hbase.ValueOnlyColumnBuilder;
import org.apache.metron.stellar.dsl.Context;
import org.apache.metron.stellar.dsl.ParseException;
import org.apache.metron.stellar.dsl.Stellar;
import org.apache.metron.stellar.dsl.StellarFunction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A Stellar function that can retrieve data contained within a Profile.
 *
 *  PROFILE_GET
 *
 * Retrieve all values for 'entity1' from 'profile1' over the past 4 hours.
 *
 *   PROFILE_GET('profile1', 'entity1', 4, 'HOURS')
 *
 * Retrieve all values for 'entity1' from 'profile1' over the past 2 days.
 *
 *   PROFILE_GET('profile1', 'entity1', 2, 'DAYS')
 *
 * Retrieve all values for 'entity1' from 'profile1' that occurred on 'weekdays' over the past month.
 *
 *   PROFILE_GET('profile1', 'entity1', 1, 'MONTHS', ['weekdays'])
 *
 * Retrieve all values for 'entity1' from 'profile1' over the past 2 days, with no 'groupBy',
 * and overriding the usual global client configuration parameters for window duration.
 *
 *   PROFILE_GET('profile1', 'entity1', 2, 'DAYS', [], {'profiler.client.period.duration' : '2', 'profiler.client.period.duration.units' : 'MINUTES'})
 *
 * Retrieve all values for 'entity1' from 'profile1' that occurred on 'weekdays' over the past month,
 * overriding the usual global client configuration parameters for window duration.
 *
 *   PROFILE_GET('profile1', 'entity1', 1, 'MONTHS', ['weekdays'], {'profiler.client.period.duration' : '2', 'profiler.client.period.duration.units' : 'MINUTES'})
 */
@Stellar(namespace = "PROFILE", name = "GET", description = "Retrieves a series of values from a stored profile.", params = { "profile - The name of the profile.", "entity - The name of the entity.", "periods - The list of profile periods to fetch. Use PROFILE_WINDOW or PROFILE_FIXED.", "groups - Optional - The groups to retrieve. Must correspond to the 'groupBy' " + "list used during profile creation. Defaults to an empty list, meaning no groups.", "config_overrides - Optional - Map (in curly braces) of name:value pairs, each overriding the global config parameter " + "of the same name. Default is the empty Map, meaning no overrides." }, returns = "The selected profile measurements.")
public class GetProfile implements StellarFunction {

    /**
     * Cached client that can retrieve profile values.
     */
    private ProfilerClient client;

    /**
     * Cached value of config map actually used to construct the previously cached client.
     */
    private Map<String, Object> cachedConfigMap = new HashMap<String, Object>(6);

    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

    /**
     * Initialization.  No longer need to do anything in initialization,
     * as all setup is done lazily and cached.
     */
    @Override
    public void initialize(Context context) {
    }

    /**
     * Is the function initialized?
     */
    @Override
    public boolean isInitialized() {
        return true;
    }

    /**
     * Apply the function.
     * @param args The function arguments.
     * @param context
     */
    @Override
    public Object apply(List<Object> args, Context context) throws ParseException {
        String profile = getArg(0, String.class, args);
        String entity = getArg(1, String.class, args);
        Optional<List<ProfilePeriod>> periods = Optional.ofNullable(getArg(2, List.class, args));
        // Optional arguments
        @SuppressWarnings("unchecked")
        List<Object> groups = null;
        Map configOverridesMap = null;
        if (args.size() < 4) {
            // no optional args, so default 'groups' and configOverridesMap remains null.
            groups = new ArrayList<>(0);
        } else if (args.get(3) instanceof List) {
            // correct extensible usage
            groups = getArg(3, List.class, args);
            if (args.size() >= 5) {
                configOverridesMap = getArg(4, Map.class, args);
                if (configOverridesMap.isEmpty())
                    configOverridesMap = null;
            }
        } else {
            // Deprecated "varargs" style usage for groups_list
            // configOverridesMap cannot be specified so it remains null.
            groups = getGroupsArg(3, args);
        }
        Map<String, Object> effectiveConfig = getEffectiveConfig(context, configOverridesMap);
        Object defaultValue = null;
        // lazily create new profiler client if needed
        if (client == null || !cachedConfigMap.equals(effectiveConfig)) {
            RowKeyBuilder rowKeyBuilder = getRowKeyBuilder(effectiveConfig);
            ColumnBuilder columnBuilder = getColumnBuilder(effectiveConfig);
            long periodDuration = getPeriodDurationInMillis(effectiveConfig);
            String tableName = PROFILER_HBASE_TABLE.get(effectiveConfig, String.class);
            Configuration hbaseConfig = HBaseConfiguration.create();
            client = new HBaseProfilerClient(getTableProvider(effectiveConfig), rowKeyBuilder, columnBuilder, periodDuration, tableName, hbaseConfig);
            cachedConfigMap = effectiveConfig;
        }
        if (cachedConfigMap != null) {
            defaultValue = ProfilerClientConfig.PROFILER_DEFAULT_VALUE.get(cachedConfigMap);
        }
        List<ProfileMeasurement> measurements = client.fetch(Object.class, profile, entity, groups, periods.orElse(new ArrayList<>(0)), Optional.ofNullable(defaultValue));
        // return only the value of each profile measurement
        List<Object> values = new ArrayList<>();
        for (ProfileMeasurement m : measurements) {
            values.add(m.getProfileValue());
        }
        return values;
    }

    /**
     * Get the groups defined by the user.
     *
     * The user can specify 0 or more groups.  All arguments from the specified position
     * on are assumed to be groups.  If there is no argument in the specified position,
     * then it is assumed the user did not specify any groups.
     *
     * @param startIndex The starting index of groups within the function argument list.
     * @param args The function arguments.
     * @return The groups.
     */
    private List<Object> getGroupsArg(int startIndex, List<Object> args) {
        List<Object> groups = new ArrayList<>();

        return groups;
    }

    /**
     * Creates the ColumnBuilder to use in accessing the profile data.
     * @param global The global configuration.
     */
    private ColumnBuilder getColumnBuilder(Map<String, Object> global) {
        ColumnBuilder columnBuilder;
        String columnFamily = PROFILER_COLUMN_FAMILY.get(global, String.class);
        columnBuilder = new ValueOnlyColumnBuilder(columnFamily);
        return columnBuilder;
    }

    /**
     * Creates the ColumnBuilder to use in accessing the profile data.
     * @param global The global configuration.
     */
    private RowKeyBuilder getRowKeyBuilder(Map<String, Object> global) {
        // how long is the profile period?
        long duration = PROFILER_PERIOD.get(global, Long.class);
        LOG.debug("profiler client: {}={}", PROFILER_PERIOD, duration);
        // which units are used to define the profile period?
        String configuredUnits = PROFILER_PERIOD_UNITS.get(global, String.class);
        TimeUnit units = TimeUnit.valueOf(configuredUnits);
        LOG.debug("profiler client: {}={}", PROFILER_PERIOD_UNITS, units);
        // what is the salt divisor?
        Integer saltDivisor = PROFILER_SALT_DIVISOR.get(global, Integer.class);
        LOG.debug("profiler client: {}={}", PROFILER_SALT_DIVISOR, saltDivisor);
        return new SaltyRowKeyBuilder(saltDivisor, duration, units);
    }

    /**
     * Create the TableProvider to use when accessing HBase.
     * @param global The global configuration.
     */
    private TableProvider getTableProvider(Map<String, Object> global) {
        String clazzName = PROFILER_HBASE_TABLE_PROVIDER.get(global, String.class);
        TableProvider provider;
        try {
            @SuppressWarnings("unchecked")
            Class<? extends TableProvider> clazz = (Class<? extends TableProvider>) Class.forName(clazzName);
            provider = clazz.getConstructor().newInstance();
        } catch (Exception e) {
            provider = new HTableProvider();
        }
        return provider;
    }
}


try {
            @SuppressWarnings("unchecked")
            Class<? extends TableProvider> clazz = (Class<? extends TableProvider>) Class.forName(clazzName);
            provider = clazz.getConstructor().newInstance();
        } catch (Exception e) {
            provider = new HTableProvider();
        }

package org.apache.metron.profiler.client.stellar;

import static org.apache.metron.profiler.client.stellar.ProfilerClientConfig.PROFILER_COLUMN_FAMILY;
import static org.apache.metron.profiler.client.stellar.ProfilerClientConfig.PROFILER_HBASE_TABLE;
import static org.apache.metron.profiler.client.stellar.ProfilerClientConfig.PROFILER_HBASE_TABLE_PROVIDER;
import static org.apache.metron.profiler.client.stellar.ProfilerClientConfig.PROFILER_PERIOD;
import static org.apache.metron.profiler.client.stellar.ProfilerClientConfig.PROFILER_PERIOD_UNITS;
import static org.apache.metron.profiler.client.stellar.ProfilerClientConfig.PROFILER_SALT_DIVISOR;
import static org.apache.metron.profiler.client.stellar.Util.getArg;
import static org.apache.metron.profiler.client.stellar.Util.getEffectiveConfig;
import static org.apache.metron.profiler.client.stellar.Util.getPeriodDurationInMillis;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.metron.hbase.HTableProvider;
import org.apache.metron.hbase.TableProvider;
import org.apache.metron.profiler.ProfileMeasurement;
import org.apache.metron.profiler.ProfilePeriod;
import org.apache.metron.profiler.client.HBaseProfilerClient;
import org.apache.metron.profiler.client.ProfilerClient;
import org.apache.metron.profiler.hbase.ColumnBuilder;
import org.apache.metron.profiler.hbase.RowKeyBuilder;
import org.apache.metron.profiler.hbase.SaltyRowKeyBuilder;
import org.apache.metron.profiler.hbase.ValueOnlyColumnBuilder;
import org.apache.metron.stellar.dsl.Context;
import org.apache.metron.stellar.dsl.ParseException;
import org.apache.metron.stellar.dsl.Stellar;
import org.apache.metron.stellar.dsl.StellarFunction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A Stellar function that can retrieve data contained within a Profile.
 *
 *  PROFILE_GET
 *
 * Retrieve all values for 'entity1' from 'profile1' over the past 4 hours.
 *
 *   PROFILE_GET('profile1', 'entity1', 4, 'HOURS')
 *
 * Retrieve all values for 'entity1' from 'profile1' over the past 2 days.
 *
 *   PROFILE_GET('profile1', 'entity1', 2, 'DAYS')
 *
 * Retrieve all values for 'entity1' from 'profile1' that occurred on 'weekdays' over the past month.
 *
 *   PROFILE_GET('profile1', 'entity1', 1, 'MONTHS', ['weekdays'])
 *
 * Retrieve all values for 'entity1' from 'profile1' over the past 2 days, with no 'groupBy',
 * and overriding the usual global client configuration parameters for window duration.
 *
 *   PROFILE_GET('profile1', 'entity1', 2, 'DAYS', [], {'profiler.client.period.duration' : '2', 'profiler.client.period.duration.units' : 'MINUTES'})
 *
 * Retrieve all values for 'entity1' from 'profile1' that occurred on 'weekdays' over the past month,
 * overriding the usual global client configuration parameters for window duration.
 *
 *   PROFILE_GET('profile1', 'entity1', 1, 'MONTHS', ['weekdays'], {'profiler.client.period.duration' : '2', 'profiler.client.period.duration.units' : 'MINUTES'})
 */
@Stellar(namespace = "PROFILE", name = "GET", description = "Retrieves a series of values from a stored profile.", params = { "profile - The name of the profile.", "entity - The name of the entity.", "periods - The list of profile periods to fetch. Use PROFILE_WINDOW or PROFILE_FIXED.", "groups - Optional - The groups to retrieve. Must correspond to the 'groupBy' " + "list used during profile creation. Defaults to an empty list, meaning no groups.", "config_overrides - Optional - Map (in curly braces) of name:value pairs, each overriding the global config parameter " + "of the same name. Default is the empty Map, meaning no overrides." }, returns = "The selected profile measurements.")
public class GetProfile implements StellarFunction {

    /**
     * Cached client that can retrieve profile values.
     */
    private ProfilerClient client;

    /**
     * Cached value of config map actually used to construct the previously cached client.
     */
    private Map<String, Object> cachedConfigMap = new HashMap<String, Object>(6);

    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

    /**
     * Initialization.  No longer need to do anything in initialization,
     * as all setup is done lazily and cached.
     */
    @Override
    public void initialize(Context context) {
    }

    /**
     * Is the function initialized?
     */
    @Override
    public boolean isInitialized() {
        return true;
    }

    /**
     * Apply the function.
     * @param args The function arguments.
     * @param context
     */
    @Override
    public Object apply(List<Object> args, Context context) throws ParseException {
        String profile = getArg(0, String.class, args);
        String entity = getArg(1, String.class, args);
        Optional<List<ProfilePeriod>> periods = Optional.ofNullable(getArg(2, List.class, args));
        // Optional arguments
        @SuppressWarnings("unchecked")
        List<Object> groups = null;
        Map configOverridesMap = null;
        if (args.size() < 4) {
            // no optional args, so default 'groups' and configOverridesMap remains null.
            groups = new ArrayList<>(0);
        } else if (args.get(3) instanceof List) {
            // correct extensible usage
            groups = getArg(3, List.class, args);
            if (args.size() >= 5) {
                configOverridesMap = getArg(4, Map.class, args);
                if (configOverridesMap.isEmpty())
                    configOverridesMap = null;
            }
        } else {
            // Deprecated "varargs" style usage for groups_list
            // configOverridesMap cannot be specified so it remains null.
            groups = getGroupsArg(3, args);
        }
        Map<String, Object> effectiveConfig = getEffectiveConfig(context, configOverridesMap);
        Object defaultValue = null;
        // lazily create new profiler client if needed
        if (client == null || !cachedConfigMap.equals(effectiveConfig)) {
            RowKeyBuilder rowKeyBuilder = getRowKeyBuilder(effectiveConfig);
            ColumnBuilder columnBuilder = getColumnBuilder(effectiveConfig);
            long periodDuration = getPeriodDurationInMillis(effectiveConfig);
            String tableName = PROFILER_HBASE_TABLE.get(effectiveConfig, String.class);
            Configuration hbaseConfig = HBaseConfiguration.create();
            client = new HBaseProfilerClient(getTableProvider(effectiveConfig), rowKeyBuilder, columnBuilder, periodDuration, tableName, hbaseConfig);
            cachedConfigMap = effectiveConfig;
        }
        if (cachedConfigMap != null) {
            defaultValue = ProfilerClientConfig.PROFILER_DEFAULT_VALUE.get(cachedConfigMap);
        }
        List<ProfileMeasurement> measurements = client.fetch(Object.class, profile, entity, groups, periods.orElse(new ArrayList<>(0)), Optional.ofNullable(defaultValue));
        // return only the value of each profile measurement
        List<Object> values = new ArrayList<>();
        for (ProfileMeasurement m : measurements) {
            values.add(m.getProfileValue());
        }
        return values;
    }

    /**
     * Get the groups defined by the user.
     *
     * The user can specify 0 or more groups.  All arguments from the specified position
     * on are assumed to be groups.  If there is no argument in the specified position,
     * then it is assumed the user did not specify any groups.
     *
     * @param startIndex The starting index of groups within the function argument list.
     * @param args The function arguments.
     * @return The groups.
     */
    private List<Object> getGroupsArg(int startIndex, List<Object> args) {
        List<Object> groups = new ArrayList<>();
        for (int i = startIndex; i < args.size(); i++) {
            String group = getArg(i, String.class, args);
            groups.add(group);
        }
        return groups;
    }

    /**
     * Creates the ColumnBuilder to use in accessing the profile data.
     * @param global The global configuration.
     */
    private ColumnBuilder getColumnBuilder(Map<String, Object> global) {
        ColumnBuilder columnBuilder;
        String columnFamily = PROFILER_COLUMN_FAMILY.get(global, String.class);
        columnBuilder = new ValueOnlyColumnBuilder(columnFamily);
        return columnBuilder;
    }

    /**
     * Creates the ColumnBuilder to use in accessing the profile data.
     * @param global The global configuration.
     */
    private RowKeyBuilder getRowKeyBuilder(Map<String, Object> global) {
        // how long is the profile period?
        long duration = PROFILER_PERIOD.get(global, Long.class);
        LOG.debug("profiler client: {}={}", PROFILER_PERIOD, duration);
        // which units are used to define the profile period?
        String configuredUnits = PROFILER_PERIOD_UNITS.get(global, String.class);
        TimeUnit units = TimeUnit.valueOf(configuredUnits);
        LOG.debug("profiler client: {}={}", PROFILER_PERIOD_UNITS, units);
        // what is the salt divisor?
        Integer saltDivisor = PROFILER_SALT_DIVISOR.get(global, Integer.class);
        LOG.debug("profiler client: {}={}", PROFILER_SALT_DIVISOR, saltDivisor);
        return new SaltyRowKeyBuilder(saltDivisor, duration, units);
    }

    /**
     * Create the TableProvider to use when accessing HBase.
     * @param global The global configuration.
     */
    private TableProvider getTableProvider(Map<String, Object> global) {
        String clazzName = PROFILER_HBASE_TABLE_PROVIDER.get(global, String.class);
        TableProvider provider;


public static BufferedImage getImage(byte[] imageBytes) throws IOException {
        BufferedImage image = null;
        if (imageBytes != null) {
            ByteArrayInputStream stream = new ByteArrayInputStream(imageBytes);
            image = ImageIO.read(stream);
            stream.close();
        }
        return image;
    }

package mil.nga.geopackage.tiles;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException;
import java.util.Iterator;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import mil.nga.geopackage.GeoPackageException;

/**
 * Image utility methods
 *
 * @author osbornb
 */
public class ImageUtils {

    /**
     * png image format
     */
    public static final String IMAGE_FORMAT_PNG = "png";

    /**
     * jpg image format
     */
    public static final String IMAGE_FORMAT_JPG = "jpg";

    /**
     * jpeg image format
     */
    public static final String IMAGE_FORMAT_JPEG = "jpeg";

    public static final String IMAGE_FORMAT_TIFF = "tiff";

    /**
     * Create a buffered image for the dimensions and image format
     *
     * @param width
     *            image width
     * @param height
     *            image height
     * @param imageFormat
     *            image format
     * @return image
     */
    public static BufferedImage createBufferedImage(int width, int height, String imageFormat) {
        int imageType;
        switch(imageFormat.toLowerCase()) {
            case IMAGE_FORMAT_JPG:
            case IMAGE_FORMAT_JPEG:
                imageType = BufferedImage.TYPE_INT_RGB;
                break;
            default:
                imageType = BufferedImage.TYPE_INT_ARGB;
        }
        BufferedImage image = new BufferedImage(width, height, imageType);
        return image;
    }

    /**
     * Check if the image is fully transparent, meaning it contains only
     * transparent pixels as an empty image
     *
     * @param image
     *            image
     * @return true if fully transparent
     */
    public static boolean isFullyTransparent(BufferedImage image) {
        boolean transparent = true;
        for (int x = 0; x < image.getWidth(); x++) {
            for (int y = 0; y < image.getHeight(); y++) {
                transparent = isTransparent(image, x, y);
                if (!transparent) {
                    break;
                }
            }
            if (!transparent) {
                break;
            }
        }
        return transparent;
    }

    /**
     * Check if the pixel in the image at the x and y is transparent
     *
     * @param image
     *            image
     * @param x
     *            x location
     * @param y
     *            y location
     * @return true if transparent
     */
    public static boolean isTransparent(BufferedImage image, int x, int y) {
        int pixel = image.getRGB(x, y);
        boolean transparent = (pixel >> 24) == 0x00;
        return transparent;
    }

    /**
     * Get a buffered image of the image bytes
     *
     * @param imageBytes
     *            image bytes
     * @return buffered image or null
     * @throws IOException
     *             upon failure
     * @since 1.1.2
     */

    /**
     * Write the image to bytes in the provided format and optional quality
     *
     * @param image
     *            buffered image
     * @param formatName
     *            image format name
     * @param quality
     *            null or quality between 0.0 and 1.0
     * @return image bytes
     * @throws IOException
     *             upon failure
     * @since 1.1.2
     */
    public static byte[] writeImageToBytes(BufferedImage image, String formatName, Float quality) throws IOException {
        byte[] bytes = null;
        if (quality != null) {
            bytes = compressAndWriteImageToBytes(image, formatName, quality);
        } else {
            bytes = writeImageToBytes(image, formatName);
        }
        return bytes;
    }

    /**
     * Write the image to bytes in the provided format
     *
     * @param image
     *            buffered image
     * @param formatName
     *            image format name
     * @return image bytes
     * @throws IOException
     *             upon failure
     * @since 1.1.2
     */
    public static byte[] writeImageToBytes(BufferedImage image, String formatName) throws IOException {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        ImageIO.write(image, formatName, stream);
        stream.flush();
        byte[] bytes = stream.toByteArray();
        stream.close();
        return bytes;
    }

    /**
     * Compress and write the image to bytes in the provided format and quality
     *
     * @param image
     *            buffered image
     * @param formatName
     *            image format name
     * @param quality
     *            quality between 0.0 and 1.0
     * @return compressed image bytes
     * @since 1.1.2
     */
    public static byte[] compressAndWriteImageToBytes(BufferedImage image, String formatName, float quality) {
        byte[] bytes = null;
        Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(formatName);
        if (writers == null || !writers.hasNext()) {
            throw new GeoPackageException("No Image Writer to compress format: " + formatName);
        }
        ImageWriter writer = writers.next();
        ImageWriteParam writeParam = writer.getDefaultWriteParam();
        writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        writeParam.setCompressionQuality(quality);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageOutputStream ios = null;
        try {
            ios = ImageIO.createImageOutputStream(baos);
            writer.setOutput(ios);
            writer.write(null, new IIOImage(image, null, null), writeParam);
            writer.dispose();
            bytes = baos.toByteArray();
        } catch (IOException e) {
            throw new GeoPackageException("Failed to compress image to format: " + formatName + ", with quality: " + quality, e);
        } finally {
            closeQuietly(ios);
            closeQuietly(baos);
        }
        return bytes;
    }

    /**
     * Close quietly
     *
     * @param closeable
     *            closeable
     * @since 1.1.2
     */
    public static void closeQuietly(Closeable closeable) {
        if (closeable != null) {
            try {
                closeable.close();
            } catch (IOException e) {
                // Eat
            }
        }
    }
}


switch(imageFormat.toLowerCase()) {
            case IMAGE_FORMAT_JPG:
            case IMAGE_FORMAT_JPEG:
                imageType = BufferedImage.TYPE_INT_RGB;
                break;
            default:
                imageType = BufferedImage.TYPE_INT_ARGB;
        }

package mil.nga.geopackage.tiles;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException;
import java.util.Iterator;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import mil.nga.geopackage.GeoPackageException;

/**
 * Image utility methods
 *
 * @author osbornb
 */
public class ImageUtils {

    /**
     * png image format
     */
    public static final String IMAGE_FORMAT_PNG = "png";

    /**
     * jpg image format
     */
    public static final String IMAGE_FORMAT_JPG = "jpg";

    /**
     * jpeg image format
     */
    public static final String IMAGE_FORMAT_JPEG = "jpeg";

    public static final String IMAGE_FORMAT_TIFF = "tiff";

    /**
     * Create a buffered image for the dimensions and image format
     *
     * @param width
     *            image width
     * @param height
     *            image height
     * @param imageFormat
     *            image format
     * @return image
     */
    public static BufferedImage createBufferedImage(int width, int height, String imageFormat) {
        int imageType;

        BufferedImage image = new BufferedImage(width, height, imageType);
        return image;
    }

    /**
     * Check if the image is fully transparent, meaning it contains only
     * transparent pixels as an empty image
     *
     * @param image
     *            image
     * @return true if fully transparent
     */
    public static boolean isFullyTransparent(BufferedImage image) {
        boolean transparent = true;
        for (int x = 0; x < image.getWidth(); x++) {
            for (int y = 0; y < image.getHeight(); y++) {
                transparent = isTransparent(image, x, y);
                if (!transparent) {
                    break;
                }
            }
            if (!transparent) {
                break;
            }
        }
        return transparent;
    }

    /**
     * Check if the pixel in the image at the x and y is transparent
     *
     * @param image
     *            image
     * @param x
     *            x location
     * @param y
     *            y location
     * @return true if transparent
     */
    public static boolean isTransparent(BufferedImage image, int x, int y) {
        int pixel = image.getRGB(x, y);
        boolean transparent = (pixel >> 24) == 0x00;
        return transparent;
    }

    /**
     * Get a buffered image of the image bytes
     *
     * @param imageBytes
     *            image bytes
     * @return buffered image or null
     * @throws IOException
     *             upon failure
     * @since 1.1.2
     */
    public static BufferedImage getImage(byte[] imageBytes) throws IOException {
        BufferedImage image = null;
        if (imageBytes != null) {
            ByteArrayInputStream stream = new ByteArrayInputStream(imageBytes);
            image = ImageIO.read(stream);
            stream.close();
        }
        return image;
    }

    /**
     * Write the image to bytes in the provided format and optional quality
     *
     * @param image
     *            buffered image
     * @param formatName
     *            image format name
     * @param quality
     *            null or quality between 0.0 and 1.0
     * @return image bytes
     * @throws IOException
     *             upon failure
     * @since 1.1.2
     */
    public static byte[] writeImageToBytes(BufferedImage image, String formatName, Float quality) throws IOException {
        byte[] bytes = null;
        if (quality != null) {
            bytes = compressAndWriteImageToBytes(image, formatName, quality);
        } else {
            bytes = writeImageToBytes(image, formatName);
        }
        return bytes;
    }

    /**
     * Write the image to bytes in the provided format
     *
     * @param image
     *            buffered image
     * @param formatName
     *            image format name
     * @return image bytes
     * @throws IOException
     *             upon failure
     * @since 1.1.2
     */
    public static byte[] writeImageToBytes(BufferedImage image, String formatName) throws IOException {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        ImageIO.write(image, formatName, stream);
        stream.flush();
        byte[] bytes = stream.toByteArray();
        stream.close();
        return bytes;
    }

    /**
     * Compress and write the image to bytes in the provided format and quality
     *
     * @param image
     *            buffered image
     * @param formatName
     *            image format name
     * @param quality
     *            quality between 0.0 and 1.0
     * @return compressed image bytes
     * @since 1.1.2
     */
    public static byte[] compressAndWriteImageToBytes(BufferedImage image, String formatName, float quality) {
        byte[] bytes = null;
        Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(formatName);
        if (writers == null || !writers.hasNext()) {
            throw new GeoPackageException("No Image Writer to compress format: " + formatName);
        }
        ImageWriter writer = writers.next();
        ImageWriteParam writeParam = writer.getDefaultWriteParam();
        writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        writeParam.setCompressionQuality(quality);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageOutputStream ios = null;
        try {
            ios = ImageIO.createImageOutputStream(baos);
            writer.setOutput(ios);
            writer.write(null, new IIOImage(image, null, null), writeParam);
            writer.dispose();
            bytes = baos.toByteArray();
        } catch (IOException e) {
            throw new GeoPackageException("Failed to compress image to format: " + formatName + ", with quality: " + quality, e);
        } finally {
            closeQuietly(ios);
            closeQuietly(baos);
        }
        return bytes;
    }

    /**
     * Close quietly
     *
     * @param closeable
     *            closeable
     * @since 1.1.2
     */
    public static void closeQuietly(Closeable closeable) {
        if (closeable != null) {
            try {
                closeable.close();
            } catch (IOException e) {
                // Eat
            }
        }
    }
}


for (int y = 0; y < image.getHeight(); y++) {
                transparent = isTransparent(image, x, y);
                if (!transparent) {
                    break;
                }
            }

package mil.nga.geopackage.tiles;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException;
import java.util.Iterator;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import mil.nga.geopackage.GeoPackageException;

/**
 * Image utility methods
 *
 * @author osbornb
 */
public class ImageUtils {

    /**
     * png image format
     */
    public static final String IMAGE_FORMAT_PNG = "png";

    /**
     * jpg image format
     */
    public static final String IMAGE_FORMAT_JPG = "jpg";

    /**
     * jpeg image format
     */
    public static final String IMAGE_FORMAT_JPEG = "jpeg";

    public static final String IMAGE_FORMAT_TIFF = "tiff";

    /**
     * Create a buffered image for the dimensions and image format
     *
     * @param width
     *            image width
     * @param height
     *            image height
     * @param imageFormat
     *            image format
     * @return image
     */
    public static BufferedImage createBufferedImage(int width, int height, String imageFormat) {
        int imageType;
        switch(imageFormat.toLowerCase()) {
            case IMAGE_FORMAT_JPG:
            case IMAGE_FORMAT_JPEG:
                imageType = BufferedImage.TYPE_INT_RGB;
                break;
            default:
                imageType = BufferedImage.TYPE_INT_ARGB;
        }
        BufferedImage image = new BufferedImage(width, height, imageType);
        return image;
    }

    /**
     * Check if the image is fully transparent, meaning it contains only
     * transparent pixels as an empty image
     *
     * @param image
     *            image
     * @return true if fully transparent
     */
    public static boolean isFullyTransparent(BufferedImage image) {
        boolean transparent = true;
        for (int x = 0; x < image.getWidth(); x++) {

            if (!transparent) {
                break;
            }
        }
        return transparent;
    }

    /**
     * Check if the pixel in the image at the x and y is transparent
     *
     * @param image
     *            image
     * @param x
     *            x location
     * @param y
     *            y location
     * @return true if transparent
     */
    public static boolean isTransparent(BufferedImage image, int x, int y) {
        int pixel = image.getRGB(x, y);
        boolean transparent = (pixel >> 24) == 0x00;
        return transparent;
    }

    /**
     * Get a buffered image of the image bytes
     *
     * @param imageBytes
     *            image bytes
     * @return buffered image or null
     * @throws IOException
     *             upon failure
     * @since 1.1.2
     */
    public static BufferedImage getImage(byte[] imageBytes) throws IOException {
        BufferedImage image = null;
        if (imageBytes != null) {
            ByteArrayInputStream stream = new ByteArrayInputStream(imageBytes);
            image = ImageIO.read(stream);
            stream.close();
        }
        return image;
    }

    /**
     * Write the image to bytes in the provided format and optional quality
     *
     * @param image
     *            buffered image
     * @param formatName
     *            image format name
     * @param quality
     *            null or quality between 0.0 and 1.0
     * @return image bytes
     * @throws IOException
     *             upon failure
     * @since 1.1.2
     */
    public static byte[] writeImageToBytes(BufferedImage image, String formatName, Float quality) throws IOException {
        byte[] bytes = null;
        if (quality != null) {
            bytes = compressAndWriteImageToBytes(image, formatName, quality);
        } else {
            bytes = writeImageToBytes(image, formatName);
        }
        return bytes;
    }

    /**
     * Write the image to bytes in the provided format
     *
     * @param image
     *            buffered image
     * @param formatName
     *            image format name
     * @return image bytes
     * @throws IOException
     *             upon failure
     * @since 1.1.2
     */
    public static byte[] writeImageToBytes(BufferedImage image, String formatName) throws IOException {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        ImageIO.write(image, formatName, stream);
        stream.flush();
        byte[] bytes = stream.toByteArray();
        stream.close();
        return bytes;
    }

    /**
     * Compress and write the image to bytes in the provided format and quality
     *
     * @param image
     *            buffered image
     * @param formatName
     *            image format name
     * @param quality
     *            quality between 0.0 and 1.0
     * @return compressed image bytes
     * @since 1.1.2
     */
    public static byte[] compressAndWriteImageToBytes(BufferedImage image, String formatName, float quality) {
        byte[] bytes = null;
        Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName(formatName);
        if (writers == null || !writers.hasNext()) {
            throw new GeoPackageException("No Image Writer to compress format: " + formatName);
        }
        ImageWriter writer = writers.next();
        ImageWriteParam writeParam = writer.getDefaultWriteParam();
        writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        writeParam.setCompressionQuality(quality);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageOutputStream ios = null;
        try {
            ios = ImageIO.createImageOutputStream(baos);
            writer.setOutput(ios);
            writer.write(null, new IIOImage(image, null, null), writeParam);
            writer.dispose();
            bytes = baos.toByteArray();
        } catch (IOException e) {
            throw new GeoPackageException("Failed to compress image to format: " + formatName + ", with quality: " + quality, e);
        } finally {
            closeQuietly(ios);
            closeQuietly(baos);
        }
        return bytes;
    }

    /**
     * Close quietly
     *
     * @param closeable
     *            closeable
     * @since 1.1.2
     */
    public static void closeQuietly(Closeable closeable) {
        if (closeable != null) {
            try {
                closeable.close();
            } catch (IOException e) {
                // Eat
            }
        }
    }
}