/**
 * This file is part of Wikiforia.
 */
package se.lth.cs.nlp.wikipedia.lang;

// Autogenerated from Wikimedia sources at 2015-04-16T13:55:11+00:00
public class IiConfig extends TemplateConfig {

    public IiConfig() {
        addNamespaceAlias(-2, "媒体文件", "媒体");
        addNamespaceAlias(-1, "特殊", "特殊");
        addNamespaceAlias(1, "讨论", "对话", "讨论");
        addNamespaceAlias(2, "用户", "用户");
        addNamespaceAlias(3, "用户讨论", "用户对话", "用户讨论");
        addNamespaceAlias(5, "Wikipedia讨论");
        addNamespaceAlias(6, "文件", "图像", "档案", "文件", "Image");
        addNamespaceAlias(7, "文件讨论", "Image_talk", "图像对话", "图像讨论", "档案对话", "档案讨论", "文件对话", "文件讨论");
        addNamespaceAlias(8, "MediaWiki");
        addNamespaceAlias(9, "MediaWiki讨论");
        addNamespaceAlias(10, "模板", "模板");
        addNamespaceAlias(11, "模板讨论", "模板对话", "模板讨论");
        addNamespaceAlias(12, "帮助", "帮助");
        addNamespaceAlias(13, "帮助讨论", "帮助对话", "帮助讨论");
        addNamespaceAlias(14, "分类", "分类");
        addNamespaceAlias(15, "分类讨论", "分类对话", "分类讨论");
        addI18nCIAlias("redirect", "#重定向", "#REDIRECT");
        addI18nCIAlias("notoc", "__无目录__", "__NOTOC__");
        addI18nCIAlias("nogallery", "__无图库__", "__NOGALLERY__");
        addI18nCIAlias("forcetoc", "__强显目录__", "__FORCETOC__");
        addI18nCIAlias("toc", "__目录__", "__TOC__");
        addI18nCIAlias("noeditsection", "__无编辑段落__", "__无段落编辑__", "__NOEDITSECTION__");
        addI18nAlias("currentmonth", "本月", "本月2", "CURRENTMONTH", "CURRENTMONTH2");
        addI18nAlias("currentmonth1", "本月1", "CURRENTMONTH1");
        addI18nAlias("currentmonthname", "本月名", "本月名称", "CURRENTMONTHNAME");
        addI18nAlias("currentmonthnamegen", "本月名属格", "本月名称属格", "CURRENTMONTHNAMEGEN");
        addI18nAlias("currentmonthabbrev", "本月简称", "CURRENTMONTHABBREV");
        addI18nAlias("currentday", "今天", "CURRENTDAY");
        addI18nAlias("currentday2", "今天2", "CURRENTDAY2");
        addI18nAlias("currentdayname", "星期", "今天名", "今天名称", "CURRENTDAYNAME");
        addI18nAlias("currentyear", "今年", "CURRENTYEAR");
        addI18nAlias("currenttime", "当前时间", "此时", "CURRENTTIME");
        addI18nAlias("currenthour", "当前小时", "CURRENTHOUR");
        addI18nAlias("localmonth", "本地月", "LOCALMONTH", "LOCALMONTH2");
        addI18nAlias("localmonthname", "本地月份名", "LOCALMONTHNAME");
        addI18nAlias("localmonthnamegen", "本地月历", "LOCALMONTHNAMEGEN");
        addI18nAlias("localday", "本地日", "LOCALDAY");
        addI18nAlias("localdayname", "本地日名", "LOCALDAYNAME");
        addI18nAlias("localyear", "本地年", "LOCALYEAR");
        addI18nAlias("localtime", "本地时间", "LOCALTIME");
        addI18nAlias("localhour", "本地小时", "LOCALHOUR");
        addI18nAlias("numberofpages", "页面数", "NUMBEROFPAGES");
        addI18nAlias("numberofarticles", "条目数", "NUMBEROFARTICLES");
        addI18nAlias("numberoffiles", "文件数", "NUMBEROFFILES");
        addI18nAlias("numberofusers", "用户数", "NUMBEROFUSERS");
        addI18nAlias("numberofactiveusers", "活跃用户数", "NUMBEROFACTIVEUSERS");
        addI18nAlias("numberofedits", "编辑数", "NUMBEROFEDITS");
        addI18nAlias("numberofviews", "访问数", "NUMBEROFVIEWS");
        addI18nAlias("pagename", "页名", "页面名", "页面名称", "PAGENAME");
        addI18nAlias("pagenamee", "页名等同", "页面名等同", "页面名E", "PAGENAMEE");
        addI18nAlias("namespace", "名字空间", "NAMESPACE");
        addI18nAlias("namespacee", "名字空间等同", "名字空间E", "NAMESPACEE");
        addI18nAlias("namespacenumber", "名字空间编号", "NAMESPACENUMBER");
        addI18nAlias("talkspace", "讨论空间", "讨论名字空间", "TALKSPACE");
        addI18nAlias("talkspacee", "讨论空间等同", "讨论名字空间E", "TALKSPACEE");
        addI18nAlias("fullpagename", "页面全名", "完整页面名", "FULLPAGENAME");
        addI18nAlias("fullpagenamee", "完整页面名E", "FULLPAGENAMEE");
        addI18nAlias("subpagename", "子页面名", "SUBPAGENAME");
        addI18nAlias("subpagenamee", "子页面名等同", "子页面名E", "SUBPAGENAMEE");
        addI18nAlias("talkpagename", "讨论页面名", "TALKPAGENAME");
        addI18nAlias("talkpagenamee", "讨论页面名等同", "讨论页面名E", "TALKPAGENAMEE");
        addI18nCIAlias("subst", "替代:", "SUBST:");
        addI18nCIAlias("safesubst", "安全替代:", "SAFESUBST:");
        addI18nAlias("img_thumbnail", "缩略图", "thumbnail", "thumb");
        addI18nAlias("img_manualthumb", "缩略图=$1", "thumbnail=$1", "thumb=$1");
        addI18nAlias("img_right", "右", "right");
        addI18nAlias("img_left", "左", "left");
        addI18nAlias("img_none", "无", "none");
        addI18nAlias("img_width", "$1像素", "$1px");
        addI18nAlias("img_center", "居中", "center", "centre");
        addI18nAlias("img_framed", "有框", "framed", "enframed", "frame");
        addI18nAlias("img_frameless", "无框", "frameless");
        addI18nAlias("img_page", "页数=$1", "$1页", "page=$1", "page $1");
        addI18nAlias("img_border", "边框", "border");
        addI18nAlias("img_link", "链接=$1", "link=$1");
        addI18nAlias("img_alt", "替代=$1", "替代文本=$1", "alt=$1");
        addI18nAlias("img_class", "类=$1", "class=$1");
        addI18nCIAlias("int", "界面:", "INT:");
        addI18nAlias("sitename", "站点名称", "SITENAME");
        addI18nCIAlias("ns", "名字空间:", "NS:");
        addI18nCIAlias("nse", "名字空间E:", "NSE:");
        addI18nCIAlias("localurl", "本地URL:", "LOCALURL:");
        addI18nCIAlias("localurle", "本地URLE:", "LOCALURLE:");
        addI18nCIAlias("articlepath", "条目路径", "ARTICLEPATH");
        addI18nCIAlias("pageid", "页面ID", "PAGEID");
        addI18nCIAlias("server", "服务器", "SERVER");
        addI18nCIAlias("servername", "服务器名", "SERVERNAME");
        addI18nCIAlias("scriptpath", "脚本路径", "SCRIPTPATH");
        addI18nCIAlias("stylepath", "样式路径", "STYLEPATH");
        addI18nCIAlias("grammar", "语法:", "GRAMMAR:");
        addI18nCIAlias("gender", "性:", "性别:", "GENDER:");
        addI18nCIAlias("notitleconvert", "__不转换标题__", "__NOTITLECONVERT__", "__NOTC__");
        addI18nCIAlias("nocontentconvert", "__不转换内容__", "__NOCONTENTCONVERT__", "__NOCC__");
        addI18nAlias("currentweek", "本周", "CURRENTWEEK");
        addI18nCIAlias("plural", "复数:", "PLURAL:");
        addI18nCIAlias("fullurl", "完整URL:", "FULLURL:");
        addI18nCIAlias("fullurle", "完整URL等同:", "完整URLE:", "FULLURLE:");
        addI18nCIAlias("lcfirst", "小写首字:", "LCFIRST:");
        addI18nCIAlias("ucfirst", "大写首字:", "UCFIRST:");
        addI18nCIAlias("lc", "小写:", "LC:");
        addI18nCIAlias("uc", "大写:", "UC:");
        addI18nAlias("displaytitle", "显示标题", "DISPLAYTITLE");
        addI18nAlias("newsectionlink", "__新段落链接__", "__NEWSECTIONLINK__");
        addI18nAlias("nonewsectionlink", "__无新段落链接__", "__NONEWSECTIONLINK__");
        addI18nAlias("currentversion", "当前版本", "CURRENTVERSION");
        addI18nCIAlias("urlencode", "URL编码:", "URLENCODE:");
        addI18nCIAlias("anchorencode", "锚编码", "ANCHORENCODE");
        addI18nAlias("currenttimestamp", "当前时间戳", "CURRENTTIMESTAMP");
        addI18nAlias("localtimestamp", "本地时间戳", "LOCALTIMESTAMP");
        addI18nAlias("directionmark", "方向标记", "DIRECTIONMARK", "DIRMARK");
        addI18nCIAlias("language", "#语言:", "#LANGUAGE:");
        addI18nAlias("contentlanguage", "内容语言", "CONTENTLANGUAGE", "CONTENTLANG");
        addI18nAlias("pagesinnamespace", "名字空间中页面数:", "PAGESINNAMESPACE:", "PAGESINNS:");
        addI18nAlias("numberofadmins", "管理员数", "NUMBEROFADMINS");
        addI18nCIAlias("formatnum", "格式化数字", "FORMATNUM");
        addI18nCIAlias("padleft", "左填充", "PADLEFT");
        addI18nCIAlias("padright", "右填充", "PADRIGHT");
        addI18nCIAlias("special", "特殊", "special");
        addI18nCIAlias("speciale", "特殊等同", "特殊e", "speciale");
        addI18nAlias("defaultsort", "默认排序:", "默认排序关键字:", "默认分类排序:", "DEFAULTSORT:", "DEFAULTSORTKEY:", "DEFAULTCATEGORYSORT:");
        addI18nCIAlias("filepath", "文件路径:", "FILEPATH:");
        addI18nCIAlias("tag", "标记", "tag");
        addI18nAlias("hiddencat", "__隐藏分类__", "__HIDDENCAT__");
        addI18nAlias("pagesincategory", "分类中页数", "分类中页面数", "PAGESINCATEGORY", "PAGESINCAT");
        addI18nAlias("pagesize", "页面大小", "PAGESIZE");
        addI18nAlias("index", "__索引__", "__INDEX__");
        addI18nAlias("noindex", "__不索引__", "__NOINDEX__");
        addI18nAlias("numberingroup", "组中用户数", "NUMBERINGROUP", "NUMINGROUP");
        addI18nAlias("staticredirect", "__静态重定向__", "__STATICREDIRECT__");
        addI18nAlias("protectionlevel", "保护级别", "PROTECTIONLEVEL");
        addI18nCIAlias("formatdate", "格式化日期", "日期格式化", "formatdate", "dateformat");
        addI18nCIAlias("defaultsort_noerror", "不报错", "noerror");
        addI18nCIAlias("defaultsort_noreplace", "不替换", "noreplace");
    }

    @Override
    protected String getSiteName() {
        return "Wikipedia";
    }

    @Override
    protected String getWikiUrl() {
        return "http://example.com";
    }

    @Override
    public String getIso639() {
        return


package com.whyalwaysmea.bigboom.view.cast.ui;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import com.jakewharton.rxbinding.support.v7.widget.RxToolbar;
import com.whyalwasymea.bigboom.dao.DBCastDao;
import com.whyalwasymea.bigboom.dao.DaoSession;
import com.whyalwaysmea.bigboom.Constants;
import com.whyalwaysmea.bigboom.R;
import com.whyalwaysmea.bigboom.base.BaseView;
import com.whyalwaysmea.bigboom.base.MvpActivity;
import com.whyalwaysmea.bigboom.bean.CastDetail;
import com.whyalwaysmea.bigboom.bean.CastWork;
import com.whyalwaysmea.bigboom.bean.db.DBCast;
import com.whyalwaysmea.bigboom.db.DBManager;
import com.whyalwaysmea.bigboom.di.component.DaggerCastComponent;
import com.whyalwaysmea.bigboom.di.module.CastModule;
import com.whyalwaysmea.bigboom.view.cast.presenter.CastPresenterImp;
import com.whyalwaysmea.bigboom.view.cast.ui.adapter.CastAdapter;
import com.whyalwaysmea.bigboom.view.cast.ui.adapter.CastWorksAdapter;
import com.whyalwaysmea.bigboom.view.cast.view.ICastDetailView;
import com.whyalwaysmea.bigboom.utils.DensityUtils;
import com.whyalwaysmea.bigboom.widget.FlexibleScrollView;
import com.whyalwaysmea.bigboom.widget.GridMarginDecoration;
import java.util.List;
import javax.inject.Inject;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import static com.whyalwaysmea.bigboom.R.id.profile_layout;

public class CastDetailActivity extends MvpActivity<ICastDetailView, CastPresenterImp> implements ICastDetailView {

    @BindView(R.id.toolbar)
    Toolbar mToolbar;

    @BindView(R.id.photos_recyclerview)
    RecyclerView mPhotosRecyclerview;

    @BindView(R.id.name)
    TextView mName;

    @BindView(R.id.name_en)
    TextView mNameEn;

    @BindView(R.id.profile_content)
    TextView mProfileContent;

    @BindView(profile_layout)
    FrameLayout mProfileLayout;

    @BindView(R.id.works_recyclerview)
    RecyclerView mWorksRecyclerview;

    @BindView(R.id.all_works)
    TextView mAllWorks;

    @BindView(R.id.year)
    TextView mYear;

    @BindView(R.id.collect_cast)
    ImageView mCollectCast;

    @BindView(R.id.swiperefreshlayout)
    SwipeRefreshLayout mSwiperefreshlayout;

    @BindView(R.id.content_view)
    FlexibleScrollView mContentView;

    private String mCastId;

    private CastDetail mCastDetail;

    private GridLayoutManager mGridLayoutManager;

    private LinearLayoutManager mLinearLayoutManager;

    private CastAdapter mCastAdapter;

    private CastWorksAdapter mCastWorksAdapter;

    @Inject
    CastPresenterImp mPresenter;

    @Override
    protected CastPresenterImp createPresenter(BaseView view) {
        return null;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cast_detail);
        ButterKnife.bind(this);
        DaggerCastComponent.builder().castModule(new CastModule(this)).build().inject(this);
        init();
    }

    @Override
    protected void initData() {
        mCastId = getIntent().getStringExtra(Constants.KEY.CASTID);
        if (!TextUtils.isEmpty(mCastId)) {
            mPresenter.getCastDetail(mCastId);
            mPresenter.getCastWorks(mCastId, 0);
        }
    }

    @Override
    protected void initView() {
        mToolbar.setNavigationIcon(R.drawable.icon_back);
        setSupportActionBar(mToolbar);
        RxToolbar.navigationClicks(mToolbar).subscribe(aVoid -> finish());
        mGridLayoutManager = new GridLayoutManager(this, 2);
        mGridLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        mGridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {

            @Override
            public int getSpanSize(int position) {
                if (position == 0) {
                    return 2;
                } else {
                    return 1;
                }
            }
        });
        mPhotosRecyclerview.setLayoutManager(mGridLayoutManager);
        mPhotosRecyclerview.addItemDecoration(new GridMarginDecoration(mContext.getResources().getDimensionPixelSize(R.dimen.gridlayout_margin_decoration2)));
        mCastAdapter = new CastAdapter(this);
        mPhotosRecyclerview.setAdapter(mCastAdapter);
        mLinearLayoutManager = new LinearLayoutManager(this);
        mLinearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        mCastWorksAdapter = new CastWorksAdapter(this);
        mWorksRecyclerview.setLayoutManager(mLinearLayoutManager);
        mWorksRecyclerview.setAdapter(mCastWorksAdapter);
        mWorksRecyclerview.addOnScrollListener(new RecyclerView.OnScrollListener() {

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                // 获取到固定的view
                View stickyInfoView = recyclerView.findChildViewUnder(10, DensityUtils.dp2px(mContext, 80));
                if (stickyInfoView != null && stickyInfoView.getContentDescription() != null) {
                    mYear.setText(String.valueOf(stickyInfoView.getContentDescription()));
                }
                // Get the sticky view's translationY by the first view below the sticky's height.
                View transInfoView = recyclerView.findChildViewUnder(DensityUtils.dp2px(mContext, 165), DensityUtils.dp2px(mContext, 80));
                if (transInfoView != null && transInfoView.getTag() != null) {
                    int transViewStatus = (int) transInfoView.getTag();
                    int dealtX = transInfoView.getLeft() - mYear.getMeasuredWidth();
                    if (transViewStatus == CastWorksAdapter.HAS_STICKY_VIEW) {
                        // If the first view below the sticky's height scroll off the screen,
                        // then recovery the sticky view's translationY.
                        if (transInfoView.getLeft() > 0 && transInfoView.getLeft() < mYear.getMeasuredWidth() + 10) {
                            mYear.setTranslationX(dealtX);
                        } else {
                            mYear.setTranslationX(0);
                        }
                    } else if (transViewStatus == CastWorksAdapter.NONE_STICKY_VIEW) {
                        mYear.setTranslationX(0);
                    }
                }
            }
        });
        mProfileLayout.setOnClickListener(v -> {
            if (mCastDetail != null) {
                Intent intent = new Intent(mContext, CastInfoActivity.class);
                intent.putExtra(Constants.KEY.CAST, mCastDetail);
                startActivity(intent);
            }
        });
        mAllWorks.setOnClickListener(v -> {
            if (mCastId != null) {
                Intent intent = new Intent(mContext, AllWorksActivity.class);
                intent.putExtra(Constants.KEY.CASTID, mCastId);
                startActivity(intent);
            }
        });
    }

    @OnClick(R.id.collect_cast)
    public void collectCast() {
        DaoSession daoSession = DBManager.getInstance().getDaoSession();
        DBCastDao dbCastDao = daoSession.getDBCastDao();
        List<DBCast> list = dbCastDao.queryBuilder().where(DBCastDao.Properties.CastId.eq(mCastDetail.getId())).build().list();
        if (list.isEmpty()) {
            DBCast dbCast = new DBCast();
            dbCast.setCastId(mCastDetail.getId());
            dbCast.setImgUrl(mCastDetail.getPhotos().get(0).getImage());
            dbCastDao.insert(dbCast);
        }
    }

    @Override
    public void showToast(String msg) {
        super.showToast(msg);
        showSnackbar(mToolbar, msg);
    }

    @Override
    public void showDetail(Object o) {
        if (o instanceof CastDetail) {
            CastDetail castDetail = (CastDetail) o;
            mCastDetail = castDetail;
            mToolbar.setTitle(castDetail.getName());
            mName.setText(castDetail.getName());
            mNameEn.setText(castDetail.getName_en());
            mProfileContent.setText(castDetail.getSummary());
            mCastAdapter.addData(castDetail.getPhotos());
            mCastAdapter.setCastId(mCastId);
            mCastAdapter.setCastName(castDetail.getName());
            collectCast();
        } else if (o instanceof CastWork) {
            CastWork castWork = (CastWork) o;
            mCastWorksAdapter.addData(castWork.getWorks());
            mAllWorks.setText(mContext.getResources().getString(R.string.all_works, castWork.getTotal() + ""));
        }
    }

{
        super.showLoading();
        mSwiperefreshlayout.post(() -> mSwiperefreshlayout.setRefreshing(true));
    }

    @Override
    public void hideLoading() {
        super.hideLoading();
        mSwiperefreshlayout.post(() -> mSwiperefreshlayout.setRefreshing(false));
        mSwiperefreshlayout.setEnabled(true);
        mContentView.setVisibility(View.VISIBLE);
    }
}


{
        super.hideLoading();
        mSwiperefreshlayout.post(() -> mSwiperefreshlayout.setRefreshing(false));
        mSwiperefreshlayout.setEnabled(true);
        mContentView.setVisibility(View.VISIBLE);
    }

package com.whyalwaysmea.bigboom.view.cast.ui;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import com.jakewharton.rxbinding.support.v7.widget.RxToolbar;
import com.whyalwasymea.bigboom.dao.DBCastDao;
import com.whyalwasymea.bigboom.dao.DaoSession;
import com.whyalwaysmea.bigboom.Constants;
import com.whyalwaysmea.bigboom.R;
import com.whyalwaysmea.bigboom.base.BaseView;
import com.whyalwaysmea.bigboom.base.MvpActivity;
import com.whyalwaysmea.bigboom.bean.CastDetail;
import com.whyalwaysmea.bigboom.bean.CastWork;
import com.whyalwaysmea.bigboom.bean.db.DBCast;
import com.whyalwaysmea.bigboom.db.DBManager;
import com.whyalwaysmea.bigboom.di.component.DaggerCastComponent;
import com.whyalwaysmea.bigboom.di.module.CastModule;
import com.whyalwaysmea.bigboom.view.cast.presenter.CastPresenterImp;
import com.whyalwaysmea.bigboom.view.cast.ui.adapter.CastAdapter;
import com.whyalwaysmea.bigboom.view.cast.ui.adapter.CastWorksAdapter;
import com.whyalwaysmea.bigboom.view.cast.view.ICastDetailView;
import com.whyalwaysmea.bigboom.utils.DensityUtils;
import com.whyalwaysmea.bigboom.widget.FlexibleScrollView;
import com.whyalwaysmea.bigboom.widget.GridMarginDecoration;
import java.util.List;
import javax.inject.Inject;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import static com.whyalwaysmea.bigboom.R.id.profile_layout;

public class CastDetailActivity extends MvpActivity<ICastDetailView, CastPresenterImp> implements ICastDetailView {

    @BindView(R.id.toolbar)
    Toolbar mToolbar;

    @BindView(R.id.photos_recyclerview)
    RecyclerView mPhotosRecyclerview;

    @BindView(R.id.name)
    TextView mName;

    @BindView(R.id.name_en)
    TextView mNameEn;

    @BindView(R.id.profile_content)
    TextView mProfileContent;

    @BindView(profile_layout)
    FrameLayout mProfileLayout;

    @BindView(R.id.works_recyclerview)
    RecyclerView mWorksRecyclerview;

    @BindView(R.id.all_works)
    TextView mAllWorks;

    @BindView(R.id.year)
    TextView mYear;

    @BindView(R.id.collect_cast)
    ImageView mCollectCast;

    @BindView(R.id.swiperefreshlayout)
    SwipeRefreshLayout mSwiperefreshlayout;

    @BindView(R.id.content_view)
    FlexibleScrollView mContentView;

    private String mCastId;

    private CastDetail mCastDetail;

    private GridLayoutManager mGridLayoutManager;

    private LinearLayoutManager mLinearLayoutManager;

    private CastAdapter mCastAdapter;

    private CastWorksAdapter mCastWorksAdapter;

    @Inject
    CastPresenterImp mPresenter;

    @Override
    protected CastPresenterImp createPresenter(BaseView view) {
        return null;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cast_detail);
        ButterKnife.bind(this);
        DaggerCastComponent.builder().castModule(new CastModule(this)).build().inject(this);
        init();
    }

    @Override
    protected void initData() {
        mCastId = getIntent().getStringExtra(Constants.KEY.CASTID);
        if (!TextUtils.isEmpty(mCastId)) {
            mPresenter.getCastDetail(mCastId);
            mPresenter.getCastWorks(mCastId, 0);
        }
    }

    @Override
    protected void initView() {
        mToolbar.setNavigationIcon(R.drawable.icon_back);
        setSupportActionBar(mToolbar);
        RxToolbar.navigationClicks(mToolbar).subscribe(aVoid -> finish());
        mGridLayoutManager = new GridLayoutManager(this, 2);
        mGridLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        mGridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {

            @Override
            public int getSpanSize(int position) {
                if (position == 0) {
                    return 2;
                } else {
                    return 1;
                }
            }
        });
        mPhotosRecyclerview.setLayoutManager(mGridLayoutManager);
        mPhotosRecyclerview.addItemDecoration(new GridMarginDecoration(mContext.getResources().getDimensionPixelSize(R.dimen.gridlayout_margin_decoration2)));
        mCastAdapter = new CastAdapter(this);
        mPhotosRecyclerview.setAdapter(mCastAdapter);
        mLinearLayoutManager = new LinearLayoutManager(this);
        mLinearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        mCastWorksAdapter = new CastWorksAdapter(this);
        mWorksRecyclerview.setLayoutManager(mLinearLayoutManager);
        mWorksRecyclerview.setAdapter(mCastWorksAdapter);
        mWorksRecyclerview.addOnScrollListener(new RecyclerView.OnScrollListener() {

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                // 获取到固定的view
                View stickyInfoView = recyclerView.findChildViewUnder(10, DensityUtils.dp2px(mContext, 80));
                if (stickyInfoView != null && stickyInfoView.getContentDescription() != null) {
                    mYear.setText(String.valueOf(stickyInfoView.getContentDescription()));
                }
                // Get the sticky view's translationY by the first view below the sticky's height.
                View transInfoView = recyclerView.findChildViewUnder(DensityUtils.dp2px(mContext, 165), DensityUtils.dp2px(mContext, 80));
                if (transInfoView != null && transInfoView.getTag() != null) {
                    int transViewStatus = (int) transInfoView.getTag();
                    int dealtX = transInfoView.getLeft() - mYear.getMeasuredWidth();
                    if (transViewStatus == CastWorksAdapter.HAS_STICKY_VIEW) {
                        // If the first view below the sticky's height scroll off the screen,
                        // then recovery the sticky view's translationY.
                        if (transInfoView.getLeft() > 0 && transInfoView.getLeft() < mYear.getMeasuredWidth() + 10) {
                            mYear.setTranslationX(dealtX);
                        } else {
                            mYear.setTranslationX(0);
                        }
                    } else if (transViewStatus == CastWorksAdapter.NONE_STICKY_VIEW) {
                        mYear.setTranslationX(0);
                    }
                }
            }
        });
        mProfileLayout.setOnClickListener(v -> {
            if (mCastDetail != null) {
                Intent intent = new Intent(mContext, CastInfoActivity.class);
                intent.putExtra(Constants.KEY.CAST, mCastDetail);
                startActivity(intent);
            }
        });
        mAllWorks.setOnClickListener(v -> {
            if (mCastId != null) {
                Intent intent = new Intent(mContext, AllWorksActivity.class);
                intent.putExtra(Constants.KEY.CASTID, mCastId);
                startActivity(intent);
            }
        });
    }

    @OnClick(R.id.collect_cast)
    public void collectCast() {
        DaoSession daoSession = DBManager.getInstance().getDaoSession();
        DBCastDao dbCastDao = daoSession.getDBCastDao();
        List<DBCast> list = dbCastDao.queryBuilder().where(DBCastDao.Properties.CastId.eq(mCastDetail.getId())).build().list();
        if (list.isEmpty()) {
            DBCast dbCast = new DBCast();
            dbCast.setCastId(mCastDetail.getId());
            dbCast.setImgUrl(mCastDetail.getPhotos().get(0).getImage());
            dbCastDao.insert(dbCast);
        }
    }

    @Override
    public void showToast(String msg) {
        super.showToast(msg);
        showSnackbar(mToolbar, msg);
    }

    @Override
    public void showDetail(Object o) {
        if (o instanceof CastDetail) {
            CastDetail castDetail = (CastDetail) o;
            mCastDetail = castDetail;
            mToolbar.setTitle(castDetail.getName());
            mName.setText(castDetail.getName());
            mNameEn.setText(castDetail.getName_en());
            mProfileContent.setText(castDetail.getSummary());
            mCastAdapter.addData(castDetail.getPhotos());
            mCastAdapter.setCastId(mCastId);
            mCastAdapter.setCastName(castDetail.getName());
            collectCast();
        } else if (o instanceof CastWork) {
            CastWork castWork = (CastWork) o;
            mCastWorksAdapter.addData(castWork.getWorks());
            mAllWorks.setText(mContext.getResources().getString(R.string.all_works, castWork.getTotal() + ""));
        }
    }

    @Override
    public void showLoading() {
        super.showLoading();
        mSwiperefreshlayout.post(() -> mSwiperefreshlayout.setRefreshing(true));
    }

    @Override
    public void hideLoading()


package com.whyalwaysmea.bigboom.view.cast.ui;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import com.jakewharton.rxbinding.support.v7.widget.RxToolbar;
import com.whyalwasymea.bigboom.dao.DBCastDao;
import com.whyalwasymea.bigboom.dao.DaoSession;
import com.whyalwaysmea.bigboom.Constants;
import com.whyalwaysmea.bigboom.R;
import com.whyalwaysmea.bigboom.base.BaseView;
import com.whyalwaysmea.bigboom.base.MvpActivity;
import com.whyalwaysmea.bigboom.bean.CastDetail;
import com.whyalwaysmea.bigboom.bean.CastWork;
import com.whyalwaysmea.bigboom.bean.db.DBCast;
import com.whyalwaysmea.bigboom.db.DBManager;
import com.whyalwaysmea.bigboom.di.component.DaggerCastComponent;
import com.whyalwaysmea.bigboom.di.module.CastModule;
import com.whyalwaysmea.bigboom.view.cast.presenter.CastPresenterImp;
import com.whyalwaysmea.bigboom.view.cast.ui.adapter.CastAdapter;
import com.whyalwaysmea.bigboom.view.cast.ui.adapter.CastWorksAdapter;
import com.whyalwaysmea.bigboom.view.cast.view.ICastDetailView;
import com.whyalwaysmea.bigboom.utils.DensityUtils;
import com.whyalwaysmea.bigboom.widget.FlexibleScrollView;
import com.whyalwaysmea.bigboom.widget.GridMarginDecoration;
import java.util.List;
import javax.inject.Inject;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import static com.whyalwaysmea.bigboom.R.id.profile_layout;

public class CastDetailActivity extends MvpActivity<ICastDetailView, CastPresenterImp> implements ICastDetailView {

    @BindView(R.id.toolbar)
    Toolbar mToolbar;

    @BindView(R.id.photos_recyclerview)
    RecyclerView mPhotosRecyclerview;

    @BindView(R.id.name)
    TextView mName;

    @BindView(R.id.name_en)
    TextView mNameEn;

    @BindView(R.id.profile_content)
    TextView mProfileContent;

    @BindView(profile_layout)
    FrameLayout mProfileLayout;

    @BindView(R.id.works_recyclerview)
    RecyclerView mWorksRecyclerview;

    @BindView(R.id.all_works)
    TextView mAllWorks;

    @BindView(R.id.year)
    TextView mYear;

    @BindView(R.id.collect_cast)
    ImageView mCollectCast;

    @BindView(R.id.swiperefreshlayout)
    SwipeRefreshLayout mSwiperefreshlayout;

    @BindView(R.id.content_view)
    FlexibleScrollView mContentView;

    private String mCastId;

    private CastDetail mCastDetail;

    private GridLayoutManager mGridLayoutManager;

    private LinearLayoutManager mLinearLayoutManager;

    private CastAdapter mCastAdapter;

    private CastWorksAdapter mCastWorksAdapter;

    @Inject
    CastPresenterImp mPresenter;

    @Override
    protected CastPresenterImp createPresenter(BaseView view) {
        return null;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cast_detail);
        ButterKnife.bind(this);
        DaggerCastComponent.builder().castModule(new CastModule(this)).build().inject(this);
        init();
    }

    @Override
    protected void initData() {
        mCastId = getIntent().getStringExtra(Constants.KEY.CASTID);
        if (!TextUtils.isEmpty(mCastId)) {
            mPresenter.getCastDetail(mCastId);
            mPresenter.getCastWorks(mCastId, 0);
        }
    }

    @Override
    protected void initView() {
        mToolbar.setNavigationIcon(R.drawable.icon_back);
        setSupportActionBar(mToolbar);
        RxToolbar.navigationClicks(mToolbar).subscribe(aVoid -> finish());
        mGridLayoutManager = new GridLayoutManager(this, 2);
        mGridLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        mGridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {

            @Override
            public int getSpanSize(int position) {
                if (position == 0) {
                    return 2;
                } else {
                    return 1;
                }
            }
        });
        mPhotosRecyclerview.setLayoutManager(mGridLayoutManager);
        mPhotosRecyclerview.addItemDecoration(new GridMarginDecoration(mContext.getResources().getDimensionPixelSize(R.dimen.gridlayout_margin_decoration2)));
        mCastAdapter = new CastAdapter(this);
        mPhotosRecyclerview.setAdapter(mCastAdapter);
        mLinearLayoutManager = new LinearLayoutManager(this);
        mLinearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        mCastWorksAdapter = new CastWorksAdapter(this);
        mWorksRecyclerview.setLayoutManager(mLinearLayoutManager);
        mWorksRecyclerview.setAdapter(mCastWorksAdapter);
        mWorksRecyclerview.addOnScrollListener(new RecyclerView.OnScrollListener() {

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                // 获取到固定的view
                View stickyInfoView = recyclerView.findChildViewUnder(10, DensityUtils.dp2px(mContext, 80));
                if (stickyInfoView != null && stickyInfoView.getContentDescription() != null) {
                    mYear.setText(String.valueOf(stickyInfoView.getContentDescription()));
                }
                // Get the sticky view's translationY by the first view below the sticky's height.
                View transInfoView = recyclerView.findChildViewUnder(DensityUtils.dp2px(mContext, 165), DensityUtils.dp2px(mContext, 80

                if (transInfoView != null && transInfoView.getTag() != null) {
                    int transViewStatus = (int) transInfoView.getTag();
                    int dealtX = transInfoView.getLeft() - mYear.getMeasuredWidth();
                    if (transViewStatus == CastWorksAdapter.HAS_STICKY_VIEW) {
                        // If the first view below the sticky's height scroll off the screen,
                        // then recovery the sticky view's translationY.
                        if (transInfoView.getLeft() > 0 && transInfoView.getLeft() < mYear.getMeasuredWidth() + 10) {
                            mYear.setTranslationX(dealtX);
                        } else {
                            mYear.setTranslationX(0);
                        }
                    } else if (transViewStatus == CastWorksAdapter.NONE_STICKY_VIEW) {
                        mYear.setTranslationX(0);
                    }
                }
            }
        });
        mProfileLayout.setOnClickListener(v -> {
            if (mCastDetail != null) {
                Intent intent = new Intent(mContext, CastInfoActivity.class);
                intent.putExtra(Constants.KEY.CAST, mCastDetail);
                startActivity(intent);
            }
        });
        mAllWorks.setOnClickListener(v -> {
            if (mCastId != null) {
                Intent intent = new Intent(mContext, AllWorksActivity.class);
                intent.putExtra(Constants.KEY.CASTID, mCastId);
                startActivity(intent);
            }
        });
    }

    @OnClick(R.id.collect_cast)
    public void collectCast() {
        DaoSession daoSession = DBManager.getInstance().getDaoSession();
        DBCastDao dbCastDao = daoSession.getDBCastDao();
        List<DBCast> list = dbCastDao.queryBuilder().where(DBCastDao.Properties.CastId.eq(mCastDetail.getId())).build().list();
        if (list.isEmpty()) {
            DBCast dbCast = new DBCast();
            dbCast.setCastId(mCastDetail.getId());
            dbCast.setImgUrl(mCastDetail.getPhotos().get(0).getImage());
            dbCastDao.insert(dbCast);
        }
    }

    @Override
    public void showToast(String msg) {
        super.showToast(msg);
        showSnackbar(mToolbar, msg);
    }

    @Override
    public void showDetail(Object o) {
        if (o instanceof CastDetail) {
            CastDetail castDetail = (CastDetail) o;
            mCastDetail = castDetail;
            mToolbar.setTitle(castDetail.getName());
            mName.setText(castDetail.getName());
            mNameEn.setText(castDetail.getName_en());
            mProfileContent.setText(castDetail.getSummary());
            mCastAdapter.addData(castDetail.getPhotos());
            mCastAdapter.setCastId(mCastId);
            mCastAdapter.setCastName(castDetail.getName());
            collectCast();
        } else if (o instanceof CastWork) {
            CastWork castWork = (CastWork) o;
            mCastWorksAdapter.addData(castWork.getWorks());
            mAllWorks.setText(mContext.getResources().getString(R.string.all_works, castWork.getTotal() + ""));
        }
    }

    @Override
    public void showLoading() {
        super.showLoading();
        mSwiperefreshlayout.post(() -> mSwiperefreshlayout.setRefreshing(true));
    }

    @Override
    public void hideLoading() {
        super.hideLoading();
        mSwiperefreshlayout.post(() -> mSwiperefreshlayout.setRefreshing(false));
        mSwiperefreshlayout.setEnabled(true);
        mContentView.setVisibility(View.VISIBLE);
    }
}


if (transInfoView.getLeft() > 0 && transInfoView.getLeft() < mYear.getMeasuredWidth() + 10) {
                            mYear.setTranslationX(dealtX);
                        } else {
                            mYear.setTranslationX(0);
                        }

package com.whyalwaysmea.bigboom.view.cast.ui;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import com.jakewharton.rxbinding.support.v7.widget.RxToolbar;
import com.whyalwasymea.bigboom.dao.DBCastDao;
import com.whyalwasymea.bigboom.dao.DaoSession;
import com.whyalwaysmea.bigboom.Constants;
import com.whyalwaysmea.bigboom.R;
import com.whyalwaysmea.bigboom.base.BaseView;
import com.whyalwaysmea.bigboom.base.MvpActivity;
import com.whyalwaysmea.bigboom.bean.CastDetail;
import com.whyalwaysmea.bigboom.bean.CastWork;
import com.whyalwaysmea.bigboom.bean.db.DBCast;
import com.whyalwaysmea.bigboom.db.DBManager;
import com.whyalwaysmea.bigboom.di.component.DaggerCastComponent;
import com.whyalwaysmea.bigboom.di.module.CastModule;
import com.whyalwaysmea.bigboom.view.cast.presenter.CastPresenterImp;
import com.whyalwaysmea.bigboom.view.cast.ui.adapter.CastAdapter;
import com.whyalwaysmea.bigboom.view.cast.ui.adapter.CastWorksAdapter;
import com.whyalwaysmea.bigboom.view.cast.view.ICastDetailView;
import com.whyalwaysmea.bigboom.utils.DensityUtils;
import com.whyalwaysmea.bigboom.widget.FlexibleScrollView;
import com.whyalwaysmea.bigboom.widget.GridMarginDecoration;
import java.util.List;
import javax.inject.Inject;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import static com.whyalwaysmea.bigboom.R.id.profile_layout;

public class CastDetailActivity extends MvpActivity<ICastDetailView, CastPresenterImp> implements ICastDetailView {

    @BindView(R.id.toolbar)
    Toolbar mToolbar;

    @BindView(R.id.photos_recyclerview)
    RecyclerView mPhotosRecyclerview;

    @BindView(R.id.name)
    TextView mName;

    @BindView(R.id.name_en)
    TextView mNameEn;

    @BindView(R.id.profile_content)
    TextView mProfileContent;

    @BindView(profile_layout)
    FrameLayout mProfileLayout;

    @BindView(R.id.works_recyclerview)
    RecyclerView mWorksRecyclerview;

    @BindView(R.id.all_works)
    TextView mAllWorks;

    @BindView(R.id.year)
    TextView mYear;

    @BindView(R.id.collect_cast)
    ImageView mCollectCast;

    @BindView(R.id.swiperefreshlayout)
    SwipeRefreshLayout mSwiperefreshlayout;

    @BindView(R.id.content_view)
    FlexibleScrollView mContentView;

    private String mCastId;

    private CastDetail mCastDetail;

    private GridLayoutManager mGridLayoutManager;

    private LinearLayoutManager mLinearLayoutManager;

    private CastAdapter mCastAdapter;

    private CastWorksAdapter mCastWorksAdapter;

    @Inject
    CastPresenterImp mPresenter;

    @Override
    protected CastPresenterImp createPresenter(BaseView view) {
        return null;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cast_detail);
        ButterKnife.bind(this);
        DaggerCastComponent.builder().castModule(new CastModule(this)).build().inject(this);
        init();
    }

    @Override
    protected void initData() {
        mCastId = getIntent().getStringExtra(Constants.KEY.CASTID);
        if (!TextUtils.isEmpty(mCastId)) {
            mPresenter.getCastDetail(mCastId);
            mPresenter.getCastWorks(mCastId, 0);
        }
    }

    @Override
    protected void initView() {
        mToolbar.setNavigationIcon(R.drawable.icon_back);
        setSupportActionBar(mToolbar);
        RxToolbar.navigationClicks(mToolbar).subscribe(aVoid -> finish());
        mGridLayoutManager = new GridLayoutManager(this, 2);
        mGridLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        mGridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {

            @Override
            public int getSpanSize(int position) {
                if (position == 0) {
                    return 2;
                } else {
                    return 1;
                }
            }
        });
        mPhotosRecyclerview.setLayoutManager(mGridLayoutManager);
        mPhotosRecyclerview.addItemDecoration(new GridMarginDecoration(mContext.getResources().getDimensionPixelSize(R.dimen.gridlayout_margin_decoration2)));
        mCastAdapter = new CastAdapter(this);
        mPhotosRecyclerview.setAdapter(mCastAdapter);
        mLinearLayoutManager = new LinearLayoutManager(this);
        mLinearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        mCastWorksAdapter = new CastWorksAdapter(this);
        mWorksRecyclerview.setLayoutManager(mLinearLayoutManager);
        mWorksRecyclerview.setAdapter(mCastWorksAdapter);
        mWorksRecyclerview.addOnScrollListener(new RecyclerView.OnScrollListener() {

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                // 获取到固定的view
                View stickyInfoView = recyclerView.findChildViewUnder(10, DensityUtils.dp2px(mContext, 80));
                if (stickyInfoView != null && stickyInfoView.getContentDescription() != null) {
                    mYear.setText(String.valueOf(stickyInfoView.getContentDescription()));
                }
                // Get the sticky view's translationY by the first view below the sticky's height.
                View transInfoView = recyclerView.findChildViewUnder(DensityUtils.dp2px(mContext, 165), DensityUtils.dp2px(mContext, 80));
                if (transInfoView != null && transInfoView.getTag() != null) {
                    int transViewStatus = (int) transInfoView.getTag();
                    int dealtX = transInfoView.getLeft() - mYear.getMeasuredWidth();
                    if (transViewStatus == CastWorksAdapter.HAS_STICKY_VIEW) {
                        // If the first view below the sticky's height scroll off the screen,
                        // then recovery the sticky view's translationY.

                    } else if (transViewStatus == CastWorksAdapter.NONE_STICKY_VIEW) {
                        mYear.setTranslationX(0);
                    }
                }
            }
        });
        mProfileLayout.setOnClickListener(v -> {
            if (mCastDetail != null) {
                Intent intent = new Intent(mContext, CastInfoActivity.class);
                intent.putExtra(Constants.KEY.CAST, mCastDetail);
                startActivity(intent);
            }
        });
        mAllWorks.setOnClickListener(v -> {
            if (mCastId != null) {
                Intent intent = new Intent(mContext, AllWorksActivity.class);
                intent.putExtra(Constants.KEY.CASTID, mCastId);
                startActivity(intent);
            }
        });
    }

    @OnClick(R.id.collect_cast)
    public void collectCast() {
        DaoSession daoSession = DBManager.getInstance().getDaoSession();
        DBCastDao dbCastDao = daoSession.getDBCastDao();
        List<DBCast> list = dbCastDao.queryBuilder().where(DBCastDao.Properties.CastId.eq(mCastDetail.getId())).build().list();
        if (list.isEmpty()) {
            DBCast dbCast = new DBCast();
            dbCast.setCastId(mCastDetail.getId());
            dbCast.setImgUrl(mCastDetail.getPhotos().get(0).getImage());
            dbCastDao.insert(dbCast);
        }
    }

    @Override
    public void showToast(String msg) {
        super.showToast(msg);
        showSnackbar(mToolbar, msg);
    }

    @Override
    public void showDetail(Object o) {
        if (o instanceof CastDetail) {
            CastDetail castDetail = (CastDetail) o;
            mCastDetail = castDetail;
            mToolbar.setTitle(castDetail.getName());
            mName.setText(castDetail.getName());
            mNameEn.setText(castDetail.getName_en());
            mProfileContent.setText(castDetail.getSummary());
            mCastAdapter.addData(castDetail.getPhotos());
            mCastAdapter.setCastId(mCastId);
            mCastAdapter.setCastName(castDetail.getName());
            collectCast();
        } else if (o instanceof CastWork) {
            CastWork castWork = (CastWork) o;
            mCastWorksAdapter.addData(castWork.getWorks());
            mAllWorks.setText(mContext.getResources().getString(R.string.all_works, castWork.getTotal() + ""));
        }
    }

    @Override
    public void showLoading() {
        super.showLoading();
        mSwiperefreshlayout.post(() -> mSwiperefreshlayout.setRefreshing(true));
    }

    @Override
    public void hideLoading() {
        super.hideLoading();
        mSwiperefreshlayout.post(() -> mSwiperefreshlayout.setRefreshing(false));
        mSwiperefreshlayout.setEnabled(true);
        mContentView.setVisibility(View.VISIBLE);
    }
}


/*
 * Bytecode Analysis Framework
 *
 */
package edu.umd.cs.findbugs.ba.bcp;

import javax.annotation.CheckForNull;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.InstructionHandle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import edu.umd.cs.findbugs.ba.DataflowAnalysisException;
import edu.umd.cs.findbugs.ba.Edge;
import edu.umd.cs.findbugs.ba.vna.ValueNumberFrame;

/**
 * A PatternElement is an element of a ByteCodePattern. It potentially matches
 * some number of bytecode instructions.
 */
public abstract class PatternElement {

    private static final Logger LOG = LoggerFactory.getLogger(PatternElement.class);

    private PatternElement next;

    private String label;

    private String dominatedBy;

    private int index;

    private boolean allowTrailingEdges = true;

    /**
     * Get the next PatternElement.
     */
    public PatternElement getNext() {
        return next;
    }

    /**
     * Set the next PatternElement.
     */
    public void setNext(PatternElement patternElement) {
        this.next = patternElement;
    }

    /**
     * Set a label for this PatternElement.
     *
     * @param label
     *            the label
     * @return this object
     */
    public PatternElement label(String label) {
        this.label = label;
        return this;
    }

    /**
     * Get the label of this PatternElement.
     *
     * @return the label, or null if the PatternElement is not labeled
     */
    public String getLabel() {
        return label;
    }

    /**
     * Set the label of another pattern element whose first matched instruction
     * must dominate the instruction(s) matched by this element.
     */
    public PatternElement dominatedBy(String dominatedBy) {
        this.dominatedBy = dominatedBy;
        return this;
    }

    /**
     * Get the label of the pattern element whose first matched instruction must
     * dominate the instruction(s) matched by this element.
     */
    public String getDominatedBy() {
        return dominatedBy;
    }

    /**
     * Set the index. This is just for debugging.
     */
    public void setIndex(int index) {
        this.index = index;
    }

    /**
     * Set whether or not this PatternElement allows trailing edges to be
     * matched. By default, trailing edges may be matched. When this value is
     * set to false, it ensures that the successor instruction must be in the
     * same basic block.
     *
     * @param allowTrailingEdges
     *            true if trailing edges may be matched, false if trailing edges
     *            will never be matched
     */
    public PatternElement setAllowTrailingEdges(boolean allowTrailingEdges) {
        this.allowTrailingEdges = allowTrailingEdges;
        return this;
    }

    /**
     * Return whether or not this PatternElement may match trailing edges.
     */
    public boolean allowTrailingEdges() {
        return allowTrailingEdges;
    }

    /**
     * Look up a variable definition in given BindingSet.
     *
     * @param varName
     *            the name of the variable
     * @param bindingSet
     *            the BindingSet to look in
     * @return the Variable, or null if no Variable is bound to the name
     */
    public static Variable lookup(String varName, BindingSet bindingSet) {
        if (bindingSet == null) {
            return null;
        }
        Binding binding = bindingSet.lookup(varName);
        return (binding != null) ? binding.getVariable() : null;
    }

    /**
     * Return whether or not this element matches the given instruction with the
     * given Bindings in effect.
     *
     * @param handle
     *            the instruction
     * @param cpg
     *            the ConstantPoolGen from the method
     * @param before
     *            the ValueNumberFrame representing values in the Java stack
     *            frame just before the execution of the instruction
     * @param after
     *            the ValueNumberFrame representing values in the Java stack
     *            frame just after the execution of the instruction
     * @param bindingSet
     *            the set of Bindings
     * @return if the match is successful, returns a MatchResult with the
     *         PatternElement and BindingSet; if the match is not successful,
     *         returns null
     */
    @CheckForNull
    public abstract MatchResult match(InstructionHandle handle, ConstantPoolGen cpg, ValueNumberFrame before, ValueNumberFrame after, BindingSet bindingSet) throws DataflowAnalysisException;

    /**
     * Return whether or not it is acceptable to take the given branch.
     *
     * @param edge
     *            the Edge representing the branch
     * @param source
     *            the source instruction of the branch
     * @return true if the Edge is acceptable, false if not
     */
    public abstract boolean acceptBranch(Edge edge, InstructionHandle source);

    /**
     * Return the minimum number of instructions this PatternElement must match
     * in the ByteCodePattern.
     */
    public abstract int minOccur();

    /**
     * Return the maximum number of instructions this PatternElement must match
     * in the ByteCodePattern.
     */
    public abstract int maxOccur();

    /**
     * Add a variable definition to the given BindingSet, or if there is an
     * existing definition, make sure it is consistent with the new definition.
     *
     * @param varName
     *            the name of the variable
     * @param variable
     *            the Variable which should be added or checked for consistency
     * @param bindingSet
     *            the existing set of bindings
     * @return the updated BindingSet (if the variable is consistent with the
     *         previous bindings), or null if the new variable is inconsistent
     *         with the previous bindings
     */
    protected static BindingSet addOrCheckDefinition(String varName, Variable variable, BindingSet bindingSet) {
        Variable existingVariable = lookup(varName, bindingSet);
        if (existingVariable == null) {
            bindingSet = new BindingSet(new Binding(varName, variable), bindingSet);
        } else {
            if (!existingVariable.sameAs(variable)) {
                LOG.debug("\tConflicting variable {}: {} != {}", varName, variable, existingVariable);
                return null;
            }
        }
        return bindingSet;
    }

{
        StringBuilder buf = new StringBuilder();
        String className = this.getClass().getName();
        buf.append(className.substring(className.lastIndexOf('.') + 1));
        buf.append('(');
        buf.append(index);
        buf.append(')');
        return buf.toString();
    }
}


{
        this.allowTrailingEdges = allowTrailingEdges;
        return this;
    }

/*
 * Bytecode Analysis Framework
 *
 */
package edu.umd.cs.findbugs.ba.bcp;

import javax.annotation.CheckForNull;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.InstructionHandle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import edu.umd.cs.findbugs.ba.DataflowAnalysisException;
import edu.umd.cs.findbugs.ba.Edge;
import edu.umd.cs.findbugs.ba.vna.ValueNumberFrame;

/**
 * A PatternElement is an element of a ByteCodePattern. It potentially matches
 * some number of bytecode instructions.
 */
public abstract class PatternElement {

    private static final Logger LOG = LoggerFactory.getLogger(PatternElement.class);

    private PatternElement next;

    private String label;

    private String dominatedBy;

    private int index;

    private boolean allowTrailingEdges = true;

    /**
     * Get the next PatternElement.
     */
    public PatternElement getNext() {
        return next;
    }

    /**
     * Set the next PatternElement.
     */
    public void setNext(PatternElement patternElement) {
        this.next = patternElement;
    }

    /**
     * Set a label for this PatternElement.
     *
     * @param label
     *            the label
     * @return this object
     */
    public PatternElement label(String label) {
        this.label = label;
        return this;
    }

    /**
     * Get the label of this PatternElement.
     *
     * @return the label, or null if the PatternElement is not labeled
     */
    public String getLabel() {
        return label;
    }

    /**
     * Set the label of another pattern element whose first matched instruction
     * must dominate the instruction(s) matched by this element.
     */
    public PatternElement dominatedBy(String dominatedBy) {
        this.dominatedBy = dominatedBy;
        return this;
    }

    /**
     * Get the label of the pattern element whose first matched instruction must
     * dominate the instruction(s) matched by this element.
     */
    public String getDominatedBy() {
        return dominatedBy;
    }

    /**
     * Set the index. This is just for debugging.
     */
    public void setIndex(int index) {
        this.index = index;
    }

    /**
     * Set whether or not this PatternElement allows trailing edges to be
     * matched. By default, trailing edges may be matched. When this value is
     * set to false, it ensures that the successor instruction must be in the
     * same basic block.
     *
     * @param allowTrailingEdges
     *            true if trailing edges may be matched, false if trailing edges
     *            will never be matched
     */
    public PatternElement setAllowTrailingEdges(boolean allowTrailingEdges)

    /**
     * Return whether or not this PatternElement may match trailing edges.
     */
    public boolean allowTrailingEdges() {
        return allowTrailingEdges;
    }

    /**
     * Look up a variable definition in given BindingSet.
     *
     * @param varName
     *            the name of the variable
     * @param bindingSet
     *            the BindingSet to look in
     * @return the Variable, or null if no Variable is bound to the name
     */
    public static Variable lookup(String varName, BindingSet bindingSet) {
        if (bindingSet == null) {
            return null;
        }
        Binding binding = bindingSet.lookup(varName);
        return (binding != null) ? binding.getVariable() : null;
    }

    /**
     * Return whether or not this element matches the given instruction with the
     * given Bindings in effect.
     *
     * @param handle
     *            the instruction
     * @param cpg
     *            the ConstantPoolGen from the method
     * @param before
     *            the ValueNumberFrame representing values in the Java stack
     *            frame just before the execution of the instruction
     * @param after
     *            the ValueNumberFrame representing values in the Java stack
     *            frame just after the execution of the instruction
     * @param bindingSet
     *            the set of Bindings
     * @return if the match is successful, returns a MatchResult with the
     *         PatternElement and BindingSet; if the match is not successful,
     *         returns null
     */
    @CheckForNull
    public abstract MatchResult match(InstructionHandle handle, ConstantPoolGen cpg, ValueNumberFrame before, ValueNumberFrame after, BindingSet bindingSet) throws DataflowAnalysisException;

    /**
     * Return whether or not it is acceptable to take the given branch.
     *
     * @param edge
     *            the Edge representing the branch
     * @param source
     *            the source instruction of the branch
     * @return true if the Edge is acceptable, false if not
     */
    public abstract boolean acceptBranch(Edge edge, InstructionHandle source);

    /**
     * Return the minimum number of instructions this PatternElement must match
     * in the ByteCodePattern.
     */
    public abstract int minOccur();

    /**
     * Return the maximum number of instructions this PatternElement must match
     * in the ByteCodePattern.
     */
    public abstract int maxOccur();

    /**
     * Add a variable definition to the given BindingSet, or if there is an
     * existing definition, make sure it is consistent with the new definition.
     *
     * @param varName
     *            the name of the variable
     * @param variable
     *            the Variable which should be added or checked for consistency
     * @param bindingSet
     *            the existing set of bindings
     * @return the updated BindingSet (if the variable is consistent with the
     *         previous bindings), or null if the new variable is inconsistent
     *         with the previous bindings
     */
    protected static BindingSet addOrCheckDefinition(String varName, Variable variable, BindingSet bindingSet) {
        Variable existingVariable = lookup(varName, bindingSet);
        if (existingVariable == null) {
            bindingSet = new BindingSet(new Binding(varName, variable), bindingSet);
        } else {
            if (!existingVariable.sameAs(variable)) {
                LOG.debug("\tConflicting variable {}: {} != {}", varName, variable, existingVariable);
                return null;
            }
        }
        return bindingSet;
    }

    @Override
    public String toString() {
        StringBuilder buf = new StringBuilder();
        String className = this.getClass().getName();
        buf.append(className.substring(className.lastIndexOf('.') + 1));
        buf.append('(');
        buf.append(index);
        buf.append(')');
        return buf.toString();
    }
}


/*
 * Bytecode Analysis Framework
 *
 */
package edu.umd.cs.findbugs.ba.bcp;

import javax.annotation.CheckForNull;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.InstructionHandle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import edu.umd.cs.findbugs.ba.DataflowAnalysisException;
import edu.umd.cs.findbugs.ba.Edge;
import edu.umd.cs.findbugs.ba.vna.ValueNumberFrame;

/**
 * A PatternElement is an element of a ByteCodePattern. It potentially matches
 * some number of bytecode instructions.
 */
public abstract class PatternElement {

    private static final Logger LOG = LoggerFactory.getLogger(PatternElement.class);

    private PatternElement next;

    private String label;

    private String dominatedBy;

    private int index;

    private boolean allowTrailingEdges = true;

    /**
     * Get the next PatternElement.
     */
    public PatternElement getNext() {
        return next;
    }

    /**
     * Set the next PatternElement.
     */
    public void setNext(PatternElement patternElement) {
        this.next = patternElement;
    }

    /**
     * Set a label for this PatternElement.
     *
     * @param label
     *            the label
     * @return this object
     */
    public PatternElement label(String label) {
        this.label = label;
        return this;
    }

    /**
     * Get the label of this PatternElement.
     *
     * @return the label, or null if the PatternElement is not labeled
     */
    public String getLabel() {
        return label;
    }

    /**
     * Set the label of another pattern element whose first matched instruction
     * must dominate the instruction(s) matched by this element.
     */
    public PatternElement dominatedBy(String dominatedBy) {
        this.dominatedBy = dominatedBy;
        return this;
    }

    /**
     * Get the label of the pattern element whose first matched instruction must
     * dominate the instruction(s) matched by this element.
     */
    public String getDominatedBy() {
        return dominatedBy;
    }

    /**
     * Set the index. This is just for debugging.
     */
    public void setIndex(int index) {
        this.index = index;
    }

    /**
     * Set whether or not this PatternElement allows trailing edges to be
     * matched. By default, trailing edges may be matched. When this value is
     * set to false, it ensures that the successor instruction must be in the
     * same basic block.
     *
     * @param allowTrailingEdges
     *            true if trailing edges may be matched, false if trailing edges
     *            will never be matched
     */
    public PatternElement setAllowTrailingEdges(boolean allowTrailingEdges) {
        this.allowTrailingEdges = allowTrailingEdges;
        return this;
    }

    /**
     * Return whether or not this PatternElement may match trailing edges.
     */
    public boolean allowTrailingEdges() {
        return allowTrailingEdges;
    }

    /**
     * Look up a variable definition in given BindingSet.
     *
     * @param varName
     *            the name of the variable
     * @param bindingSet
     *            the BindingSet to look in
     * @return the Variable, or null if no Variable is bound to the name
     */
    public static Variable lookup(String varName, BindingSet bindingSet) {
        if (bindingSet == null) {
            return null;
        }
        Binding binding = bindingSet.lookup(varName);
        return (binding != null) ? binding.getVariable() : null;
    }

    /**
     * Return whether or not this element matches the given instruction with the
     * given Bindings in effect.
     *
     * @param handle
     *            the instruction
     * @param cpg
     *            the ConstantPoolGen from the method
     * @param before
     *            the ValueNumberFrame representing values in the Java stack
     *            frame just before the execution of the instruction
     * @param after
     *            the ValueNumberFrame representing values in the Java stack
     *            frame just after the execution of the instruction
     * @param bindingSet
     *            the set of Bindings
     * @return if the match is successful, returns a MatchResult with the
     *         PatternElement and BindingSet; if the match is not successful,
     *         returns null
     */
    @CheckForNull
    public abstract MatchResult match(InstructionHandle handle, ConstantPoolGen cpg, ValueNumberFrame before, ValueNumberFrame after, BindingSet bindingSet) throws DataflowAnalysisException;

    /**
     * Return whether or not it is acceptable to take the given branch.
     *
     * @param edge
     *            the Edge representing the branch
     * @param source
     *            the source instruction of the branch
     * @return true if the Edge is acceptable, false if not
     */
    public abstract boolean acceptBranch(Edge edge, InstructionHandle source);

    /**
     * Return the minimum number of instructions this PatternElement must match
     * in the ByteCodePattern.
     */
    public abstract int minOccur();

    /**
     * Return the maximum number of instructions this PatternElement must match
     * in the ByteCodePattern.
     */
    public abstract int maxOccur();

    /**
     * Add a variable definition to the given BindingSet, or if there is an
     * existing definition, make sure it is consistent with the new definition.
     *
     * @param varName
     *            the name of the variable
     * @param variable
     *            the Variable which should be added or checked for consistency
     * @param bindingSet
     *            the existing set of bindings
     * @return the updated BindingSet (if the variable is consistent with the
     *         previous bindings), or null if the new variable is inconsistent
     *         with the previous bindings
     */
    protected static BindingSet addOrCheckDefinition(String varName, Variable variable, BindingSet bindingSet) {
        Variable existingVariable = lookup(varName, bindingSet);
        if (existingVariable == null) {
            bindingSet = new BindingSet(new Binding(varName, variable), bindingSet);
        } else {
            if (!existingVariable.sameAs(variable)) {
                LOG.debug("\tConflicting variable {}: {} != {}", varName, variable, existingVariable);
                return null;
            }
        }
        return bindingSet;
    }

    @Override
    public String toString() {
        StringBuilder buf = new StringBuilder();
        String className = this.getClass().getName();
        buf.a

        buf.append('(');
        buf.append(index);
        buf.append(')');
        return buf.toString();
    }
}


public boolean allowTrailingEdges() {
        return allowTrailingEdges;
    }

/*
 * Bytecode Analysis Framework
 *
 */
package edu.umd.cs.findbugs.ba.bcp;

import javax.annotation.CheckForNull;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.InstructionHandle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import edu.umd.cs.findbugs.ba.DataflowAnalysisException;
import edu.umd.cs.findbugs.ba.Edge;
import edu.umd.cs.findbugs.ba.vna.ValueNumberFrame;

/**
 * A PatternElement is an element of a ByteCodePattern. It potentially matches
 * some number of bytecode instructions.
 */
public abstract class PatternElement {

    private static final Logger LOG = LoggerFactory.getLogger(PatternElement.class);

    private PatternElement next;

    private String label;

    private String dominatedBy;

    private int index;

    private boolean allowTrailingEdges = true;

    /**
     * Get the next PatternElement.
     */
    public PatternElement getNext() {
        return next;
    }

    /**
     * Set the next PatternElement.
     */
    public void setNext(PatternElement patternElement) {
        this.next = patternElement;
    }

    /**
     * Set a label for this PatternElement.
     *
     * @param label
     *            the label
     * @return this object
     */
    public PatternElement label(String label) {
        this.label = label;
        return this;
    }

    /**
     * Get the label of this PatternElement.
     *
     * @return the label, or null if the PatternElement is not labeled
     */
    public String getLabel() {
        return label;
    }

    /**
     * Set the label of another pattern element whose first matched instruction
     * must dominate the instruction(s) matched by this element.
     */
    public PatternElement dominatedBy(String dominatedBy) {
        this.dominatedBy = dominatedBy;
        return this;
    }

    /**
     * Get the label of the pattern element whose first matched instruction must
     * dominate the instruction(s) matched by this element.
     */
    public String getDominatedBy() {
        return dominatedBy;
    }

    /**
     * Set the index. This is just for debugging.
     */
    public void setIndex(int index) {
        this.index = index;
    }

    /**
     * Set whether or not this PatternElement allows trailing edges to be
     * matched. By default, trailing edges may be matched. When this value is
     * set to false, it ensures that the successor instruction must be in the
     * same basic block.
     *
     * @param allowTrailingEdges
     *            true if trailing edges may be matched, false if trailing edges
     *            will never be matched
     */
    public PatternElement setAllowTrailingEdges(boolean allowTrailingEdges) {
        this.allowTrailingEdges = allowTrailingEdges;
        return this;
    }

    /**
     * Return whether or not this PatternElement may match trailing edges.
     */

    /**
     * Look up a variable definition in given BindingSet.
     *
     * @param varName
     *            the name of the variable
     * @param bindingSet
     *            the BindingSet to look in
     * @return the Variable, or null if no Variable is bound to the name
     */
    public static Variable lookup(String varName, BindingSet bindingSet) {
        if (bindingSet == null) {
            return null;
        }
        Binding binding = bindingSet.lookup(varName);
        return (binding != null) ? binding.getVariable() : null;
    }

    /**
     * Return whether or not this element matches the given instruction with the
     * given Bindings in effect.
     *
     * @param handle
     *            the instruction
     * @param cpg
     *            the ConstantPoolGen from the method
     * @param before
     *            the ValueNumberFrame representing values in the Java stack
     *            frame just before the execution of the instruction
     * @param after
     *            the ValueNumberFrame representing values in the Java stack
     *            frame just after the execution of the instruction
     * @param bindingSet
     *            the set of Bindings
     * @return if the match is successful, returns a MatchResult with the
     *         PatternElement and BindingSet; if the match is not successful,
     *         returns null
     */
    @CheckForNull
    public abstract MatchResult match(InstructionHandle handle, ConstantPoolGen cpg, ValueNumberFrame before, ValueNumberFrame after, BindingSet bindingSet) throws DataflowAnalysisException;

    /**
     * Return whether or not it is acceptable to take the given branch.
     *
     * @param edge
     *            the Edge representing the branch
     * @param source
     *            the source instruction of the branch
     * @return true if the Edge is acceptable, false if not
     */
    public abstract boolean acceptBranch(Edge edge, InstructionHandle source);

    /**
     * Return the minimum number of instructions this PatternElement must match
     * in the ByteCodePattern.
     */
    public abstract int minOccur();

    /**
     * Return the maximum number of instructions this PatternElement must match
     * in the ByteCodePattern.
     */
    public abstract int maxOccur();

    /**
     * Add a variable definition to the given BindingSet, or if there is an
     * existing definition, make sure it is consistent with the new definition.
     *
     * @param varName
     *            the name of the variable
     * @param variable
     *            the Variable which should be added or checked for consistency
     * @param bindingSet
     *            the existing set of bindings
     * @return the updated BindingSet (if the variable is consistent with the
     *         previous bindings), or null if the new variable is inconsistent
     *         with the previous bindings
     */
    protected static BindingSet addOrCheckDefinition(String varName, Variable variable, BindingSet bindingSet) {
        Variable existingVariable = lookup(varName, bindingSet);
        if (existingVariable == null) {
            bindingSet = new BindingSet(new Binding(varName, variable), bindingSet);
        } else {
            if (!existingVariable.sameAs(variable)) {
                LOG.debug("\tConflicting variable {}: {} != {}", varName, variable, existingVariable);
                return null;
            }
        }
        return bindingSet;
    }

    @Override
    public String toString() {
        StringBuilder buf = new StringBuilder();
        String className = this.getClass().getName();
        buf.append(className.substring(className.lastIndexOf('.') + 1));
        buf.append('(');
        buf.append(index);
        buf.append(')');
        return buf.toString();
    }
}


static PigEntity create(KelpLocation location)

package de.pxav.kelp.core.entity.type;

import de.pxav.kelp.core.KelpPlugin;
import de.pxav.kelp.core.entity.KelpEntity;
import de.pxav.kelp.core.entity.KelpEntityType;
import de.pxav.kelp.core.entity.type.general.AnimalEntity;
import de.pxav.kelp.core.entity.type.general.BreedableAnimalEntity;
import de.pxav.kelp.core.entity.type.general.VehicleEntity;
import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
import de.pxav.kelp.core.world.KelpLocation;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Pig;

public interface PigEntity extends AnimalEntity<PigEntity>, BreedableAnimalEntity<PigEntity>, VehicleEntity<PigEntity> {

    /**
     * Creates a new entity of this type at the given location.
     *
     * While this creates a new instance, it won't actually spawn the entity.
     * You can first do some modifications on it and then call the
     * {@link KelpEntity#spawn()} method.
     *
     * If you don't want to create a new entity, but just a new kelp
     * entity instance based of an existing bukkit entity, you can use
     * {@link #from(Entity)} instead.
     *
     * @param location The location, where the entity should be spawned later.
     * @return A new instance of a sheep entity.
     */

{
        return (PigEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class).newKelpEntity(getEntityType(), location.getBukkitLocation());
    }

    /**
     * Takes a bukkit entity and converts it to a kelp entity of the same type.
     *
     * This can be used if you are for example handling an event that returns a bukkit entity,
     * but you want to use a kelp entity for your operations. You can also use
     * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
     * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
     * but this way you don't have to cast your entity to the specific type
     * manually.
     *
     * @param entity The entity you want to convert.
     * @return The kelp instance of the given bukkit entity.
     */
    static PigEntity from(Entity entity) {
        return (PigEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class).getKelpEntity(entity);
    }

    static KelpEntityType getEntityType() {
        return KelpEntityType.PIG;
    }

    @Override
    default KelpEntityType getType() {
        return getEntityType();
    }

    boolean hasSaddle();

    PigEntity setSaddled(boolean saddled);
}


package de.pxav.kelp.core.entity.type;

import de.pxav.kelp.core.KelpPlugin;
import de.pxav.kelp.core.entity.KelpEntity;
import de.pxav.kelp.core.entity.KelpEntityType;
import de.pxav.kelp.core.entity.type.general.AnimalEntity;
import de.pxav.kelp.core.entity.type.general.BreedableAnimalEntity;
import de.pxav.kelp.core.entity.type.general.VehicleEntity;
import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
import de.pxav.kelp.core.world.KelpLocation;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Pig;

public interface PigEntity extends AnimalEntity<PigEntity>, BreedableAnimalEntity<PigEntity>, VehicleEntity<PigEntity> {

    /**
     * Creates a new entity of this type at the given location.
     *
     * While this creates a new instance, it won't actually spawn the entity.
     * You can first do some modifications on it and then call the
     * {@link KelpEntity#spawn()} method.
     *
     * If you don't want to create a new entity, but just a new kelp
     * entity instance based of an existing bukkit entity, you can use
     * {@link #from(Entity)} instead.
     *
     * @param location The location, where the entity should be spawned later.
     * @return A new instance of a sheep entity.
     */
    static PigEntity create(KelpLocation location) {
        return (PigEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class).newKelpEntity(getEntityType(), location.getBukkitLocation());
    }

    /**
     * Takes a bukkit entity and converts it to a kelp entity of the same type.
     *
     * This can be used if you are for example handling an event that returns a bukkit entity,
     * but you want to use a kelp entity for your operations. You can also use
     * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
     * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
     * but this way you don't have to cast your entity to the specific type
     * manually.
     *
     * @param entity The entity you want to convert.
     * @return The kelp instance of the given bukkit entity.
     */
    static PigEntity from(Entity entity) {
        return (PigEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class).getKelpEntity(entity);
    }

    static KelpEntityType getEntityType() {
        return KelpEntityType.PIG;
    }

    @Override
    default KelpEntityType getType()

    boolean hasSaddle();

    PigEntity setSaddled(boolean saddled);
}


package de.pxav.kelp.core.entity.type;

import de.pxav.kelp.core.KelpPlugin;
import de.pxav.kelp.core.entity.KelpEntity;
import de.pxav.kelp.core.entity.KelpEntityType;
import de.pxav.kelp.core.entity.type.general.AnimalEntity;
import de.pxav.kelp.core.entity.type.general.BreedableAnimalEntity;
import de.pxav.kelp.core.entity.type.general.VehicleEntity;
import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
import de.pxav.kelp.core.world.KelpLocation;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Pig;

public interface PigEntity extends AnimalEntity<PigEntity>, BreedableAnimalEntity<PigEntity>, VehicleEntity<PigEntity> {

    /**
     * Creates a new entity of this type at the given location.
     *
     * While this creates a new instance, it won't actually spawn the entity.
     * You can first do some modifications on it and then call the
     * {@link KelpEntity#spawn()} method.
     *
     * If you don't want to create a new entity, but just a new kelp
     * entity instance based of an existing bukkit entity, you can use
     * {@link #from(Entity)} instead.
     *
     * @param location The location, where the entity should be spawned later.
     * @return A new instance of a sheep entity.
     */
    static PigEntity create(KelpLocation location) {
        return (PigEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class).newKelpEntity(getEntityType(), location.getBukkitLocation());
    }

    /**
     * Takes a bukkit entity and converts it to a kelp entity of the same type.
     *
     * This can be used if you are for example handling an event that returns a bukkit entity,
     * but you want to use a kelp entity for your operations. You can also use
     * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
     * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
     * but this way you don't have to cast your entity to the specific type
     * manually.
     *
     * @param entity The entity you want to convert.
     * @return The kelp instance of the given bukkit entity.
     */
    static PigEntity from(Entity entity) {
        return (PigEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class).getKelpEntity(entity);
    }

    static KelpEntityType getEntityType() {

    }

    @Override
    default KelpEntityType getType() {
        return getEntityType();
    }

    boolean hasSaddle();

    PigEntity setSaddled(boolean saddled);
}


static PigEntity from(Entity entity) {
        return (PigEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class).getKelpEntity(entity);
    }

package de.pxav.kelp.core.entity.type;

import de.pxav.kelp.core.KelpPlugin;
import de.pxav.kelp.core.entity.KelpEntity;
import de.pxav.kelp.core.entity.KelpEntityType;
import de.pxav.kelp.core.entity.type.general.AnimalEntity;
import de.pxav.kelp.core.entity.type.general.BreedableAnimalEntity;
import de.pxav.kelp.core.entity.type.general.VehicleEntity;
import de.pxav.kelp.core.entity.version.EntityTypeVersionTemplate;
import de.pxav.kelp.core.world.KelpLocation;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Pig;

public interface PigEntity extends AnimalEntity<PigEntity>, BreedableAnimalEntity<PigEntity>, VehicleEntity<PigEntity> {

    /**
     * Creates a new entity of this type at the given location.
     *
     * While this creates a new instance, it won't actually spawn the entity.
     * You can first do some modifications on it and then call the
     * {@link KelpEntity#spawn()} method.
     *
     * If you don't want to create a new entity, but just a new kelp
     * entity instance based of an existing bukkit entity, you can use
     * {@link #from(Entity)} instead.
     *
     * @param location The location, where the entity should be spawned later.
     * @return A new instance of a sheep entity.
     */
    static PigEntity create(KelpLocation location) {
        return (PigEntity) KelpPlugin.getInjector().getInstance(EntityTypeVersionTemplate.class).newKelpEntity(getEntityType(), location.getBukkitLocation());
    }

    /**
     * Takes a bukkit entity and converts it to a kelp entity of the same type.
     *
     * This can be used if you are for example handling an event that returns a bukkit entity,
     * but you want to use a kelp entity for your operations. You can also use
     * the more general method provided by {@link de.pxav.kelp.core.entity.KelpEntity the
     * kelp entity base class}: {@link de.pxav.kelp.core.entity.KelpEntity#from(Entity)},
     * but this way you don't have to cast your entity to the specific type
     * manually.
     *
     * @param entity The entity you want to convert.
     * @return The kelp instance of the given bukkit entity.
     */

    static KelpEntityType getEntityType() {
        return KelpEntityType.PIG;
    }

    @Override
    default KelpEntityType getType() {
        return getEntityType();
    }

    boolean hasSaddle();

    PigEntity setSaddled(boolean saddled);
}


@Override
    public Arbitrary<Byte> generate(AnnotationSource annotationSource)

package com.navercorp.fixturemonkey.generator;

import java.math.BigDecimal;
import net.jqwik.api.Arbitraries;
import net.jqwik.api.Arbitrary;
import net.jqwik.api.arbitraries.ByteArbitrary;

public class ByteAnnotatedArbitraryGenerator implements AnnotatedArbitraryGenerator<Byte> {

    public static final ByteAnnotatedArbitraryGenerator INSTANCE = new ByteAnnotatedArbitraryGenerator();

{
        AnnotatedGeneratorConstraint constraint = AnnotatedGeneratorConstraints.findConstraintByClass(Byte.class, annotationSource);
        return generate(constraint);
    }

    private ByteArbitrary generate(AnnotatedGeneratorConstraint constraint) {
        ByteArbitrary arbitrary = Arbitraries.bytes();
        BigDecimal min = constraint.getMin();
        BigDecimal max = constraint.getMax();
        if (min != null && max != null) {
            return arbitrary.between(min.byteValue(), max.byteValue());
        } else if (max != null) {
            return arbitrary.lessOrEqual(max.byteValue());
        } else if (min != null) {
            return arbitrary.greaterOrEqual(min.byteValue());
        } else {
            return arbitrary;
        }
    }
}


{
        AnnotatedGeneratorConstraint constraint = AnnotatedGeneratorConstraints.findConstraintByClass(Byte.class, annotationSource);
        return generate(constraint);
    }

package com.navercorp.fixturemonkey.generator;

import java.math.BigDecimal;
import net.jqwik.api.Arbitraries;
import net.jqwik.api.Arbitrary;
import net.jqwik.api.arbitraries.ByteArbitrary;

public class ByteAnnotatedArbitraryGenerator implements AnnotatedArbitraryGenerator<Byte> {

    public static final ByteAnnotatedArbitraryGenerator INSTANCE = new ByteAnnotatedArbitraryGenerator();

    @Override
    public Arbitrary<Byte> generate(AnnotationSource annotationSource)

    private ByteArbitrary generate(AnnotatedGeneratorConstraint constraint) {
        ByteArbitrary arbitrary = Arbitraries.bytes();
        BigDecimal min = constraint.getMin();
        BigDecimal max = constraint.getMax();
        if (min != null && max != null) {
            return arbitrary.between(min.byteValue(), max.byteValue());
        } else if (max != null) {
            return arbitrary.lessOrEqual(max.byteValue());
        } else if (min != null) {
            return arbitrary.greaterOrEqual(min.byteValue());
        } else {
            return arbitrary;
        }
    }
}


package com.navercorp.fixturemonkey.generator;

import java.math.BigDecimal;
import net.jqwik.api.Arbitraries;
import net.jqwik.api.Arbitrary;
import net.jqwik.api.arbitraries.ByteArbitrary;

public class ByteAnnotatedArbitraryGenerator implements AnnotatedArbitraryGenerator<Byte> {

    public static final ByteAnnotatedArbitraryGenerator INSTANCE = new ByteAnnotatedArbitraryGenerator();

    @Override
    public Arbitrary<Byte> generate(AnnotationSource annotationSource) {
        AnnotatedGeneratorConstraint constraint = AnnotatedGeneratorConstrai

        return generate(constraint);
    }

    private ByteArbitrary generate(AnnotatedGeneratorConstraint constraint) {
        ByteArbitrary arbitrary = Arbitraries.bytes();
        BigDecimal min = constraint.getMin();
        BigDecimal max = constraint.getMax();
        if (min != null && max != null) {
            return arbitrary.between(min.byteValue(), max.byteValue());
        } else if (max != null) {
            return arbitrary.lessOrEqual(max.byteValue());
        } else if (min != null) {
            return arbitrary.greaterOrEqual(min.byteValue());
        } else {
            return arbitrary;
        }
    }
}


@Nonnull
    public static <T> UBL20WriterBuilder<T> create(@Nonnull final Class<T> aClass)

package com.helger.ubl20;

import javax.annotation.Nonnull;
import javax.annotation.concurrent.NotThreadSafe;
import com.helger.jaxb.builder.JAXBWriterBuilder;
import com.helger.xml.namespace.MapBasedNamespaceContext;

/**
 * A writer builder for UBL 2.0 documents.
 *
 * @author Philip Helger
 * @param <JAXBTYPE>
 *        The UBL 2.0 implementation class to be read
 */
@NotThreadSafe
public class UBL20WriterBuilder<JAXBTYPE> extends JAXBWriterBuilder<JAXBTYPE, UBL20WriterBuilder<JAXBTYPE>> {

    public UBL20WriterBuilder(@Nonnull final EUBL20DocumentType eDocType) {
        super(eDocType);
        // Create a special namespace context for the passed document type
        final MapBasedNamespaceContext aNSContext = UBL20NamespaceContext.getInstance().getClone();
        // Avoid overwriting an already mapped context
        if (!aNSContext.isNamespaceURIMapped(m_aDocType.getNamespaceURI()))
            aNSContext.addDefaultNamespaceURI(m_aDocType.getNamespaceURI());
        setNamespaceContext(aNSContext);
    }

    public UBL20WriterBuilder(@Nonnull final Class<JAXBTYPE> aClass) {
        this(UBL20DocumentTypes.getDocumentTypeOfImplementationClass(aClass));
    }

    /**
     * Create a new writer builder.
     *
     * @param aClass
     *        The UBL class to be written. May not be null.
     * @return The new writer builder. Never null.
     * @param <T>
     *        The UBL 2.0 document implementation type
     */

{
        return new UBL20WriterBuilder<>(aClass);
    }
}


{
        return new UBL20WriterBuilder<>(aClass);
    }

package com.helger.ubl20;

import javax.annotation.Nonnull;
import javax.annotation.concurrent.NotThreadSafe;
import com.helger.jaxb.builder.JAXBWriterBuilder;
import com.helger.xml.namespace.MapBasedNamespaceContext;

/**
 * A writer builder for UBL 2.0 documents.
 *
 * @author Philip Helger
 * @param <JAXBTYPE>
 *        The UBL 2.0 implementation class to be read
 */
@NotThreadSafe
public class UBL20WriterBuilder<JAXBTYPE> extends JAXBWriterBuilder<JAXBTYPE, UBL20WriterBuilder<JAXBTYPE>> {

    public UBL20WriterBuilder(@Nonnull final EUBL20DocumentType eDocType) {
        super(eDocType);
        // Create a special namespace context for the passed document type
        final MapBasedNamespaceContext aNSContext = UBL20NamespaceContext.getInstance().getClone();
        // Avoid overwriting an already mapped context
        if (!aNSContext.isNamespaceURIMapped(m_aDocType.getNamespaceURI()))
            aNSContext.addDefaultNamespaceURI(m_aDocType.getNamespaceURI());
        setNamespaceContext(aNSContext);
    }

    public UBL20WriterBuilder(@Nonnull final Class<JAXBTYPE> aClass) {
        this(UBL20DocumentTypes.getDocumentTypeOfImplementationClass(aClass));
    }

    /**
     * Create a new writer builder.
     *
     * @param aClass
     *        The UBL class to be written. May not be null.
     * @return The new writer builder. Never null.
     * @param <T>
     *        The UBL 2.0 document implementation type
     */
    @Nonnull
    public static <T> UBL20WriterBuilder<T> create(@Nonnull final Class<T> aClass)


package com.helger.ubl20;

import javax.annotation.Nonnull;
import javax.annotation.concurrent.NotThreadSafe;
import com.helger.jaxb.builder.JAXBWriterBuilder;
import com.helger.xml.namespace.MapBasedNamespaceContext;

/**
 * A writer builder for UBL 2.0 documents.
 *
 * @author Philip Helger
 * @param <JAXBTYPE>
 *        The UBL 2.0 implementation class to be read
 */
@NotThreadSafe
public class UBL20WriterBuilder<JAXBTYPE> extends JAXBWriterBuilder<JAXBTYPE, UBL20WriterBuilder<JAXBTYPE>> {

    public UBL20WriterBuilder(@Nonnull final EUBL20DocumentType eDocType) {
        super(eDocType);
        // Create a special namespace context for the passed document type
        final MapBasedNamespaceContext aNSContext = UBL20NamespaceContext.getInstance().getClone();
        // Avoid overwriting an already mapped context
        if (!aNSContext.isNamespaceURIMapped(m_aDocType.getNamespaceURI()))
            aNSContext.addDefaultNamespaceURI(m_aDocType.getNamespaceURI());
        setNamespaceContext(aNSContext);
    }

    public UBL20WriterBuilder(@Nonnull final Class<JAXBTYPE> aClass) {
        this(UBL20DocumentTypes.getDocumentTypeOfImplementationClass(aClass));
    }

    /**
     * Create a new writer builder.
     *
     * @param aClass
     *        The UBL class to be written. May not be null.
     * @return The new writer builder. Never null.
     * @param <T>
     *        The UBL 2.0 document implementation type
     */
    @Nonnull
    public static <T> UBL20WriterBuilder<T> create(@Nonnull final Class<T> aClass) {
        return new UBL20WriterBuilder<>(aCla


@Nonnull
    public static <T> UBL20WriterBuilder<T> create(@Nonnull final Class<T> aClass) {
        return new UBL20WriterBuilder<>(aClass);
    }


@Override
    public <T> T unwrap(Class<T> iface) throws SQLException

package com.ctrip.framework.dal.cluster.client.cluster;

import com.ctrip.framework.dal.cluster.client.Cluster;
import com.ctrip.framework.dal.cluster.client.base.UnsupportedListenable;
import com.ctrip.framework.dal.cluster.client.config.ClusterConfigImpl;
import com.ctrip.framework.dal.cluster.client.config.DalConfigCustomizedOption;
import com.ctrip.framework.dal.cluster.client.config.LocalizationConfig;
import com.ctrip.framework.dal.cluster.client.database.Database;
import com.ctrip.framework.dal.cluster.client.database.DatabaseCategory;
import com.ctrip.framework.dal.cluster.client.exception.ClusterRuntimeException;
import com.ctrip.framework.dal.cluster.client.multihost.ClusterRouteStrategyConfig;
import com.ctrip.framework.dal.cluster.client.shard.DatabaseShard;
import com.ctrip.framework.dal.cluster.client.sharding.context.DbShardContext;
import com.ctrip.framework.dal.cluster.client.sharding.context.TableShardContext;
import com.ctrip.framework.dal.cluster.client.sharding.idgen.ClusterIdGeneratorConfig;
import java.sql.SQLException;
import java.util.*;

/**
 * @author c7ch23en
 */
public class DefaultCluster extends UnsupportedListenable<ClusterSwitchedEvent> implements Cluster {

    private ClusterConfigImpl clusterConfig;

    private Map<Integer, DatabaseShard> databaseShards = new HashMap<>();

    private ShardStrategyProxy shardStrategyProxy;

    private ClusterIdGeneratorConfig idGeneratorConfig;

    private ClusterRouteStrategyConfig routeStrategyConfig;

    private LocalizationConfig localizationConfig;

    private LocalizationConfig lastLocalizationConfig;

    private DalConfigCustomizedOption customizedOption;

    public DefaultCluster(ClusterConfigImpl clusterConfig) {
        this.clusterConfig = clusterConfig;
    }

    @Override
    public String getClusterName() {
        return clusterConfig.getClusterName();
    }

    @Override
    public ClusterType getClusterType() {
        return clusterConfig.getClusterType();
    }

    @Override
    public DatabaseCategory getDatabaseCategory() {
        return clusterConfig.getDatabaseCategory();
    }

    @Override
    public boolean dbShardingEnabled() {
        return databaseShards.size() > 1;
    }

    @Override
    public Integer getDbShard(String tableName, DbShardContext context) {
        return shardStrategyProxy.getDbShard(tableName, context);
    }

    @Override
    public Set<Integer> getAllDbShards() {
        return databaseShards.keySet();
    }

    @Override
    public boolean tableShardingEnabled(String tableName) {
        return shardStrategyProxy.tableShardingEnabled(tableName);
    }

    @Override
    public String getTableShard(String tableName, TableShardContext context) {
        return shardStrategyProxy.getTableShard(tableName, context);
    }

    @Override
    public Set<String> getAllTableShards(String tableName) {
        return shardStrategyProxy.getAllTableShards(tableName);
    }

    @Override
    public String getTableShardSeparator(String tableName) {
        return shardStrategyProxy.getTableShardSeparator(tableName);
    }

    @Override
    public List<Database> getDatabases() {
        List<Database> databases = new LinkedList<>();
        for (DatabaseShard databaseShard : databaseShards.values()) {
            databases.addAll(databaseShard.getMasters());
            databases.addAll(databaseShard.getSlaves());
        }
        return databases;
    }

    @Override
    public Database getMasterOnShard(int shardIndex) {
        List<Database> masters = databaseShards.get(shardIndex).getMasters();
        if (masters == null || masters.isEmpty())
            throw new ClusterRuntimeException("no master available");
        // throw new ClusterRuntimeException("multi masters available");
        return masters.iterator().next();
    }

    @Override
    public List<Database> getSlavesOnShard(int shardIndex) {
        return databaseShards.get(shardIndex).getSlaves();
    }

    @Override
    public ClusterIdGeneratorConfig getIdGeneratorConfig() {
        return idGeneratorConfig;
    }

    @Override
    public ClusterRouteStrategyConfig getRouteStrategyConfig() {
        return routeStrategyConfig;
    }

    @Override
    public LocalizationConfig getLocalizationConfig() {
        return localizationConfig;
    }

    @Override
    public LocalizationConfig getLastLocalizationConfig() {
        return this.lastLocalizationConfig;
    }

    @Override
    public DalConfigCustomizedOption getCustomizedOption() {
        return this.customizedOption;
    }

    @Override
    public DatabaseShard getDatabaseShard(int shardIndex) {
        return databaseShards.get(shardIndex);
    }

    public void setCustomizedOption(DalConfigCustomizedOption customizedOption) {
        this.customizedOption = customizedOption;
    }

    public void setLastLocalizationConfig(LocalizationConfig lastConfig) {
        this.lastLocalizationConfig = lastConfig;
    }

    public void addDatabaseShard(DatabaseShard databaseShard) {
        databaseShards.put(databaseShard.getShardIndex(), databaseShard);
    }

    public void setShardStrategy(ShardStrategyProxy shardStrategyProxy) {
        this.shardStrategyProxy = shardStrategyProxy;
    }

    public void setIdGeneratorConfig(ClusterIdGeneratorConfig idGeneratorConfig) {
        this.idGeneratorConfig = idGeneratorConfig;
    }

    public void setRouteStrategyConfig(ClusterRouteStrategyConfig routeStrategyConfig) {
        this.routeStrategyConfig = routeStrategyConfig;
    }

    public void setLocalizationConfig(LocalizationConfig localizationConfig) {
        this.localizationConfig = localizationConfig;
    }

    public void validate() {
    }

{
        try {
            return iface.cast(this);
        } catch (ClassCastException e) {
            throw new ClusterRuntimeException(String.format("Unable to unwrap %s to %s", this.toString(), iface.toString()));
        }
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return iface.isInstance(this);
    }
}