try {
                writer.writeOrbitEphemerisLine(generator, metadata, currentState.getPVCoordinates(), true);
            } catch (IOException e) {
                throw new OrekitException(e, LocalizedCoreFormats.SIMPLE_MESSAGE, e.getLocalizedMessage());
            }

package org.orekit.files.ccsds.ndm.odm.oem;

import java.io.IOException;
import org.hipparchus.exception.LocalizedCoreFormats;
import org.orekit.errors.OrekitException;
import org.orekit.errors.OrekitMessages;
import org.orekit.files.ccsds.definitions.FrameFacade;
import org.orekit.files.ccsds.section.Header;
import org.orekit.files.ccsds.utils.generation.Generator;
import org.orekit.propagation.Propagator;
import org.orekit.propagation.SpacecraftState;
import org.orekit.propagation.sampling.OrekitFixedStepHandler;
import org.orekit.time.AbsoluteDate;

/**
 * A writer for OEM files.
 *
 *
 Each instance corresponds to a single OEM file. A new OEM ephemeris segment is
 * started by calling {@link #newSegment()}.
 *
 *
 This class can be used as a step handler for a {@link Propagator}.
 *
 *
{@code
 * Propagator propagator = ...; // pre-configured propagator
 * OEMWriter  aemWriter  = ...; // pre-configured writer
 *   try (Generator out = ...;  // set-up output stream
 *        StreamingOemWriter sw = new StreamingOemWriter(out, oemWriter)) { // set-up streaming writer
 *
 *     // write segment 1
 *     propagator.getMultiplexer().add(step, sw.newSegment());
 *     propagator.propagate(startDate1, stopDate1);
 *
 *     ...
 *
 *     // write segment n
 *     propagator.getMultiplexer().clear();
 *     propagator.getMultiplexer().add(step, sw.newSegment());
 *     propagator.propagate(startDateN, stopDateN);
 *
 *   }
 * }

 *
 * @author Evan Ward
 * @see CCSDS 502.0-B-2 Orbit Data
 *      Messages
 * @see CCSDS 500.0-G-4 Navigation
 *      Data Definitions and Conventions
 * @see OemWriter
 */
public class StreamingOemWriter implements AutoCloseable {

    /**
     * Generator for OEM output.
     */
    private final Generator generator;

    /**
     * Writer for the OEM message format.
     */
    private final OemWriter writer;

    private final Header header;

    /**
     * Current metadata.
     */
    private final OemMetadata metadata;

    /**
     * Indicator for writing header.
     */
    private boolean headerWritePending;

    /**
     * Simple constructor.
     * @param generator generator for OEM output
     * @param writer writer for the AEM message format
     * @param header file header (may be null)
     * @param template template for metadata
     * @since 11.0
     */
    public StreamingOemWriter(final Generator generator, final OemWriter writer, final Header header, final OemMetadata template) {
        this.generator = generator;
        this.writer = writer;
        this.header = header;
        this.metadata = template.copy(header == null ? writer.getDefaultVersion() : header.getFormatVersion());
        this.headerWritePending = true;
    }

    /**
     * Create a writer for a new OEM ephemeris segment.
     *
 The returned writer can only write a single ephemeris segment in an OEM.
     * This method must be called to create a writer for each ephemeris segment.
     * @return a new OEM segment writer, ready for use.
     */
    public SegmentWriter newSegment() {
        return new SegmentWriter();
    }

    @Override
    public void close() throws IOException {
        writer.writeFooter(generator);
    }

    /**
     * A writer for a segment of an OEM.
     */
    public class SegmentWriter implements OrekitFixedStepHandler {

        /**
         * {@inheritDoc}
         *
         *
 Sets the {@link OemMetadataKey#START_TIME} and {@link OemMetadataKey#STOP_TIME} in this
         * segment's metadata if not already set by the user. Then calls {@link OemWriter#writeHeader(Generator, Header)
         * writeHeader} if it is the first segment) and {@link OemWriter#writeMetadata(Generator, OemMetadata)}
         * to start the segment.
         */
        @Override
        public void init(final SpacecraftState s0, final AbsoluteDate t, final double step) {
            try {
                final AbsoluteDate date = s0.getDate();
                if (t.isBefore(date)) {
                    throw new OrekitException(OrekitMessages.NON_CHRONOLOGICALLY_SORTED_ENTRIES, date, t, date.durationFrom(t));
                }
                if (headerWritePending) {
                    // we write the header only for the first segment
                    writer.writeHeader(generator, header);
                    headerWritePending = false;
                }
                metadata.setStartTime(date);
                metadata.setUseableStartTime(null);
                metadata.setUseableStopTime(null);
                metadata.setStopTime(t);
                metadata.setReferenceFrame(FrameFacade.map(s0.getAttitude().getReferenceFrame()));
                writer.writeMetadata(generator, metadata);
                writer.startData(generator);
            } catch (IOException e) {
                throw new OrekitException(e, LocalizedCoreFormats.SIMPLE_MESSAGE, e.getLocalizedMessage());
            }
        }

        @Override
        public void handleStep(final SpacecraftState currentState) {

        }

        @Override
        public void finish(final SpacecraftState finalState) {
            try {
                writer.endData(generator);
            } catch (IOException e) {
                throw new OrekitException(e, LocalizedCoreFormats.SIMPLE_MESSAGE, e.getLocalizedMessage());
            }
        }
    }
}


public T get(Thread thread) {
        return (T) get(this, thread);
    }

package org.apache.geode.distributed.internal.deadlock;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Most of this thread local is safe to use, except for the getValue(Thread) method. That is not
 * guaranteed to be correct. But for our deadlock detection tool I think it's good enough, and this
 * class provides a very low overhead way for us to record what thread holds a particular resource.
 */
public class UnsafeThreadLocal<T> extends ThreadLocal<T> {

    /**
     * Dangerous method. Uses reflection to extract the thread local for a given thread.
     *
     * Unlike get(), this method does not set the initial value if none is found
     */

    private static Object get(ThreadLocal threadLocal, Thread thread) {
        try {
            Object threadLocalMap = invokePrivate(threadLocal, "getMap", new Class[] { Thread.class }, new Object[] { thread });
            if (threadLocalMap != null) {
                Object entry = invokePrivate(threadLocalMap, "getEntry", new Class[] { ThreadLocal.class }, new Object[] { threadLocal });
                if (entry != null) {
                    return getPrivate(entry, "value");
                }
            }
            return null;
        } catch (Exception e) {
            throw new RuntimeException("Unable to extract thread local", e);
        }
    }

    private static Object getPrivate(Object object, String fieldName) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
        Field field = object.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        return field.get(object);
    }

    private static Object invokePrivate(Object object, String methodName, Class[] argTypes, Object[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        Method method = null;
        Class clazz = object.getClass();
        while (method == null) {
            try {
                method = clazz.getDeclaredMethod(methodName, argTypes);
            } catch (NoSuchMethodException e) {
                clazz = clazz.getSuperclass();
                if (clazz == null) {
                    throw e;
                }
            }
        }
        method.setAccessible(true);
        Object result = method.invoke(object, args);
        return result;
    }
}


while (method == null) {
            try {
                method = clazz.getDeclaredMethod(methodName, argTypes);
            } catch (NoSuchMethodException e) {
                clazz = clazz.getSuperclass();
                if (clazz == null) {
                    throw e;
                }
            }
        }

package org.apache.geode.distributed.internal.deadlock;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Most of this thread local is safe to use, except for the getValue(Thread) method. That is not
 * guaranteed to be correct. But for our deadlock detection tool I think it's good enough, and this
 * class provides a very low overhead way for us to record what thread holds a particular resource.
 */
public class UnsafeThreadLocal<T> extends ThreadLocal<T> {

    /**
     * Dangerous method. Uses reflection to extract the thread local for a given thread.
     *
     * Unlike get(), this method does not set the initial value if none is found
     */
    public T get(Thread thread) {
        return (T) get(this, thread);
    }

    private static Object get(ThreadLocal threadLocal, Thread thread) {
        try {
            Object threadLocalMap = invokePrivate(threadLocal, "getMap", new Class[] { Thread.class }, new Object[] { thread });
            if (threadLocalMap != null) {
                Object entry = invokePrivate(threadLocalMap, "getEntry", new Class[] { ThreadLocal.class }, new Object[] { threadLocal });
                if (entry != null) {
                    return getPrivate(entry, "value");
                }
            }
            return null;
        } catch (Exception e) {
            throw new RuntimeException("Unable to extract thread local", e);
        }
    }

    private static Object getPrivate(Object object, String fieldName) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
        Field field = object.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        return field.get(object);
    }

    private static Object invokePrivate(Object object, String methodName, Class[] argTypes, Object[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        Method method = null;
        Class clazz = object.getClass();

        method.setAccessible(true);
        Object result = method.invoke(object, args);
        return result;
    }
}


try {
                method = clazz.getDeclaredMethod(methodName, argTypes);
            } catch (NoSuchMethodException e) {
                clazz = clazz.getSuperclass();
                if (clazz == null) {
                    throw e;
                }
            }

package org.apache.geode.distributed.internal.deadlock;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Most of this thread local is safe to use, except for the getValue(Thread) method. That is not
 * guaranteed to be correct. But for our deadlock detection tool I think it's good enough, and this
 * class provides a very low overhead way for us to record what thread holds a particular resource.
 */
public class UnsafeThreadLocal<T> extends ThreadLocal<T> {

    /**
     * Dangerous method. Uses reflection to extract the thread local for a given thread.
     *
     * Unlike get(), this method does not set the initial value if none is found
     */
    public T get(Thread thread) {
        return (T) get(this, thread);
    }

    private static Object get(ThreadLocal threadLocal, Thread thread) {
        try {
            Object threadLocalMap = invokePrivate(threadLocal, "getMap", new Class[] { Thread.class }, new Object[] { thread });
            if (threadLocalMap != null) {
                Object entry = invokePrivate(threadLocalMap, "getEntry", new Class[] { ThreadLocal.class }, new Object[] { threadLocal });
                if (entry != null) {
                    return getPrivate(entry, "value");
                }
            }
            return null;
        } catch (Exception e) {
            throw new RuntimeException("Unable to extract thread local", e);
        }
    }

    private static Object getPrivate(Object object, String fieldName) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
        Field field = object.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        return field.get(object);
    }

    private static Object invokePrivate(Object object, String methodName, Class[] argTypes, Object[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        Method method = null;
        Class clazz = object.getClass();
        while (method == null) {

        }
        method.setAccessible(true);
        Object result = method.invoke(object, args);
        return result;
    }
}


package org.hyperledger.besu.plugin.services;

import org.hyperledger.besu.plugin.services.permissioning.NodeConnectionPermissioningProvider;
import org.hyperledger.besu.plugin.services.permissioning.NodeMessagePermissioningProvider;

/**
 * This service allows plugins to decide who you should connect to and what you should send them.
 *
 *
Currently, there are two hooks available: connection permissioning and message permissioning.
 *
 *

 *
Connection permissioning - checks if inbound and outbound connections to peers are
 *       permitted. {@link NodeConnectionPermissioningProvider}
 *
Message permissioning - checks if a devp2p message can be sent to a peer. {@link
 *       NodeMessagePermissioningProvider}
 *

 */
public interface PermissioningService extends BesuService {

    /**
     * Registers a callback to allow the interception of a peer connection request
     *
     * @param provider The provider to register
     */
    void registerNodePermissioningProvider(NodeConnectionPermissioningProvider provider);

    /**
     * Registers a callback to allow the interception of a devp2p message sending request
     *
     * @param provider The provider to register
     */


for (int i = 0; i < number; i++) conversion.append("1");

/**
 * All rights reserved.
 */
package org.cleartk.util;

/**
 * <br>
 * All rights reserved.
 */
public class BaseConversion {

    public static String convertBase(int number, int base) {
        if (number == 0)
            return "0";
        if (base > 62)
            throw new IllegalArgumentException("base must be 62 or less: base=" + base);
        if (base <= 0)
            throw new IllegalArgumentException("base must be greater than zero: base=" + base);
        StringBuffer conversion = new StringBuffer();
        if (base == 1) {

            return conversion.toString();
        }
        String digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
        while (number > 0) {
            int digitIndex = number % base;
            conversion.insert(0, digits.charAt(digitIndex));
            number = number / base;
        }
        return conversion.toString();
    }
}


while (number > 0) {
            int digitIndex = number % base;
            conversion.insert(0, digits.charAt(digitIndex));
            number = number / base;
        }

/**
 * All rights reserved.
 */
package org.cleartk.util;

/**
 * <br>
 * All rights reserved.
 */
public class BaseConversion {

    public static String convertBase(int number, int base) {
        if (number == 0)
            return "0";
        if (base > 62)
            throw new IllegalArgumentException("base must be 62 or less: base=" + base);
        if (base <= 0)
            throw new IllegalArgumentException("base must be greater than zero: base=" + base);
        StringBuffer conversion = new StringBuffer();
        if (base == 1) {
            for (int i = 0; i < number; i++) conversion.append("1");
            return conversion.toString();
        }
        String digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

        return conversion.toString();
    }
}


java/github/EgorKulikov/yaal/archive/2011.10/2011.10.07 - Codeforces Beta Round #89/TaskB.java

for (int i = 1; i < 2 * size; i++) {
            for (int j = 0; j < Math.abs(size - i); j++) out.print("  ");
            for (int j = 0; j < size - Math.abs(size - i) - 1; j++) out.print(j + " ");
            out.print(size - Math.abs(size - i) - 1);
            for (int j = size - Math.abs(size - i) - 1 - 1; j >= 0; j--) out.print(" " + j);
            out.println();
        }

import net.egork.utils.Solver;
import net.egork.utils.old.io.old.InputReader;
import java.io.PrintWriter;

public class TaskB implements Solver {

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int size = in.readInt() + 1;


switch(error) {
            case 1280:
                return "invalid enum";
            case 1281:
                return "invalid value";
            case 1282:
                return "invalid operation";
            case 1283:
                return "stack overflow";
            case 1284:
                return "stack underflow";
            case 1285:
                return "out of memory";
            default:
                return null;
        }

package android.opengl;

import javax.microedition.khronos.opengles.GL10;

public class GLU {

    private static final float[] sScratch = new float[32];

    public static String gluErrorString(int error) {
        if (error == 0) {
            return "no error";
        }

    }

    public static void gluLookAt(GL10 gl, float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ) {
        float[] scratch = sScratch;
        synchronized (scratch) {
            try {
                Matrix.setLookAtM(scratch, 0, eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
                gl.glMultMatrixf(scratch, 0);
            } catch (Throwable th) {
                th = th;
                throw th;
            }
        }
    }

    public static void gluOrtho2D(GL10 gl, float left, float right, float bottom, float top) {
        gl.glOrthof(left, right, bottom, top, -1.0f, 1.0f);
    }

    public static void gluPerspective(GL10 gl, float fovy, float aspect, float zNear, float zFar) {
        float top = ((float) Math.tan(((double) fovy) * 0.008726646259971648d)) * zNear;
        float bottom = -top;
        gl.glFrustumf(bottom * aspect, top * aspect, bottom, top, zNear, zFar);
    }

    public static int gluProject(float objX, float objY, float objZ, float[] model, int modelOffset, float[] project, int projectOffset, int[] view, int viewOffset, float[] win, int winOffset) {
        float[] scratch = sScratch;
        synchronized (scratch) {
            Matrix.multiplyMM(scratch, 0, project, projectOffset, model, modelOffset);
            scratch[16] = objX;
            scratch[17] = objY;
            scratch[18] = objZ;
            scratch[19] = 1.0f;
            Matrix.multiplyMV(scratch, 20, scratch, 0, scratch, 16);
            float w = scratch[23];
            if (w == 0.0f) {
                return 0;
            }
            float rw = 1.0f / w;
            win[winOffset] = ((float) view[viewOffset]) + (((float) view[viewOffset + 2]) * ((scratch[20] * rw) + 1.0f) * 0.5f);
            win[winOffset + 1] = ((float) view[viewOffset + 1]) + (((float) view[viewOffset + 3]) * ((scratch[21] * rw) + 1.0f) * 0.5f);
            win[winOffset + 2] = ((scratch[22] * rw) + 1.0f) * 0.5f;
            return 1;
        }
    }

    public static int gluUnProject(float winX, float winY, float winZ, float[] model, int modelOffset, float[] project, int projectOffset, int[] view, int viewOffset, float[] obj, int objOffset) {
        float[] scratch = sScratch;
        synchronized (scratch) {
            Matrix.multiplyMM(scratch, 0, project, projectOffset, model, modelOffset);
            if (!Matrix.invertM(scratch, 16, scratch, 0)) {
                return 0;
            }
            scratch[0] = (((winX - ((float) view[viewOffset + 0])) * 2.0f) / ((float) view[viewOffset + 2])) - 1.0f;
            scratch[1] = (((winY - ((float) view[viewOffset + 1])) * 2.0f) / ((float) view[viewOffset + 3])) - 1.0f;
            scratch[2] = (winZ * 2.0f) - 1.0f;
            scratch[3] = 1.0f;
            Matrix.multiplyMV(obj, objOffset, scratch, 16, scratch, 0);
            return 1;
        }
    }
}


try {
                Matrix.setLookAtM(scratch, 0, eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
                gl.glMultMatrixf(scratch, 0);
            } catch (Throwable th) {
                th = th;
                throw th;
            }

package android.opengl;

import javax.microedition.khronos.opengles.GL10;

public class GLU {

    private static final float[] sScratch = new float[32];

    public static String gluErrorString(int error) {
        if (error == 0) {
            return "no error";
        }
        switch(error) {
            case 1280:
                return "invalid enum";
            case 1281:
                return "invalid value";
            case 1282:
                return "invalid operation";
            case 1283:
                return "stack overflow";
            case 1284:
                return "stack underflow";
            case 1285:
                return "out of memory";
            default:
                return null;
        }
    }

    public static void gluLookAt(GL10 gl, float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ) {
        float[] scratch = sScratch;
        synchronized (scratch) {

        }
    }

    public static void gluOrtho2D(GL10 gl, float left, float right, float bottom, float top) {
        gl.glOrthof(left, right, bottom, top, -1.0f, 1.0f);
    }

    public static void gluPerspective(GL10 gl, float fovy, float aspect, float zNear, float zFar) {
        float top = ((float) Math.tan(((double) fovy) * 0.008726646259971648d)) * zNear;
        float bottom = -top;
        gl.glFrustumf(bottom * aspect, top * aspect, bottom, top, zNear, zFar);
    }

    public static int gluProject(float objX, float objY, float objZ, float[] model, int modelOffset, float[] project, int projectOffset, int[] view, int viewOffset, float[] win, int winOffset) {
        float[] scratch = sScratch;
        synchronized (scratch) {
            Matrix.multiplyMM(scratch, 0, project, projectOffset, model, modelOffset);
            scratch[16] = objX;
            scratch[17] = objY;
            scratch[18] = objZ;
            scratch[19] = 1.0f;
            Matrix.multiplyMV(scratch, 20, scratch, 0, scratch, 16);
            float w = scratch[23];
            if (w == 0.0f) {
                return 0;
            }
            float rw = 1.0f / w;
            win[winOffset] = ((float) view[viewOffset]) + (((float) view[viewOffset + 2]) * ((scratch[20] * rw) + 1.0f) * 0.5f);
            win[winOffset + 1] = ((float) view[viewOffset + 1]) + (((float) view[viewOffset + 3]) * ((scratch[21] * rw) + 1.0f) * 0.5f);
            win[winOffset + 2] = ((scratch[22] * rw) + 1.0f) * 0.5f;
            return 1;
        }
    }

    public static int gluUnProject(float winX, float winY, float winZ, float[] model, int modelOffset, float[] project, int projectOffset, int[] view, int viewOffset, float[] obj, int objOffset) {
        float[] scratch = sScratch;
        synchronized (scratch) {
            Matrix.multiplyMM(scratch, 0, project, projectOffset, model, modelOffset);
            if (!Matrix.invertM(scratch, 16, scratch, 0)) {
                return 0;
            }
            scratch[0] = (((winX - ((float) view[viewOffset + 0])) * 2.0f) / ((float) view[viewOffset + 2])) - 1.0f;
            scratch[1] = (((winY - ((float) view[viewOffset + 1])) * 2.0f) / ((float) view[viewOffset + 3])) - 1.0f;
            scratch[2] = (winZ * 2.0f) - 1.0f;
            scratch[3] = 1.0f;
            Matrix.multiplyMV(obj, objOffset, scratch, 16, scratch, 0);
            return 1;
        }
    }
}


public void setM_Product_ID(int M_Product_ID) {
        if (M_Product_ID < 1)
            set_ValueNoCheck(COLUMNNAME_M_Product_ID, null);
        else
            set_ValueNoCheck(COLUMNNAME_M_Product_ID, Integer.valueOf(M_Product_ID));
    }

/**
 * ***************************************************************************
 *  Product: ADempiere ERP & CRM Smart Business Solution                       *
 *  For the text or an alternative of this public license, you may reach us    *
 *  or via example@nnthink.com or http://example.com         *
 * ***************************************************************************
 */
/**
 * Generated Model - DO NOT CHANGE
 */
package org.compiere.model;

import java.math.BigDecimal;
import java.sql.ResultSet;
import java.util.Properties;
import org.compiere.util.Env;
import org.compiere.util.KeyNamePair;

/**
 * Generated Model for M_DemandLine
 *  @author Adempiere (generated)
 *  @version Release 3.9.2 - $Id$
 */
public class X_M_DemandLine extends PO implements I_M_DemandLine, I_Persistent {

    private static final long serialVersionUID = 20191120L;

    /**
     * Standard Constructor
     */
    public X_M_DemandLine(Properties ctx, int M_DemandLine_ID, String trxName) {
        super(ctx, M_DemandLine_ID, trxName);
    }

    /**
     * Load Constructor
     */
    public X_M_DemandLine(Properties ctx, ResultSet rs, String trxName) {
        super(ctx, rs, trxName);
    }

    protected int get_AccessLevel() {
        return accessLevel.intValue();
    }

    /**
     * Load Meta Data
     */
    protected POInfo initPO(Properties ctx) {
        POInfo poi = POInfo.getPOInfo(ctx, Table_ID, get_TrxName());
        return poi;
    }

    public String toString() {
        StringBuffer sb = new StringBuffer("X_M_DemandLine[").append(get_ID()).append("]");
        return sb.toString();
    }

    public org.compiere.model.I_C_Period getC_Period() throws RuntimeException {
        return (org.compiere.model.I_C_Period) MTable.get(getCtx(), org.compiere.model.I_C_Period.Table_Name).getPO(getC_Period_ID(), get_TrxName());
    }

    /**
     *  Set Period.
     * 		@param C_Period_ID
     * 		Period of the Calendar
     */
    public void setC_Period_ID(int C_Period_ID) {
        if (C_Period_ID < 1)
            set_ValueNoCheck(COLUMNNAME_C_Period_ID, null);
        else
            set_ValueNoCheck(COLUMNNAME_C_Period_ID, Integer.valueOf(C_Period_ID));
    }

    /**
     *  Get Period.
     * 		@return Period of the Calendar
     */
    public int getC_Period_ID() {
        Integer ii = (Integer) get_Value(COLUMNNAME_C_Period_ID);
        if (ii == null)
            return 0;
        return ii.intValue();
    }

    /**
     * Get Record ID/ColumnName
     *        @return ID/ColumnName pair
     */
    public KeyNamePair getKeyNamePair() {
        return new KeyNamePair(get_ID(), String.valueOf(getC_Period_ID()));
    }

    /**
     *  Set Demand Line.
     * 		@param M_DemandLine_ID
     * 		Material Demand Line
     */
    public void setM_DemandLine_ID(int M_DemandLine_ID) {
        if (M_DemandLine_ID < 1)
            set_ValueNoCheck(COLUMNNAME_M_DemandLine_ID, null);
        else
            set_ValueNoCheck(COLUMNNAME_M_DemandLine_ID, Integer.valueOf(M_DemandLine_ID));
    }

    /**
     *  Get Demand Line.
     * 		@return Material Demand Line
     */
    public int getM_DemandLine_ID() {
        Integer ii = (Integer) get_Value(COLUMNNAME_M_DemandLine_ID);
        if (ii == null)
            return 0;
        return ii.intValue();
    }

    public org.compiere.model.I_M_Demand getM_Demand() throws RuntimeException {
        return (org.compiere.model.I_M_Demand) MTable.get(getCtx(), org.compiere.model.I_M_Demand.Table_Name).getPO(getM_Demand_ID(), get_TrxName());
    }

    /**
     *  Set Demand.
     * 		@param M_Demand_ID
     * 		Material Demand
     */
    public void setM_Demand_ID(int M_Demand_ID) {
        if (M_Demand_ID < 1)
            set_ValueNoCheck(COLUMNNAME_M_Demand_ID, null);
        else
            set_ValueNoCheck(COLUMNNAME_M_Demand_ID, Integer.valueOf(M_Demand_ID));
    }

    /**
     *  Get Demand.
     * 		@return Material Demand
     */
    public int getM_Demand_ID() {
        Integer ii = (Integer) get_Value(COLUMNNAME_M_Demand_ID);
        if (ii == null)
            return 0;
        return ii.intValue();
    }

    public org.compiere.model.I_M_Product getM_Product() throws RuntimeException {
        return (org.compiere.model.I_M_Product) MTable.get(getCtx(), org.compiere.model.I_M_Product.Table_Name).getPO(getM_Product_ID(), get_TrxName());
    }

    /**
     *  Set Product.
     * 		@param M_Product_ID
     * 		Product, Service, Item
     */

    /**
     *  Get Product.
     * 		@return Product, Service, Item
     */
    public int getM_Product_ID() {
        Integer ii = (Integer) get_Value(COLUMNNAME_M_Product_ID);
        if (ii == null)
            return 0;
        return ii.intValue();
    }

    /**
     *  Set Quantity.
     * 		@param Qty
     * 		Quantity
     */
    public void setQty(BigDecimal Qty) {
        set_Value(COLUMNNAME_Qty, Qty);
    }

    /**
     *  Get Quantity.
     * 		@return Quantity
     */
    public BigDecimal getQty() {
        BigDecimal bd = (BigDecimal) get_Value(COLUMNNAME_Qty);
        if (bd == null)
            return Env.ZERO;
        return bd;
    }

    /**
     *  Set Calculated Quantity.
     * 		@param QtyCalculated
     * 		Calculated Quantity
     */
    public void setQtyCalculated(BigDecimal QtyCalculated) {
        set_Value(COLUMNNAME_QtyCalculated, QtyCalculated);
    }

    /**
     *  Get Calculated Quantity.
     * 		@return Calculated Quantity
     */
    public BigDecimal getQtyCalculated() {
        BigDecimal bd = (BigDecimal) get_Value(COLUMNNAME_QtyCalculated);
        if (bd == null)
            return Env.ZERO;
        return bd;
    }

    /**
     *  Set Immutable Universally Unique Identifier.
     * 		@param UUID
     * 		Immutable Universally Unique Identifier
     */
    public void setUUID(String UUID) {
        set_Value(COLUMNNAME_UUID, UUID);
    }

    /**
     *  Get Immutable Universally Unique Identifier.
     * 		@return Immutable Universally Unique Identifier
     */
    public String getUUID() {
        return (String) get_Value(COLUMNNAME_UUID);
    }
}


try {
            return this.isValidFloat(this.decimalFormat.parse(value).floatValue());
        } catch (ParseException e) {
            return false;
        }

package net.ilexiconn.llibrary.server.property.wrapper;

import net.ilexiconn.llibrary.server.property.IDoubleProperty;
import net.ilexiconn.llibrary.server.property.IFloatProperty;
import net.ilexiconn.llibrary.server.property.IIntProperty;
import net.ilexiconn.llibrary.server.property.IStringProperty;
import java.text.DecimalFormat;
import java.text.ParseException;

public abstract class FloatPropertyWrapperBase<T extends IFloatProperty> implements IFloatProperty, IDoubleProperty, IIntProperty, IStringProperty {

    protected final T delegateFor;

    protected final DecimalFormat decimalFormat;

    public FloatPropertyWrapperBase(T delegateFor, DecimalFormat decimalFormat) {
        this.delegateFor = delegateFor;
        this.decimalFormat = decimalFormat;
    }

    @Override
    public float getFloat() {
        return this.delegateFor.getFloat();
    }

    @Override
    public void setFloat(float value) {
        this.delegateFor.setFloat(value);
    }

    @Override
    public boolean isValidFloat(float value) {
        return this.delegateFor.isValidFloat(value);
    }

    @Override
    public double getDouble() {
        return (double) this.getFloat();
    }

    @Override
    public void setDouble(double value) {
        this.setFloat((float) value);
    }

    @Override
    public boolean isValidDouble(double value) {
        return this.isValidFloat((float) value);
    }

    @Override
    public int getInt() {
        return Math.round(this.getFloat());
    }

    @Override
    public void setInt(int value) {
        this.setFloat(value);
    }

    @Override
    public boolean isValidInt(int value) {
        return this.isValidFloat(value);
    }

    @Override
    public String getString() {
        return this.decimalFormat.format(this.getFloat());
    }

    @Override
    public void setString(String value) {
        try {
            this.setFloat(this.decimalFormat.parse(value).floatValue());
        } catch (ParseException e) {
        }
    }

    @Override
    public boolean isValidString(String value) {


try {
            // Register BaseRenderEngine as an Implementation
            // of RenderEngine
            dc.registerComponentImplementation(RenderEngine.class, BaseRenderEngine.class);
        } catch (Exception e) {
            log.error("Could not register component.");
        }

/*
 * This file is part of "SnipSnap Radeox Rendering Engine".
 *
 * All Rights Reserved.
 *
 * Please visit http://example.com for updates and contact.
 *
 * --LICENSE NOTICE--
 */
package examples;

import java.util.Locale;
import java.util.Enumeration;
import java.util.ResourceBundle;
import lombok.extern.slf4j.Slf4j;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.picocontainer.PicoContainer;
import org.picocontainer.defaults.DefaultPicoContainer;
import org.radeox.api.engine.RenderEngine;
import org.radeox.api.engine.context.InitialRenderContext;
import org.radeox.api.engine.context.RenderContext;
import org.radeox.engine.BaseRenderEngine;
import org.radeox.engine.context.BaseRenderContext;
import org.radeox.engine.context.BaseInitialRenderContext;

/**
 * Example which shows howto use Radeox with PicoContainer
 *
 * @author Stephan J. Schmidt
 * @version $Id$
 */
@Slf4j
public class PicoContainerExample extends RadeoxTestSupport {

    public PicoContainerExample(String name) {
        super(name);
    }

    protected void setUp() throws Exception {
        super.setUp();
    }

    public static Test suite() {
        return new TestSuite(PicoContainerExample.class);
    }

    public void testPicoContainer() {
        DefaultPicoContainer dc = new DefaultPicoContainer();

// now only work with container
        PicoContainer container = dc;
        // Only ask for RenderEngine, we automatically
        // get an available object
        // that implements RenderEngine
        RenderEngine engine = (RenderEngine) container.getComponentInstance(RenderEngine.class);
        RenderContext context = new BaseRenderContext();
        String result = engine.render("__SnipSnap__", context);
        assertEquals("Rendered with PicoContainer.", "SnipSnap", result);
    }

    public void testPicoWithInitialRenderContext() {
        DefaultPicoContainer dc = new DefaultPicoContainer();
        try {
            InitialRenderContext initialContext = new BaseInitialRenderContext();
            initialContext.set(RenderContext.OUTPUT_LOCALE, new Locale("mywiki", "mywiki"));
            dc.registerComponentInstance(InitialRenderContext.class, initialContext);
            dc.registerComponentImplementation(RenderEngine.class, BaseRenderEngine.class);
        } catch (Exception e) {
            log.error("Could not register component.");
        }
        // now only work with container
        PicoContainer container = dc;
        // Only ask for RenderEngine, we automatically
        // get an available object
        // that implements RenderEngine
        RenderEngine engine = (RenderEngine) container.getComponentInstance(RenderEngine.class);
        assertNotNull("Component found.", engine);
        RenderContext context = new BaseRenderContext();
        String result = engine.render("__SnipSnap__", context);
        assertEquals("Rendered with PicoContainer and otherwiki Locale.", "SnipSnap", result);
    }
}


public static void writeToFile(InputStream in, File target) throws IOException {
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(target));
        int count;
        byte[] data = new byte[BUFFER_SIZE];
        while ((count = in.read(data, 0, BUFFER_SIZE)) != -1) {
            bos.write(data, 0, count);
        }
        bos.close();
    }

package com.safframework.bytekit.utils;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.FileChannel;

/**
 * Created by tony on 2017/10/16.
 */
public class IOUtils {

    private final static int BUFFER_SIZE = 0x400;

    /**
     * 从输入流读取数据
     * @param inStream
     * @return
     * @throws Exception
     */
    public static byte[] readInputStream(InputStream inStream) throws IOException {
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[BUFFER_SIZE];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            if (len != 0) {
                outSteam.write(buffer, 0, len);
            }
        }
        outSteam.close();
        inStream.close();
        return outSteam.toByteArray();
    }

    /**
     * 从输入流读取数据
     * @param inStream
     * @return
     * @throws Exception
     */
    public static String inputStream2String(InputStream inStream) throws IOException {
        return new String(readInputStream(inStream), "UTF-8");
    }

    /**
     * @param is
     * @param os
     * @throws IOException
     */
    public static void copyStream(InputStream is, OutputStream os) throws IOException {
        byte[] bytes = new byte[BUFFER_SIZE];
        for (; ; ) {
            int count = is.read(bytes, 0, BUFFER_SIZE);
            if (count == -1)
                break;
            os.write(bytes, 0, count);
        }
    }

    /**
     * 文件拷贝
     * @param src source {@link File}
     * @param dst destination {@link File}
     * @throws IOException
     */
    public static void copyFile(File src, File dst) throws IOException {
        FileInputStream in = new FileInputStream(src);
        FileOutputStream out = new FileOutputStream(dst);
        FileChannel inChannel = in.getChannel();
        FileChannel outChannel = out.getChannel();
        try {
            inChannel.transferTo(0, inChannel.size(), outChannel);
        } finally {
            if (inChannel != null) {
                inChannel.close();
            }
            if (outChannel != null) {
                outChannel.close();
            }
        }
        in.close();
        out.close();
    }

    /**
     * 将流写入文件
     * @param in
     * @param target
     * @throws IOException
     */

    /**
     * 安全关闭io流
     * @param closeable
     */
    public static void closeQuietly(Closeable closeable) {
        if (closeable != null) {
            try {
                closeable.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 安全关闭io流
     * @param closeables
     */
    public static void closeQuietly(Closeable... closeables) {
        if (Preconditions.isNotBlank(closeables)) {
            for (Closeable closeable : closeables) {
                // 系统先匹配确定参数的方法，没有再去匹配调用不定项参数的方法
                closeQuietly(closeable);
            }
        }
    }
}


for (; ; ) {
            int count = is.read(bytes, 0, BUFFER_SIZE);
            if (count == -1)
                break;
            os.write(bytes, 0, count);
        }

package com.safframework.bytekit.utils;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.FileChannel;

/**
 * Created by tony on 2017/10/16.
 */
public class IOUtils {

    private final static int BUFFER_SIZE = 0x400;

    /**
     * 从输入流读取数据
     * @param inStream
     * @return
     * @throws Exception
     */
    public static byte[] readInputStream(InputStream inStream) throws IOException {
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[BUFFER_SIZE];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            if (len != 0) {
                outSteam.write(buffer, 0, len);
            }
        }
        outSteam.close();
        inStream.close();
        return outSteam.toByteArray();
    }

    /**
     * 从输入流读取数据
     * @param inStream
     * @return
     * @throws Exception
     */
    public static String inputStream2String(InputStream inStream) throws IOException {
        return new String(readInputStream(inStream), "UTF-8");
    }

    /**
     * @param is
     * @param os
     * @throws IOException
     */
    public static void copyStream(InputStream is, OutputStream os) throws IOException {
        byte[] bytes = new byte[BUFFER_SIZE];

    }

    /**
     * 文件拷贝
     * @param src source {@link File}
     * @param dst destination {@link File}
     * @throws IOException
     */
    public static void copyFile(File src, File dst) throws IOException {
        FileInputStream in = new FileInputStream(src);
        FileOutputStream out = new FileOutputStream(dst);
        FileChannel inChannel = in.getChannel();
        FileChannel outChannel = out.getChannel();
        try {
            inChannel.transferTo(0, inChannel.size(), outChannel);
        } finally {
            if (inChannel != null) {
                inChannel.close();
            }
            if (outChannel != null) {
                outChannel.close();
            }
        }
        in.close();
        out.close();
    }

    /**
     * 将流写入文件
     * @param in
     * @param target
     * @throws IOException
     */
    public static void writeToFile(InputStream in, File target) throws IOException {
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(target));
        int count;
        byte[] data = new byte[BUFFER_SIZE];
        while ((count = in.read(data, 0, BUFFER_SIZE)) != -1) {
            bos.write(data, 0, count);
        }
        bos.close();
    }

    /**
     * 安全关闭io流
     * @param closeable
     */
    public static void closeQuietly(Closeable closeable) {
        if (closeable != null) {
            try {
                closeable.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 安全关闭io流
     * @param closeables
     */
    public static void closeQuietly(Closeable... closeables) {
        if (Preconditions.isNotBlank(closeables)) {
            for (Closeable closeable : closeables) {
                // 系统先匹配确定参数的方法，没有再去匹配调用不定项参数的方法
                closeQuietly(closeable);
            }
        }
    }
}


while ((count = in.read(data, 0, BUFFER_SIZE)) != -1) {
            bos.write(data, 0, count);
        }

package com.safframework.bytekit.utils;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.FileChannel;

/**
 * Created by tony on 2017/10/16.
 */
public class IOUtils {

    private final static int BUFFER_SIZE = 0x400;

    /**
     * 从输入流读取数据
     * @param inStream
     * @return
     * @throws Exception
     */
    public static byte[] readInputStream(InputStream inStream) throws IOException {
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[BUFFER_SIZE];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            if (len != 0) {
                outSteam.write(buffer, 0, len);
            }
        }
        outSteam.close();
        inStream.close();
        return outSteam.toByteArray();
    }

    /**
     * 从输入流读取数据
     * @param inStream
     * @return
     * @throws Exception
     */
    public static String inputStream2String(InputStream inStream) throws IOException {
        return new String(readInputStream(inStream), "UTF-8");
    }

    /**
     * @param is
     * @param os
     * @throws IOException
     */
    public static void copyStream(InputStream is, OutputStream os) throws IOException {
        byte[] bytes = new byte[BUFFER_SIZE];
        for (; ; ) {
            int count = is.read(bytes, 0, BUFFER_SIZE);
            if (count == -1)
                break;
            os.write(bytes, 0, count);
        }
    }

    /**
     * 文件拷贝
     * @param src source {@link File}
     * @param dst destination {@link File}
     * @throws IOException
     */
    public static void copyFile(File src, File dst) throws IOException {
        FileInputStream in = new FileInputStream(src);
        FileOutputStream out = new FileOutputStream(dst);
        FileChannel inChannel = in.getChannel();
        FileChannel outChannel = out.getChannel();
        try {
            inChannel.transferTo(0, inChannel.size(), outChannel);
        } finally {
            if (inChannel != null) {
                inChannel.close();
            }
            if (outChannel != null) {
                outChannel.close();
            }
        }
        in.close();
        out.close();
    }

    /**
     * 将流写入文件
     * @param in
     * @param target
     * @throws IOException
     */
    public static void writeToFile(InputStream in, File target) throws IOException {
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(target));
        int count;
        byte[] data = new byte[BUFFER_SIZE];

        bos.close();
    }

    /**
     * 安全关闭io流
     * @param closeable
     */
    public static void closeQuietly(Closeable closeable) {
        if (closeable != null) {
            try {
                closeable.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 安全关闭io流
     * @param closeables
     */
    public static void closeQuietly(Closeable... closeables) {
        if (Preconditions.isNotBlank(closeables)) {
            for (Closeable closeable : closeables) {
                // 系统先匹配确定参数的方法，没有再去匹配调用不定项参数的方法
                closeQuietly(closeable);
            }
        }
    }
}


try {
                closeable.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

package com.safframework.bytekit.utils;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.FileChannel;

/**
 * Created by tony on 2017/10/16.
 */
public class IOUtils {

    private final static int BUFFER_SIZE = 0x400;

    /**
     * 从输入流读取数据
     * @param inStream
     * @return
     * @throws Exception
     */
    public static byte[] readInputStream(InputStream inStream) throws IOException {
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[BUFFER_SIZE];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            if (len != 0) {
                outSteam.write(buffer, 0, len);
            }
        }
        outSteam.close();
        inStream.close();
        return outSteam.toByteArray();
    }

    /**
     * 从输入流读取数据
     * @param inStream
     * @return
     * @throws Exception
     */
    public static String inputStream2String(InputStream inStream) throws IOException {
        return new String(readInputStream(inStream), "UTF-8");
    }

    /**
     * @param is
     * @param os
     * @throws IOException
     */
    public static void copyStream(InputStream is, OutputStream os) throws IOException {
        byte[] bytes = new byte[BUFFER_SIZE];
        for (; ; ) {
            int count = is.read(bytes, 0, BUFFER_SIZE);
            if (count == -1)
                break;
            os.write(bytes, 0, count);
        }
    }

    /**
     * 文件拷贝
     * @param src source {@link File}
     * @param dst destination {@link File}
     * @throws IOException
     */
    public static void copyFile(File src, File dst) throws IOException {
        FileInputStream in = new FileInputStream(src);
        FileOutputStream out = new FileOutputStream(dst);
        FileChannel inChannel = in.getChannel();
        FileChannel outChannel = out.getChannel();
        try {
            inChannel.transferTo(0, inChannel.size(), outChannel);
        } finally {
            if (inChannel != null) {
                inChannel.close();
            }
            if (outChannel != null) {
                outChannel.close();
            }
        }
        in.close();
        out.close();
    }

    /**
     * 将流写入文件
     * @param in
     * @param target
     * @throws IOException
     */
    public static void writeToFile(InputStream in, File target) throws IOException {
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(target));
        int count;
        byte[] data = new byte[BUFFER_SIZE];
        while ((count = in.read(data, 0, BUFFER_SIZE)) != -1) {
            bos.write(data, 0, count);
        }
        bos.close();
    }

    /**
     * 安全关闭io流
     * @param closeable
     */
    public static void closeQuietly(Closeable closeable) {
        if (closeable != null) {

        }
    }

    /**
     * 安全关闭io流
     * @param closeables
     */
    public static void closeQuietly(Closeable... closeables) {
        if (Preconditions.isNotBlank(closeables)) {
            for (Closeable closeable : closeables) {
                // 系统先匹配确定参数的方法，没有再去匹配调用不定项参数的方法
                closeQuietly(closeable);
            }
        }
    }
}


@Override
    public void call(final SearchLatticeNode<NodeType, EdgeType> node, final Collection<Extension<NodeType, EdgeType>> extensions) {
        final int size = node.toHPFragment().toHPGraph().getEdgeCount();
        if (size < min) {
            node.store(false);
        }
        if (size > max) {
            node.store(false);
        } else {
            callNext(node, extensions);
        }
    }

/**
 * created May 25, 2006
 *
 * @by Marc Woerlein (example@nnthink.com)
 *
 * This file is part of parsemis.
 *
 * Licence:
 *   See the LICENSE file in the project's top-level directory for details.
 */
package de.parsemis.miner.chain;

import java.util.Collection;

/**
 * This class implements the general pruning of fragments according to their
 * edge count.
 *
 * @author Marc Woerlein (woerlein@informatik.uni-erlangen.de)
 *
 * @param <NodeType>
 *            the type of the node labels (will be hashed and checked with
 *            .equals(..))
 * @param <EdgeType>
 *            the type of the edge labels (will be hashed and checked with
 *            .equals(..))
 */
public class EdgeCountStep<NodeType, EdgeType> extends MiningStep<NodeType, EdgeType> {

    private final int min, max;

    /**
     * creates a new node count pruning
     *
     * @param next
     * @param min
     *            the minimal number of nodes a fragment shall have to be
     *            reported
     * @param max
     *            the maximal number of nodes a fragment shall have to be
     *            reported
     */
    public EdgeCountStep(final MiningStep<NodeType, EdgeType> next, final int min, final int max) {
        super(next);
        this.min = min;
        this.max = max;
    }

    /*
	 * (non-Javadoc)
	 *
	 * @see de.parsemis.miner.MiningStep#call(de.parsemis.miner.SearchLatticeNode,
	 *      java.util.Collection)
	 */


@SideOnly(Side.CLIENT)
    @Override
    public void registerModel(Item item, IModelManager manager) {
        manager.registerItemModel(item, new GermlingMeshDefinition());
        for (IAllele allele : AlleleManager.alleleRegistry.getRegisteredAlleles().values()) {
            if (allele instanceof IAlleleTreeSpecies) {
                ((IAlleleTreeSpecies) allele).registerModels(item, manager, type);
            }
        }
    }

/**
 * ****************************************************************************
 *
 *  Various Contributors including, but not limited to:
 *  SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges
 * ****************************************************************************
 */
package forestry.arboriculture.items;

import javax.annotation.Nullable;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.ItemMeshDefinition;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import forestry.api.arboriculture.EnumGermlingType;
import forestry.api.arboriculture.IAlleleTreeSpecies;
import forestry.api.arboriculture.ITree;
import forestry.api.arboriculture.TreeManager;
import forestry.api.core.IModelManager;
import forestry.api.core.Tabs;
import forestry.api.genetics.AlleleManager;
import forestry.api.genetics.IAllele;
import forestry.api.genetics.IAlleleSpecies;
import forestry.api.genetics.ICheckPollinatable;
import forestry.api.genetics.IIndividual;
import forestry.api.genetics.IPollinatable;
import forestry.api.recipes.IVariableFermentable;
import forestry.arboriculture.genetics.TreeDefinition;
import forestry.arboriculture.genetics.TreeGenome;
import forestry.core.config.Config;
import forestry.core.genetics.ItemGE;
import forestry.core.items.IColoredItem;
import forestry.core.network.packets.PacketFXSignal;
import forestry.core.utils.GeneticsUtil;
import forestry.core.utils.NetworkUtil;
import forestry.core.utils.Translator;

public class ItemGermlingGE extends ItemGE implements IVariableFermentable, IColoredItem {

    private final EnumGermlingType type;

    public ItemGermlingGE(EnumGermlingType type) {
        super(Tabs.tabArboriculture);
        this.type = type;
    }

    @Override
    @Nullable
    public ITree getIndividual(ItemStack itemstack) {
        return TreeManager.treeRoot.getMember(itemstack);
    }

    @Override
    protected IAlleleTreeSpecies getSpecies(ItemStack itemStack) {
        return TreeGenome.getSpecies(itemStack);
    }

    @Override
    public String getItemStackDisplayName(ItemStack itemstack) {
        if (itemstack.getTagCompound() == null) {
            return "Unknown";
        }
        IAlleleSpecies species = getSpecies(itemstack);
        String customTreeKey = "for.trees.custom." + type.getName() + "." + species.getUnlocalizedName().replace("for.trees.species.", "");
        if (Translator.canTranslateToLocal(customTreeKey)) {
            return Translator.translateToLocal(customTreeKey);
        }
        String typeString = Translator.translateToLocal("for.trees.grammar." + type.getName() + ".type");
        return Translator.translateToLocal("for.trees.grammar." + type.getName()).replaceAll("%SPECIES", species.getAlleleName()).replaceAll("%TYPE", typeString);
    }

    @Override
    public void getSubItems(CreativeTabs tab, NonNullList<ItemStack> subItems) {
        if (this.isInCreativeTab(tab)) {
            addCreativeItems(subItems, true);
        }
    }

    public void addCreativeItems(NonNullList<ItemStack> subItems, boolean hideSecrets) {
        for (IIndividual individual : TreeManager.treeRoot.getIndividualTemplates()) {
            // Don't show secrets unless ordered to.
            if (hideSecrets && individual.isSecret() && !Config.isDebug) {
                continue;
            }
            subItems.add(TreeManager.treeRoot.getMemberStack(individual, type));
        }
    }

    @Override
    @SideOnly(Side.CLIENT)
    public int getColorFromItemstack(ItemStack itemstack, int renderPass) {
        return TreeGenome.getSpecies(itemstack).getGermlingColour(type, renderPass);
    }

    /* MODELS */

    @SideOnly(Side.CLIENT)
    private class GermlingMeshDefinition implements ItemMeshDefinition {

        @Override
        public ModelResourceLocation getModelLocation(ItemStack stack) {
            IAlleleTreeSpecies treeSpecies;
            if (!stack.hasTagCompound()) {
                treeSpecies = TreeDefinition.Oak.getGenome().getPrimary();
            } else {
                treeSpecies = getSpecies(stack);
            }
            return treeSpecies.getGermlingModel(type);
        }
    }

    @Override
    public ActionResult<ItemStack> onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand handIn) {
        RayTraceResult raytraceresult = this.rayTrace(worldIn, playerIn, true);
        ItemStack itemStack = playerIn.getHeldItem(handIn);
        if (raytraceresult != null && raytraceresult.typeOfHit == RayTraceResult.Type.BLOCK) {
            BlockPos pos = raytraceresult.getBlockPos();
            ITree tree = TreeManager.treeRoot.getMember(itemStack);
            if (tree != null) {
                if (type == EnumGermlingType.SAPLING) {
                    return onItemRightClickSapling(itemStack, worldIn, playerIn, pos, tree);
                } else if (type == EnumGermlingType.POLLEN) {
                    return onItemRightClickPollen(itemStack, worldIn, playerIn, pos, tree);
                }
            }
        }
        return new ActionResult<>(EnumActionResult.PASS, itemStack);
    }

    private static ActionResult<ItemStack> onItemRightClickPollen(ItemStack itemStackIn, World worldIn, EntityPlayer playerIn, BlockPos pos, ITree tree) {
        ICheckPollinatable checkPollinatable = GeneticsUtil.getCheckPollinatable(worldIn, pos);
        if (checkPollinatable == null || !checkPollinatable.canMateWith(tree)) {
            return new ActionResult<>(EnumActionResult.FAIL, itemStackIn);
        }
        IPollinatable pollinatable = GeneticsUtil.getOrCreatePollinatable(playerIn.getGameProfile(), worldIn, pos, true);
        if (pollinatable == null || !pollinatable.canMateWith(tree)) {
            return new ActionResult<>(EnumActionResult.FAIL, itemStackIn);
        }
        if (worldIn.isRemote) {
            return new ActionResult<>(EnumActionResult.SUCCESS, itemStackIn);
        } else {
            pollinatable.mateWith(tree);
            IBlockState blockState = worldIn.getBlockState(pos);
            PacketFXSignal packet = new PacketFXSignal(PacketFXSignal.VisualFXType.BLOCK_BREAK, PacketFXSignal.SoundFXType.BLOCK_BREAK, pos, blockState);
            NetworkUtil.sendNetworkPacket(packet, pos, worldIn);
            if (!playerIn.capabilities.isCreativeMode) {
                itemStackIn.shrink(1);
            }
            return new ActionResult<>(EnumActionResult.SUCCESS, itemStackIn);
        }
    }

    private static ActionResult<ItemStack> onItemRightClickSapling(ItemStack itemStackIn, World worldIn, EntityPlayer playerIn, BlockPos pos, ITree tree) {
        // x, y, z are the coordinates of the block "hit", can thus either be the soil or tall grass, etc.
        IBlockState hitBlock = worldIn.getBlockState(pos);
        if (!hitBlock.getBlock().isReplaceable(worldIn, pos)) {
            if (!worldIn.isAirBlock(pos.up())) {
                return new ActionResult<>(EnumActionResult.FAIL, itemStackIn);
            }
            pos = pos.up();
        }
        if (tree.canStay(worldIn, pos)) {
            if (TreeManager.treeRoot.plantSapling(worldIn, tree, playerIn.getGameProfile(), pos)) {
                if (!playerIn.capabilities.isCreativeMode) {
                    itemStackIn.shrink(1);
                }
                return new ActionResult<>(EnumActionResult.SUCCESS, itemStackIn);
            }
        }
        return new ActionResult<>(EnumActionResult.FAIL, itemStackIn);
    }

    @Override
    public float getFermentationModifier(ItemStack itemstack) {
        itemstack = GeneticsUtil.convertToGeneticEquivalent(itemstack);
        ITree tree = TreeManager.treeRoot.getMember(itemstack);
        if (tree == null) {
            return 1.0f;
        }
        return tree.getGenome().getSappiness() * 10;
    }

    @Override
    public int getItemBurnTime(ItemStack itemStack) {
        return 100;
    }
}


while (requestedDateTime.compareTo(subscriptionStartDate) < 0) {
            requestedDateTime = requestedDateTime.plusMonths(1);
        }

package org.killbill.billing.subscription.api.svcs;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.annotation.Nullable;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.killbill.billing.ErrorCode;
import org.killbill.billing.ObjectType;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.catalog.api.BillingActionPolicy;
import org.killbill.billing.catalog.api.CatalogApiException;
import org.killbill.billing.catalog.api.Plan;
import org.killbill.billing.catalog.api.PlanPhasePriceOverridesWithCallContext;
import org.killbill.billing.catalog.api.Product;
import org.killbill.billing.catalog.api.ProductCategory;
import org.killbill.billing.catalog.api.StaticCatalog;
import org.killbill.billing.catalog.api.VersionedCatalog;
import org.killbill.billing.entitlement.api.Entitlement.EntitlementState;
import org.killbill.billing.entitlement.api.EntitlementAOStatusDryRun;
import org.killbill.billing.entitlement.api.EntitlementAOStatusDryRun.DryRunChangeReason;
import org.killbill.billing.entitlement.api.EntitlementSpecifier;
import org.killbill.billing.events.EffectiveSubscriptionInternalEvent;
import org.killbill.billing.invoice.api.DryRunArguments;
import org.killbill.billing.subscription.api.SubscriptionBase;
import org.killbill.billing.subscription.api.SubscriptionBaseApiService;
import org.killbill.billing.subscription.api.SubscriptionBaseInternalApi;
import org.killbill.billing.subscription.api.SubscriptionBaseWithAddOns;
import org.killbill.billing.subscription.api.SubscriptionBaseWithAddOnsSpecifier;
import org.killbill.billing.subscription.api.user.DefaultEffectiveSubscriptionEvent;
import org.killbill.billing.subscription.api.user.DefaultSubscriptionBase;
import org.killbill.billing.subscription.api.user.DefaultSubscriptionBaseBundle;
import org.killbill.billing.subscription.api.user.DefaultSubscriptionStatusDryRun;
import org.killbill.billing.subscription.api.user.SubscriptionBaseApiException;
import org.killbill.billing.subscription.api.user.SubscriptionBaseBundle;
import org.killbill.billing.subscription.api.user.SubscriptionBaseTransition;
import org.killbill.billing.subscription.api.user.SubscriptionBaseTransitionData;
import org.killbill.billing.subscription.api.user.SubscriptionBillingEvent;
import org.killbill.billing.subscription.api.user.SubscriptionBuilder;
import org.killbill.billing.subscription.catalog.DefaultSubscriptionCatalogApi;
import org.killbill.billing.subscription.catalog.SubscriptionCatalog;
import org.killbill.billing.subscription.catalog.SubscriptionCatalogApi;
import org.killbill.billing.subscription.engine.addon.AddonUtils;
import org.killbill.billing.subscription.engine.dao.SubscriptionDao;
import org.killbill.billing.subscription.engine.dao.model.SubscriptionBundleModelDao;
import org.killbill.billing.subscription.events.SubscriptionBaseEvent;
import org.killbill.billing.subscription.events.bcd.BCDEvent;
import org.killbill.billing.subscription.events.bcd.BCDEventData;
import org.killbill.billing.util.api.AuditLevel;
import org.killbill.billing.util.audit.AuditLogWithHistory;
import org.killbill.billing.util.cache.AccountIdFromBundleIdCacheLoader;
import org.killbill.billing.util.cache.BundleIdFromSubscriptionIdCacheLoader;
import org.killbill.billing.util.cache.Cachable.CacheType;
import org.killbill.billing.util.cache.CacheController;
import org.killbill.billing.util.cache.CacheControllerDispatcher;
import org.killbill.billing.util.cache.CacheLoaderArgument;
import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.callcontext.TenantContext;
import org.killbill.billing.util.entity.Entity;
import org.killbill.billing.util.entity.Pagination;
import org.killbill.billing.util.entity.dao.DefaultPaginationHelper.SourcePaginationBuilder;
import org.killbill.clock.Clock;
import org.killbill.clock.DefaultClock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.inject.Inject;
import static org.killbill.billing.util.entity.dao.DefaultPaginationHelper.getEntityPaginationNoException;

public class DefaultSubscriptionInternalApi extends DefaultSubscriptionBaseCreateApi implements SubscriptionBaseInternalApi {

    private static final Logger log = LoggerFactory.getLogger(DefaultSubscriptionInternalApi.class);

    private final AddonUtils addonUtils;

    private final InternalCallContextFactory internalCallContextFactory;

    private final SubscriptionCatalogApi subscriptionCatalogApi;

    private final CacheController<UUID, UUID> accountIdCacheController;

    private final CacheController<UUID, UUID> bundleIdCacheController;

    public static final Comparator<SubscriptionBase> SUBSCRIPTIONS_COMPARATOR = new Comparator<SubscriptionBase>() {

        @Override
        public int compare(final SubscriptionBase o1, final SubscriptionBase o2) {
            if (o1.getCategory() == ProductCategory.BASE) {
                return -1;
            } else if (o2.getCategory() == ProductCategory.BASE) {
                return 1;
            } else {
                return ((DefaultSubscriptionBase) o1).getAlignStartDate().compareTo(((DefaultSubscriptionBase) o2).getAlignStartDate());
            }
        }
    };

    @Inject
    public DefaultSubscriptionInternalApi(final SubscriptionDao dao, final SubscriptionBaseApiService apiService, final Clock clock, final SubscriptionCatalogApi subscriptionCatalogApi, final AddonUtils addonUtils, final CacheControllerDispatcher cacheControllerDispatcher, final InternalCallContextFactory internalCallContextFactory) {
        super(dao, apiService, clock);
        this.addonUtils = addonUtils;
        this.internalCallContextFactory = internalCallContextFactory;
        this.subscriptionCatalogApi = subscriptionCatalogApi;
        this.accountIdCacheController = cacheControllerDispatcher.getCacheController(CacheType.ACCOUNT_ID_FROM_BUNDLE_ID);
        this.bundleIdCacheController = cacheControllerDispatcher.getCacheController(CacheType.BUNDLE_ID_FROM_SUBSCRIPTION_ID);
    }

    @Override
    public List<SubscriptionBaseWithAddOns> createBaseSubscriptionsWithAddOns(final VersionedCatalog publicCatalog, final Iterable<SubscriptionBaseWithAddOnsSpecifier> subscriptionWithAddOnsSpecifiers, final boolean renameCancelledBundleIfExist, final InternalCallContext context) throws SubscriptionBaseApiException {
        try {
            final SubscriptionCatalog catalog = DefaultSubscriptionCatalogApi.wrapCatalog(publicCatalog, clock);
            final CallContext callContext = internalCallContextFactory.createCallContext(context);
            return super.createBaseSubscriptionsWithAddOns(subscriptionWithAddOnsSpecifiers, renameCancelledBundleIfExist, catalog, addonUtils, accountIdCacheController, bundleIdCacheController, callContext, context);
        } catch (final CatalogApiException e) {
            throw new SubscriptionBaseApiException(e);
        }
    }

    @Override
    public void cancelBaseSubscriptions(final Iterable<SubscriptionBase> subscriptions, final BillingActionPolicy policy, final InternalCallContext context) throws SubscriptionBaseApiException {
        try {
            final SubscriptionCatalog catalog = subscriptionCatalogApi.getFullCatalog(context);
            apiService.cancelWithPolicyNoValidationAndCatalog(Iterables.<SubscriptionBase, DefaultSubscriptionBase>transform(subscriptions, new Function<SubscriptionBase, DefaultSubscriptionBase>() {

                @Override
                public DefaultSubscriptionBase apply(final SubscriptionBase subscriptionBase) {
                    try {
                        return getDefaultSubscriptionBase(subscriptionBase, catalog, context);
                    } catch (final CatalogApiException e) {
                        throw new RuntimeException(e);
                    }
                }
            }), policy, catalog, context);
        } catch (CatalogApiException e) {
            throw new SubscriptionBaseApiException(e);
        }
    }

    @VisibleForTesting
    @Override
    public SubscriptionBaseBundle createBundleForAccount(final UUID accountId, final String bundleKey, final boolean renameCancelledBundleIfExist, final InternalCallContext context) throws SubscriptionBaseApiException {
        final DateTime now = context.getCreatedDate();
        final DefaultSubscriptionBaseBundle bundle = new DefaultSubscriptionBaseBundle(bundleKey, accountId, now, now, now, now);
        if (null != bundleKey && bundleKey.length() > 255) {
            throw new SubscriptionBaseApiException(ErrorCode.EXTERNAL_KEY_LIMIT_EXCEEDED);
        }
        try {
            final SubscriptionCatalog catalog = subscriptionCatalogApi.getFullCatalog(context);
            return super.createBundleForAccount(accountId, bundleKey, renameCancelledBundleIfExist, catalog, accountIdCacheController, context);
        } catch (final CatalogApiException e) {
            throw new SubscriptionBaseApiException(e);
        }
    }

    @Override
    public List<SubscriptionBaseBundle> getBundlesForAccountAndKey(final UUID accountId, final String bundleKey, final InternalTenantContext context) throws SubscriptionBaseApiException {
        final SubscriptionBaseBundle subscriptionBundlesForAccountAndKey = dao.getSubscriptionBundlesForAccountAndKey(accountId, bundleKey, context);
        return subscriptionBundlesForAccountAndKey != null ? ImmutableList.of(subscriptionBundlesForAccountAndKey) : ImmutableList.<SubscriptionBaseBundle>of();
    }

    @Override
    public List<SubscriptionBaseBundle> getBundlesForAccount(final UUID accountId, final InternalTenantContext context) {
        return dao.getSubscriptionBundleForAccount(accountId, context);
    }

    @Override
    public List<SubscriptionBaseBundle> getBundlesForKey(final String bundleKey, final InternalTenantContext context) {
        return dao.getSubscriptionBundlesForKey(bundleKey, context);
    }

    @Override
    public Pagination<SubscriptionBaseBundle> getBundles(final Long offset, final Long limit, final InternalTenantContext context) {
        return getEntityPaginationNoException(limit, new SourcePaginationBuilder<SubscriptionBundleModelDao, SubscriptionBaseApiException>() {

            @Override
            public Pagination<SubscriptionBundleModelDao> build() {
                return dao.get(offset, limit, context);
            }
        }, new Function<SubscriptionBundleModelDao, SubscriptionBaseBundle>() {

            @Override
            public SubscriptionBaseBundle apply(final SubscriptionBundleModelDao bundleModelDao) {
                return SubscriptionBundleModelDao.toSubscriptionBundle(bundleModelDao);
            }
        });
    }

    @Override
    public Pagination<SubscriptionBaseBundle> searchBundles(final String searchKey, final Long offset, final Long limit, final InternalTenantContext context) {
        return getEntityPaginationNoException(limit, new SourcePaginationBuilder<SubscriptionBundleModelDao, SubscriptionBaseApiException>() {

            @Override
            public Pagination<SubscriptionBundleModelDao> build() {
                return dao.searchSubscriptionBundles(searchKey, offset, limit, context);
            }
        }, new Function<SubscriptionBundleModelDao, SubscriptionBaseBundle>() {

            @Override
            public SubscriptionBaseBundle apply(final SubscriptionBundleModelDao bundleModelDao) {
                return SubscriptionBundleModelDao.toSubscriptionBundle(bundleModelDao);
            }
        });
    }

    @Override
    public Iterable<UUID> getNonAOSubscriptionIdsForKey(final String bundleKey, final InternalTenantContext context) {
        return dao.getNonAOSubscriptionIdsForKey(bundleKey, context);
    }

    @Override
    public SubscriptionBaseBundle getActiveBundleForKey(final VersionedCatalog publicCatalog, final String bundleKey, final InternalTenantContext context) {
        try {
            final SubscriptionCatalog catalog = DefaultSubscriptionCatalogApi.wrapCatalog(publicCatalog, clock);
            return super.getActiveBundleForKey(bundleKey, catalog, context);
        } catch (final CatalogApiException e) {
            log.warn("Failed to get subscriptions", e);
            return null;
        }
    }

    @Override
    public List<SubscriptionBase> getSubscriptionsForBundle(final UUID bundleId, @Nullable final DryRunArguments dryRunArguments, final InternalTenantContext context) throws SubscriptionBaseApiException {
        try {
            final SubscriptionCatalog catalog = subscriptionCatalogApi.getFullCatalog(context);
            final TenantContext tenantContext = internalCallContextFactory.createTenantContext(context);
            final List<DefaultSubscriptionBase> subscriptionsForBundle = super.getSubscriptionsForBundle(bundleId, dryRunArguments, catalog, addonUtils, tenantContext, context);
            return new ArrayList<SubscriptionBase>(subscriptionsForBundle);
        } catch (final CatalogApiException e) {
            throw new SubscriptionBaseApiException(e);
        }
    }

    @Override
    public Map<UUID, List<SubscriptionBase>> getSubscriptionsForAccount(final VersionedCatalog publicCatalog, final InternalTenantContext context) throws SubscriptionBaseApiException {
        try {
            final SubscriptionCatalog catalog = DefaultSubscriptionCatalogApi.wrapCatalog(publicCatalog, clock);
            final Map<UUID, List<DefaultSubscriptionBase>> internalSubscriptions = dao.getSubscriptionsForAccount(catalog, context);
            final Map<UUID, List<SubscriptionBase>> result = new HashMap<UUID, List<SubscriptionBase>>();
            for (final UUID bundleId : internalSubscriptions.keySet()) {
                final List<DefaultSubscriptionBase> subscriptionsForApiUse = createSubscriptionsForApiUse(internalSubscriptions.get(bundleId));
                result.put(bundleId, new ArrayList<SubscriptionBase>(subscriptionsForApiUse));
            }
            return result;
        } catch (final CatalogApiException e) {
            throw new SubscriptionBaseApiException(e);
        }
    }

    @Override
    public SubscriptionBase getBaseSubscription(final UUID bundleId, final InternalTenantContext context) throws SubscriptionBaseApiException {
        try {
            final SubscriptionCatalog catalog = subscriptionCatalogApi.getFullCatalog(context);
            return super.getBaseSubscription(bundleId, catalog, context);
        } catch (final CatalogApiException e) {
            throw new SubscriptionBaseApiException(e);
        }
    }

    @Override
    public SubscriptionBase getSubscriptionFromId(final UUID id, final InternalTenantContext context) throws SubscriptionBaseApiException {
        try {
            final SubscriptionCatalog catalog = subscriptionCatalogApi.getFullCatalog(context);
            final SubscriptionBase result = dao.getSubscriptionFromId(id, catalog, context);
            if (result == null) {
                throw new SubscriptionBaseApiException(ErrorCode.SUB_INVALID_SUBSCRIPTION_ID, id);
            }
            return createSubscriptionForApiUse(result);
        } catch (final CatalogApiException e) {
            throw new SubscriptionBaseApiException(e);
        }
    }

    @Override
    public SubscriptionBase getSubscriptionFromExternalKey(final String externalKey, final InternalTenantContext context) throws SubscriptionBaseApiException {
        try {
            final SubscriptionCatalog catalog = subscriptionCatalogApi.getFullCatalog(context);
            final SubscriptionBase result = dao.getSubscriptionFromExternalKey(externalKey, catalog, context);
            if (result == null) {
                throw new SubscriptionBaseApiException(ErrorCode.SUB_INVALID_SUBSCRIPTION_EXTERNAL_KEY, externalKey);
            }
            return createSubscriptionForApiUse(result);
        } catch (final CatalogApiException e) {
            throw new SubscriptionBaseApiException(e);
        }
    }

    @Override
    public SubscriptionBaseBundle getBundleFromId(final UUID id, final InternalTenantContext context) throws SubscriptionBaseApiException {
        final SubscriptionBaseBundle result = dao.getSubscriptionBundleFromId(id, context);
        if (result == null) {
            throw new SubscriptionBaseApiException(ErrorCode.SUB_GET_INVALID_BUNDLE_ID, id.toString());
        }
        return result;
    }

    @Override
    public void setChargedThroughDate(final UUID subscriptionId, final DateTime chargedThruDate, final InternalCallContext context) throws SubscriptionBaseApiException {
        try {
            final SubscriptionCatalog catalog = subscriptionCatalogApi.getFullCatalog(context);
            final DefaultSubscriptionBase subscription = (DefaultSubscriptionBase) dao.getSubscriptionFromId(subscriptionId, catalog, context);
            final SubscriptionBuilder builder = new SubscriptionBuilder(subscription).setChargedThroughDate(chargedThruDate);
            dao.updateChargedThroughDate(new DefaultSubscriptionBase(builder), context);
        } catch (final CatalogApiException e) {
            throw new SubscriptionBaseApiException(e);
        }
    }

    @Override
    public List<EffectiveSubscriptionInternalEvent> getAllTransitions(final SubscriptionBase subscription, final InternalTenantContext context) {
        final List<SubscriptionBaseTransition> transitions = subscription.getAllTransitions();
        return convertEffectiveSubscriptionInternalEventFromSubscriptionTransitions(subscription, context, transitions);
    }

    @Override
    public List<SubscriptionBillingEvent> getSubscriptionBillingEvents(final VersionedCatalog publicCatalog, final SubscriptionBase subscription, final InternalTenantContext context) throws SubscriptionBaseApiException {
        final SubscriptionCatalog catalog = DefaultSubscriptionCatalogApi.wrapCatalog(publicCatalog, clock);
        return subscription.getSubscriptionBillingEvents(catalog.getCatalog());
    }

    @Override
    public DateTime getDryRunChangePlanEffectiveDate(final SubscriptionBase subscription, final EntitlementSpecifier spec, final DateTime requestedDateWithMs, final BillingActionPolicy requestedPolicy, final InternalCallContext context) throws SubscriptionBaseApiException, CatalogApiException {
        final TenantContext tenantContext = internalCallContextFactory.createTenantContext(context);
        final CallContext callContext = internalCallContextFactory.createCallContext(context);
        // verify the number of subscriptions (of the same kind) allowed per bundle
        final SubscriptionCatalog catalog = subscriptionCatalogApi.getFullCatalog(context);
        final DateTime effectiveDate = (requestedDateWithMs != null) ? DefaultClock.truncateMs(requestedDateWithMs) : null;
        final DateTime effectiveCatalogDate = effectiveDate != null ? effectiveDate : context.getCreatedDate();
        final PlanPhasePriceOverridesWithCallContext overridesWithContext = new DefaultPlanPhasePriceOverridesWithCallContext(spec.getOverrides(), callContext);
        final StaticCatalog catalogVersion = catalog.versionForDate(effectiveCatalogDate);
        final Plan plan = catalogVersion.createOrFindPlan(spec.getPlanPhaseSpecifier(), overridesWithContext);
        if (ProductCategory.ADD_ON.toString().equalsIgnoreCase(plan.getProduct().getCategory().toString())) {
            if (plan.getPlansAllowedInBundle() != -1 && plan.getPlansAllowedInBundle() > 0 && addonUtils.countExistingAddOnsWithSamePlanName(getSubscriptionsForBundle(subscription.getBundleId(), null, catalog, addonUtils, callContext, context), plan.getName()) >= plan.getPlansAllowedInBundle()) {
                // the plan can be changed to the new value, because it has reached its limit by bundle
                throw new SubscriptionBaseApiException(ErrorCode.SUB_CHANGE_AO_MAX_PLAN_ALLOWED_BY_BUNDLE, plan.getName());
            }
        }
        return apiService.dryRunChangePlan((DefaultSubscriptionBase) subscription, spec, effectiveDate, requestedPolicy, tenantContext);
    }

    @Override
    public List<EntitlementAOStatusDryRun> getDryRunChangePlanStatus(final UUID subscriptionId, @Nullable final String baseProductName, final DateTime requestedDate, final InternalTenantContext context) throws SubscriptionBaseApiException {
        try {
            final SubscriptionCatalog catalog = subscriptionCatalogApi.getFullCatalog(context);
            final SubscriptionBase subscription = dao.getSubscriptionFromId(subscriptionId, catalog, context);
            if (subscription == null) {
                throw new SubscriptionBaseApiException(ErrorCode.SUB_INVALID_SUBSCRIPTION_ID, subscriptionId);
            }
            if (subscription.getCategory() != ProductCategory.BASE) {
                throw new SubscriptionBaseApiException(ErrorCode.SUB_CHANGE_DRY_RUN_NOT_BP);
            }
            final List<EntitlementAOStatusDryRun> result = new LinkedList<EntitlementAOStatusDryRun>();
            final List<DefaultSubscriptionBase> bundleSubscriptions = dao.getSubscriptions(subscription.getBundleId(), ImmutableList.<SubscriptionBaseEvent>of(), catalog, context);
            for (final SubscriptionBase cur : bundleSubscriptions) {
                if (cur.getId().equals(subscriptionId)) {
                    continue;
                }
                // If ADDON is cancelled, skip
                if (cur.getState() == EntitlementState.CANCELLED) {
                    continue;
                }
                final StaticCatalog catalogVersion = catalog.versionForDate(requestedDate);
                final Product baseProduct = baseProductName != null ? catalogVersion.findProduct(baseProductName) : null;
                final DryRunChangeReason reason;
                // If baseProductName is null, it's a cancellation dry-run. In this case, return all addons, so they are cancelled
                if (baseProduct != null && addonUtils.isAddonIncluded(baseProduct, cur.getCurrentPlan())) {
                    reason = DryRunChangeReason.AO_INCLUDED_IN_NEW_PLAN;
                } else if (baseProduct != null && addonUtils.isAddonAvailable(baseProduct, cur.getCurrentPlan())) {
                    reason = DryRunChangeReason.AO_AVAILABLE_IN_NEW_PLAN;
                } else {
                    reason = DryRunChangeReason.AO_NOT_AVAILABLE_IN_NEW_PLAN;
                }
                final EntitlementAOStatusDryRun status = new DefaultSubscriptionStatusDryRun(cur.getId(), cur.getCurrentPlan().getProduct().getName(), cur.getCurrentPhase().getPhaseType(), cur.getCurrentPlan().getRecurringBillingPeriod(), cur.getCurrentPriceList().getName(), reason);
                result.add(status);
            }
            return result;
        } catch (final CatalogApiException e) {
            throw new SubscriptionBaseApiException(e);
        }
    }

    @Override
    public void updateExternalKey(final UUID bundleId, final String newExternalKey, final InternalCallContext context) {
        dao.updateBundleExternalKey(bundleId, newExternalKey, context);
    }

    @Override
    public void updateBCD(final UUID subscriptionId, final int bcd, @Nullable final LocalDate effectiveFromDate, final InternalCallContext internalCallContext) throws SubscriptionBaseApiException {
        try {
            final SubscriptionCatalog catalog = subscriptionCatalogApi.getFullCatalog(internalCallContext);
            final DefaultSubscriptionBase subscription = (DefaultSubscriptionBase) getSubscriptionFromId(subscriptionId, internalCallContext);
            final DateTime effectiveDate = getEffectiveDateForNewBCD(bcd, effectiveFromDate, subscription.getStartDate(), internalCallContext);
            final BCDEvent bcdEvent = BCDEventData.createBCDEvent(subscription, effectiveDate, bcd);
            dao.createBCDChangeEvent(subscription, bcdEvent, catalog, internalCallContext);
        } catch (final CatalogApiException e) {
            throw new SubscriptionBaseApiException(e);
        }
    }

    @Override
    public UUID getAccountIdFromBundleId(final UUID bundleId, final InternalTenantContext context) throws SubscriptionBaseApiException {
        final CacheLoaderArgument arg = createAccountIdFromBundleIdCacheLoaderArgument(context);
        return accountIdCacheController.get(bundleId, arg);
    }

    @Override
    public UUID getBundleIdFromSubscriptionId(final UUID subscriptionId, final InternalTenantContext context) throws SubscriptionBaseApiException {
        final CacheLoaderArgument arg = createBundleIdFromSubscriptionIdCacheLoaderArgument(context);
        return bundleIdCacheController.get(subscriptionId, arg);
    }

    @Override
    public UUID getAccountIdFromSubscriptionId(final UUID subscriptionId, final InternalTenantContext context) throws SubscriptionBaseApiException {
        final UUID bundleId = getBundleIdFromSubscriptionId(subscriptionId, context);
        if (bundleId == null) {
            throw new SubscriptionBaseApiException(ErrorCode.SUB_GET_NO_BUNDLE_FOR_SUBSCRIPTION, subscriptionId);
        }
        final UUID accountId = getAccountIdFromBundleId(bundleId, context);
        if (accountId == null) {
            throw new SubscriptionBaseApiException(ErrorCode.SUB_GET_INVALID_BUNDLE_ID, bundleId);
        }
        return accountId;
    }

    @Override
    public UUID getSubscriptionIdFromSubscriptionExternalKey(final String externalKey, final InternalTenantContext context) throws SubscriptionBaseApiException {
        return dao.getSubscriptionIdFromSubscriptionExternalKey(externalKey, context);
    }

    @Override
    public List<AuditLogWithHistory> getSubscriptionBundleAuditLogsWithHistoryForId(final UUID bundleId, final AuditLevel auditLevel, final TenantContext tenantContext) {
        return dao.getSubscriptionBundleAuditLogsWithHistoryForId(bundleId, auditLevel, internalCallContextFactory.createInternalTenantContext(bundleId, ObjectType.BUNDLE, tenantContext));
    }

    @Override
    public List<AuditLogWithHistory> getSubscriptionAuditLogsWithHistoryForId(final UUID subscriptionId, final AuditLevel auditLevel, final TenantContext tenantContext) {
        return dao.getSubscriptionAuditLogsWithHistoryForId(subscriptionId, auditLevel, internalCallContextFactory.createInternalTenantContext(subscriptionId, ObjectType.SUBSCRIPTION, tenantContext));
    }

    @Override
    public List<AuditLogWithHistory> getSubscriptionEventAuditLogsWithHistoryForId(final UUID eventId, final AuditLevel auditLevel, final TenantContext tenantContext) {
        return dao.getSubscriptionEventAuditLogsWithHistoryForId(eventId, auditLevel, internalCallContextFactory.createInternalTenantContext(eventId, ObjectType.SUBSCRIPTION_EVENT, tenantContext));
    }

    private CacheLoaderArgument createAccountIdFromBundleIdCacheLoaderArgument(final InternalTenantContext internalTenantContext) {
        final AccountIdFromBundleIdCacheLoader.LoaderCallback loaderCallback = new AccountIdFromBundleIdCacheLoader.LoaderCallback() {

            public UUID loadAccountId(final UUID bundleId, final InternalTenantContext internalTenantContext) {
                final SubscriptionBaseBundle bundle;
                try {
                    bundle = getBundleFromId(bundleId, internalTenantContext);
                } catch (final SubscriptionBaseApiException e) {
                    log.warn("Unable to retrieve bundle for id='{}'", bundleId);
                    return null;
                }
                return bundle.getAccountId();
            }
        };
        final Object[] args = { loaderCallback };
        return new CacheLoaderArgument(null, args, internalTenantContext);
    }

    private CacheLoaderArgument createBundleIdFromSubscriptionIdCacheLoaderArgument(final InternalTenantContext internalTenantContext) {
        final BundleIdFromSubscriptionIdCacheLoader.LoaderCallback loaderCallback = new BundleIdFromSubscriptionIdCacheLoader.LoaderCallback() {

            public UUID loadBundleId(final UUID subscriptionId, final InternalTenantContext internalTenantContext) {
                return dao.getBundleIdFromSubscriptionId(subscriptionId, internalTenantContext);
            }
        };
        final Object[] args = { loaderCallback };
        return new CacheLoaderArgument(null, args, internalTenantContext);
    }

    @VisibleForTesting
    DateTime getEffectiveDateForNewBCD(final int bcd, @Nullable final LocalDate effectiveFromDate, final DateTime subscriptionStartDate, final InternalCallContext internalCallContext) {
        if (internalCallContext.getAccountRecordId() == null) {
            throw new IllegalStateException("Need to have a valid context with accountRecordId");
        }
        // Today as seen by this account
        final LocalDate startDate = effectiveFromDate != null ? effectiveFromDate : internalCallContext.toLocalDate(internalCallContext.getCreatedDate());
        // We want to compute a LocalDate in account TZ which maps to the provided 'bcd' and then compute an effectiveDate for when that BCD_CHANGE event needs to be triggered
        // There is a bit of complexity to make sure the date we chose exists (e.g: a BCD of 31 in a february month would not make sense).
        final int currentDay = startDate.getDayOfMonth();
        final int lastDayOfMonth = startDate.dayOfMonth().getMaximumValue();
        final LocalDate requestedDate;
        if (bcd < currentDay) {
            final LocalDate startDatePlusOneMonth = startDate.plusMonths(1);
            final int lastDayOfNextMonth = startDatePlusOneMonth.dayOfMonth().getMaximumValue();
            final int originalBCDORLastDayOfMonth = bcd <= lastDayOfNextMonth ? bcd : lastDayOfNextMonth;
            requestedDate = new LocalDate(startDatePlusOneMonth.getYear(), startDatePlusOneMonth.getMonthOfYear(), originalBCDORLastDayOfMonth);
        } else if (bcd == currentDay && effectiveFromDate == null) {
            // will default to immediate event
            requestedDate = null;
        } else if (bcd <= lastDayOfMonth) {
            requestedDate = new LocalDate(startDate.getYear(), startDate.getMonthOfYear(), bcd);
        } else /* bcd > lastDayOfMonth && bcd > currentDay */
        {
            requestedDate = new LocalDate(startDate.getYear(), startDate.getMonthOfYear(), lastDayOfMonth);
        }
        DateTime requestedDateTime = requestedDate == null ? internalCallContext.getCreatedDate() : internalCallContext.toUTCDateTime(requestedDate);
        // The event needs to be after the subscription start date

        return requestedDateTime;
    }

    private List<EffectiveSubscriptionInternalEvent> convertEffectiveSubscriptionInternalEventFromSubscriptionTransitions(final SubscriptionBase subscription, final InternalTenantContext context, final Collection<SubscriptionBaseTransition> transitions) {
        return ImmutableList.<EffectiveSubscriptionInternalEvent>copyOf(Collections2.transform(transitions, new Function<SubscriptionBaseTransition, EffectiveSubscriptionInternalEvent>() {

            @Override
            @Nullable
            public EffectiveSubscriptionInternalEvent apply(@Nullable final SubscriptionBaseTransition input) {
                return new DefaultEffectiveSubscriptionEvent((SubscriptionBaseTransitionData) input, ((DefaultSubscriptionBase) subscription).getAlignStartDate(), null, context.getAccountRecordId(), context.getTenantRecordId());
            }
        }));
    }

    // For forward-compatibility
    private DefaultSubscriptionBase getDefaultSubscriptionBase(final Entity subscriptionBase, final SubscriptionCatalog catalog, final InternalTenantContext context) throws CatalogApiException {
        if (subscriptionBase instanceof DefaultSubscriptionBase) {
            return (DefaultSubscriptionBase) subscriptionBase;
        } else {
            // Safe cast, see above
            return (DefaultSubscriptionBase) dao.getSubscriptionFromId(subscriptionBase.getId(), catalog, context);
        }
    }
}