// Path: src/main/java/com/eclecticlogic/pedal/dialect/postgresql/eval/EvaluatorChain.java
// public interface EvaluatorChain {
// 
//     Class<?> getEntityClass();
// 
// 
//     /**
//      * Add attribute to evaluated attributes list.
//      * @param attribute
//      */
//     void add(CopyAttribute attribute);
// 
// 
//     /**
//      * Call the next method evaluator.
//      */
//     void doNext();
// }
// 
// Path: src/main/java/com/eclecticlogic/pedal/dialect/postgresql/eval/MethodEvaluator.java
// public interface MethodEvaluator {
// 
//     void evaluate(Method method, EvaluatorChain chain);
// 
// 
//     default void evaluate(Method method, Class<?> clz, List<CopyAttribute> attributes) {
//         List<MethodEvaluator> evaluators = new ArrayList<>();
//         evaluators.add(new IdentityIdEvaluator());
//         evaluators.add(new SimpleColumnEvaluator());
//         evaluators.add(new JoinColumnEvaluator());
//         evaluators.add(new EmbeddedIdColumnEvaluator());
//         evaluators.add(new EmbeddedColumnEvaluator());
// 
//         EvaluatorChain chain = new EvaluatorChain() {
//             int index = 0;
// 
// 
//             @Override
//             public Class<?> getEntityClass() {
//                 return clz;
//             }
// 
// 
//             @Override
//             public void add(CopyAttribute attribute) {
//                 attributes.add(attribute);
//             }
// 
// 
//             @Override
//             public void doNext() {
//                 index++;
//                 if (index < evaluators.size()) {
//                     evaluators.get(index).evaluate(method, this);
//                 }
//             }
//         };
// 
//         evaluators.get(0).evaluate(method, chain);
//     }
// }


import com.eclecticlogic.pedal.dialect.postgresql.eval.EvaluatorChain;
import com.eclecticlogic.pedal.dialect.postgresql.eval.MethodEvaluator;
import com.google.common.base.Stopwatch;
import javassist.*;
import org.postgresql.copy.CopyIn;
import org.postgresql.copy.CopyManager;
import org.postgresql.core.BaseConnection;
import org.postgresql.core.Encoding;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.stringtemplate.v4.ST;
import org.stringtemplate.v4.STGroup;
import org.stringtemplate.v4.STGroupFile;
import javax.persistence.EntityManager;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import static java.util.stream.Collectors.toList;
                try {
                    for (E e : entityList) {
                        byte[] buf = encoding.encode(extractor.getValueList(e));
                        cp.writeToCopy(buf, 0, buf.length);
                    }
                    records = cp.endCopy();
                } finally {
                    if (cp.isActive()) {
                        cp.cancelCopy();
                    }
                }
                assert records == entityList.size();
                logger.info("Wrote {} inserts in {}", records, timer.stop());// auto-selects units
            } catch (Exception e) {
                throw new RuntimeException(e.getMessage(), e);
            }
        });
    }


    protected List<CopyAttribute> getAttributesOfInterest(Class<? extends Serializable> clz) {
        List<CopyAttribute> attributes = new ArrayList<>();

        for (Method method : Arrays.stream(clz.getMethods()).filter(it -> it.getParameterCount() == 0).collect(toList())) {
            getMethodEvaluator().evaluate(method, clz, attributes);
        }
        return attributes;
    }


// Path: src/main/java/com/eclecticlogic/pedal/dialect/postgresql/eval/EvaluatorChain.java
// public interface EvaluatorChain {
// 
//     Class<?> getEntityClass();
// 
// 
//     /**
//      * Add attribute to evaluated attributes list.
//      * @param attribute
//      */
//     void add(CopyAttribute attribute);
// 
// 
//     /**
//      * Call the next method evaluator.
//      */
//     void doNext();
// }
// 
// Path: src/main/java/com/eclecticlogic/pedal/dialect/postgresql/eval/MethodEvaluator.java
// public interface MethodEvaluator {
// 
//     void evaluate(Method method, EvaluatorChain chain);
// 
// 
//     default void evaluate(Method method, Class<?> clz, List<CopyAttribute> attributes) {
//         List<MethodEvaluator> evaluators = new ArrayList<>();
//         evaluators.add(new IdentityIdEvaluator());
//         evaluators.add(new SimpleColumnEvaluator());
//         evaluators.add(new JoinColumnEvaluator());
//         evaluators.add(new EmbeddedIdColumnEvaluator());
//         evaluators.add(new EmbeddedColumnEvaluator());
// 
//         EvaluatorChain chain = new EvaluatorChain() {
//             int index = 0;
// 
// 
//             @Override
//             public Class<?> getEntityClass() {
//                 return clz;
//             }
// 
// 
//             @Override
//             public void add(CopyAttribute attribute) {
//                 attributes.add(attribute);
//             }
// 
// 
//             @Override
//             public void doNext() {
//                 index++;
//                 if (index < evaluators.size()) {
//                     evaluators.get(index).evaluate(method, this);
//                 }
//             }
//         };
// 
//         evaluators.get(0).evaluate(method, chain);
//     }
// }


// Path: src/main/java/com/eclecticlogic/pedal/dialect/postgresql/CopyCommandImpl.java
import com.eclecticlogic.pedal.dialect.postgresql.eval.EvaluatorChain;
import com.eclecticlogic.pedal.dialect.postgresql.eval.MethodEvaluator;
import com.google.common.base.Stopwatch;
import javassist.*;
import org.postgresql.copy.CopyIn;
import org.postgresql.copy.CopyManager;
import org.postgresql.core.BaseConnection;
import org.postgresql.core.Encoding;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.stringtemplate.v4.ST;
import org.stringtemplate.v4.STGroup;
import org.stringtemplate.v4.STGroupFile;
import javax.persistence.EntityManager;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import static java.util.stream.Collectors.toList;

                try {
                    for (E e : entityList) {
                        byte[] buf = encoding.encode(extractor.getValueList(e));
                        cp.writeToCopy(buf, 0, buf.length);
                    }
                    records = cp.endCopy();
                } finally {
                    if (cp.isActive()) {
                        cp.cancelCopy();
                    }
                }
                assert records == entityList.size();
                logger.info("Wrote {} inserts in {}", records, timer.stop());// auto-selects units
            } catch (Exception e) {
                throw new RuntimeException(e.getMessage(), e);
            }
        });
    }


    protected List<CopyAttribute> getAttributesOfInterest(Class<? extends Serializable> clz) {
        List<CopyAttribute> attributes = new ArrayList<>();

        for (Method method : Arrays.stream(clz.getMethods()).filter(it -> it.getParameterCount() == 0).collect(toList())) {
            getMethodEvaluator().evaluate(method, clz, attributes);
        }
        return attributes;
    }


    protected MethodEvaluator getMethodEvaluator() {