text:
package org.nutz.dao.impl;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;

import javax.sql.DataSource;

import org.nutz.dao.Chain;
import org.nutz.dao.Condition;
import org.nutz.dao.ConnCallback;
import org.nutz.dao.Dao;
import org.nutz.dao.DaoException;
import org.nutz.dao.FieldFilter;
import org.nutz.dao.FieldMatcher;
import org.nutz.dao.SqlManager;
import org.nutz.dao.Sqls;
import org.nutz.dao.entity.Entity;
import org.nutz.dao.entity.EntityMaker;
import org.nutz.dao.entity.LinkField;
import org.nutz.dao.entity.LinkVisitor;
import org.nutz.dao.entity.Record;
import org.nutz.dao.impl.link.DoClearLinkVisitor;
import org.nutz.dao.impl.link.DoClearRelationByHostFieldLinkVisitor;
import org.nutz.dao.impl.link.DoClearRelationByLinkedFieldLinkVisitor;
import org.nutz.dao.impl.link.DoDeleteLinkVisitor;
import org.nutz.dao.impl.link.DoInsertLinkVisitor;
import org.nutz.dao.impl.link.DoInsertRelationLinkVisitor;
import org.nutz.dao.impl.link.DoUpdateLinkVisitor;
import org.nutz.dao.impl.link.DoUpdateRelationLinkVisitor;
import org.nutz.dao.impl.sql.pojo.ConditionPItem;
import org.nutz.dao.impl.sql.pojo.PojoEachEntityCallback;
import org.nutz.dao.impl.sql.pojo.PojoEachRecordCallback;
import org.nutz.dao.impl.sql.pojo.PojoFetchEntityCallback;
import org.nutz.dao.impl.sql.pojo.PojoFetchIntCallback;
import org.nutz.dao.impl.sql.pojo.PojoFetchObjectCallback;
import org.nutz.dao.impl.sql.pojo.PojoFetchRecordCallback;
import org.nutz.dao.impl.sql.pojo.PojoQueryEntityCallback;
import org.nutz.dao.impl.sql.pojo.PojoQueryRecordCallback;
import org.nutz.dao.jdbc.JdbcExpert;
import org.nutz.dao.jdbc.Jdbcs;
import org.nutz.dao.pager.Pager;
import org.nutz.dao.sql.Criteria;
import org.nutz.dao.sql.DaoStatement;
import org.nutz.dao.sql.PItem;
import org.nutz.dao.sql.Pojo;
import org.nutz.dao.sql.PojoCallback;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.Daos;
import org.nutz.dao.util.Pojos;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.lang.ContinueLoop;
import org.nutz.lang.Each;
import org.nutz.lang.ExitLoop;
import org.nutz.lang.Lang;
import org.nutz.lang.LoopException;
import org.nutz.lang.Strings;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.trans.Atom;
import org.nutz.trans.Molecule;

public class NutDao extends DaoSupport implements Dao {

    private static final Log log = Logs.get();

    private static final AtomicLong atomLong = new AtomicLong();

    private PojoCallback _pojo_queryEntity;

    private PojoCallback _pojo_fetchEntity;

    private PojoCallback _pojo_eachEntity;

    private PojoCallback _pojo_queryRecord;

    private PojoCallback _pojo_fetchRecord;

    private PojoCallback _pojo_eachRecord;

    private PojoCallback _pojo_fetchInt;

    private PojoCallback _pojo_fetchObject;

    protected volatile long _selfId;

    // ==========================================================
    // 下面是 3 个构造函数
    public NutDao() {
        super();
        _selfId = atomLong.getAndIncrement();
        // 设置默认的回调
        _pojo_queryEntity = new PojoQueryEntityCallback();
        _pojo_fetchEntity = new PojoFetchEntityCallback();
        _pojo_eachEntity = new PojoEachEntityCallback();
        _pojo_fetchInt = new PojoFetchIntCallback();
        _pojo_fetchObject = new PojoFetchObjectCallback();
        _pojo_queryRecord = new PojoQueryRecordCallback();
        _pojo_fetchRecord = new PojoFetchRecordCallback();
        _pojo_eachRecord = new PojoEachRecordCallback();

        // check for spring DataSourceTransactionManager
        for (StackTraceElement ele : Thread.currentThread().getStackTrace()) {
            if (ele.getClassName().startsWith("org.springframework")) {
                log.info("Note: Make sure set SpringDaoRunner if using DataSourceTransactionManager.");
                break;
            }
        }
    }

    public NutDao(DataSource dataSource) {
        this();
        this.setDataSource(dataSource);
    }

    public NutDao(DataSource dataSource, SqlManager sqlManager) {
        this(dataSource);
        this.setSqlManager(sqlManager);
    }

    public NutDao(DataSource dataSource, EntityMaker maker) {
        this(dataSource);
        this.holder.maker = maker;
        maker.init(dataSource, expert, holder);
    }

    // 上面是 4 个构造函数
    // ==========================================================

    public <T> T getObject(Class<T> classOfT, ResultSet rs, FieldMatcher fm) {
        return getObject(classOfT, rs, fm, null);
    }

    public <T> T getObject(Class<T> classOfT, ResultSet rs, FieldMatcher fm, String prefix) {
        return holder.getEntity(classOfT).getObject(rs, fm, prefix);
    }

    public <T> T insert(final T obj) {
        final EntityOperator opt = _optBy(Lang.first(obj));
        if (null == opt)
            return null;
        Lang.each(obj, false, new Each<Object>() {
            public void invoke(int i, Object ele, int length) throws ExitLoop, LoopException {
                opt.addInsert(opt.entity, ele);
            }
        });
        opt.exec();
        return obj;
    }

    public <T> T insert(final T obj, FieldFilter filter) {
        if (filter == null)
            return insert(obj);
        filter.run(new Atom() {
            public void run() {
                insert(obj);
            }
        });
        return obj;
    }

    public void insert(String tableName, Chain chain) {
        if (chain.isSpecial()) {
            Daos.insertBySpecialChain(this, null, tableName, chain);
            return;
        }
        EntityOperator opt = _optBy(chain.toEntityMap(tableName));
        if (null == opt)
            return;
        opt.addInsert();
        opt.exec();
    }

    public void insert(Class<?> classOfT, Chain chain) {
        if (chain.isSpecial()) {
            Daos.insertBySpecialChain(this, getEntity(classOfT), null, chain);
            return;
        }
        EntityOperator opt = _opt(classOfT);
        opt.myObj = chain;
        opt.addInsertSelfOnly();
        // insert(chain.toObject(classOfT));// TODO 这样的效率,未免太低了,需要改进
        opt.exec();
    }

    public <T> T fastInsert(T obj) {
        EntityOperator opt = _optBy(obj);
        if (null == opt)
            return null;
        opt.addInsertSelfOnly();
        opt.exec();
        return obj;
    }

    public <T> T insertWith(T obj, String regex) {
        // TODO 天啊,每个调用都有4个正则表达式,能快起来不?
        // TODO zzh: NutEntity 会缓存正则表达式计算的结果的,会很快的
        EntityOperator opt = _optBy(obj);
        if (null == opt)
            return null;
        final LinkVisitor one = doInsert(opt);
        final boolean[] flag = new boolean[1];
        // issue 889. hostField是@Id(auto=true)的时候
        // 需要把相应的@One对象,押后到host对象插入之后
        opt.entity.visitOne(obj, regex, new LinkVisitor() {
            public void visit(Object obj, LinkField lnk) {
                if (lnk.getHostField().isId()) {
                    flag[0] = true;
                    return;
                }
                one.visit(obj, lnk);
            }
        });
        opt.addInsert();
        opt.entity.visitMany(obj, regex, doInsert(opt));
        opt.entity.visitManyMany(obj, regex, doInsert(opt));
        opt.entity.visitManyMany(obj, regex, doInsertRelation(opt));
        opt.exec();

        if (flag[0]) {
            opt = _optBy(obj);
            final LinkVisitor _one = doInsert(opt);
            opt.entity.visitOne(obj, regex, new LinkVisitor() {
                public void visit(Object obj, LinkField lnk) {
                    if (!lnk.getHostField().isId())
                        return;
                    _one.visit(obj, lnk);
                }
            });
            opt.exec();
        }

        return obj;
    }

    public <T> T insertLinks(T obj, String regex) {
        // TODO 天啊,每个调用都有4个正则表达式,能快起来不?
        // TODO zzh: NutEntity 会缓存正则表达式计算的结果的,会很快的
        EntityOperator opt = _optBy(obj);
        if (null == opt)
            return null;

        opt.entity.visitOne(obj, regex, doInsert(opt));
        opt.entity.visitMany(obj, regex, doInsert(opt));
        opt.entity.visitManyMany(obj, regex, doInsert(opt));
        opt.entity.visitManyMany(obj, regex, doInsertRelation(opt));
        opt.exec();

        return obj;
    }

    public <T> T insertRelation(T obj, String regex) {
        EntityOperator opt = _optBy(obj);
        if (null == opt)
            return null;

        opt.entity.visitManyMany(obj, regex, doInsertRelation(opt));
        opt.exec();

        return obj;
    }

    public int update(Object obj) {
        EntityOperator opt = _optBy(obj);
        if (null == opt)
            return 0;
        opt.addUpdate();
        opt.exec();
        return opt.getUpdateCount();
    }

    public int update(final Object obj, String regex) {
        Object first = Lang.first(obj);
        if (null == first)
            return 0;

        if (Strings.isBlank(regex))
            return update(obj);

        Molecule<Integer> m = new Molecule<Integer>() {
            public void run() {
                setObj(update(obj));
            }
        };
        FieldFilter.create(first.getClass(), regex).run(m);
        return m.getObj();
    }

    public int updateIgnoreNull(final Object obj) {
        EntityOperator opt = _optBy(obj);
        if (null == opt)
            return 0;
        opt.addUpdateForIgnoreNull(opt.entity, obj, FieldFilter.get(opt.entity.getType()));
        opt.exec();
        return opt.getUpdateCount();
    }

    public int update(String tableName, Chain chain, Condition cnd) {
        if (chain.isSpecial())
            return Daos.updateBySpecialChain(this, null, tableName, chain, cnd);
        EntityOperator opt = _optBy(chain.toEntityMap(tableName));
        if (null == opt)
            return 0;
        opt.addUpdate(cnd);
        opt.exec();
        return opt.getUpdateCount();
    }

    public int update(Class<?> classOfT, Chain chain, Condition cnd) {
        if (chain.isSpecial())
            return Daos.updateBySpecialChain(this, getEntity(classOfT), null, chain, cnd);
        EntityOperator opt = _opt(classOfT);
        opt.addUpdate(chain, cnd);
        opt.exec();
        return opt.getUpdateCount();
    }

    public <T> T updateWith(T obj, final String regex) {
        if (null == obj)
            return null;
        Lang.each(obj, false, new Each<Object>() {
            public void invoke(int index, Object ele, int length) throws ExitLoop, ContinueLoop,
                    LoopException {
                EntityOperator opt = _optBy(ele);
                if (null == opt)
                    return;

                opt.entity.visitOne(ele, regex, doUpdate(opt));
                opt.addUpdate();
                opt.entity.visitMany(ele, regex, doUpdate(opt));
                opt.entity.visitManyMany(ele, regex, doUpdate(opt));

                opt.exec();
            }
        });
        return obj;
    }

    public <T> T updateLinks(T obj, final String regex) {
        if (null == obj)
            return null;
        Lang.each(obj, false, new Each<Object>() {
            public void invoke(int index, Object ele, int length) throws ExitLoop, ContinueLoop,
                    LoopException {
                EntityOperator opt = _optBy(ele);
                if (null == opt)
                    return;

                opt.entity.visitOne(ele, regex, doUpdate(opt));
                opt.entity.visitMany(ele, regex, doUpdate(opt));
                opt.entity.visitManyMany(ele, regex, doUpdate(opt));

                opt.exec();
            }
        });
        return obj;
    }

    public int updateRelation(Class<?> classOfT, String regex, Chain chain, Condition cnd) {
        if (chain.isSpecial())
            throw Lang.noImplement();

        EntityOperator opt = this._opt(classOfT);

        opt.entity.visitManyMany(null, regex, doUpdateRelation(opt, chain, cnd));
        opt.exec();

        return opt.getUpdateCount();
    }

    public int delete(Class<?> classOfT, long id) {
        Entity<?> en = holder.getEntity(classOfT);
        Pojo pojo = pojoMaker.makeDelete(en).append(Pojos.Items.cndId(en, id));
        pojo.addParamsBy(id);
        _exec(pojo);
        return pojo.getUpdateCount();
    }

    public int delete(Class<?> classOfT, String name) {
        Entity<?> en = holder.getEntity(classOfT);
        Pojo pojo = pojoMaker.makeDelete(en)
                             .append(Pojos.Items.cndName(en, name))
                             .addParamsBy(name);
        _exec(pojo);
        return pojo.getUpdateCount();
    }

    public <T> int deletex(Class<T> classOfT, Object... pks) {
        Entity<T> en = holder.getEntity(classOfT);
        Pojo pojo = pojoMaker.makeDelete(en).append(Pojos.Items.cndPk(en, pks));
        _exec(pojo);
        return pojo.getUpdateCount();
    }

    public int delete(Object obj) {
        EntityOperator opt = _optBy(obj);
        if (null == opt)
            return 0;
        opt.addDeleteSelfOnly();
        opt.exec();
        return opt.getUpdateCount();
    }

    public int deleteWith(Object obj, final String regex) {
        if (null == obj)
            return 0;
        final int[] re = new int[1];
        Lang.each(obj, false, new Each<Object>() {
            public void invoke(int index, Object ele, int length) throws ExitLoop, ContinueLoop,
                    LoopException {
                EntityOperator opt = _optBy(ele);
                if (null == opt)
                    return;
                opt.entity.visitMany(ele, regex, doDelete(opt));
                opt.entity.visitManyMany(ele, regex, doClearRelationByLinkedField(opt));
                opt.entity.visitManyMany(ele, regex, doDelete(opt));
                opt.addDeleteSelfOnly();
                opt.entity.visitOne(ele, regex, doDelete(opt));

                re[0] += opt.exec().getUpdateCount();
            }
        });
        return re[0];
    }

    public int deleteLinks(Object obj, final String regex) {
        if (null == obj)
            return 0;
        final int[] re = new int[1];
        Lang.each(obj, false, new Each<Object>() {
            public void invoke(int index, Object ele, int length) throws ExitLoop, ContinueLoop,
                    LoopException {
                EntityOperator opt = _optBy(ele);
                if (null == opt)
                    return;
                opt.entity.visitMany(ele, regex, doDelete(opt));
                opt.entity.visitManyMany(ele, regex, doClearRelationByLinkedField(opt));
                opt.entity.visitManyMany(ele, regex, doDelete(opt));
                opt.entity.visitOne(ele, regex, doDelete(opt));

                re[0] += opt.exec().getUpdateCount();
            }
        });
        return re[0];
    }

    public <T> List<T> query(Class<T> classOfT, Condition cnd, Pager pager) {
        Pojo pojo = pojoMaker.makeQuery(holder.getEntity(classOfT))
                             .append(Pojos.Items.cnd(cnd))
                             .addParamsBy("*")
                             .setPager(pager)
                             .setAfter(_pojo_queryEntity);
        expert.formatQuery(pojo);
        _exec(pojo);
        return pojo.getList(classOfT);
    }

    public <T> List<T> query(Class<T> classOfT, Condition cnd) {
        return query(classOfT, cnd, Pojos.Items.pager(cnd));
    }

    public <T> int each(Class<T> classOfT, Condition cnd, Pager pager, Each<T> callback) {
        Pojo pojo = pojoMaker.makeQuery(holder.getEntity(classOfT))
                             .append(Pojos.Items.cnd(cnd))
                             .addParamsBy("*")
                             .setPager(pager)
                             .setAfter(_pojo_queryEntity);
        expert.formatQuery(pojo);
        pojo.setAfter(_pojo_eachEntity);
        pojo.getContext().attr(Each.class.getName(), callback);
        _exec(pojo);
        return pojo.getInt();
    }

    public <T> int each(Class<T> classOfT, Condition cnd, Each<T> callback) {
        return each(classOfT, cnd, Pojos.Items.pager(cnd), callback);
    }

    public List<Record> query(String tableName, Condition cnd, Pager pager) {
        Pojo pojo = pojoMaker.makeQuery(tableName)
                             .addParamsBy("*")
                             .setPager(pager)
                             .append(Pojos.Items.cnd(cnd));
        expert.formatQuery(pojo);
        pojo.setAfter(_pojo_queryRecord);
        _exec(pojo);
        return pojo.getList(Record.class);
    }

    public List<Record> query(String tableName, Condition cnd) {
        return query(tableName, cnd, Pojos.Items.pager(cnd));
    }

    public int each(String tableName, Condition cnd, Pager pager, Each<Record> callback) {
        Pojo pojo = pojoMaker.makeQuery(tableName)
                             .addParamsBy("*")
                             .setPager(pager)
                             .append(Pojos.Items.cnd(cnd));
        expert.formatQuery(pojo);
        pojo.setAfter(_pojo_eachRecord);
        pojo.getContext().attr(Each.class.getName(), callback);
        _exec(pojo);
        return pojo.getInt();
    }

    public int each(String tableName, Condition cnd, Each<Record> callback) {
        return each(tableName, cnd, Pojos.Items.pager(cnd), callback);
    }

    public <T> T fetch(Class<T> classOfT, long id) {
        Entity<T> en = holder.getEntity(classOfT);
        if (en.getIdField() == null)
            throw new DaoException("Need @Id for " + classOfT);
        Pojo pojo = pojoMaker.makeQuery(en)
                             .append(Pojos.Items.cndId(en, id))
                             .addParamsBy(id)
                             .setAfter(_pojo_fetchEntity);
        _exec(pojo);
        return pojo.getObject(classOfT);
    }

    public <T> T fetch(Class<T> classOfT, String name) {
        if (name == null)
            throw new IllegalArgumentException("name MUST NOT NULL!");
        Entity<T> en = holder.getEntity(classOfT);
        if (en.getNameField() == null)
            throw new DaoException("Need @Name for " + classOfT);
        Pojo pojo = pojoMaker.makeQuery(en)
                             .append(Pojos.Items.cndName(en, name))
                             .addParamsBy(name)
                             .setAfter(_pojo_fetchEntity);
        _exec(pojo);
        return pojo.getObject(classOfT);
    }

    public <T> T fetchx(Class<T> classOfT, Object... pks) {
        Entity<T> en = holder.getEntity(classOfT);
        Pojo pojo = pojoMaker.makeQuery(en)
                             .append(Pojos.Items.cndPk(en, pks))
                             .setAfter(_pojo_fetchEntity);
        _exec(pojo);
        return pojo.getObject(classOfT);
    }

    public <T> T fetch(Class<T> classOfT, Condition cnd) {
        Pojo pojo = pojoMaker.makeQuery(holder.getEntity(classOfT))
                             .append(Pojos.Items.cnd(cnd))
                             .addParamsBy("*")
                             .setPager(createPager(1, 1))
                             .setAfter(_pojo_fetchEntity);
        expert.formatQuery(pojo);
        _exec(pojo);
        return pojo.getObject(classOfT);
    }

    public Record fetch(String tableName, Condition cnd) {
        Pojo pojo = pojoMaker.makeQuery(tableName)
                             .append(Pojos.Items.cnd(cnd))
                             .addParamsBy("*")
                             .setPager(createPager(1, 1))
                             .setAfter(_pojo_fetchRecord);
        expert.formatQuery(pojo);
        _exec(pojo);
        return pojo.getObject(Record.class);
    }

    @SuppressWarnings("unchecked")
    public <T> T fetch(T obj) {
        Entity<?> en = holder.getEntityBy(obj);
        Pojo pojo = pojoMaker.makeQuery(en)
                             .append(Pojos.Items.cndAuto(en, obj))
                             .setAfter(_pojo_fetchEntity)
                             .setPager(createPager(1, 1));
        _exec(pojo);
        return (T) pojo.getResult();
    }

    public <T> T fetch(Class<T> classOfT) {
        List<T> list = query(classOfT, null, createPager(1, 1));
        if (null != list && !list.isEmpty())
            return list.get(0);
        return null;
    }

    public <T> T fetchLinks(T obj, final String regex) {
        return fetchLinks(obj, regex, null);
    }

    public <T> T fetchLinks(final T obj, final String regex, final Condition cnd) {
        if (null == obj)
            return null;
        Lang.each(obj, false, new Each<Object>() {
            public void invoke(int index, Object ele, int length) throws ExitLoop, ContinueLoop,
                    LoopException {
                EntityOperator opt = _optBy(ele);
                if (null == opt)
                    return;
                opt.entity.visitMany(ele, regex, doLinkQuery(opt, cnd));
                opt.entity.visitManyMany(ele, regex, doLinkQuery(opt, cnd));
                opt.entity.visitOne(ele, regex, doFetch(opt));
                opt.exec();
            }
        });
        return obj;
    }

    public int clear(Class<?> classOfT, Condition cnd) {
        Pojo pojo = pojoMaker.makeDelete(holder.getEntity(classOfT)).append(Pojos.Items.cnd(cnd));
        _exec(pojo);
        return pojo.getUpdateCount();
    }

    public int clear(String tableName, Condition cnd) {
        Pojo pojo = pojoMaker.makeDelete(tableName).append(Pojos.Items.cnd(cnd));
        _exec(pojo);
        return pojo.getUpdateCount();
    }

    public int clear(Class<?> classOfT) {
        return clear(classOfT, null);
    }

    public int clear(String tableName) {
        return clear(tableName, null);
    }

    public <T> T clearLinks(T obj, final String regex) {
        if (null == obj)
            return null;
        Lang.each(obj, false, new Each<Object>() {
            public void invoke(int index, Object ele, int length) throws ExitLoop, ContinueLoop,
                    LoopException {
                EntityOperator opt = _optBy(ele);
                if (null == opt)
                    return;
                opt.entity.visitMany(ele, regex, doClear(opt));
                opt.entity.visitManyMany(ele, regex, doClearRelationByHostField(opt));
                opt.entity.visitOne(ele, regex, doClear(opt));

                opt.exec();
            }
        });
        return obj;
    }

    public <T> Entity<T> getEntity(Class<T> classOfT) {
        return holder.getEntity(classOfT);
    }

    public int count(Class<?> classOfT, Condition cnd) {
        Entity<?> en = holder.getEntity(classOfT);
        return _count(en, en.getViewName(), cnd);
    }

    public int count(Class<?> classOfT) {
        Entity<?> en = holder.getEntity(classOfT);
        return _count(en, en.getViewName(), null);
    }

    public int count(String tableName) {
        return count(tableName, null);
    }

    public int count(String tableName, Condition cnd) {
        return _count(null, tableName, cnd);
    }

    private int _count(Entity<?> en, String tableName, Condition cnd) {
        // 如果有条件的话
        if (null != cnd) {
            Pojo pojo = pojoMaker.makeFunc(tableName, "COUNT", "*");
            pojo.setEntity(en);
            // 高级条件接口,直接得到 WHERE 子句
            if (cnd instanceof Criteria) {
                pojo.append(((Criteria) cnd).where());
            }
            // 否则暴力获取 WHERE 子句
            else {
                String str = Pojos.formatCondition(en, cnd);
                if (!Strings.isBlank(str)) {
                    String[] ss = str.toUpperCase().split("ORDER BY");
                    pojo.append(Pojos.Items.wrap(str.substring(0, ss[0].length())));
                }
            }
            // 设置回调,并执行 SQL
            pojo.setAfter(_pojo_fetchInt);
            _exec(pojo);
            return pojo.getInt();
        }
        // 没有条件,直接生成表达式
        return func(tableName, "COUNT", "*");
    }

    public int getMaxId(Class<?> classOfT) {
        Entity<?> en = holder.getEntity(classOfT);
        return func(en.getViewName(), "MAX", en.getIdField().getColumnName());
    }

    public int func(Class<?> classOfT, String funcName, String fieldName) {
        return func(classOfT, funcName, fieldName, null);
    }

    public int func(String tableName, String funcName, String colName) {
        return func(tableName, funcName, colName, null);
    }

    public int func(Class<?> classOfT, String funcName, String colName, Condition cnd) {
        Entity<?> en = holder.getEntity(classOfT);
        if (null != en.getField(colName))
            colName = en.getField(colName).getColumnName();
        DaoStatement pojo = pojoMaker.makeFunc(en.getViewName(), funcName, colName)
                                     .append(Pojos.Items.cnd(cnd))
                                     .setAfter(_pojo_fetchInt)
                                     .setEntity(en);
        _exec(pojo);
        return pojo.getInt();
    }

    public int func(String tableName, String funcName, String colName, Condition cnd) {
        DaoStatement pojo = pojoMaker.makeFunc(tableName, funcName, colName)
                                     .append(Pojos.Items.cnd(cnd))
                                     .setAfter(_pojo_fetchInt);
        _exec(pojo);
        return pojo.getInt();
    }

    public Object func2(Class<?> classOfT, String func2Name, String fieldName) {
        return func2(classOfT, func2Name, fieldName, null);
    }

    public Object func2(String tableName, String func2Name, String colName) {
        return func2(tableName, func2Name, colName, null);
    }

    public Object func2(Class<?> classOfT, String func2Name, String colName, Condition cnd) {
        Entity<?> en = holder.getEntity(classOfT);
        if (null != en.getField(colName))
            colName = en.getField(colName).getColumnName();
        DaoStatement pojo = pojoMaker.makeFunc(en.getViewName(), func2Name, colName)
                                     .append(Pojos.Items.cnd(cnd))
                                     .setAfter(_pojo_fetchObject)
                                     .setEntity(en);
        _exec(pojo);
        return pojo.getResult();
    }

    public Object func2(String tableName, String func2Name, String colName, Condition cnd) {
        DaoStatement pojo = pojoMaker.makeFunc(tableName, func2Name, colName)
                                     .append(Pojos.Items.cnd(cnd))
                                     .setAfter(_pojo_fetchObject);
        _exec(pojo);
        return pojo.getResult();
    }

    public Pager createPager(int pageNumber, int pageSize) {
        Pager pager = new Pager();
        pager.setPageNumber(pageNumber);
        pager.setPageSize(pageSize);
        return pager;
    }

    public synchronized <T> Entity<T> create(Class<T> classOfT, boolean dropIfExists) {
        Entity<T> en = holder.getEntity(classOfT);
        if (exists(en.getTableName())) {
            if (dropIfExists) {
                expert.dropEntity(this, en);
            } else {
                return en;
            }
        }
        return holder.reloadEntity(this, classOfT);
    }

    public boolean drop(Class<?> classOfT) {
        Entity<?> en = holder.getEntity(classOfT);
        if (!exists(en.getTableName()))
            return false;
        return expert.dropEntity(this, en);
    }

    public boolean drop(String tableName) {
        if (!exists(tableName))
            return false;
        Sql sql = Sqls.createf("DROP TABLE %s", tableName);
        _exec(sql);
        return true;
    }

    public boolean exists(Class<?> classOfT) {
        return exists(getEntity(classOfT).getViewName());
    }

    public boolean exists(final String tableName) {
        final boolean[] ee = {false};
        this.run(new ConnCallback() {
            public void invoke(Connection conn) {
                Statement stat = null;
                ResultSet rs = null;
                try {
                    stat = conn.createStatement();
                    // 增加不等式,减少sql执行时间
                    String sql = "SELECT COUNT(1) FROM " + tableName + " where 1!=1";
                    rs = stat.executeQuery(sql);
                    if (rs.next())
                        ee[0] = true;
                }
                catch (SQLException e) {}
                finally {
                    Daos.safeClose(stat, rs);
                }
            }
        });
        return ee[0];
    }

    // ==========================================================
    // 下面几个是快速创建映射操作回调的帮助函数

    private LinkVisitor doInsert(EntityOperator opt) {
        return new DoInsertLinkVisitor().opt(opt);
    }

    private LinkVisitor doInsertRelation(EntityOperator opt) {
        return new DoInsertRelationLinkVisitor(holder).opt(opt);
    }

    private LinkVisitor doUpdate(EntityOperator opt) {
        return new DoUpdateLinkVisitor().opt(opt);
    }

    private LinkVisitor doUpdateRelation(EntityOperator opt, Chain chain, Condition cnd) {
        return new DoUpdateRelationLinkVisitor(chain.toMap(), cnd).opt(opt);
    }

    private LinkVisitor doClearRelationByLinkedField(EntityOperator opt) {
        return new DoClearRelationByLinkedFieldLinkVisitor().opt(opt);
    }

    private LinkVisitor doClearRelationByHostField(EntityOperator opt) {
        return new DoClearRelationByHostFieldLinkVisitor().opt(opt);
    }

    private LinkVisitor doDelete(EntityOperator opt) {
        return new DoDeleteLinkVisitor().opt(opt);
    }

    private LinkVisitor doClear(EntityOperator opt) {
        return new DoClearLinkVisitor().opt(opt);
    }

    private LinkVisitor doFetch(final EntityOperator opt) {
        return new LinkVisitor() {
            public void visit(final Object obj, final LinkField lnk) {
                Pojo pojo = opt.maker().makeQuery(lnk.getLinkedEntity());
                pojo.setOperatingObject(obj);
                pojo.append(Pojos.Items.cnd(lnk.createCondition(obj)));
                pojo.setAfter(lnk.getCallback());
                _exec(pojo);
                lnk.setValue(obj, pojo.getObject(Object.class));
            }
        };
    }

    private LinkVisitor doLinkQuery(final EntityOperator opt, final Condition cnd) {
        return new LinkVisitor() {
            public void visit(final Object obj, final LinkField lnk) {
                Pojo pojo = opt.maker().makeQuery(lnk.getLinkedEntity());
                pojo.setOperatingObject(obj);
                PItem[] _cndItems = Pojos.Items.cnd(lnk.createCondition(obj));
                pojo.append(_cndItems);
                if (cnd != null) {
                    if (cnd instanceof Criteria) {
                        Criteria cri = (Criteria) cnd;
                        SqlExpressionGroup seg = cri.where();
                        if (_cndItems.length > 0 && seg != null && !seg.isEmpty()) {
                            seg.setTop(false);
                            pojo.append(Pojos.Items.wrap(" AND "));
                        }
                        pojo.append(cri);
                        if (cri.getPager() != null) {
                            pojo.setPager(cri.getPager());
                            expert.formatQuery(pojo);
                        }
                    }
                    // 普通条件
                    else {
                        pojo.append(new ConditionPItem(cnd));
                    }
                }
                pojo.setAfter(lnk.getCallback());
                pojo.setEntity(lnk.getLinkedEntity());
                _exec(pojo);
                lnk.setValue(obj, pojo.getResult());
            }
        };
    }

    // ==========================================================
    // 下面几个是快速创建实体操作对象的帮助函数

    private <T> EntityOperator _opt() {
        EntityOperator opt = new EntityOperator();
        opt.dao = this;
        return opt;
    }

    <T> EntityOperator _opt(Entity<T> en) {
        EntityOperator opt = _opt();
        opt.entity = en;
        return opt;
    }

    <T> EntityOperator _opt(Class<T> classOfT) {
        return _opt(holder.getEntity(classOfT));
    }

    EntityOperator _optBy(Object obj) {
        // 阻止空对象
        if (null == obj)
            return null;
        // 对象是否有内容,这里会考虑集合与数组
        Entity<?> en = holder.getEntityBy(obj);
        if (null == en)
            return null;
        // 创建操作对象
        EntityOperator re = _opt(en);
        re.myObj = obj.getClass().isArray() ? Lang.array2list((Object[]) obj) : obj;
        return re;
    }

    // ---------------------------------------------------------------
    // 专属于NutDao的一些帮助方法

    /**
     * 当本对象被GC的时候,打印之.
     * <p/>
     * 因为NutDao是线程安全的,用户反复创建NutDao的话,下面的方法将有提示作用
     */
    protected void finalize() throws Throwable {
        log.debugf("%s[_selfId=%d] finalize", getClass().getSimpleName(), _selfId);
        super.finalize();
    }

    public void setExpert(Object obj) throws Exception {
        if (obj == null)
            throw new NullPointerException("expert MUST NOT NULL!!");
        if (obj instanceof JdbcExpert) {
            this.expert = (JdbcExpert) obj;
        } else {
            String name = obj.toString();
            this.expert = Jdbcs.getExpert(name, "");
            if (this.expert == null) {
                if (name.contains(".")) {
                    this.expert = (JdbcExpert) Lang.loadClass(name).newInstance();
                } else {
                    throw new DaoException("not such expert=" + obj);
                }
            }
        }
        DataSource ds = this.dataSource;
        // 如果数据源比expert先设置,那么需要重新设置一次
        if (ds != null) {
            this.dataSource = null;
            setDataSource(ds);
        }
    }

    public Sql execute(Sql sql) {
        if (sql != null)
            execute(new Sql[]{sql});
        return sql;
    }
}


text:
package egcmd

import (
	"reflect"
	"testing"
)

func TestLevelExample(t *testing.T) {
	level := Level{name: "root"}
	testCases := []struct {
		name        string
		arguments   string
		description string
		want        Example
	}{
		{
			"NoArguments",
			"",
			"Default behaviour",
			Example{Description: "Default behaviour"},
		},
		{
			"WithArguments",
			"--verbose",
			"verbose output",
			Example{Arguments: "--verbose", Description: "verbose output"},
		},
	}

	for i, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			actual := level.Example(tc.arguments, tc.description)
			count := i + 1

			if got := len(level.examples); count != got {
				t.Errorf("Expected level example count to be %d, got %d", count, got)
			}
			if got := *actual; tc.want != got {
				t.Errorf("Expected returned example to be %v, got %v", tc.want, got)
			}
			if got := *level.examples[i]; tc.want != got {
				t.Errorf("Expected level example %d to be %v, got %v", i, tc.want, got)
			}
		})
	}
}

func TestLevelEnvs(t *testing.T) {
	level := Level{name: "root"}
	testCases := []struct {
		name        string
		envVars     string
		arguments   string
		description string
		want        Example
	}{
		{
			"NoEnvs",
			"",
			"",
			"Default behaviour",
			Example{Description: "Default behaviour"},
		},
		{
			"WithEnvs",
			"LOGGING=verbose",
			"",
			"verbose output",
			Example{EnvVars: "LOGGING=verbose", Description: "verbose output"},
		},
	}

	for i, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			actual := level.Envs(tc.envVars, tc.arguments, tc.description)
			count := i + 1

			if got := len(level.examples); count != got {
				t.Errorf("Expected level example count to be %d, got %d", count, got)
			}
			if got := *actual; tc.want != got {
				t.Errorf("Expected returned example to be %v, got %v", tc.want, got)
			}
			if got := *level.examples[i]; tc.want != got {
				t.Errorf("Expected level example %d to be %v, got %v", i, tc.want, got)
			}
		})
	}
}

func TestAppCommand(t *testing.T) {
	app := App{Level: Level{name: "root"}, commands: make(map[string]*Command)}
	testCases := []struct {
		name             string
		command          string
		exampleToAppend  *Example
		duplicateCommand bool
	}{
		{
			"FirstCommand",
			"init",
			&Example{Description: "first"},
			false,
		},
		{
			"DuplicateCommand",
			"init",
			&Example{Description: "second"},
			true,
		},
		{
			"NextCommand",
			"LOGGING=verbose",
			&Example{Description: "next"},
			false,
		},
	}

	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			actual := app.Command(tc.command)
			isDuplicate := len(actual.examples) > 0
			appCommand, found := app.commands[tc.command]

			actual.examples = append(actual.examples, tc.exampleToAppend)

			if got := actual.name; tc.command != got {
				t.Errorf("Expected returned command to be %q, got %q", tc.command, got)
			}

			if !found {
				t.Errorf("Expected command in app to be present, but was not found")
				return
			}

			if got := appCommand.name; tc.command != got {
				t.Errorf("Expected command in app to have the name %q, got %q", tc.command, got)
			}
			if got := isDuplicate; tc.duplicateCommand != got {
				t.Errorf("Expected command to have an example count of %t, got %t", tc.duplicateCommand, got)
			}

		})
	}
}

func TestAppFind(t *testing.T) {
	appExamples := []*Example{
		{"", "Action: default", ""},
		{"simple", "Action: simple", ""},
		{"complex sub-action", "Action: complex sub-action", ""},
	}
	simpleExamples := []*Example{
		{"", "Default for simple", ""},
		{"--debug", "Simple with debug", ""},
	}
	complexExamples := []*Example{
		{"--json", "Default for complex with json arg", ""},
		{"sub-action", "complex action with sub-action", ""},
	}
	subActionExamples := []*Example{
		{"", "Subaction", "APP_KEY=1234"},
	}

	app := App{
		Level: Level{"root", appExamples},
		commands: map[string]*Command{
			"simple":             {Level: Level{"simple", simpleExamples}},
			"complex":            {Level: Level{"complex", complexExamples}},
			"complex sub-action": {Level: Level{"complex sub-action", subActionExamples}},
		},
	}

	testCases := []struct {
		testName string
		command  string
		want     ExamplesFound
	}{
		{
			"Root",
			"",
			ExamplesFound{Context: "root", Examples: appExamples},
		},
		{
			"SimpleCommand",
			"simple",
			ExamplesFound{Context: "root simple", Examples: simpleExamples},
		},
		{
			"ComplexCommand",
			"complex",
			ExamplesFound{Context: "root complex", Examples: complexExamples},
		},
		{
			"ComplexSubCommand",
			"complex sub-action",
			ExamplesFound{Context: "root complex sub-action", Examples: subActionExamples},
		},
		{
			"CommandNotFound",
			"no-match",
			ExamplesFound{Context: "root no-match"},
		},
	}

	for _, tc := range testCases {
		t.Run(tc.testName, func(t *testing.T) {
			got := app.Find(tc.command)

			if tc.want.Context != got.Context {
				t.Errorf("Expected context to be %#v, got %#v", tc.want, got)
			}

			if !reflect.DeepEqual(tc.want.Examples, got.Examples) {
				t.Errorf("Expected the examples found to be list %#v, got %#v", tc.want, got)
			}
		})
	}
}

redpajama_set_name: RedPajamaGithub


text:
// Copyright 2014 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.lib.pkgcache;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Verify;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.packages.BuildFileNotFoundException;
import com.google.devtools.build.lib.packages.NoSuchPackageException;
import com.google.devtools.build.lib.vfs.FileStatus;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.Symlinks;
import com.google.devtools.build.lib.vfs.UnixGlob;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;

/**
 * A mapping from the name of a package to the location of its BUILD file.
 * The implementation composes an ordered sequence of directories according to
 * the package-path rules.
 *
 *
All methods are thread-safe, and (assuming no change to the underlying
 * filesystem) idempotent.
 */
public class PathPackageLocator implements Serializable {

  public static final Set<String> DEFAULT_TOP_LEVEL_EXCLUDES = ImmutableSet.of("experimental");

  private final ImmutableList<Path> pathEntries;
  // Transient because this is an injected value in Skyframe, and as such, its serialized
  // representation is used as a key. We want a change to output base not to invalidate things.
  private final transient Path outputBase;

  public static final PathPackageLocator EMPTY =
      new PathPackageLocator(null, ImmutableList.<Path>of());

  @VisibleForTesting
  public PathPackageLocator(Path outputBase, List<Path> pathEntries) {
    this.outputBase = outputBase;
    this.pathEntries = ImmutableList.copyOf(pathEntries);
  }

  /**
   * Constructs a PathPackageLocator based on the specified list of package root directories.
   */
  @VisibleForTesting
  public PathPackageLocator(Path... pathEntries) {
    this(null, Arrays.asList(pathEntries));
  }

  /**
   * Returns the path to the build file for this package.
   *
   *
The package's root directory may be computed by calling getParentFile()
   * on the result of this function.
   *
   *
Instances of this interface do not attempt to do any caching, nor
   * implement checks for package-boundary crossing logic; the PackageCache
   * does that.
   *
   *
If the same package exists beneath multiple package path entries, the
   * first path that matches always wins.
   */
  public Path getPackageBuildFile(PackageIdentifier packageName) throws NoSuchPackageException {
    Path buildFile  = getPackageBuildFileNullable(packageName, UnixGlob.DEFAULT_SYSCALLS_REF);
    if (buildFile == null) {
      throw new BuildFileNotFoundException(packageName, "BUILD file not found on package path");
    }
    return buildFile;
  }

  /**
   * Like #getPackageBuildFile(), but returns null instead of throwing.
   *  @param packageIdentifier the name of the package.
   * @param cache a filesystem-level cache of stat() calls.
   */
  public Path getPackageBuildFileNullable(PackageIdentifier packageIdentifier,
      AtomicReference<? extends UnixGlob.FilesystemCalls> cache)  {
    if (packageIdentifier.getRepository().isDefault()) {
      return getFilePath(packageIdentifier.getPackageFragment().getRelative("BUILD"), cache);
    } else if (!packageIdentifier.getRepository().isDefault()) {
      Verify.verify(outputBase != null, String.format(
          "External package '%s' needs to be loaded but this PathPackageLocator instance does not "
              + "support external packages", packageIdentifier));
      // This works only to some degree, because it relies on the presence of the repository under
      // $OUTPUT_BASE/external, which is created by the appropriate RepositoryValue. This is true
      // for the invocation in GlobCache, but not for the locator.getBuildFileForPackage()
      // invocation in Parser#include().
      Path buildFile = outputBase.getRelative(
          packageIdentifier.getPathFragment()).getRelative("BUILD");
      FileStatus stat = cache.get().statNullable(buildFile, Symlinks.FOLLOW);
      if (stat != null && stat.isFile()) {
        return buildFile;
      } else {
        return null;
      }
    } else {
      return null;
    }
  }

  /**
   * Returns an immutable ordered list of the directories on the package path.
   */
  public ImmutableList<Path> getPathEntries() {
    return pathEntries;
  }

  @Override
  public String toString() {
    return "PathPackageLocator" + pathEntries;
  }

  /**
   * A factory of PathPackageLocators from a list of path elements.  Elements
   * may contain "%workspace%", indicating the workspace.
   *
   * @param outputBase the output base. Can be null if remote repositories are not in use.
   * @param pathElements Each element must be an absolute path, relative path,
   *                     or some string "%workspace%" + relative, where relative is itself a
   *                     relative path.  The special symbol "%workspace%" means to interpret
   *                     the path relative to the nearest enclosing workspace.  Relative
   *                     paths are interpreted relative to the client's working directory,
   *                     which may be below the workspace.
   * @param eventHandler The eventHandler.
   * @param workspace The nearest enclosing package root directory.
   * @param clientWorkingDirectory The client's working directory.
   * @param checkExistence If true, verify that the element exists before adding it to the locator.
   * @return a list of {@link Path}s.
   */
  public static PathPackageLocator create(Path outputBase,
                                          List<String> pathElements,
                                          EventHandler eventHandler,
                                          Path workspace,
                                          Path clientWorkingDirectory,
                                          boolean checkExistence) {
    List<Path> resolvedPaths = new ArrayList<>();
    final String workspaceWildcard = "%workspace%";

    for (String pathElement : pathElements) {
      // Replace "%workspace%" with the path of the enclosing workspace directory.
      pathElement = pathElement.replace(workspaceWildcard, workspace.getPathString());

      PathFragment pathElementFragment = new PathFragment(pathElement);

      // If the path string started with "%workspace%" or "/", it is already absolute,
      // so the following line is a no-op.
      Path rootPath = clientWorkingDirectory.getRelative(pathElementFragment);

      if (!pathElementFragment.isAbsolute() && !clientWorkingDirectory.equals(workspace)) {
        eventHandler.handle(
            Event.warn("The package path element '" + pathElementFragment + "' will be "
                + "taken relative to your working directory. You may have intended "
                + "to have the path taken relative to your workspace directory. "
                + "If so, please use the '" + workspaceWildcard + "' wildcard."));
      }

      if (!checkExistence || rootPath.exists()) {
        resolvedPaths.add(rootPath);
      }
    }

    return new PathPackageLocator(outputBase, resolvedPaths);
  }

    /**
     * A factory of PathPackageLocators from a list of path elements.  Elements
     * may contain "%workspace%", indicating the workspace.
     *
     * @param outputBase the output base. Can be null if remote repositories are not in use.
     * @param pathElements Each element must be an absolute path, relative path,
     *                     or some string "%workspace%" + relative, where relative is itself a
     *                     relative path.  The special symbol "%workspace%" means to interpret
     *                     the path relative to the nearest enclosing workspace.  Relative
     *                     paths are interpreted relative to the client's working directory,
     *                     which may be below the workspace.
     * @param eventHandler The eventHandler.
     * @param workspace The nearest enclosing package root directory.
     * @param clientWorkingDirectory The client's working directory.
     * @return a list of {@link Path}s.
     */
    public static PathPackageLocator create(Path outputBase,
            List<String> pathElements, EventHandler eventHandler, Path workspace,
            Path clientWorkingDirectory) {
        return create(outputBase, pathElements, eventHandler, workspace, clientWorkingDirectory,
                /*checkExistence=*/true);
    }

  /**
   * Returns the path to the WORKSPACE file for this build.
   *
   *
If there are WORKSPACE files beneath multiple package path entries, the first one always
   * wins.
   */
  public Path getWorkspaceFile() {
    AtomicReference<? extends UnixGlob.FilesystemCalls> cache = UnixGlob.DEFAULT_SYSCALLS_REF;
    // TODO(bazel-team): correctness in the presence of changes to the location of the WORKSPACE
    // file.
    return getFilePath(new PathFragment("WORKSPACE"), cache);
  }

  private Path getFilePath(PathFragment suffix,
      AtomicReference<? extends UnixGlob.FilesystemCalls> cache) {
    for (Path pathEntry : pathEntries) {
      Path buildFile = pathEntry.getRelative(suffix);
      FileStatus stat = cache.get().statNullable(buildFile, Symlinks.FOLLOW);
      if (stat != null && stat.isFile()) {
        return buildFile;
      }
    }
    return null;
  }

  @Override
  public int hashCode() {
    return Objects.hash(pathEntries, outputBase);
  }

  @Override
  public boolean equals(Object other) {
    if (this == other) {
      return true;
    }
    if (!(other instanceof PathPackageLocator)) {
      return false;
    }
    PathPackageLocator pathPackageLocator = (PathPackageLocator) other;
    return Objects.equals(getPathEntries(), pathPackageLocator.getPathEntries())
        && Objects.equals(outputBase, pathPackageLocator.outputBase);
  }

  public Path getOutputBase() {
    return outputBase;
  }
}


text:
package com.madebyatomicrobot.vinyl.samples;

import com.madebyatomicrobot.vinyl.annotations.Record;
import com.madebyatomicrobot.vinyl.annotations.Projection;

@Record
public interface Planet {
    @Projection(PlanetContract.Planet._ID)
    long id();

    String name();

    @Projection(PlanetContract.Planet.COLUMN_NAME_RADIUS_IN_METERS)
    double radiusInMeters();

    @Projection(PlanetContract.Planet.COLUMN_NAME_INHABITED_BY_HUMANS)
    boolean inhabitedByHumans();
}


text:
package vpp1908

import (
	govppapi "git.fd.io/govpp.git/api"
	"github.com/ligato/cn-infra/logging"
	vpe_vppcalls "github.com/ligato/vpp-agent/plugins/govppmux/vppcalls"
	vpe_vpp1908 "github.com/ligato/vpp-agent/plugins/govppmux/vppcalls/vpp1908"
	"github.com/ligato/vpp-agent/plugins/vpp/binapi/vpp1908/sr"
	"github.com/ligato/vpp-agent/plugins/vpp/binapi/vpp1908/vpe"
	"github.com/ligato/vpp-agent/plugins/vpp/ifplugin/ifaceidx"
	"github.com/ligato/vpp-agent/plugins/vpp/srplugin/vppcalls"
)

func init() {
	var msgs []govppapi.Message
	msgs = append(msgs, sr.AllMessages()...)
	msgs = append(msgs, vpe.AllMessages()...) // using also vpe -> need to have correct vpp version also for vpe

	vppcalls.Versions["vpp1908"] = vppcalls.HandlerVersion{
		Msgs: msgs,
		New: func(ch govppapi.Channel, ifIndexes ifaceidx.IfaceMetadataIndex, log logging.Logger) vppcalls.SRv6VppAPI {
			return NewSRv6VppHandler(ch, ifIndexes, log)
		},
	}
}

// SRv6VppHandler is accessor for SRv6-related vppcalls methods
type SRv6VppHandler struct {
	vpe_vppcalls.VpeVppAPI

	log          logging.Logger
	ifIndexes    ifaceidx.IfaceMetadataIndex
	callsChannel govppapi.Channel
}

// NewSRv6VppHandler creates new instance of SRv6 vppcalls handler
func NewSRv6VppHandler(vppChan govppapi.Channel, ifIndexes ifaceidx.IfaceMetadataIndex, log logging.Logger) *SRv6VppHandler {
	return &SRv6VppHandler{
		callsChannel: vppChan,
		ifIndexes:    ifIndexes,
		log:          log,
		VpeVppAPI:    vpe_vpp1908.NewVpeHandler(vppChan),
	}
}


text:
package test

import (
	"github.com/nats-io/nats-streaming-server/server"
)

// RunServer launches a server with the specified ID and default options.
func RunServer(ID string) *server.StanServer {
	return server.RunServer(ID)
}

// RunServerWithDebugTrace is a helper to assist debugging
func RunServerWithDebugTrace(ID string, enableSTANDebug, enableSTANTrace, enableNATSDebug, enableNATSTrace bool) *server.StanServer {

	nOpts := server.DefaultNatsServerOptions
	nOpts.Debug = enableNATSDebug
	nOpts.Trace = enableNATSTrace
	nOpts.NoLog = false

	sOpts := server.GetDefaultOptions()
	sOpts.Debug = enableSTANDebug
	sOpts.Trace = enableSTANTrace
	sOpts.ID = ID

	// enable logging
	server.ConfigureLogger(sOpts, &nOpts)

	return server.RunServerWithOpts(sOpts, &nOpts)
}


text:
Pattern: Old style class

Issue: -

## Description

Used when a class is defined that does not inherit from another class and does not inherit explicitly from `object`. This message can't be emitted when using Python >= 3.0.

## Further Reading

* [Pylint - C1001](http://pylint-messages.wikidot.com/messages:c1001)


text:
RouterCacheKey const RouterCacheKeyApp = @"RouterCacheDataApp";
RouterCacheKey const RouterCacheKeyRTM = @"RouterCacheDataRTM";
static RouterCacheKey RouterCacheKeyData = @"data";
static RouterCacheKey RouterCacheKeyTimestamp = @"timestamp";

static NSString *serverURLString;
/// { 'module key' : 'URL' }
static NSMutableDictionary<NSString *, NSString *> *customAppServerTable;

@implementation LCRouter

+ (NSString *)serverURLString {
    return serverURLString;
}

+ (void)setServerURLString:(NSString *)URLString {
    serverURLString = [URLString copy];
}

+ (instancetype)sharedInstance
{
    static LCRouter *instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[LCRouter alloc] init];
    });
    return instance;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        self->_lock = [NSLock new];

        NSMutableDictionary *(^ loadCacheToMemoryBlock)(NSString *) = ^NSMutableDictionary *(NSString *key) {
            NSString *filePath = [[LCRouter routerCacheDirectoryPath] stringByAppendingPathComponent:key];
            BOOL isDirectory;
            if ([[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:&isDirectory] && !isDirectory) {
                NSData *data = [NSData dataWithContentsOfFile:filePath];
                if ([data length]) {
                    NSError *error = nil;
                    NSMutableDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
                    if (error || ![NSMutableDictionary _lc_isTypeOf:dictionary]) {
                        if (!error) { error = LCErrorInternalServer([NSString stringWithFormat:@"file: %@ is invalid.", filePath]); }
                        LCLoggerError(LCLoggerDomainDefault, @"%@", error);
                    } else {
                        return dictionary;
                    }
                }
            }
            return [NSMutableDictionary dictionary];
        };
        self->_appRouterMap = loadCacheToMemoryBlock(RouterCacheKeyApp);
        self->_RTMRouterMap = loadCacheToMemoryBlock(RouterCacheKeyRTM);

        self->_isUpdatingAppRouter = false;
        self->_RTMRouterCallbacksMap = [NSMutableDictionary dictionary];

        self->_keyToModule = ({
            @{ RouterKeyAppAPIServer : AppModuleAPI,
               RouterKeyAppEngineServer : AppModuleEngine,
               RouterKeyAppPushServer : AppModulePush,
               RouterKeyAppRTMRouterServer : AppModuleRTMRouter,
               RouterKeyAppStatsServer : AppModuleStats };
        });
    }
    return self;
}

// MARK: - API Version

+ (NSString *)APIVersion
{
    return @"1.1";
}

static NSString * pathWithVersion(NSString *path)
{
    NSString *version = [LCRouter APIVersion];
    if ([path hasPrefix:[@"/" stringByAppendingPathComponent:version]]) {
        return path;
    } else if ([path hasPrefix:version]) {
        return [@"/" stringByAppendingPathComponent:path];
    } else {
        return [[@"/" stringByAppendingPathComponent:version] stringByAppendingPathComponent:path];
    }
}

// MARK: - RTM Router Path

+ (NSString *)RTMRouterPath
{
    return @"/v1/route";
}

// MARK: - Disk Cache

+ (NSString *)routerCacheDirectoryPath
{
    return [LCPersistenceUtils homeDirectoryLibraryCachesLeanCloudCachesRouter];
}

static void cachingRouterData(NSDictionary *routerDataMap, RouterCacheKey key)
{
#if DEBUG
    assert(routerDataMap);
    assert(key);
#endif
    NSData *data = ({
        NSError *error = nil;
        NSData *data = [NSJSONSerialization dataWithJSONObject:routerDataMap options:0 error:&error];
        if (error || ![data length]) {
            if (!error) { error = LCErrorInternalServer(@"data invalid."); }
            LCLoggerError(LCLoggerDomainDefault, @"%@", error);
            return;
        }
        data;
    });
    NSString *filePath = ({
        NSString *routerCacheDirectoryPath = [LCRouter routerCacheDirectoryPath];
        BOOL isDirectory;
        BOOL isExists = [[NSFileManager defaultManager] fileExistsAtPath:routerCacheDirectoryPath isDirectory:&isDirectory];
        if (!isExists) {
            NSError *error = nil;
            [[NSFileManager defaultManager] createDirectoryAtPath:routerCacheDirectoryPath withIntermediateDirectories:true attributes:nil error:&error];
            if (error) {
                LCLoggerError(LCLoggerDomainDefault, @"%@", error);
                return;
            }
        } else if (isExists && !isDirectory) {
            LCLoggerError(LCLoggerDomainDefault, @"%@", LCErrorInternalServer(@"can't create directory for router."));
            return;
        }
        [routerCacheDirectoryPath stringByAppendingPathComponent:key];
    });
    [data writeToFile:filePath atomically:true];
}

- (BOOL)cleanCacheWithKey:(RouterCacheKey)key
                    error:(NSError * __autoreleasing *)error
{
    NSParameterAssert(key);
    BOOL result = false;
    NSString *filePath = [[LCRouter routerCacheDirectoryPath] stringByAppendingPathComponent:key];
    if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
        result = [[NSFileManager defaultManager] removeItemAtPath:filePath error:error];
    }
    return result;
}

- (BOOL)cleanCacheWithApplication:(LCApplication *)application
                              key:(RouterCacheKey)key
                            error:(NSError * __autoreleasing *)error
{
    NSString *appID = [application identifierThrowException];
    if (key == RouterCacheKeyApp) {
        [self->_lock lock];
        [self->_appRouterMap removeObjectForKey:appID];
        [self->_lock unlock];
    } else if (key == RouterCacheKeyRTM) {
        [self->_lock lock];
        [self->_RTMRouterMap removeObjectForKey:appID];
        [self->_lock unlock];
    }
    return [self cleanCacheWithKey:key error:error];
}

// MARK: - App Router

- (void)getAppRouterDataWithAppID:(NSString *)appID callback:(void (^)(NSDictionary *dataDictionary, NSError *error))callback
{
    NSParameterAssert(appID);
    [[LCPaasClient sharedInstance] getObject:AppRouterURLString withParameters:@{@"appId":appID} block:^(id _Nullable object, NSError * _Nullable error) {
        if (error) {
            callback(nil, error);
        } else {
            NSDictionary *dictionary = (NSDictionary *)object;
            if ([NSDictionary _lc_isTypeOf:dictionary]) {
                callback(dictionary, nil);
            } else {
                callback(nil, LCErrorInternalServer(@"response data invalid."));
            }
        }
    }];
}

- (void)tryUpdateAppRouterWithAppID:(NSString *)appID callback:(void (^)(NSError *error))callback
{
    NSParameterAssert(appID);
    if (self.isUpdatingAppRouter) {
        return;
    }
    self.isUpdatingAppRouter = true;
    [self getAppRouterDataWithAppID:appID callback:^(NSDictionary *dataDictionary, NSError *error) {
        if (error) { LCLoggerError(LCLoggerDomainDefault, @"%@", error); }
        if (dataDictionary) {
            NSDictionary *routerDataTuple = ({
                @{ RouterCacheKeyData : dataDictionary,
                   RouterCacheKeyTimestamp : @(NSDate.date.timeIntervalSince1970) };
            });
            NSDictionary *appRouterMapCopy = nil;
            [self->_lock lock];
            self->_appRouterMap[appID] = routerDataTuple;
            appRouterMapCopy = [self->_appRouterMap copy];
            [self->_lock unlock];
            cachingRouterData(appRouterMapCopy, RouterCacheKeyApp);
        }
        self.isUpdatingAppRouter = false;
        if (callback) { callback(error); }
    }];
}

- (NSString *)appURLForPath:(NSString *)path appID:(NSString *)appID
{
    NSParameterAssert(path);
    NSParameterAssert(appID);

    RouterKey serverKey = serverKeyForPath(path);

    NSString *(^constructedURL)(NSString *) = ^NSString *(NSString *host) {
        if ([serverKey isEqualToString:RouterKeyAppRTMRouterServer]) {
            return absoluteURLStringWithHostAndPath(host, path);
        } else {
            return absoluteURLStringWithHostAndPath(host, pathWithVersion(path));
        }
    };

    ({  /// get server URL from custom server table.
        NSString *customServerURL = [NSString _lc_decoding:customAppServerTable key:serverKey];
        if ([customServerURL length]) {
            return constructedURL(customServerURL);
        }
    });

    if ([LCRouter serverURLString].length) {
        return constructedURL([LCRouter serverURLString]);
    }

    if ([appID hasSuffix:AppIDSuffixUS]) {
        NSDictionary *appRouterDataTuple = nil;
        [self->_lock lock];
        appRouterDataTuple = [NSDictionary _lc_decoding:self->_appRouterMap key:appID];
        [self->_lock unlock];
        if (shouldUpdateRouterData(appRouterDataTuple)) {
            [self tryUpdateAppRouterWithAppID:appID callback:nil];
        }
        NSDictionary *dataDic = [NSDictionary _lc_decoding:appRouterDataTuple key:RouterCacheKeyData];
        NSString *serverURL = [NSString _lc_decoding:dataDic key:serverKey];
        if ([serverURL length]) {
            return constructedURL(serverURL);
        } else {
            NSString *fallbackServerURL = [self appRouterFallbackURLWithKey:serverKey appID:appID];
            return constructedURL(fallbackServerURL);
        }
    }

    return nil;
}

+ (NSString *)appDomainForAppID:(NSString *)appID
{
    NSString *appDomain;
    if ([appID hasSuffix:AppIDSuffixCN]) {
        appDomain = AppDomainCN;
    } else if ([appID hasSuffix:AppIDSuffixCE]) {
        appDomain = AppDomainCE;
    } else if ([appID hasSuffix:AppIDSuffixUS]) {
        appDomain = AppDomainUS;
    } else {
        appDomain = AppDomainCN;
    }
    return appDomain;
}

- (NSString *)appRouterFallbackURLWithKey:(NSString *)key appID:(NSString *)appID
{
    NSParameterAssert(key);
    NSParameterAssert(appID);
    return [NSString stringWithFormat:@"%@.%@.%@",
            [[appID substringToIndex:8] lowercaseString],
            self->_keyToModule[key],
            [LCRouter appDomainForAppID:appID]];
}

// MARK: - RTM Router

- (NSString *)RTMRouterURLForAppID:(NSString *)appID
{
    NSParameterAssert(appID);
    return [self appURLForPath:[LCRouter RTMRouterPath] appID:appID];
}

- (void)getRTMRouterDataWithAppID:(NSString *)appID RTMRouterURL:(NSString *)RTMRouterURL callback:(void (^)(NSDictionary *dataDictionary, NSError *error))callback
{
    NSParameterAssert(appID);
    NSParameterAssert(RTMRouterURL);
    LCPaasClient *paasClient = [LCPaasClient sharedInstance];
    NSURLRequest *request = [paasClient requestWithPath:RTMRouterURL
                                                 method:@"GET"
                                                headers:nil
                                             parameters:@{
                                                 @"appId": appID,
                                                 @"secure": @"1",
                                             }];
    [paasClient performRequest:request success:^(NSHTTPURLResponse *response, id responseObject) {
        if ([NSDictionary _lc_isTypeOf:responseObject]) {
            callback(responseObject, nil);
        } else {
            callback(nil, LCError(LCErrorInternalErrorCodeMalformedData,
                                  @"Response data is malformed.",
                                  @{ @"data": (responseObject ?: @"nil") }));
        }
    } failure:^(NSHTTPURLResponse *response, id responseObject, NSError *error) {
        callback(nil, error);
    }];
}

- (void)getAndCacheRTMRouterDataWithAppID:(NSString *)appID RTMRouterURL:(NSString *)RTMRouterURL callback:(void (^)(NSDictionary *dataDictionary, NSError *error))callback
{
    NSParameterAssert(appID);
    NSParameterAssert(RTMRouterURL);
    [self getRTMRouterDataWithAppID:appID RTMRouterURL:RTMRouterURL callback:^(NSDictionary *dataDictionary, NSError *error) {
        if (error) {
            callback(nil, error);
            return;
        }
        NSDictionary *routerDataTuple = ({
            @{ RouterCacheKeyData : dataDictionary,
               RouterCacheKeyTimestamp : @(NSDate.date.timeIntervalSince1970) };
        });
        NSDictionary *RTMRouterMapCopy = nil;
        [self->_lock lock];
        self->_RTMRouterMap[appID] = routerDataTuple;
        RTMRouterMapCopy = [self->_RTMRouterMap copy];
        [self->_lock unlock];
        cachingRouterData(RTMRouterMapCopy, RouterCacheKeyRTM);
        callback(dataDictionary, nil);
    }];
}

- (void)getRTMURLWithAppID:(NSString *)appID callback:(void (^)(NSDictionary *dictionary, NSError *error))callback
{
    NSParameterAssert(appID);

    /// get RTM router URL & try update app router
    NSString *RTMRouterURL = [self RTMRouterURLForAppID:appID];
    if (!RTMRouterURL) {
        callback(nil, LCError(9973, @"RTM Router URL not found.", nil));
        return;
    }

    ({  /// add callback to map
        BOOL addCallbacksToArray = false;
        [self->_lock lock];
        NSMutableArray<void (^)(NSDictionary *, NSError *)> *callbacks = self->_RTMRouterCallbacksMap[appID];
        if (callbacks) {
            [callbacks addObject:callback];
            addCallbacksToArray = true;
        } else {
            callbacks = [NSMutableArray arrayWithObject:callback];
            self->_RTMRouterCallbacksMap[appID] = callbacks;
        }
        [self->_lock unlock];
        if (addCallbacksToArray) {
            return;
        }
    });

    void(^invokeCallbacks)(NSDictionary *, NSError *) = ^(NSDictionary *data, NSError *error) {
        NSMutableArray<void (^)(NSDictionary *, NSError *)> *callbacks = nil;
        [self->_lock lock];
        callbacks = self->_RTMRouterCallbacksMap[appID];
        [self->_RTMRouterCallbacksMap removeObjectForKey:appID];
        [self->_lock unlock];
        for (void (^block)(NSDictionary *, NSError *) in callbacks) {
            block(data, error);
        }
    };

    ({  /// get RTM URL data from memory
        NSDictionary *RTMRouterDataTuple = nil;
        [self->_lock lock];
        RTMRouterDataTuple = [NSDictionary _lc_decoding:self->_RTMRouterMap key:appID];
        [self->_lock unlock];
        if (!shouldUpdateRouterData(RTMRouterDataTuple)) {
            NSDictionary *dataDic = [NSDictionary _lc_decoding:RTMRouterDataTuple key:RouterCacheKeyData];
            invokeCallbacks(dataDic, nil);
            return;
        }
    });

    [self getAndCacheRTMRouterDataWithAppID:appID RTMRouterURL:RTMRouterURL callback:^(NSDictionary *dataDictionary, NSError *error) {
        invokeCallbacks(dataDictionary, error);
    }];
}

// MARK: - Batch Path

- (NSString *)batchPathForPath:(NSString *)path
{
    NSParameterAssert(path);
    return pathWithVersion(path);
}

// MARK: - Custom App URL

+ (void)customAppServerURL:(NSString *)URLString key:(RouterKey)key
{
    if (!customAppServerTable) {
        customAppServerTable = [NSMutableDictionary dictionary];
    }
    if (!key) { return; }
    if (URLString) {
        customAppServerTable[key] = URLString;
    } else {
        [customAppServerTable removeObjectForKey:key];
    }
}

// MARK: - Misc

static BOOL shouldUpdateRouterData(NSDictionary *routerDataTuple)
{
    if (!routerDataTuple) {
        return true;
    }
    NSDictionary *dataDic = [NSDictionary _lc_decoding:routerDataTuple key:RouterCacheKeyData];
    NSTimeInterval lastTimestamp = [[NSNumber _lc_decoding:routerDataTuple key:RouterCacheKeyTimestamp] doubleValue];
    if (!dataDic) {
        return true;
    }
    NSTimeInterval ttl = [[NSNumber _lc_decoding:dataDic key:RouterKeyTTL] doubleValue];
    NSTimeInterval currentTimestamp = [[NSDate date] timeIntervalSince1970];
    if (currentTimestamp >= lastTimestamp && currentTimestamp <= (lastTimestamp + ttl)) {
        return false;
    } else {
        return true;
    }
}

static RouterKey serverKeyForPath(NSString *path)
{
#if DEBUG
    assert(path);
#endif
    if ([path hasPrefix:@"call"] || [path hasPrefix:@"functions"]) {
        return RouterKeyAppEngineServer;
    } else if ([path hasPrefix:@"push"] || [path hasPrefix:@"installations"]) {
        return RouterKeyAppPushServer;
    } else if ([path hasPrefix:@"stats"] || [path hasPrefix:@"statistics"] || [path hasPrefix:@"always_collect"]) {
        return RouterKeyAppStatsServer;
    } else if ([path isEqualToString:[LCRouter RTMRouterPath]]) {
        return RouterKeyAppRTMRouterServer;
    } else {
        return RouterKeyAppAPIServer;
    }
}

static NSString * absoluteURLStringWithHostAndPath(NSString *host, NSString *path)
{
#if DEBUG
    assert(host);
    assert(path);
#endif
    NSString *unifiedHost = ({
        NSString *unifiedHost = nil;
        /// For "example.com:8080", the scheme is "example.com". Here, we need a farther check.
        NSURL *URL = [NSURL URLWithString:host];
        if (URL.scheme && [host hasPrefix:[URL.scheme stringByAppendingString:@"://"]]) {
            unifiedHost = host;
        } else {
            unifiedHost = [@"https://" stringByAppendingString:host];
        }
        unifiedHost;
    });

    NSURLComponents *URLComponents = ({
        NSURLComponents *URLComponents = [[NSURLComponents alloc] initWithString:unifiedHost];
        if ([path length]) {
            NSString *pathString = nil;
            if ([URLComponents.path length]) {
                pathString = [URLComponents.path stringByAppendingPathComponent:path];
            } else {
                pathString = path;
            }
            NSURL *pathURL = [NSURL URLWithString:pathString];
            URLComponents.path = pathURL.path;
            URLComponents.query = pathURL.query;
            URLComponents.fragment = pathURL.fragment;
        }
        URLComponents;
    });

    return [[URLComponents URL] absoluteString];
}

@end


text:
package dst.solr

import play.api.Play
import play.api.Logger

import scala.concurrent._
import scala.language.implicitConversions

import play.api.libs.json._
import play.api.libs.ws.WS

import java.net.URLEncoder

object SolrHelper {
  def selectUrl(index: SolrIndex) =                   "http://%s:%d/%s/select".format(index.host, index.port, index.name)
  def updateUrl(index: SolrIndex, commit: Boolean) =  "http://%s:%d/%s/update/json".format(index.host,index.port,index.name) + { if (commit) "?commitWithin=30000" else "" }

  def select(index: SolrIndex, queryString: String, rows: Int = 20)(implicit context: ExecutionContext) = {
    WS.url(selectUrl(index) + "?wt=json&rows=%d&q=%s".format(rows,queryString)).withRequestTimeout(5000).get.map { response =>
      val result : Option[JsObject] = try {
        Some(response.json.asInstanceOf[JsObject])
      }
      catch {
        case t: Throwable => {
          Logger.error("Request failed: " + selectUrl(index) + "?wt=json&q=" + queryString, t)
          None
        }
      }

      result
    }
  }

  def select(index: SolrIndex, query: SolrQuery)(implicit context: ExecutionContext) = {
    WS.url(selectUrl(index) +  query.toString).withRequestTimeout(5000).get().map { response =>
      if (response.status == 200) {
        Some(response.json.asInstanceOf[JsObject])
      }
      else {
        Logger.debug("Request failed: " + selectUrl(index) + query.toString + " (status code=" + response.status + ")")
        None
      }
    }
  }

  def insert(value: JsArray, index: SolrIndex, commit: Boolean = true)(implicit context: ExecutionContext) = {
    WS.url(updateUrl(index, commit)).withHeaders("Content-type" -> "application/json").post (value)
  }

  def delete(query: String, index: SolrIndex, commit: Boolean = true)(implicit context: ExecutionContext) = {
    WS.url(updateUrl(index, commit)).post(Json.obj( "delete" -> Json.obj("query" ->query)))
  }
}


text:
package com.communityblogproject;

public class Comment extends Content{
	String authorId,text,postId,date;
	int upvote,downvote;
	public String getAuthorId() {
		return authorId;
	}

	public void setAuthorId(String authorId) {
		this.authorId = authorId;
	}

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}

	public String getPostId() {
		return postId;
	}

	public void setPostId(String postId) {
		this.postId = postId;
	}

	public int getUpvote() {
		return upvote;
	}

	public void setUpvote(int upvote) {
		this.upvote = upvote;
	}

	public int getDownvote() {
		return downvote;
	}

	public void setDownvote(int downvote) {
		this.downvote = downvote;
	}

	public String getDate() {
		return date;
	}

	public void setDate(String date) {
		this.date = date;
	}
}


text:
package com.theateamiu.mms.dao;

import com.theateamiu.mms.models.Manager;

public interface ManagerDAO {
    public static final String DEFAULT_VALUE="";
    public static final String MANAGER_IMAGE_URI = "manager_image_uri";
    public static final String MANAGER_NAME = "manager_name";
    public static final String MANAGER_AGE = "manager_age";
    public static final String MANAGER_PHONE_NO = "manager_phone_no";
    public static final String MANAGER_EMAIL = "manager_email";
    public static final String MANAGER_PROFESSION = "manager_profession";
    public static final String MANAGER_ADDRESS = "manager_address";
    public static final String MANAGER_PASSWORD = "manager_password";

    public Manager getManagerFromSharedPreferences();
    public boolean updateManagerOnSharedPreferences(Manager manager);
}


text:
using System;
using System.Security.Cryptography;

using Granados.PKI;

namespace Granados {

    /// <summary>
    /// Fill the properties of ConnectionParameter object before you start the connection.
    /// </summary>
    /// <exclude/>
    public class SSHConnectionParameter : ICloneable {

        //protocol
        private SSHProtocol _protocol;
        public SSHProtocol Protocol {
            get {
                return _protocol;
            }
            set {
                _versionEOL = value == SSHProtocol.SSH1 ? "\n" : "\r\n";
                _protocol = value;
            }
        }

        //algorithm

        private CipherAlgorithm[] _cipherAlgorithms;
        public CipherAlgorithm[] PreferableCipherAlgorithms {
            get {
                return _cipherAlgorithms;
            }
            set {
                _cipherAlgorithms = value;
            }
        }
        private PublicKeyAlgorithm[] _hostkeyAlgorithms;
        public PublicKeyAlgorithm[] PreferableHostKeyAlgorithms {
            get {
                return _hostkeyAlgorithms;
            }
            set {
                _hostkeyAlgorithms = value;
            }
        }

        //account

        private AuthenticationType _authtype;
        public AuthenticationType AuthenticationType {
            get {
                return _authtype;
            }
            set {
                _authtype = value;
            }
        }
        private string _username;
        public string UserName {
            get {
                return _username;
            }
            set {
                _username = value;
            }
        }
        private string _password;
        public string Password {
            get {
                return _password;
            }
            set {
                _password = value;
            }
        }
        private string _identityFile;
        public string IdentityFile {
            get {
                return _identityFile;
            }
            set {
                _identityFile = value;
            }
        }

        //host
        private HostKeyCheckCallback _keycheck;
        public HostKeyCheckCallback KeyCheck {
            get {
                return _keycheck;
            }
            set {
                _keycheck = value;
            }
        }

        //terminal

        private string _terminalname;
        public string TerminalName {
            get {
                return _terminalname;
            }
            set {
                _terminalname = value;
            }
        }
        private int _width;
        public int TerminalWidth {
            get {
                return _width;
            }
            set {
                _width = value;
            }
        }
        private int _height;
        public int TerminalHeight {
            get {
                return _height;
            }
            set {
                _height = value;
            }
        }
        private int _pixelWidth;
        public int TerminalPixelWidth {
            get {
                return _pixelWidth;
            }
            set {
                _pixelWidth = value;
            }
        }
        private int _pixelHeight;
        public int TerminalPixelHeight {
            get {
                return _pixelHeight;
            }
            set {
                _pixelHeight = value;
            }
        }

        private bool _checkMACError;
        public bool CheckMACError {
            get {
                return _checkMACError;
            }
            set {
                _checkMACError = value;
            }
        }

        //SSH2 only property
        private int _windowsize;
        public int WindowSize {
            get {
                return _windowsize;
            }
            set {
                _windowsize = value;
            }
        }
        //SSH2 only property
        private int _maxpacketsize;
        public int MaxPacketSize {
            get {
                return _maxpacketsize;
            }
            set {
                _maxpacketsize = value;
            }
        }

        //some server may expect irregular end-of-line character(s).
        //initial value is '\n' for SSH1 and '/r/n' for SSH2
        private string _versionEOL;
        public string VersionEOL {
            get {
                return _versionEOL;
            }
            set {
                _versionEOL = value;
            }
        }

        //protocol negotiation tracer (optional)
        private ISSHEventTracer _tracer;
        public ISSHEventTracer EventTracer {
            get {
                return _tracer;
            }
            set {
                _tracer = value;
            }
        }

        //Agent forward (optional)
        private IAgentForward _agentForward;
        public IAgentForward AgentForward {
            get {
                return _agentForward;
            }
            set {
                _agentForward = value;
            }
        }

        public SSHConnectionParameter() {
            _authtype = AuthenticationType.Password;
            _terminalname = "vt100";
            _width = 80;
            _height = 25;
            _protocol = SSHProtocol.SSH2;
            _cipherAlgorithms = new CipherAlgorithm[] { CipherAlgorithm.AES256CTR, CipherAlgorithm.AES256, CipherAlgorithm.AES192CTR, CipherAlgorithm.AES192, CipherAlgorithm.AES128CTR, CipherAlgorithm.AES128, CipherAlgorithm.Blowfish, CipherAlgorithm.TripleDES };
            _hostkeyAlgorithms = new PublicKeyAlgorithm[] { PublicKeyAlgorithm.DSA, PublicKeyAlgorithm.RSA };
            _windowsize = 0x1000;
            _maxpacketsize = 0x10000;
            _checkMACError = true;
            _tracer = null;
        }

        public object Clone() {
            SSHConnectionParameter n = new SSHConnectionParameter();
            n._authtype = _authtype;
            n._cipherAlgorithms = _cipherAlgorithms;
            n._height = _height;
            n._hostkeyAlgorithms = _hostkeyAlgorithms;
            n._identityFile = _identityFile;
            n._keycheck = _keycheck;
            n._maxpacketsize = _maxpacketsize;
            n._password = _password;
            n._protocol = _protocol;
            n._terminalname = _terminalname;
            n._username = _username;
            n._width = _width;
            n._windowsize = _windowsize;
            n._checkMACError = _checkMACError;
            n._tracer = _tracer;
            n._agentForward = _agentForward;
            return n;
        }
    }

    //To receive the events of the SSH protocol negotiation, set an implementation of this interface to ConnectionParameter
    //note that :
    // * these methods are called by different threads asynchronously
    // * DO NOT throw any exceptions in the implementation
    /// <summary>
    ///
    /// </summary>
    /// <exclude/>
    public interface ISSHEventTracer {
        void OnTranmission(string type, string detail);
        void OnReception(string type, string detail);
    }
}


text:
var assert = require('assert'),
	testUtil = require('./testUtil');

var arrowDBEntryPoint = (process.env.ARROWDB_ENTRYPOINT ? process.env.ARROWDB_ENTRYPOINT : 'https://api.cloud.appcelerator.com');
var arrowDBKey = process.env.ARROWDB_APPKEY;
if (!arrowDBKey) {
	console.error('Please create an ArrowDB app and assign ARROWDB_APPKEY in environment vars.');
	process.exit(1);
}
console.log('ArrowDB Entry Point: %s', arrowDBEntryPoint);
console.log('MD5 of ARROWDB_APPKEY: %s', testUtil.md5(arrowDBKey));

var ArrowDB = require('../index'),
	arrowDBApp = new ArrowDB(arrowDBKey, {
		apiEntryPoint: arrowDBEntryPoint,
		prettyJson: true
	}),
	arrowDBUsername = null,
	arrowDBPassword = 'cocoafish',
	event_id = null,
	checkin_id = null,
	custom_object_id = null,
	like_id = null;

describe('Likes Test', function() {
	this.timeout(50000);
	before(function(done) {
		testUtil.generateUsername(function(username) {
			arrowDBUsername = username;
			console.log('\tGenerated arrowdb user: %s', arrowDBUsername);
			done();
		});
	});

	describe('create user and event', function() {
		it('Should create user successfully', function(done) {
			arrowDBApp.usersCreate({
				username: arrowDBUsername,
				password: arrowDBPassword,
				password_confirmation: arrowDBPassword
			}, function(err, result) {
				assert.ifError(err);
				assert(result.body);
				assert(result.body.meta);
				assert.equal(result.body.meta.code, 200);
				assert.equal(result.body.meta.method_name, 'createUser');
				var obj = result.body.response.users[0];
				assert.equal(obj.username, arrowDBUsername);

				arrowDBApp.usersLogin({
					login: arrowDBUsername,
					password: arrowDBPassword
				}, function (err, result) {
					assert.ifError(err);
					assert(result);
					done();
				});
			});
		});

		it('Should create an event successfully', function(done) {
			arrowDBApp.eventsCreate({
				name: 'Test - checkins(event)',
				start_time: new Date(),
				duration: 8
			}, function(err, result) {
				assert.ifError(err);
				assert(result.body);
				assert(result.body.meta);
				assert.equal(result.body.meta.code, 200);
				var obj = result.body.response.events[0];
				event_id = obj.id;
				done();
			});
		});

		it('Should create a checkin successfully - create', function(done) {
			arrowDBApp.checkinsCreate({
				name: 'Test - checkins',
				event_id: event_id
			}, function(err, result) {
				assert.ifError(err);
				assert(result.body);
				assert(result.body.meta);
				assert.equal(result.body.meta.code, 200);
				var obj = result.body.response.checkins[0];
				checkin_id = obj.id;
				done();
			});
		});

		it('Should create a custom object successfully - create', function(done) {
			var classname = 'Car';
			arrowDBApp.customObjectsCreate({
				classname: classname,
				fields: '{"city":"beijing"}'
			}, function(err, result) {
				assert.ifError(err);
				assert(result.body);
				assert(result.body.meta);
				assert.equal(result.body.meta.code, 200);
				assert.equal(result.body.meta.method_name, 'createObject');
				var obj = result.body.response[classname][0];
				assert.equal(obj.city, 'beijing');
				custom_object_id = obj.id;
				done();
			});
		});
	});

	describe('positive likes tests', function() {
		it('Should create a like(event) successfully', function(done) {
			arrowDBApp.likesCreate({
				event_id: event_id
			}, function(err, result) {
				assert.ifError(err);
				assert(result.body);
				assert(result.body.meta);
				assert.equal(result.body.meta.code, 200);
				var obj = result.body.response.likes[0];
				like_id = obj.id;
				assert.equal(obj.likeable_type, 'Event');
				assert.equal(obj.likeable_id, event_id);
				done();
			});
		});

		it('Should create a like(checkin) successfully', function(done) {
			arrowDBApp.likesCreate({
				checkin_id: checkin_id
			}, function(err, result) {
				assert.ifError(err);
				assert(result.body);
				assert(result.body.meta);
				assert.equal(result.body.meta.code, 200);
				var obj = result.body.response.likes[0];
				like_id = obj.id;
				assert.equal(obj.likeable_type, 'Checkin');
				assert.equal(obj.likeable_id, checkin_id);
				done();
			});
		});

		it('Should query likes successfully', function(done) {
			arrowDBApp.likesQuery({}, function(err, result) {
				assert.ifError(err);
				assert(result.body);
				assert(result.body.meta);
				assert.equal(result.body.meta.code, 200);
				done();
			});
		});

		it('Should create a like(custom object) successfully', function(done) {
			arrowDBApp.likesCreate({
				custom_object_id: custom_object_id
			}, function(err, result) {
				assert.ifError(err);
				assert(result.body);
				assert(result.body.meta);
				assert.equal(result.body.meta.code, 200);
				var obj = result.body.response.likes[0];
				assert.equal(obj.likeable_type, 'CustomObject');
				assert.equal(obj.likeable_id, custom_object_id);
				done();
			});
		});

		it('Should delete a like(event) successfully', function(done) {
			arrowDBApp.likesDelete({
				event_id: event_id
			}, function(err, result) {
				assert.ifError(err);
				assert(result.body);
				assert(result.body.meta);
				assert.equal(result.body.meta.code, 200);
				assert.equal(result.body.meta.method_name, 'deleteLike');
				done();
			});
		});

		it('Should delete a like(checkin) successfully', function(done) {
			arrowDBApp.likesDelete({
				checkin_id: checkin_id
			}, function(err, result) {
				assert.ifError(err);
				assert(result.body);
				assert(result.body.meta);
				assert.equal(result.body.meta.code, 200);
				assert.equal(result.body.meta.method_name, 'deleteLike');
				done();
			});
		});

		it('Should delete a like(custom object) successfully', function(done) {
			arrowDBApp.likesDelete({
				custom_object_id: custom_object_id
			}, function(err, result) {
				assert.ifError(err);
				assert(result.body);
				assert(result.body.meta);
				assert.equal(result.body.meta.code, 200);
				assert.equal(result.body.meta.method_name, 'deleteLike');
				done();
			});
		});

		it('Should fail to delete an unlike(custom object) successfully', function(done) {
			arrowDBApp.likesDelete({
				custom_object_id: custom_object_id
			}, function(err) {
				assert(err);
				assert.equal(err.statusCode, 400);
				assert.equal(err.body.meta.message, 'Invalid CustomObject id or current user hasn\'t liked it');
				done();
			});
		});
	});

	describe('negative likes tests', function() {
		it('Should fail to create a like successfully', function(done) {
			arrowDBApp.likesCreate({}, function(err) {
				assert(err);
				assert.equal(err.statusCode, 400);
				assert.equal(err.body.meta.message, 'Invalid like type');
				done();
			});
		});

		it('Should fail to delete a no-existing like(custom object) successfully', function(done) {
			arrowDBApp.likesDelete({
				custom_object_id: '545980ebdda095222c000004'
			}, function(err) {
				assert(err);
				assert.equal(err.statusCode, 400);
				assert.equal(err.body.meta.message, 'custom_object not found');
				done();
			});
		});
	});

	describe('cleanup', function() {
		it('Should delete current user successfully', function(done) {
			arrowDBApp.usersRemove(function(err, result) {
				assert.ifError(err);
				assert(result);
				assert(result.body);
				assert(result.body.meta);
				assert.equal(result.body.meta.code, 200);
				assert.equal(result.body.meta.method_name, 'deleteUser');
				done();
			});
		});
	});
});