try {
            // 4.1.1必报错，不知道为什么
            super.onDestroy();
        } catch (Exception e) {
            Logger.printExc(getClass(), e);
        }

package org.aisen.android.ui.fragment;

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.aisen.android.R;
import org.aisen.android.common.utils.Logger;
import org.aisen.android.common.utils.ViewUtils;
import org.aisen.android.component.bitmaploader.BitmapLoader;
import org.aisen.android.component.bitmaploader.core.BitmapOwner;
import org.aisen.android.network.biz.ABizLogic.CacheMode;
import org.aisen.android.network.biz.IResult;
import org.aisen.android.network.task.ITaskManager;
import org.aisen.android.network.task.TaskException;
import org.aisen.android.network.task.TaskManager;
import org.aisen.android.network.task.WorkTask;
import org.aisen.android.support.inject.InjectUtility;
import org.aisen.android.support.inject.ViewInject;
import org.aisen.android.ui.activity.basic.BaseActivity;
import java.text.SimpleDateFormat;

/**
 * 基于ABaseFragment，维护与Activity之间的生命周期绑定，管理WorkTask线程，支持四种个基本视图之间的自动切换

 *
 * 1、处理缓存数据过期后，自动刷新页面

 * 2、处理页面离开设定时间后，自动刷新页面

 */
public abstract class ABaseFragment extends Fragment implements ITaskManager, BitmapOwner {

    static final String TAG = "AFragment-Base";

    public enum ABaseTaskState {

        none,
        prepare,
        falid,
        success,
        finished,
        canceled
    }

    // 管理线程
    private TaskManager taskManager;

    // 根视图
    ViewGroup rootView;

    @ViewInject(idStr = "layoutLoading")
    View // 加载中视图
    loadingLayout;

    @ViewInject(idStr = "layoutLoadFailed")
    View // 加载失败视图
    loadFailureLayout;

    @ViewInject(idStr = "layoutContent")
    View // 内容视图
    contentLayout;

    @ViewInject(idStr = "layoutEmpty")
    View // 空视图
    emptyLayout;

    // 标志是否ContentView是否为空
    private boolean contentEmpty = true;

    // 最后一次非缓存数据获取时间
    protected long lastResultGetTime = 0;

    private boolean destory = false;

    // UI线程的Handler
    Handler mHandler = new Handler(Looper.getMainLooper()) {
    };

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        if (activity instanceof BaseActivity)
            ((BaseActivity) activity).addFragment(toString(), this);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        taskManager = new TaskManager();
        if (savedInstanceState != null)
            taskManager.restore(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if (inflateContentView() > 0) {
            ViewGroup contentView = (ViewGroup) inflater.inflate(inflateContentView(), null);
            contentView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
            setupContentView(inflater, contentView, savedInstanceState);
            return getContentView();
        }
        return super.onCreateView(inflater, container, savedInstanceState);
    }

    /**
     * 根据ContentView初始化视图
     *
     * @param inflater
     * @param contentView
     * @param savedInstanceState
     */
    protected void setupContentView(LayoutInflater inflater, ViewGroup contentView, Bundle savedInstanceState) {
        setContentView(contentView);
        _layoutInit(inflater, savedInstanceState);
        layoutInit(inflater, savedInstanceState);
    }

    public void setContentView(ViewGroup view) {
        this.rootView = view;
    }

    public ViewGroup getContentView() {
        return rootView;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (savedInstanceState == null)
            requestData();
    }

    /**
     * Action的home被点击了
     *
     * @return
     */
    public boolean onHomeClick() {
        return onBackClick();
    }

    public boolean onBackClick() {
        return false;
    }

    public void requestData() {
    }

    /**
     * 延迟时间刷新
     *
     * @param delay
     */
    public void requestDataDelay(long delay) {
        Runnable requestDelayRunnable = new Runnable() {

            @Override
            public void run() {
                Logger.d(TAG, "延迟刷新，开始刷新, " + toString());
                requestData();
            }
        };
        runUIRunnable(requestDelayRunnable, delay);
    }

    public void requestDataOutofdate() {
        requestData();
    }

    /**
     * A*Fragment重写这个方法
     *
     * @param inflater
     * @param savedInstanceSate
     */
    void _layoutInit(LayoutInflater inflater, Bundle savedInstanceSate) {
        InjectUtility.initInjectedView(getActivity(), this, getContentView());
        if (emptyLayout != null) {
            View reloadView = emptyLayout.findViewById(R.id.layoutReload);
            if (reloadView != null)
                setViewOnClick(reloadView);
        }
        if (loadFailureLayout != null) {
            View reloadView = loadFailureLayout.findViewById(R.id.layoutReload);
            if (reloadView != null)
                setViewOnClick(reloadView);
        }
        setViewVisiable(loadingLayout, View.GONE);
        setViewVisiable(loadFailureLayout, View.GONE);
        setViewVisiable(emptyLayout, View.GONE);
        if (isContentEmpty()) {
            // 如果视图为空，就开始加载数据
            if (savedInstanceSate != null) {
                requestData();
            } else {
                setViewVisiable(emptyLayout, View.VISIBLE);
                setViewVisiable(contentLayout, View.GONE);
            }
        } else {
            setViewVisiable(contentLayout, View.VISIBLE);
        }
    }

    public View findViewById(int viewId) {
        if (getContentView() == null)
            return null;
        return getContentView().findViewById(viewId);
    }

    public void setContentEmpty(boolean empty) {
        this.contentEmpty = empty;
    }

    public boolean isContentEmpty() {
        return contentEmpty;
    }

    /**
     * 视图点击回调，子类重写
     *
     * @param view
     */
    public void onViewClicked(View view) {
        if (view.getId() == R.id.layoutReload)
            requestData();
        else if (view.getId() == R.id.layoutRefresh)
            requestData();
    }

    protected void setViewVisiable(View v, int visibility) {
        if (v != null && v.getVisibility() != visibility)
            v.setVisibility(visibility);
    }

    /**
     * 根据{@link ABaseTask} 的加载状态，刷新视图
     *
     * @param state
     *
     * @param exception
     */
    protected void onTaskStateChanged(ABaseTaskState state, TaskException exception) {
        // 开始Task
        if (state == ABaseTaskState.prepare) {
            if (isContentEmpty()) {
                setViewVisiable(loadingLayout, View.VISIBLE);
                setViewVisiable(contentLayout, View.GONE);
            } else {
                setViewVisiable(loadingLayout, View.GONE);
                setViewVisiable(contentLayout, View.VISIBLE);
            }
            setViewVisiable(emptyLayout, View.GONE);
            if (isContentEmpty() && loadingLayout == null) {
                setViewVisiable(contentLayout, View.VISIBLE);
            }
            setViewVisiable(loadFailureLayout, View.GONE);
        } else // Task成功
        if (state == ABaseTaskState.success) {
            setViewVisiable(loadingLayout, View.GONE);
            if (isContentEmpty()) {
                setViewVisiable(emptyLayout, View.VISIBLE);
                setViewVisiable(contentLayout, View.GONE);
            } else {
                setViewVisiable(contentLayout, View.VISIBLE);
                setViewVisiable(emptyLayout, View.GONE);
            }
        } else // 取消Task
        if (state == ABaseTaskState.canceled) {
            if (isContentEmpty()) {
                setViewVisiable(loadingLayout, View.GONE);
                setViewVisiable(emptyLayout, View.VISIBLE);
            }
        } else // Task失败
        if (state == ABaseTaskState.falid) {
            if (isContentEmpty()) {
                if (loadFailureLayout != null) {
                    setViewVisiable(loadFailureLayout, View.VISIBLE);
                    if (exception != null) {
                        TextView txtLoadFailed = (TextView) loadFailureLayout.findViewById(R.id.txtLoadFailed);
                        if (txtLoadFailed != null)
                            txtLoadFailed.setText(exception.getMessage());
                    }
                    setViewVisiable(emptyLayout, View.GONE);
                } else {
                    setViewVisiable(emptyLayout, View.VISIBLE);
                }
                setViewVisiable(loadingLayout, View.GONE);
            }
        } else // Task结束
        if (state == ABaseTaskState.finished) {
        }
    }

    public void showMessage(CharSequence msg) {
        if (!TextUtils.isEmpty(msg) && getActivity() != null)
            ViewUtils.showMessage(getActivity(), msg.toString());
    }

    public void showMessage(int msgId) {
        if (getActivity() != null)
            showMessage(getString(msgId));
    }

    /**
     * Fragment主要的刷新任务线程，定义任务加载流程，耦合Fragment各个状态下的视图刷新方法
     *
     * @param <Params>
     * @param <Progress>
     * @param <Result>
     */
    protected abstract class ABaseTask<Params, Progress, Result> extends WorkTask<Params, Progress, Result> {

        public ABaseTask(String taskId) {
            super(taskId, ABaseFragment.this);
        }

        @Override
        protected void onPrepare() {
            super.onPrepare();
            onTaskStateChanged(ABaseTaskState.prepare, null);
        }

        @Override
        protected void onSuccess(Result result) {
            super.onSuccess(result);
            // 默认加载数据成功，且ContentView有数据展示
            ABaseFragment.this.setContentEmpty(resultIsEmpty(result));
            onTaskStateChanged(ABaseTaskState.success, null);
            if (Logger.DEBUG)
                Logger.d(TAG, "Result获取时间：%s", new SimpleDateFormat("HH:mm:ss").format(lastResultGetTime));
            if (result instanceof IResult) {
                IResult iResult = (IResult) result;
                // 数据是缓存数据
                if (iResult.fromCache()) {
                    // 缓存过期刷新数据
                    if (iResult.outofdate()) {
                        runUIRunnable(new Runnable() {

                            @Override
                            public void run() {
                                Logger.d(TAG, "数据过期，开始刷新, " + toString());
                                requestDataOutofdate();
                            }
                        }, configRequestDelay());
                    }
                } else {
                    lastResultGetTime = System.currentTimeMillis();
                }
            } else {
                lastResultGetTime = System.currentTimeMillis();
            }
        }

        @Override
        protected void onFailure(TaskException exception) {
            super.onFailure(exception);
            onTaskStateChanged(ABaseTaskState.falid, exception);
        }

        @Override
        protected void onCancelled() {
            super.onCancelled();
            onTaskStateChanged(ABaseTaskState.canceled, null);
        }

        @Override
        protected void onFinished() {
            super.onFinished();
            onTaskStateChanged(ABaseTaskState.finished, null);
        }

        /**
         * 返回数据是否空
         *
         * @param result
         * @return
         */
        protected boolean resultIsEmpty(Result result) {
            return result == null ? true : false;
        }
    }

    @Override
    public void onDestroy() {
        destory = true;

        removeAllTask(true);
        if (BitmapLoader.getInstance() != null)
            BitmapLoader.getInstance().cancelPotentialTask(this);
    }

    public boolean isDestory() {
        return destory;
    }

    public boolean isActivityRunning() {
        return getActivity() != null;
    }

    @Override
    public void onDetach() {
        super.onDetach();
        if (getActivity() != null && getActivity() instanceof BaseActivity)
            ((BaseActivity) getActivity()).removeFragment(this.toString());
    }

    @Override
    final public void addTask(@SuppressWarnings("rawtypes") WorkTask task) {
        taskManager.addTask(task);
    }

    @Override
    final public void removeTask(String taskId, boolean cancelIfRunning) {
        taskManager.removeTask(taskId, cancelIfRunning);
    }

    @Override
    final public void removeAllTask(boolean cancelIfRunning) {
        taskManager.removeAllTask(cancelIfRunning);
    }

    @Override
    final public int getTaskCount(String taskId) {
        return taskManager.getTaskCount(taskId);
    }

    /**
     * 初步定义，当Task执行BizLogic方法时，第一次创建时拉取缓存，其他都只拉取网络
     *
     * @param task
     * @return
     */
    final protected CacheMode getTaskCacheMode(WorkTask task) {
        if (task == null || !TextUtils.isEmpty(task.getTaskId()))
            return getTaskCount(task.getTaskId()) == 1 ? CacheMode.auto : CacheMode.disable;
        return CacheMode.disable;
    }

    @Override
    public void clearTaskCount(String taskId) {
        taskManager.clearTaskCount(taskId);
    }

    protected void setViewOnClick(View v) {
        if (v == null)
            return;
        v.setOnClickListener(innerOnClickListener);
    }

    View.OnClickListener innerOnClickListener = new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            onViewClicked(v);
        }
    };

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        if (taskManager != null)
            taskManager.save(outState);
    }

    protected ITaskManager getTaskManager() {
        return taskManager;
    }

    public void runUIRunnable(Runnable runnable) {
        runUIRunnable(runnable, 0);
    }

    public void runUIRunnable(Runnable runnable, long delay) {
        if (delay > 0) {
            mHandler.removeCallbacks(runnable);
            mHandler.postDelayed(runnable, delay);
        } else {
            mHandler.post(runnable);
        }
    }

    /**
     * 子类重写这个方法，初始化视图
     *
     * @param inflater
     * @param savedInstanceSate
     */
    protected void layoutInit(LayoutInflater inflater, Bundle savedInstanceSate) {
    }

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

    /**
     * 指定Fragment的LayoutID
     *
     * @return
     */
    abstract public int inflateContentView();

    /**
     * 指定Activity的ContentViewID
     *
     * @return
     */
    public int inflateActivityContentView() {
        return -1;
    }

    /**
     * 设置Activity的Theme
     *
     * @return
     */
    public int setActivityTheme() {
        return -1;
    }

    public int configRequestDelay() {
        return 500;
    }

    public View getLoadingLayout() {
        return loadingLayout;
    }

    public View getLoadFailureLayout() {
        return loadFailureLayout;
    }

    public View getContentLayout() {
        return contentLayout;
    }

    public View getEmptyLayout() {
        return emptyLayout;
    }
}


package org.robolectric.android.internal;

import androidx.test.internal.platform.ThreadChecker;

/**
 * In Robolectric environment, everything is executed on the main thread except for when you
 * manually create and run your code on worker thread.
 */
@SuppressWarnings("RestrictTo")
public class NoOpThreadChecker implements ThreadChecker {

    @Override
    public void checkMainThread() {
    }

    @Override
    public void checkNotMainThread()


{
        if (sha1 == null) {
            this.sha1 = HashUtil.sha1(getFile());
        }
        return sha1;
    }

package org.gradle.internal.resource.local;

import org.gradle.internal.hash.HashUtil;
import org.gradle.internal.hash.HashValue;

public abstract class AbstractLocallyAvailableResource implements LocallyAvailableResource {

    // Calculated on demand
    private HashValue sha1;

    private Long contentLength;

    private Long lastModified;

    protected AbstractLocallyAvailableResource() {
    }

    protected AbstractLocallyAvailableResource(HashValue sha1) {
        this.sha1 = sha1;
    }

    public HashValue getSha1()

    public long getContentLength() {
        if (contentLength == null) {
            contentLength = getFile().length();
        }
        return contentLength;
    }

    public long getLastModified() {
        if (lastModified == null) {
            lastModified = getFile().lastModified();
        }
        return lastModified;
    }
}


{
        try {
            _commerceDiscountRelLocalService.deleteCommerceDiscountRels(cpDefinition.getModelClassName(), cpDefinition.getCPDefinitionId());
        } catch (PortalException portalException) {
            if (_log.isWarnEnabled()) {
                _log.warn(portalException, portalException);
            }
        }
    }

package com.liferay.commerce.discount.internal.model.listener;

import com.liferay.commerce.discount.service.CommerceDiscountRelLocalService;
import com.liferay.commerce.product.model.CPDefinition;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.model.BaseModelListener;
import com.liferay.portal.kernel.model.ModelListener;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

/**
 * @author Alessio Antonio Rendina
 */
@Component(enabled = false, immediate = true, service = ModelListener.class)
public class CPDefinitionModelListener extends BaseModelListener<CPDefinition> {

    @Override
    public void onBeforeRemove(CPDefinition cpDefinition)

    private static final Log _log = LogFactoryUtil.getLog(CPDefinitionModelListener.class);

    @Reference
    private CommerceDiscountRelLocalService _commerceDiscountRelLocalService;
}


try {
            _commerceDiscountRelLocalService.deleteCommerceDiscountRels(cpDefinition.getModelClassName(), cpDefinition.getCPDefinitionId());
        } catch (PortalException portalException) {
            if (_log.isWarnEnabled()) {
                _log.warn(portalException, portalException);
            }
        }

package com.liferay.commerce.discount.internal.model.listener;

import com.liferay.commerce.discount.service.CommerceDiscountRelLocalService;
import com.liferay.commerce.product.model.CPDefinition;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.model.BaseModelListener;
import com.liferay.portal.kernel.model.ModelListener;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

/**
 * @author Alessio Antonio Rendina
 */
@Component(enabled = false, immediate = true, service = ModelListener.class)
public class CPDefinitionModelListener extends BaseModelListener<CPDefinition> {

    @Override
    public void onBeforeRemove(CPDefinition cpDefinition) {

    }

    private static final Log _log = LogFactoryUtil.getLog(CPDefinitionModelListener.class);

    @Reference
    private CommerceDiscountRelLocalService _commerceDiscountRelLocalService;
}


{
        return handle.getPlayerInfoDataLists().read(0);
    }

package de.photon.aacadditionpro.protocol.packetwrappers.sentbyserver;

import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.wrappers.EnumWrappers;
import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction;
import com.comphenix.protocol.wrappers.PlayerInfoData;
import com.comphenix.protocol.wrappers.WrappedChatComponent;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
import de.photon.aacadditionpro.protocol.packetwrappers.AbstractPacket;
import lombok.val;
import org.bukkit.entity.Player;
import java.util.Collections;
import java.util.List;

public class WrapperPlayServerPlayerInfo extends AbstractPacket {

    public static final PacketType TYPE = PacketType.Play.Server.PLAYER_INFO;

    public WrapperPlayServerPlayerInfo() {
        super(new PacketContainer(TYPE), TYPE);
        handle.getModifier().writeDefaults();
    }

    public WrapperPlayServerPlayerInfo(PacketContainer packet) {
        super(packet, TYPE);
    }

    /**
     * This method updates the player information, and thus the tablist of a player.
     *
     * @param action         the {@link PlayerInfoAction} that will be executed.
     * @param gameProfile    the {@link WrappedGameProfile} of the player whose information will be updated.<br>
     *                       Use {@link WrappedGameProfile#fromPlayer(Player)} in order to get a {@link WrappedGameProfile} from a {@link Player}.
     * @param ping           the new ping of the updated {@link Player}.
     *                       Use {@link de.photon.aacadditionpro.util.server.ping.PingProvider#getPing(Player)} to get the ping of a {@link Player}.
     * @param gameMode       the {@link EnumWrappers.NativeGameMode} of the updated {@link Player}.
     * @param displayName    the new displayName of the updated {@link Player}
     * @param affectedPlayer the {@link Player} who will see the updated information as the packet is sent to him.
     */
    public static void updatePlayerInformation(final PlayerInfoAction action, final WrappedGameProfile gameProfile, final int ping, final EnumWrappers.NativeGameMode gameMode, final WrappedChatComponent displayName, final Player affectedPlayer) {
        val playerInfoData = new PlayerInfoData(gameProfile, ping, gameMode, displayName);
        val playerInfoWrapper = new WrapperPlayServerPlayerInfo();
        playerInfoWrapper.setAction(action);
        playerInfoWrapper.setData(Collections.singletonList(playerInfoData));
        playerInfoWrapper.sendPacket(affectedPlayer);
    }

    public PlayerInfoAction getAction() {
        return handle.getPlayerInfoAction().read(0);
    }

    public void setAction(PlayerInfoAction value) {
        handle.getPlayerInfoAction().write(0, value);
    }

    public List<PlayerInfoData> getData()

    public void setData(List<PlayerInfoData> value) {
        handle.getPlayerInfoDataLists().write(0, value);
    }
}


{
        return Arrays.asList(SELLING_INSTANCE, CHECKING_INSTANCE);
    }

package com.github.robozonky.app.daemon;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import com.github.robozonky.internal.jobs.JobService;
import com.github.robozonky.internal.jobs.SimpleJob;
import com.github.robozonky.internal.jobs.TenantJob;

public final class SellingJobService implements JobService {

    private static final SellingJob SELLING_INSTANCE = new SellingJob();

    private static final SaleCheckJob CHECKING_INSTANCE = new SaleCheckJob();

    @Override
    public Collection<SimpleJob> getSimpleJobs() {
        return Collections.emptyList();
    }

    @Override
    public Collection<TenantJob> getTenantJobs()


{
        notEmpty(version, "bible_required", USER_MISSING_FIELD);
        String[] extraVersionsAsString = StringUtils.split(extraVersions, ",");
        return this.optionsValidationService.getAvailableFeaturesForVersion(version, Arrays.asList(extraVersionsAsString), displayMode, InterlinearMode.valueOf(displayMode));
    }

/**
 * ****************************************************************************
 *  All rights reserved.
 *
 * ****************************************************************************
 */
package com.tyndalehouse.step.rest.controllers;

import static com.tyndalehouse.step.core.exceptions.UserExceptionType.APP_MISSING_FIELD;
import static com.tyndalehouse.step.core.exceptions.UserExceptionType.USER_MISSING_FIELD;
import static com.tyndalehouse.step.core.utils.StringUtils.isNotBlank;
import static com.tyndalehouse.step.core.utils.ValidateUtils.notEmpty;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.inject.Provider;
import com.google.inject.Singleton;
import com.tyndalehouse.step.core.models.BibleVersion;
import com.tyndalehouse.step.core.models.InterlinearMode;
import com.tyndalehouse.step.core.service.PassageOptionsValidationService;
import com.tyndalehouse.step.core.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.servlet.RequestScoped;
import com.tyndalehouse.step.core.models.AvailableFeatures;
import com.tyndalehouse.step.core.models.BookName;
import com.tyndalehouse.step.core.models.ClientSession;
import com.tyndalehouse.step.core.models.EnrichedLookupOption;
import com.tyndalehouse.step.core.models.KeyWrapper;
import com.tyndalehouse.step.core.models.OsisWrapper;
import com.tyndalehouse.step.core.models.search.StrongCountsAndSubjects;
import com.tyndalehouse.step.core.service.BibleInformationService;
import com.tyndalehouse.step.core.utils.language.ContemporaryLanguageUtils;
import com.tyndalehouse.step.models.ModulesForLanguageUser;
import com.yammer.metrics.annotation.Timed;

/**
 * The controller for retrieving information on the bible or texts from the bible.
 *
 * @author chrisburrell
 */
@Singleton
public class BibleController {

    private static final Logger LOGGER = LoggerFactory.getLogger(BibleController.class);

    private final BibleInformationService bibleInformation;

    private final Provider<ClientSession> clientSession;

    private final PassageOptionsValidationService optionsValidationService;

    /**
     * creates the controller giving access to bible information.
     *
     * @param bibleInformation the service allowing access to biblical material
     * @param clientSession    clientSession given on the request
     */
    @Inject
    public BibleController(final BibleInformationService bibleInformation, final Provider<ClientSession> clientSession, PassageOptionsValidationService optionsValidationService) {
        this.bibleInformation = bibleInformation;
        this.clientSession = clientSession;
        this.optionsValidationService = optionsValidationService;
        LOGGER.debug("Created Bible Controller");
    }

    /**
     * a REST method that returns version of the Bible that are available.
     *
     * @param allVersions boolean to indicate whether all versions should be returned
     * @return all versions of modules that are considered to be Bibles.
     */
    public ModulesForLanguageUser getModules(final String allVersions) {
        final String language = this.clientSession.get().getLanguage();
        final Locale userLocale = this.clientSession.get().getLocale();
        final ModulesForLanguageUser versions = new ModulesForLanguageUser();
        versions.setLanguageCode(userLocale.getLanguage());
        versions.setLanguageName(ContemporaryLanguageUtils.capitaliseFirstLetter(userLocale.getDisplayLanguage(userLocale)));
        versions.setVersions(this.bibleInformation.getAvailableModules(Boolean.valueOf(allVersions), language, userLocale));
        final Iterator<BibleVersion> iterator = versions.getVersions().iterator();
        while (iterator.hasNext()) {
            if (!iterator.next().getInitials().startsWith("Chi")) {
                iterator.remove();
            }
        }
        return versions;
    }

    /**
     * a REST method that returns text from the Bible.
     *
     * @param version   the initials identifying the version
     * @param reference the reference to lookup
     * @return the text to be displayed, formatted as HTML
     */
    public OsisWrapper getBibleText(final String version, final String reference) {
        return getBibleText(version, reference, null, null, null);
    }

    /**
     * Returns the plain text for version and reference
     * @param version the version of interest
     * @param reference the reference that we are interested in
     * @return the plain text data
     */
    public String getPlainTextPreview(final String version, final String reference) {
        return this.bibleInformation.getPlainText(version, reference, true);
    }

    /**
     * a REST method that returns text from the Bible.
     *
     * @param version   the initials identifying the version
     * @param reference the reference to lookup
     * @param options   the list of options to be passed through and affect the retrieval process
     * @return the text to be displayed, formatted as HTML
     */
    public OsisWrapper getBibleText(final String version, final String reference, final String options) {
        return getBibleText(version, reference, options, null, null);
    }

    /**
     * a REST method that returns Bible Text
     *
     * @param version            the initials identifying the version
     * @param reference          the reference to lookup
     * @param options            a list of options to be passed in
     * @param interlinearVersion the interlinear version if provided adds lines under the text
     * @return the text to be displayed, formatted as HTML
     */
    public OsisWrapper getBibleText(final String version, final String reference, final String options, final String interlinearVersion) {
        return getBibleText(version, reference, options, interlinearVersion, null);
    }

    /**
     * a REST method that returns.
     *
     * @param version            the initials identifying the version
     * @param reference          the reference to lookup
     * @param options            a list of options to be passed in
     * @param interlinearVersion the interlinear version if provided adds lines under the text
     * @param interlinearMode    the mode to use for displaying
     * @return the text to be displayed, formatted as HTML
     */
    @Timed(name = "getText", rateUnit = TimeUnit.SECONDS, durationUnit = TimeUnit.MILLISECONDS)
    public OsisWrapper getBibleText(final String version, final String reference, final String options, final String interlinearVersion, final String interlinearMode) {
        notEmpty(version, "bible_required", USER_MISSING_FIELD);
        notEmpty(reference, "reference_required", USER_MISSING_FIELD);
        return this.bibleInformation.getPassageText(version, reference, options, interlinearVersion, interlinearMode, "en");
    }

    /**
     * Looks up the bible text by verse numbers, mostly used for continuous scrolling.
     *
     * @param version      the version initials
     * @param startVerseId the start verse ordinal
     * @param endVerseId   the end verse ordinal
     * @param roundUp      indicates that verse numbers will be rounded up
     * @param options      the comma-separated list of options (optional)
     * @return the osis wrapper
     */
    public OsisWrapper getBibleByVerseNumber(final String version, final String startVerseId, final String endVerseId, final String roundUp, final String options) {
        return getBibleByVerseNumber(version, startVerseId, endVerseId, roundUp, options, null);
    }

    /**
     * Looks up the bible text by verse numbers, mostly used for continuous scrolling.
     *
     * @param version            the version initials
     * @param startVerseId       the start verse ordinal
     * @param endVerseId         the end verse ordinal
     * @param roundUp            true to indicate rounding up, false to indicate rounding down, anything else for no
     *                           rounding
     * @param options            the comma-separated list of options (optional)
     * @param interlinearVersion an interlinear versions if available (optional)
     * @return the osis wrapper
     */
    public OsisWrapper getBibleByVerseNumber(final String version, final String startVerseId, final String endVerseId, final String roundUp, final String options, final String interlinearVersion) {
        notEmpty(version, "bible_required", USER_MISSING_FIELD);
        notEmpty(startVerseId, "You need to provide a start verse id", APP_MISSING_FIELD);
        notEmpty(endVerseId, "You need to a provide a end verse id", APP_MISSING_FIELD);
        Boolean roundingUp = null;
        if (isNotBlank(roundUp)) {
            if ("true".equalsIgnoreCase(roundUp)) {
                roundingUp = Boolean.TRUE;
            } else if ("false".equalsIgnoreCase(roundUp)) {
                roundingUp = Boolean.FALSE;
            }
        }
        return this.bibleInformation.getPassageText(version, Integer.parseInt(startVerseId), Integer.parseInt(endVerseId), options, interlinearVersion, roundingUp);
    }

    public StrongCountsAndSubjects getStrongNumbersAndSubjects(final String version, final String reference) {
        return this.getStrongNumbersAndSubjects(version, reference, "");
    }

    /**
     * Gets the strong numbers for a particular passage
     *
     * @param reference the reference the passage reference
     * @return the strong numbers attached to the passage
     */
    @Timed(name = "vocab-popup", group = "analysis", rateUnit = TimeUnit.SECONDS, durationUnit = TimeUnit.MILLISECONDS)
    public StrongCountsAndSubjects getStrongNumbersAndSubjects(final String version, final String reference, final String userLanguage) {
        notEmpty(reference, "A verse must be provided", APP_MISSING_FIELD);
        notEmpty(reference, "A version must be provided", APP_MISSING_FIELD);
        return this.bibleInformation.getStrongNumbersAndSubjects(version, reference, userLanguage);
    }

    /**
     * a REST method that returns version of the Bible that are available.
     *
     * @param version       the version initials or full version name to retrieve the versions for
     * @param extraVersions other selected versions - for options such as interlinears/interleaved, this plays a role
     * @param displayMode   the current displayMode
     * @return all versions of modules that are considered to be Bibles.
     */
    public AvailableFeatures getFeatures(final String version, final String extraVersions, final String displayMode)

    /**
     * retrieves the list of features currently supported by the application.
     *
     * @return a list of features currently supported by the application
     */
    public List<EnrichedLookupOption> getAllFeatures() {
        return this.bibleInformation.getAllFeatures();
    }

    /**
     * Gets the bible book names.
     *
     * @param bookStart the phrase input so far in a textbox to use for the lookup
     * @param version   the version to lookup upon
     * @return a list of items
     */
    public List<BookName> getBibleBookNames(final String bookStart, final String version) {
        return this.bibleInformation.getBibleBookNames(bookStart, version, true);
    }

    /**
     * ascertains the next reference to lookup.
     *
     * @param reference the current ref
     * @param version   the current version
     * @return the next reference
     */
    public KeyWrapper getNextChapter(final String reference, final String version) {
        return this.bibleInformation.getSiblingChapter(reference, version, false);
    }

    /**
     * ascertains the next reference to lookup.
     *
     * @param reference     the current ref
     * @param sourceVersion the current version
     * @param targetVersion the version in which we want the reference
     * @return the next reference
     */
    public KeyWrapper convertReferenceForBook(final String reference, final String sourceVersion, final String targetVersion) {
        return this.bibleInformation.convertReferenceForBook(reference, sourceVersion, targetVersion);
    }

    /**
     * ascertains the previous reference to lookup.
     *
     * @param reference the current ref
     * @param version   the current version
     * @return the previous reference
     */
    public KeyWrapper getPreviousChapter(final String reference, final String version) {
        return this.bibleInformation.getSiblingChapter(reference, version, true);
    }

    /**
     * Takes a reference and returns the chapter it is part of.
     *
     * @param version   the version to lookup the key in
     * @param reference the reference that we are interested in
     * @return the new reference with full chapter
     */
    public KeyWrapper expandKeyToChapter(final String sourceVersion, final String version, final String reference) {
        return this.bibleInformation.expandKeyToChapter(sourceVersion, version, reference);
    }

    /**
     * Retrieves key information.
     *
     * @param reference     the reference that we are interested in
     * @param sourceVersion the version attached to the reference text
     * @param version       the version to lookup the key in
     * @return the information about that particular key, e.g. OSIS-ID
     */
    public KeyWrapper getKeyInfo(final String reference, final String sourceVersion, final String version) {
        return this.bibleInformation.getKeyInfo(reference, sourceVersion, version);
    }
}


public KeyWrapper getNextChapter(final String reference, final String version) {
        return this.bibleInformation.getSiblingChapter(reference, version, false);
    }

/**
 * ****************************************************************************
 *  All rights reserved.
 *
 * ****************************************************************************
 */
package com.tyndalehouse.step.rest.controllers;

import static com.tyndalehouse.step.core.exceptions.UserExceptionType.APP_MISSING_FIELD;
import static com.tyndalehouse.step.core.exceptions.UserExceptionType.USER_MISSING_FIELD;
import static com.tyndalehouse.step.core.utils.StringUtils.isNotBlank;
import static com.tyndalehouse.step.core.utils.ValidateUtils.notEmpty;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.inject.Provider;
import com.google.inject.Singleton;
import com.tyndalehouse.step.core.models.BibleVersion;
import com.tyndalehouse.step.core.models.InterlinearMode;
import com.tyndalehouse.step.core.service.PassageOptionsValidationService;
import com.tyndalehouse.step.core.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.servlet.RequestScoped;
import com.tyndalehouse.step.core.models.AvailableFeatures;
import com.tyndalehouse.step.core.models.BookName;
import com.tyndalehouse.step.core.models.ClientSession;
import com.tyndalehouse.step.core.models.EnrichedLookupOption;
import com.tyndalehouse.step.core.models.KeyWrapper;
import com.tyndalehouse.step.core.models.OsisWrapper;
import com.tyndalehouse.step.core.models.search.StrongCountsAndSubjects;
import com.tyndalehouse.step.core.service.BibleInformationService;
import com.tyndalehouse.step.core.utils.language.ContemporaryLanguageUtils;
import com.tyndalehouse.step.models.ModulesForLanguageUser;
import com.yammer.metrics.annotation.Timed;

/**
 * The controller for retrieving information on the bible or texts from the bible.
 *
 * @author chrisburrell
 */
@Singleton
public class BibleController {

    private static final Logger LOGGER = LoggerFactory.getLogger(BibleController.class);

    private final BibleInformationService bibleInformation;

    private final Provider<ClientSession> clientSession;

    private final PassageOptionsValidationService optionsValidationService;

    /**
     * creates the controller giving access to bible information.
     *
     * @param bibleInformation the service allowing access to biblical material
     * @param clientSession    clientSession given on the request
     */
    @Inject
    public BibleController(final BibleInformationService bibleInformation, final Provider<ClientSession> clientSession, PassageOptionsValidationService optionsValidationService) {
        this.bibleInformation = bibleInformation;
        this.clientSession = clientSession;
        this.optionsValidationService = optionsValidationService;
        LOGGER.debug("Created Bible Controller");
    }

    /**
     * a REST method that returns version of the Bible that are available.
     *
     * @param allVersions boolean to indicate whether all versions should be returned
     * @return all versions of modules that are considered to be Bibles.
     */
    public ModulesForLanguageUser getModules(final String allVersions) {
        final String language = this.clientSession.get().getLanguage();
        final Locale userLocale = this.clientSession.get().getLocale();
        final ModulesForLanguageUser versions = new ModulesForLanguageUser();
        versions.setLanguageCode(userLocale.getLanguage());
        versions.setLanguageName(ContemporaryLanguageUtils.capitaliseFirstLetter(userLocale.getDisplayLanguage(userLocale)));
        versions.setVersions(this.bibleInformation.getAvailableModules(Boolean.valueOf(allVersions), language, userLocale));
        final Iterator<BibleVersion> iterator = versions.getVersions().iterator();
        while (iterator.hasNext()) {
            if (!iterator.next().getInitials().startsWith("Chi")) {
                iterator.remove();
            }
        }
        return versions;
    }

    /**
     * a REST method that returns text from the Bible.
     *
     * @param version   the initials identifying the version
     * @param reference the reference to lookup
     * @return the text to be displayed, formatted as HTML
     */
    public OsisWrapper getBibleText(final String version, final String reference) {
        return getBibleText(version, reference, null, null, null);
    }

    /**
     * Returns the plain text for version and reference
     * @param version the version of interest
     * @param reference the reference that we are interested in
     * @return the plain text data
     */
    public String getPlainTextPreview(final String version, final String reference) {
        return this.bibleInformation.getPlainText(version, reference, true);
    }

    /**
     * a REST method that returns text from the Bible.
     *
     * @param version   the initials identifying the version
     * @param reference the reference to lookup
     * @param options   the list of options to be passed through and affect the retrieval process
     * @return the text to be displayed, formatted as HTML
     */
    public OsisWrapper getBibleText(final String version, final String reference, final String options) {
        return getBibleText(version, reference, options, null, null);
    }

    /**
     * a REST method that returns Bible Text
     *
     * @param version            the initials identifying the version
     * @param reference          the reference to lookup
     * @param options            a list of options to be passed in
     * @param interlinearVersion the interlinear version if provided adds lines under the text
     * @return the text to be displayed, formatted as HTML
     */
    public OsisWrapper getBibleText(final String version, final String reference, final String options, final String interlinearVersion) {
        return getBibleText(version, reference, options, interlinearVersion, null);
    }

    /**
     * a REST method that returns.
     *
     * @param version            the initials identifying the version
     * @param reference          the reference to lookup
     * @param options            a list of options to be passed in
     * @param interlinearVersion the interlinear version if provided adds lines under the text
     * @param interlinearMode    the mode to use for displaying
     * @return the text to be displayed, formatted as HTML
     */
    @Timed(name = "getText", rateUnit = TimeUnit.SECONDS, durationUnit = TimeUnit.MILLISECONDS)
    public OsisWrapper getBibleText(final String version, final String reference, final String options, final String interlinearVersion, final String interlinearMode) {
        notEmpty(version, "bible_required", USER_MISSING_FIELD);
        notEmpty(reference, "reference_required", USER_MISSING_FIELD);
        return this.bibleInformation.getPassageText(version, reference, options, interlinearVersion, interlinearMode, "en");
    }

    /**
     * Looks up the bible text by verse numbers, mostly used for continuous scrolling.
     *
     * @param version      the version initials
     * @param startVerseId the start verse ordinal
     * @param endVerseId   the end verse ordinal
     * @param roundUp      indicates that verse numbers will be rounded up
     * @param options      the comma-separated list of options (optional)
     * @return the osis wrapper
     */
    public OsisWrapper getBibleByVerseNumber(final String version, final String startVerseId, final String endVerseId, final String roundUp, final String options) {
        return getBibleByVerseNumber(version, startVerseId, endVerseId, roundUp, options, null);
    }

    /**
     * Looks up the bible text by verse numbers, mostly used for continuous scrolling.
     *
     * @param version            the version initials
     * @param startVerseId       the start verse ordinal
     * @param endVerseId         the end verse ordinal
     * @param roundUp            true to indicate rounding up, false to indicate rounding down, anything else for no
     *                           rounding
     * @param options            the comma-separated list of options (optional)
     * @param interlinearVersion an interlinear versions if available (optional)
     * @return the osis wrapper
     */
    public OsisWrapper getBibleByVerseNumber(final String version, final String startVerseId, final String endVerseId, final String roundUp, final String options, final String interlinearVersion) {
        notEmpty(version, "bible_required", USER_MISSING_FIELD);
        notEmpty(startVerseId, "You need to provide a start verse id", APP_MISSING_FIELD);
        notEmpty(endVerseId, "You need to a provide a end verse id", APP_MISSING_FIELD);
        Boolean roundingUp = null;
        if (isNotBlank(roundUp)) {
            if ("true".equalsIgnoreCase(roundUp)) {
                roundingUp = Boolean.TRUE;
            } else if ("false".equalsIgnoreCase(roundUp)) {
                roundingUp = Boolean.FALSE;
            }
        }
        return this.bibleInformation.getPassageText(version, Integer.parseInt(startVerseId), Integer.parseInt(endVerseId), options, interlinearVersion, roundingUp);
    }

    public StrongCountsAndSubjects getStrongNumbersAndSubjects(final String version, final String reference) {
        return this.getStrongNumbersAndSubjects(version, reference, "");
    }

    /**
     * Gets the strong numbers for a particular passage
     *
     * @param reference the reference the passage reference
     * @return the strong numbers attached to the passage
     */
    @Timed(name = "vocab-popup", group = "analysis", rateUnit = TimeUnit.SECONDS, durationUnit = TimeUnit.MILLISECONDS)
    public StrongCountsAndSubjects getStrongNumbersAndSubjects(final String version, final String reference, final String userLanguage) {
        notEmpty(reference, "A verse must be provided", APP_MISSING_FIELD);
        notEmpty(reference, "A version must be provided", APP_MISSING_FIELD);
        return this.bibleInformation.getStrongNumbersAndSubjects(version, reference, userLanguage);
    }

    /**
     * a REST method that returns version of the Bible that are available.
     *
     * @param version       the version initials or full version name to retrieve the versions for
     * @param extraVersions other selected versions - for options such as interlinears/interleaved, this plays a role
     * @param displayMode   the current displayMode
     * @return all versions of modules that are considered to be Bibles.
     */
    public AvailableFeatures getFeatures(final String version, final String extraVersions, final String displayMode) {
        notEmpty(version, "bible_required", USER_MISSING_FIELD);
        String[] extraVersionsAsString = StringUtils.split(extraVersions, ",");
        return this.optionsValidationService.getAvailableFeaturesForVersion(version, Arrays.asList(extraVersionsAsString), displayMode, InterlinearMode.valueOf(displayMode));
    }

    /**
     * retrieves the list of features currently supported by the application.
     *
     * @return a list of features currently supported by the application
     */
    public List<EnrichedLookupOption> getAllFeatures() {
        return this.bibleInformation.getAllFeatures();
    }

    /**
     * Gets the bible book names.
     *
     * @param bookStart the phrase input so far in a textbox to use for the lookup
     * @param version   the version to lookup upon
     * @return a list of items
     */
    public List<BookName> getBibleBookNames(final String bookStart, final String version) {
        return this.bibleInformation.getBibleBookNames(bookStart, version, true);
    }

    /**
     * ascertains the next reference to lookup.
     *
     * @param reference the current ref
     * @param version   the current version
     * @return the next reference
     */

    /**
     * ascertains the next reference to lookup.
     *
     * @param reference     the current ref
     * @param sourceVersion the current version
     * @param targetVersion the version in which we want the reference
     * @return the next reference
     */
    public KeyWrapper convertReferenceForBook(final String reference, final String sourceVersion, final String targetVersion) {
        return this.bibleInformation.convertReferenceForBook(reference, sourceVersion, targetVersion);
    }

    /**
     * ascertains the previous reference to lookup.
     *
     * @param reference the current ref
     * @param version   the current version
     * @return the previous reference
     */
    public KeyWrapper getPreviousChapter(final String reference, final String version) {
        return this.bibleInformation.getSiblingChapter(reference, version, true);
    }

    /**
     * Takes a reference and returns the chapter it is part of.
     *
     * @param version   the version to lookup the key in
     * @param reference the reference that we are interested in
     * @return the new reference with full chapter
     */
    public KeyWrapper expandKeyToChapter(final String sourceVersion, final String version, final String reference) {
        return this.bibleInformation.expandKeyToChapter(sourceVersion, version, reference);
    }

    /**
     * Retrieves key information.
     *
     * @param reference     the reference that we are interested in
     * @param sourceVersion the version attached to the reference text
     * @param version       the version to lookup the key in
     * @return the information about that particular key, e.g. OSIS-ID
     */
    public KeyWrapper getKeyInfo(final String reference, final String sourceVersion, final String version) {
        return this.bibleInformation.getKeyInfo(reference, sourceVersion, version);
    }
}


while (iterator.hasNext()) {
            if (!iterator.next().getInitials().startsWith("Chi")) {
                iterator.remove();
            }
        }

/**
 * ****************************************************************************
 *  All rights reserved.
 *
 * ****************************************************************************
 */
package com.tyndalehouse.step.rest.controllers;

import static com.tyndalehouse.step.core.exceptions.UserExceptionType.APP_MISSING_FIELD;
import static com.tyndalehouse.step.core.exceptions.UserExceptionType.USER_MISSING_FIELD;
import static com.tyndalehouse.step.core.utils.StringUtils.isNotBlank;
import static com.tyndalehouse.step.core.utils.ValidateUtils.notEmpty;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.inject.Provider;
import com.google.inject.Singleton;
import com.tyndalehouse.step.core.models.BibleVersion;
import com.tyndalehouse.step.core.models.InterlinearMode;
import com.tyndalehouse.step.core.service.PassageOptionsValidationService;
import com.tyndalehouse.step.core.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.servlet.RequestScoped;
import com.tyndalehouse.step.core.models.AvailableFeatures;
import com.tyndalehouse.step.core.models.BookName;
import com.tyndalehouse.step.core.models.ClientSession;
import com.tyndalehouse.step.core.models.EnrichedLookupOption;
import com.tyndalehouse.step.core.models.KeyWrapper;
import com.tyndalehouse.step.core.models.OsisWrapper;
import com.tyndalehouse.step.core.models.search.StrongCountsAndSubjects;
import com.tyndalehouse.step.core.service.BibleInformationService;
import com.tyndalehouse.step.core.utils.language.ContemporaryLanguageUtils;
import com.tyndalehouse.step.models.ModulesForLanguageUser;
import com.yammer.metrics.annotation.Timed;

/**
 * The controller for retrieving information on the bible or texts from the bible.
 *
 * @author chrisburrell
 */
@Singleton
public class BibleController {

    private static final Logger LOGGER = LoggerFactory.getLogger(BibleController.class);

    private final BibleInformationService bibleInformation;

    private final Provider<ClientSession> clientSession;

    private final PassageOptionsValidationService optionsValidationService;

    /**
     * creates the controller giving access to bible information.
     *
     * @param bibleInformation the service allowing access to biblical material
     * @param clientSession    clientSession given on the request
     */
    @Inject
    public BibleController(final BibleInformationService bibleInformation, final Provider<ClientSession> clientSession, PassageOptionsValidationService optionsValidationService) {
        this.bibleInformation = bibleInformation;
        this.clientSession = clientSession;
        this.optionsValidationService = optionsValidationService;
        LOGGER.debug("Created Bible Controller");
    }

    /**
     * a REST method that returns version of the Bible that are available.
     *
     * @param allVersions boolean to indicate whether all versions should be returned
     * @return all versions of modules that are considered to be Bibles.
     */
    public ModulesForLanguageUser getModules(final String allVersions) {
        final String language = this.clientSession.get().getLanguage();
        final Locale userLocale = this.clientSession.get().getLocale();
        final ModulesForLanguageUser versions = new ModulesForLanguageUser();
        versions.setLanguageCode(userLocale.getLanguage());
        versions.setLanguageName(ContemporaryLanguageUtils.capitaliseFirstLetter(userLocale.getDisplayLanguage(userLocale)));
        versions.setVersions(this.bibleInformation.getAvailableModules(Boolean.valueOf(allVersions), language, userLocale));
        final Iterator<BibleVersion> iterator = versions.getVersions().iterator();

        return versions;
    }

    /**
     * a REST method that returns text from the Bible.
     *
     * @param version   the initials identifying the version
     * @param reference the reference to lookup
     * @return the text to be displayed, formatted as HTML
     */
    public OsisWrapper getBibleText(final String version, final String reference) {
        return getBibleText(version, reference, null, null, null);
    }

    /**
     * Returns the plain text for version and reference
     * @param version the version of interest
     * @param reference the reference that we are interested in
     * @return the plain text data
     */
    public String getPlainTextPreview(final String version, final String reference) {
        return this.bibleInformation.getPlainText(version, reference, true);
    }

    /**
     * a REST method that returns text from the Bible.
     *
     * @param version   the initials identifying the version
     * @param reference the reference to lookup
     * @param options   the list of options to be passed through and affect the retrieval process
     * @return the text to be displayed, formatted as HTML
     */
    public OsisWrapper getBibleText(final String version, final String reference, final String options) {
        return getBibleText(version, reference, options, null, null);
    }

    /**
     * a REST method that returns Bible Text
     *
     * @param version            the initials identifying the version
     * @param reference          the reference to lookup
     * @param options            a list of options to be passed in
     * @param interlinearVersion the interlinear version if provided adds lines under the text
     * @return the text to be displayed, formatted as HTML
     */
    public OsisWrapper getBibleText(final String version, final String reference, final String options, final String interlinearVersion) {
        return getBibleText(version, reference, options, interlinearVersion, null);
    }

    /**
     * a REST method that returns.
     *
     * @param version            the initials identifying the version
     * @param reference          the reference to lookup
     * @param options            a list of options to be passed in
     * @param interlinearVersion the interlinear version if provided adds lines under the text
     * @param interlinearMode    the mode to use for displaying
     * @return the text to be displayed, formatted as HTML
     */
    @Timed(name = "getText", rateUnit = TimeUnit.SECONDS, durationUnit = TimeUnit.MILLISECONDS)
    public OsisWrapper getBibleText(final String version, final String reference, final String options, final String interlinearVersion, final String interlinearMode) {
        notEmpty(version, "bible_required", USER_MISSING_FIELD);
        notEmpty(reference, "reference_required", USER_MISSING_FIELD);
        return this.bibleInformation.getPassageText(version, reference, options, interlinearVersion, interlinearMode, "en");
    }

    /**
     * Looks up the bible text by verse numbers, mostly used for continuous scrolling.
     *
     * @param version      the version initials
     * @param startVerseId the start verse ordinal
     * @param endVerseId   the end verse ordinal
     * @param roundUp      indicates that verse numbers will be rounded up
     * @param options      the comma-separated list of options (optional)
     * @return the osis wrapper
     */
    public OsisWrapper getBibleByVerseNumber(final String version, final String startVerseId, final String endVerseId, final String roundUp, final String options) {
        return getBibleByVerseNumber(version, startVerseId, endVerseId, roundUp, options, null);
    }

    /**
     * Looks up the bible text by verse numbers, mostly used for continuous scrolling.
     *
     * @param version            the version initials
     * @param startVerseId       the start verse ordinal
     * @param endVerseId         the end verse ordinal
     * @param roundUp            true to indicate rounding up, false to indicate rounding down, anything else for no
     *                           rounding
     * @param options            the comma-separated list of options (optional)
     * @param interlinearVersion an interlinear versions if available (optional)
     * @return the osis wrapper
     */
    public OsisWrapper getBibleByVerseNumber(final String version, final String startVerseId, final String endVerseId, final String roundUp, final String options, final String interlinearVersion) {
        notEmpty(version, "bible_required", USER_MISSING_FIELD);
        notEmpty(startVerseId, "You need to provide a start verse id", APP_MISSING_FIELD);
        notEmpty(endVerseId, "You need to a provide a end verse id", APP_MISSING_FIELD);
        Boolean roundingUp = null;
        if (isNotBlank(roundUp)) {
            if ("true".equalsIgnoreCase(roundUp)) {
                roundingUp = Boolean.TRUE;
            } else if ("false".equalsIgnoreCase(roundUp)) {
                roundingUp = Boolean.FALSE;
            }
        }
        return this.bibleInformation.getPassageText(version, Integer.parseInt(startVerseId), Integer.parseInt(endVerseId), options, interlinearVersion, roundingUp);
    }

    public StrongCountsAndSubjects getStrongNumbersAndSubjects(final String version, final String reference) {
        return this.getStrongNumbersAndSubjects(version, reference, "");
    }

    /**
     * Gets the strong numbers for a particular passage
     *
     * @param reference the reference the passage reference
     * @return the strong numbers attached to the passage
     */
    @Timed(name = "vocab-popup", group = "analysis", rateUnit = TimeUnit.SECONDS, durationUnit = TimeUnit.MILLISECONDS)
    public StrongCountsAndSubjects getStrongNumbersAndSubjects(final String version, final String reference, final String userLanguage) {
        notEmpty(reference, "A verse must be provided", APP_MISSING_FIELD);
        notEmpty(reference, "A version must be provided", APP_MISSING_FIELD);
        return this.bibleInformation.getStrongNumbersAndSubjects(version, reference, userLanguage);
    }

    /**
     * a REST method that returns version of the Bible that are available.
     *
     * @param version       the version initials or full version name to retrieve the versions for
     * @param extraVersions other selected versions - for options such as interlinears/interleaved, this plays a role
     * @param displayMode   the current displayMode
     * @return all versions of modules that are considered to be Bibles.
     */
    public AvailableFeatures getFeatures(final String version, final String extraVersions, final String displayMode) {
        notEmpty(version, "bible_required", USER_MISSING_FIELD);
        String[] extraVersionsAsString = StringUtils.split(extraVersions, ",");
        return this.optionsValidationService.getAvailableFeaturesForVersion(version, Arrays.asList(extraVersionsAsString), displayMode, InterlinearMode.valueOf(displayMode));
    }

    /**
     * retrieves the list of features currently supported by the application.
     *
     * @return a list of features currently supported by the application
     */
    public List<EnrichedLookupOption> getAllFeatures() {
        return this.bibleInformation.getAllFeatures();
    }

    /**
     * Gets the bible book names.
     *
     * @param bookStart the phrase input so far in a textbox to use for the lookup
     * @param version   the version to lookup upon
     * @return a list of items
     */
    public List<BookName> getBibleBookNames(final String bookStart, final String version) {
        return this.bibleInformation.getBibleBookNames(bookStart, version, true);
    }

    /**
     * ascertains the next reference to lookup.
     *
     * @param reference the current ref
     * @param version   the current version
     * @return the next reference
     */
    public KeyWrapper getNextChapter(final String reference, final String version) {
        return this.bibleInformation.getSiblingChapter(reference, version, false);
    }

    /**
     * ascertains the next reference to lookup.
     *
     * @param reference     the current ref
     * @param sourceVersion the current version
     * @param targetVersion the version in which we want the reference
     * @return the next reference
     */
    public KeyWrapper convertReferenceForBook(final String reference, final String sourceVersion, final String targetVersion) {
        return this.bibleInformation.convertReferenceForBook(reference, sourceVersion, targetVersion);
    }

    /**
     * ascertains the previous reference to lookup.
     *
     * @param reference the current ref
     * @param version   the current version
     * @return the previous reference
     */
    public KeyWrapper getPreviousChapter(final String reference, final String version) {
        return this.bibleInformation.getSiblingChapter(reference, version, true);
    }

    /**
     * Takes a reference and returns the chapter it is part of.
     *
     * @param version   the version to lookup the key in
     * @param reference the reference that we are interested in
     * @return the new reference with full chapter
     */
    public KeyWrapper expandKeyToChapter(final String sourceVersion, final String version, final String reference) {
        return this.bibleInformation.expandKeyToChapter(sourceVersion, version, reference);
    }

    /**
     * Retrieves key information.
     *
     * @param reference     the reference that we are interested in
     * @param sourceVersion the version attached to the reference text
     * @param version       the version to lookup the key in
     * @return the information about that particular key, e.g. OSIS-ID
     */
    public KeyWrapper getKeyInfo(final String reference, final String sourceVersion, final String version) {
        return this.bibleInformation.getKeyInfo(reference, sourceVersion, version);
    }
}


{
        return ContactInformation.EMPTY;
    }

package net.fabricmc.loader.impl.metadata;

import net.fabricmc.loader.api.metadata.ContactInformation;
import net.fabricmc.loader.api.metadata.Person;

/**
 * Represents a simple implementation of person which is only identified by name.
 */
class SimplePerson implements Person {

    private final String name;

    SimplePerson(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public ContactInformation getContact()


{
        Log.printLine(getName() + " is starting...");
        schedule(getId(), 0, WorkflowSimTags.START_SIMULATION);
    }

package org.workflowsim;

import java.util.ArrayList;
import java.util.List;
import org.cloudbus.cloudsim.Log;
import org.cloudbus.cloudsim.core.CloudSimTags;
import org.cloudbus.cloudsim.core.SimEntity;
import org.cloudbus.cloudsim.core.SimEvent;
import org.workflowsim.clustering.BasicClustering;
import org.workflowsim.clustering.BlockClustering;
import org.workflowsim.clustering.HorizontalClustering;
import org.workflowsim.clustering.VerticalClustering;
import org.workflowsim.clustering.balancing.BalancedClustering;
import org.workflowsim.utils.ClusteringParameters;
import org.workflowsim.utils.Parameters;
import org.workflowsim.utils.Parameters.ClassType;
import org.workflowsim.utils.ReplicaCatalog;

/**
 * ClusteringEngine is an optional component of WorkflowSim and it merges tasks
 * into jobs
 *
 * @author Weiwei Chen
 * @since WorkflowSim Toolkit 1.0
 * @date Apr 9, 2013
 */
public final class ClusteringEngine extends SimEntity {

    /**
     * The task list
     */
    protected List<Task> taskList;

    /**
     * The job list
     */
    protected List<Job> jobList;

    /**
     * The task submitted list.
     */
    protected List<? extends Task> taskSubmittedList;

    /**
     * The task received list.
     */
    protected List<? extends Task> taskReceivedList;

    /**
     * The number of tasks submitted.
     */
    protected int cloudletsSubmitted;

    /**
     * The clustering engine to use
     */
    protected BasicClustering engine;

    /**
     * The WorkflowEngineId of the WorkflowEngine
     */
    private final int workflowEngineId;

    /**
     * The WorkflowEngine used in this ClusteringEngine
     */
    private final WorkflowEngine workflowEngine;

    /**
     * Created a new ClusteringEngine object.
     *
     * @param name name to be associated with this entity (as required by
     * Sim_entity class from simjava package)
     * @param schedulers the number of schedulers in this ClusteringEngine
     * @throws Exception the exception
     * @pre name != null
     * @post $none
     */
    public ClusteringEngine(String name, int schedulers) throws Exception {
        super(name);
        setJobList(new ArrayList<>());
        setTaskList(new ArrayList<>());
        setTaskSubmittedList(new ArrayList<>());
        setTaskReceivedList(new ArrayList<>());
        cloudletsSubmitted = 0;
        this.workflowEngine = new WorkflowEngine(name + "_Engine_0", schedulers);
        this.workflowEngineId = this.workflowEngine.getId();
    }

    /**
     * returns the WorkflowEngineId
     *
     * @return workflow engine id
     */
    public int getWorkflowEngineId() {
        return this.workflowEngineId;
    }

    /**
     * returns the WorkflowEngine
     *
     * @return workflow engine
     */
    public WorkflowEngine getWorkflowEngine() {
        return this.workflowEngine;
    }

    /**
     * This method is used to send to the broker the list of cloudlets.
     *
     * @param list the list
     * @pre list !=null
     * @post $none
     */
    public void submitTaskList(List<Task> list) {
        getTaskList().addAll(list);
    }

    /**
     * Processes events available for this ClusteringEngine.
     *
     * @pre ev != null
     * @post $none
     */
    protected void processClustering() {
        /**
         * The parameters from configuration file
         */
        ClusteringParameters params = Parameters.getClusteringParameters();
        switch(params.getClusteringMethod()) {
            /**
             * Perform Horizontal Clustering
             */
            case HORIZONTAL:
                // if clusters.num is set in configuration file
                if (params.getClustersNum() != 0) {
                    this.engine = new HorizontalClustering(params.getClustersNum(), 0);
                } else // if clusters.size is set in configuration file
                if (params.getClustersSize() != 0) {
                    this.engine = new HorizontalClustering(0, params.getClustersSize());
                }
                break;
            /**
             * Perform Vertical Clustering
             */
            case VERTICAL:
                int depth = 1;
                this.engine = new VerticalClustering(depth);
                break;
            /**
             * Perform Block Clustering
             */
            case BLOCK:
                this.engine = new BlockClustering(params.getClustersNum(), params.getClustersSize());
                break;
            /**
             * Perform Balanced Clustering
             */
            case BALANCED:
                this.engine = new BalancedClustering(params.getClustersNum());
                break;
            /**
             * By default, it does no clustering
             */
            default:
                this.engine = new BasicClustering();
                break;
        }
        engine.setTaskList(getTaskList());
        engine.run();
        setJobList(engine.getJobList());
    }

    /**
     * Adds data stage-in jobs to the job list
     */
    protected void processDatastaging() {
        /**
         * All the files of this workflow, it is saved in the workflow engine
         */
        List<FileItem> list = this.engine.getTaskFiles();
        /**
         * A bug of cloudsim, you cannot set the length of a cloudlet to be
         * smaller than 110 otherwise it will fail The reason why we set the id
         * of this job to be getJobList().size() is so that the job id is the
         * next available id
         */
        Job job = new Job(getJobList().size(), 110);
        /**
         * This is a very simple implementation of stage-in job, in which we Add
         * all the files to be the input of this stage-in job so that
         * WorkflowSim will transfers them when this job is executed
         */
        List<FileItem> fileList = new ArrayList<>();
        for (FileItem file : list) {
            /**
             * To avoid duplicate files
             */
            if (file.isRealInputFile(list)) {
                ReplicaCatalog.addFileToStorage(file.getName(), Parameters.SOURCE);
                fileList.add(file);
            }
        }
        job.setFileList(fileList);
        job.setClassType(ClassType.STAGE_IN.value);
        /**
         * stage-in is always first level job
         */
        job.setDepth(0);
        job.setPriority(0);
        /**
         * A very simple strategy if you have multiple schedulers and
         * sub-workflows just use the first scheduler
         */
        job.setUserId(getWorkflowEngine().getSchedulerId(0));
        /**
         * add stage-in job
         */
        for (Job cJob : getJobList()) {
            /**
             * first level jobs
             */
            if (cJob.getParentList().isEmpty()) {
                cJob.addParent(job);
                job.addChild(cJob);
            }
        }
        getJobList().add(job);
    }

    /**
     * Processes events available for this Broker.
     *
     * @param ev a SimEvent object
     * @pre ev != null
     * @post $none
     */
    @Override
    public void processEvent(SimEvent ev) {
        switch(ev.getTag()) {
            case WorkflowSimTags.START_SIMULATION:
                break;
            case WorkflowSimTags.JOB_SUBMIT:
                List list = (List) ev.getData();
                setTaskList(list);
                /**
                 * It doesn't mean we must do clustering here because by default
                 * the processClustering() does nothing unless in the
                 * configuration file we have specified to use clustering
                 */
                processClustering();
                /**
                 * Add stage-in jobs Currently we just add a job that has
                 * minimum runtime but inputs all input data at the beginning of
                 * the workflow execution
                 */
                processDatastaging();
                sendNow(this.workflowEngineId, WorkflowSimTags.JOB_SUBMIT, getJobList());
                break;
            case CloudSimTags.END_OF_SIMULATION:
                shutdownEntity();
                break;
            default:
                processOtherEvent(ev);
                break;
        }
    }

    /**
     * Overrides this method when making a new and different type of Broker.
     * This method is called by {@link #body()} for incoming unknown tags.
     *
     * @param ev a SimEvent object
     * @pre ev != null
     * @post $none
     */
    protected void processOtherEvent(SimEvent ev) {
        if (ev == null) {
            Log.printLine(getName() + ".processOtherEvent(): " + "Error - an event is null.");
            return;
        }
        Log.printLine(getName() + ".processOtherEvent(): " + "Error - event unknown by this DatacenterBroker.");
    }

    /**
     * Send an internal event communicating the end of the simulation.
     *
     * @pre $none
     * @post $none
     */
    protected void finishExecution() {
    }

    /*
     * (non-Javadoc)
     * @see cloudsim.core.SimEntity#shutdownEntity()
     */
    @Override
    public void shutdownEntity() {
        Log.printLine(getName() + " is shutting down...");
    }

    /*
     * (non-Javadoc)
     * @see cloudsim.core.SimEntity#startEntity()
     */
    @Override
    public void startEntity()

    /**
     * Gets the task list.
     *
     * @return the task list
     */
    @SuppressWarnings("unchecked")
    public List<Task> getTaskList() {
        return (List<Task>) taskList;
    }

    /**
     * Gets the job list.
     *
     * @return the job list
     */
    public List<Job> getJobList() {
        return jobList;
    }

    /**
     * Sets the task list.
     *
     * @param taskList the new task list
     */
    protected void setTaskList(List<Task> taskList) {
        this.taskList = taskList;
    }

    /**
     * Sets the job list.
     *
     * @param jobList the new job list
     */
    protected void setJobList(List<Job> jobList) {
        this.jobList = jobList;
    }

    /**
     * Gets the tasks submitted list.
     *
     * @return the task submitted list
     */
    @SuppressWarnings("unchecked")
    public List<Task> getTaskSubmittedList() {
        return (List<Task>) taskSubmittedList;
    }

    /**
     * Sets the tasks submitted list.
     *
     * @param taskSubmittedList the new task submitted list
     */
    protected void setTaskSubmittedList(List<Task> taskSubmittedList) {
        this.taskSubmittedList = taskSubmittedList;
    }

    /**
     * Gets the task received list.
     *
     * @return the task received list
     */
    @SuppressWarnings("unchecked")
    public List<Task> getTaskReceivedList() {
        return (List<Task>) taskReceivedList;
    }

    /**
     * Sets the task received list.
     *
     * @param taskReceivedList the new cloudlet received list
     */
    protected void setTaskReceivedList(List<Task> taskReceivedList) {
        this.taskReceivedList = taskReceivedList;
    }
}


@SuppressWarnings("unchecked")
    public List<Task> getTaskReceivedList() {
        return (List<Task>) taskReceivedList;
    }

package org.workflowsim;

import java.util.ArrayList;
import java.util.List;
import org.cloudbus.cloudsim.Log;
import org.cloudbus.cloudsim.core.CloudSimTags;
import org.cloudbus.cloudsim.core.SimEntity;
import org.cloudbus.cloudsim.core.SimEvent;
import org.workflowsim.clustering.BasicClustering;
import org.workflowsim.clustering.BlockClustering;
import org.workflowsim.clustering.HorizontalClustering;
import org.workflowsim.clustering.VerticalClustering;
import org.workflowsim.clustering.balancing.BalancedClustering;
import org.workflowsim.utils.ClusteringParameters;
import org.workflowsim.utils.Parameters;
import org.workflowsim.utils.Parameters.ClassType;
import org.workflowsim.utils.ReplicaCatalog;

/**
 * ClusteringEngine is an optional component of WorkflowSim and it merges tasks
 * into jobs
 *
 * @author Weiwei Chen
 * @since WorkflowSim Toolkit 1.0
 * @date Apr 9, 2013
 */
public final class ClusteringEngine extends SimEntity {

    /**
     * The task list
     */
    protected List<Task> taskList;

    /**
     * The job list
     */
    protected List<Job> jobList;

    /**
     * The task submitted list.
     */
    protected List<? extends Task> taskSubmittedList;

    /**
     * The task received list.
     */
    protected List<? extends Task> taskReceivedList;

    /**
     * The number of tasks submitted.
     */
    protected int cloudletsSubmitted;

    /**
     * The clustering engine to use
     */
    protected BasicClustering engine;

    /**
     * The WorkflowEngineId of the WorkflowEngine
     */
    private final int workflowEngineId;

    /**
     * The WorkflowEngine used in this ClusteringEngine
     */
    private final WorkflowEngine workflowEngine;

    /**
     * Created a new ClusteringEngine object.
     *
     * @param name name to be associated with this entity (as required by
     * Sim_entity class from simjava package)
     * @param schedulers the number of schedulers in this ClusteringEngine
     * @throws Exception the exception
     * @pre name != null
     * @post $none
     */
    public ClusteringEngine(String name, int schedulers) throws Exception {
        super(name);
        setJobList(new ArrayList<>());
        setTaskList(new ArrayList<>());
        setTaskSubmittedList(new ArrayList<>());
        setTaskReceivedList(new ArrayList<>());
        cloudletsSubmitted = 0;
        this.workflowEngine = new WorkflowEngine(name + "_Engine_0", schedulers);
        this.workflowEngineId = this.workflowEngine.getId();
    }

    /**
     * returns the WorkflowEngineId
     *
     * @return workflow engine id
     */
    public int getWorkflowEngineId() {
        return this.workflowEngineId;
    }

    /**
     * returns the WorkflowEngine
     *
     * @return workflow engine
     */
    public WorkflowEngine getWorkflowEngine() {
        return this.workflowEngine;
    }

    /**
     * This method is used to send to the broker the list of cloudlets.
     *
     * @param list the list
     * @pre list !=null
     * @post $none
     */
    public void submitTaskList(List<Task> list) {
        getTaskList().addAll(list);
    }

    /**
     * Processes events available for this ClusteringEngine.
     *
     * @pre ev != null
     * @post $none
     */
    protected void processClustering() {
        /**
         * The parameters from configuration file
         */
        ClusteringParameters params = Parameters.getClusteringParameters();
        switch(params.getClusteringMethod()) {
            /**
             * Perform Horizontal Clustering
             */
            case HORIZONTAL:
                // if clusters.num is set in configuration file
                if (params.getClustersNum() != 0) {
                    this.engine = new HorizontalClustering(params.getClustersNum(), 0);
                } else // if clusters.size is set in configuration file
                if (params.getClustersSize() != 0) {
                    this.engine = new HorizontalClustering(0, params.getClustersSize());
                }
                break;
            /**
             * Perform Vertical Clustering
             */
            case VERTICAL:
                int depth = 1;
                this.engine = new VerticalClustering(depth);
                break;
            /**
             * Perform Block Clustering
             */
            case BLOCK:
                this.engine = new BlockClustering(params.getClustersNum(), params.getClustersSize());
                break;
            /**
             * Perform Balanced Clustering
             */
            case BALANCED:
                this.engine = new BalancedClustering(params.getClustersNum());
                break;
            /**
             * By default, it does no clustering
             */
            default:
                this.engine = new BasicClustering();
                break;
        }
        engine.setTaskList(getTaskList());
        engine.run();
        setJobList(engine.getJobList());
    }

    /**
     * Adds data stage-in jobs to the job list
     */
    protected void processDatastaging() {
        /**
         * All the files of this workflow, it is saved in the workflow engine
         */
        List<FileItem> list = this.engine.getTaskFiles();
        /**
         * A bug of cloudsim, you cannot set the length of a cloudlet to be
         * smaller than 110 otherwise it will fail The reason why we set the id
         * of this job to be getJobList().size() is so that the job id is the
         * next available id
         */
        Job job = new Job(getJobList().size(), 110);
        /**
         * This is a very simple implementation of stage-in job, in which we Add
         * all the files to be the input of this stage-in job so that
         * WorkflowSim will transfers them when this job is executed
         */
        List<FileItem> fileList = new ArrayList<>();
        for (FileItem file : list) {
            /**
             * To avoid duplicate files
             */
            if (file.isRealInputFile(list)) {
                ReplicaCatalog.addFileToStorage(file.getName(), Parameters.SOURCE);
                fileList.add(file);
            }
        }
        job.setFileList(fileList);
        job.setClassType(ClassType.STAGE_IN.value);
        /**
         * stage-in is always first level job
         */
        job.setDepth(0);
        job.setPriority(0);
        /**
         * A very simple strategy if you have multiple schedulers and
         * sub-workflows just use the first scheduler
         */
        job.setUserId(getWorkflowEngine().getSchedulerId(0));
        /**
         * add stage-in job
         */
        for (Job cJob : getJobList()) {
            /**
             * first level jobs
             */
            if (cJob.getParentList().isEmpty()) {
                cJob.addParent(job);
                job.addChild(cJob);
            }
        }
        getJobList().add(job);
    }

    /**
     * Processes events available for this Broker.
     *
     * @param ev a SimEvent object
     * @pre ev != null
     * @post $none
     */
    @Override
    public void processEvent(SimEvent ev) {
        switch(ev.getTag()) {
            case WorkflowSimTags.START_SIMULATION:
                break;
            case WorkflowSimTags.JOB_SUBMIT:
                List list = (List) ev.getData();
                setTaskList(list);
                /**
                 * It doesn't mean we must do clustering here because by default
                 * the processClustering() does nothing unless in the
                 * configuration file we have specified to use clustering
                 */
                processClustering();
                /**
                 * Add stage-in jobs Currently we just add a job that has
                 * minimum runtime but inputs all input data at the beginning of
                 * the workflow execution
                 */
                processDatastaging();
                sendNow(this.workflowEngineId, WorkflowSimTags.JOB_SUBMIT, getJobList());
                break;
            case CloudSimTags.END_OF_SIMULATION:
                shutdownEntity();
                break;
            default:
                processOtherEvent(ev);
                break;
        }
    }

    /**
     * Overrides this method when making a new and different type of Broker.
     * This method is called by {@link #body()} for incoming unknown tags.
     *
     * @param ev a SimEvent object
     * @pre ev != null
     * @post $none
     */
    protected void processOtherEvent(SimEvent ev) {
        if (ev == null) {
            Log.printLine(getName() + ".processOtherEvent(): " + "Error - an event is null.");
            return;
        }
        Log.printLine(getName() + ".processOtherEvent(): " + "Error - event unknown by this DatacenterBroker.");
    }

    /**
     * Send an internal event communicating the end of the simulation.
     *
     * @pre $none
     * @post $none
     */
    protected void finishExecution() {
    }

    /*
     * (non-Javadoc)
     * @see cloudsim.core.SimEntity#shutdownEntity()
     */
    @Override
    public void shutdownEntity() {
        Log.printLine(getName() + " is shutting down...");
    }

    /*
     * (non-Javadoc)
     * @see cloudsim.core.SimEntity#startEntity()
     */
    @Override
    public void startEntity() {
        Log.printLine(getName() + " is starting...");
        schedule(getId(), 0, WorkflowSimTags.START_SIMULATION);
    }

    /**
     * Gets the task list.
     *
     * @return the task list
     */
    @SuppressWarnings("unchecked")
    public List<Task> getTaskList() {
        return (List<Task>) taskList;
    }

    /**
     * Gets the job list.
     *
     * @return the job list
     */
    public List<Job> getJobList() {
        return jobList;
    }

    /**
     * Sets the task list.
     *
     * @param taskList the new task list
     */
    protected void setTaskList(List<Task> taskList) {
        this.taskList = taskList;
    }

    /**
     * Sets the job list.
     *
     * @param jobList the new job list
     */
    protected void setJobList(List<Job> jobList) {
        this.jobList = jobList;
    }

    /**
     * Gets the tasks submitted list.
     *
     * @return the task submitted list
     */
    @SuppressWarnings("unchecked")
    public List<Task> getTaskSubmittedList() {
        return (List<Task>) taskSubmittedList;
    }

    /**
     * Sets the tasks submitted list.
     *
     * @param taskSubmittedList the new task submitted list
     */
    protected void setTaskSubmittedList(List<Task> taskSubmittedList) {
        this.taskSubmittedList = taskSubmittedList;
    }

    /**
     * Gets the task received list.
     *
     * @return the task received list
     */

    /**
     * Sets the task received list.
     *
     * @param taskReceivedList the new cloudlet received list
     */
    protected void setTaskReceivedList(List<Task> taskReceivedList) {
        this.taskReceivedList = taskReceivedList;
    }
}


{
        return withNewChild(Iterables.getOnlyElement(newChildren));
    }

/*
 * ValueWithChild.java
 *
 * This source file is part of the FoundationDB open source project
 *
 *
 */
package com.apple.foundationdb.record.query.predicates;

import com.apple.foundationdb.annotation.API;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import javax.annotation.Nonnull;
import java.util.List;

/**
 * A scalar value type that has children.
 */
@API(API.Status.EXPERIMENTAL)
public interface ValueWithChild extends Value {

    /**
     * Method to retrieve a list of children values.
     * @return a list of children
     */
    @Nonnull
    @Override
    default List<? extends Value> getChildren() {
        return ImmutableList.of(getChild());
    }

    /**
     * Method to retrieve the only child value.
     * @return this child {@link Value}
     */
    @Nonnull
    Value getChild();

    @Nonnull
    @Override
    default ValueWithChild withChildren(@Nonnull final Iterable<? extends Value> newChildren)

    @Nonnull
    ValueWithChild withNewChild(@Nonnull final Value rebasedChild);
}


/*
 * ValueWithChild.java
 *
 * This source file is part of the FoundationDB open source project
 *
 *
 */
package com.apple.foundationdb.record.query.predicates;

import com.apple.foundationdb.annotation.API;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import javax.annotation.Nonnull;
import java.util.List;

/**
 * A scalar value type that has children.
 */
@API(API.Status.EXPERIMENTAL)
public interface ValueWithChild extends Value {

    /**
     * Method to retrieve a list of children values.
     * @return a list of children
     */
    @Nonnull
    @Override
    default List<? extends Value> getChildren() {
        return ImmutableList.of(getChild());
    }

    /**
     * Method to retrieve the only child value.
     * @return this child {@link Value}
     */

    @Nonnull
    @Override
    default ValueWithChild withChildren(@Nonnull final Iterable<? extends Value> newChildren) {
        return withNewChild(Iterables.getOnlyElement(newChildren));
    }

    @Nonnull
    ValueWithChild withNewChild(@Nonnull final Value rebasedChild);
}


package br.com.swconsultoria.nfe.schema_4.enviNFe;

import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

/**
 *  Tipo Pedido de Concessão de Autorização da Nota Fiscal Eletrônica
 *
 *
Classe Java de TEnviNFe complex type.
 *
 *
O seguinte fragmento do esquema especifica o conteúdo esperado contido dentro desta classe.
 *
 *

 * <complexType name="TEnviNFe">
 *   <complexContent>
 *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       <sequence>
 *         <element name="idLote" type="{http://www.portalfiscal.inf.br/nfe}TIdLote"/>
 *         <element name="indSinc">
 *           <simpleType>
 *             <restriction base="{http://www.w3.org/2001/XMLSchema}string">
 *               <whiteSpace value="preserve"/>
 *               <enumeration value="0"/>
 *               <enumeration value="1"/>
 *             </restriction>
 *           </simpleType>
 *         </element>
 *         <element name="NFe" type="{http://www.portalfiscal.inf.br/nfe}TNFe" maxOccurs="50"/>
 *       </sequence>
 *       <attribute name="versao" use="required" type="{http://www.portalfiscal.inf.br/nfe}TVerNFe" />
 *     </restriction>
 *   </complexContent>
 * </complexType>
 *

 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "TEnviNFe", namespace = "http://example.com", propOrder = { "idLote", "indSinc", "nFe" })
public class TEnviNFe {

    @XmlElement(namespace = "http://www.portalfiscal.inf.br/nfe", required = true)
    protected String idLote;

    @XmlElement(namespace = "http://www.portalfiscal.inf.br/nfe", required = true)
    protected String indSinc;

    @XmlElement(name = "NFe", namespace = "http://www.portalfiscal.inf.br/nfe", required = true)
    protected List<TNFe> nFe;

    @XmlAttribute(name = "versao", required = true)
    protected String versao;

    public String getIdLote() {
        return idLote;
    }

    /**
     * Define o valor da propriedade idLote.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     */
    public void setIdLote(String value) {
        this.idLote = value;
    }

    public String getIndSinc()

/**
     * Define o valor da propriedade indSinc.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     */
    public void setIndSinc(String value) {
        this.indSinc = value;
    }

    /**
     * Gets the value of the nFe property.
     *
     *

     * This accessor method returns a reference to the live list,
     * not a snapshot. Therefore any modification you make to the
     * returned list will be present inside the JAXB object.
     * This is why there is not a set method for the nFe property.
     *
     *

     * For example, to add a new item, do as follows:
     *

     *    getNFe().add(newItem);
     *

     *
     *

     * Objects of the following type(s) are allowed in the list
     * {@link TNFe }
     */
    public List<TNFe> getNFe() {
        if (nFe == null) {
            nFe = new ArrayList<TNFe>();
        }
        return this.nFe;
    }

    public String getVersao() {
        return versao;
    }

    /**
     * Define o valor da propriedade versao.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     */
    public void setVersao(String value) {
        this.versao = value;
    }
}


public void setIndSinc(String value) {
        this.indSinc = value;
    }

package br.com.swconsultoria.nfe.schema_4.enviNFe;

import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

/**
 *  Tipo Pedido de Concessão de Autorização da Nota Fiscal Eletrônica
 *
 *
Classe Java de TEnviNFe complex type.
 *
 *
O seguinte fragmento do esquema especifica o conteúdo esperado contido dentro desta classe.
 *
 *

 * <complexType name="TEnviNFe">
 *   <complexContent>
 *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       <sequence>
 *         <element name="idLote" type="{http://www.portalfiscal.inf.br/nfe}TIdLote"/>
 *         <element name="indSinc">
 *           <simpleType>
 *             <restriction base="{http://www.w3.org/2001/XMLSchema}string">
 *               <whiteSpace value="preserve"/>
 *               <enumeration value="0"/>
 *               <enumeration value="1"/>
 *             </restriction>
 *           </simpleType>
 *         </element>
 *         <element name="NFe" type="{http://www.portalfiscal.inf.br/nfe}TNFe" maxOccurs="50"/>
 *       </sequence>
 *       <attribute name="versao" use="required" type="{http://www.portalfiscal.inf.br/nfe}TVerNFe" />
 *     </restriction>
 *   </complexContent>
 * </complexType>
 *

 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "TEnviNFe", namespace = "http://example.com", propOrder = { "idLote", "indSinc", "nFe" })
public class TEnviNFe {

    @XmlElement(namespace = "http://www.portalfiscal.inf.br/nfe", required = true)
    protected String idLote;

    @XmlElement(namespace = "http://www.portalfiscal.inf.br/nfe", required = true)
    protected String indSinc;

    @XmlElement(name = "NFe", namespace = "http://www.portalfiscal.inf.br/nfe", required = true)
    protected List<TNFe> nFe;

    @XmlAttribute(name = "versao", required = true)
    protected String versao;

    public String getIdLote() {
        return idLote;
    }

    /**
     * Define o valor da propriedade idLote.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     */
    public void setIdLote(String value) {
        this.idLote = value;
    }

    public String getIndSinc() {
        return indSinc;
    }

    /**
     * Define o valor da propriedade indSinc.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     */

/**
     * Gets the value of the nFe property.
     *
     *

     * This accessor method returns a reference to the live list,
     * not a snapshot. Therefore any modification you make to the
     * returned list will be present inside the JAXB object.
     * This is why there is not a set method for the nFe property.
     *
     *

     * For example, to add a new item, do as follows:
     *

     *    getNFe().add(newItem);
     *

     *
     *

     * Objects of the following type(s) are allowed in the list
     * {@link TNFe }
     */
    public List<TNFe> getNFe() {
        if (nFe == null) {
            nFe = new ArrayList<TNFe>();
        }
        return this.nFe;
    }

    public String getVersao() {
        return versao;
    }

    /**
     * Define o valor da propriedade versao.
     *
     * @param value
     *     allowed object is
     *     {@link String }
     */
    public void setVersao(String value) {
        this.versao = value;
    }
}