text:
namespace g{namespace Fuse{namespace Video{struct CancellationTokenSource;}}}
namespace g{namespace Fuse{namespace Video{struct LoadResult;}}}
namespace g{namespace Fuse{namespace Video{struct VideoContainer;}}}
namespace g{namespace Uno{namespace Graphics{struct VideoTexture;}}}
namespace g{namespace Uno{namespace UX{struct FileSource;}}}
namespace g{namespace Uno{struct EventArgs;}}
namespace g{namespace Uno{struct Int2;}}

namespace g{
namespace Fuse{
namespace Video{

// internal sealed class VideoContainer :58
// {
struct VideoContainer_type : uType
{
    ::g::Fuse::Triggers::IMediaPlayback interface0;
    ::g::Fuse::Triggers::IPlayback interface1;
    ::g::Fuse::Triggers::IProgress interface2;
};

VideoContainer_type* VideoContainer_typeof();
void VideoContainer__ctor__fn(VideoContainer* __this);
void VideoContainer__get_AutoPlay_fn(VideoContainer* __this, bool* __retval);
void VideoContainer__set_AutoPlay_fn(VideoContainer* __this, bool* value);
void VideoContainer__Cancel_fn(VideoContainer* __this);
void VideoContainer__get_CanPause_fn(VideoContainer* __this, bool* __retval);
void VideoContainer__get_CanPlayTo_fn(VideoContainer* __this, bool* __retval);
void VideoContainer__get_CanResume_fn(VideoContainer* __this, bool* __retval);
void VideoContainer__get_CanStop_fn(VideoContainer* __this, bool* __retval);
void VideoContainer__add_Completed_fn(VideoContainer* __this, uDelegate* value);
void VideoContainer__remove_Completed_fn(VideoContainer* __this, uDelegate* value);
void VideoContainer__DisposePlayer_fn(VideoContainer* __this);
void VideoContainer__get_Duration_fn(VideoContainer* __this, double* __retval);
void VideoContainer__add_Error_fn(VideoContainer* __this, uDelegate* value);
void VideoContainer__remove_Error_fn(VideoContainer* __this, uDelegate* value);
void VideoContainer__set_File_fn(VideoContainer* __this, ::g::Uno::UX::FileSource* value);
void VideoContainer__get_Flip_fn(VideoContainer* __this, bool* __retval);
void VideoContainer__add_FrameAvailable_fn(VideoContainer* __this, uDelegate* value);
void VideoContainer__remove_FrameAvailable_fn(VideoContainer* __this, uDelegate* value);
void VideoContainer__get_IsLooping_fn(VideoContainer* __this, bool* __retval);
void VideoContainer__set_IsLooping_fn(VideoContainer* __this, bool* value);
void VideoContainer__get_IsPlaying_fn(VideoContainer* __this, bool* __retval);
void VideoContainer__Load_fn(VideoContainer* __this, uString* url);
void VideoContainer__Load1_fn(VideoContainer* __this, ::g::Uno::UX::FileSource* fileSource);
void VideoContainer__add_Loading_fn(VideoContainer* __this, uDelegate* value);
void VideoContainer__remove_Loading_fn(VideoContainer* __this, uDelegate* value);
void VideoContainer__New1_fn(VideoContainer** __retval);
void VideoContainer__OnCompleted_fn(VideoContainer* __this, uObject* sender, ::g::Uno::EventArgs* args);
void VideoContainer__OnError_fn(VideoContainer* __this, uObject* sender, uString* msg);
void VideoContainer__OnFrameAvailable_fn(VideoContainer* __this, uObject* sender, ::g::Uno::EventArgs* args);
void VideoContainer__OnLoadedHandler_fn(VideoContainer* __this, ::g::Fuse::Video::LoadResult* result);
void VideoContainer__OnLoading_fn(VideoContainer* __this);
void VideoContainer__OnParamChanged_fn(VideoContainer* __this);
void VideoContainer__OnPaused_fn(VideoContainer* __this);
void VideoContainer__OnPrepared_fn(VideoContainer* __this);
void VideoContainer__OnStarted_fn(VideoContainer* __this);
void VideoContainer__OnStopped_fn(VideoContainer* __this);
void VideoContainer__Pause_fn(VideoContainer* __this);
void VideoContainer__add_Paused_fn(VideoContainer* __this, uDelegate* value);
void VideoContainer__remove_Paused_fn(VideoContainer* __this, uDelegate* value);
void VideoContainer__Play_fn(VideoContainer* __this);
void VideoContainer__PlayTo_fn(VideoContainer* __this, double* progress);
void VideoContainer__get_Position_fn(VideoContainer* __this, double* __retval);
void VideoContainer__set_Position_fn(VideoContainer* __this, double* value);
void VideoContainer__add_Prepared_fn(VideoContainer* __this, uDelegate* value);
void VideoContainer__remove_Prepared_fn(VideoContainer* __this, uDelegate* value);
void VideoContainer__get_Progress_fn(VideoContainer* __this, double* __retval);
void VideoContainer__set_Progress_fn(VideoContainer* __this, double* value);
void VideoContainer__add_ProgressChanged_fn(VideoContainer* __this, uDelegate* value);
void VideoContainer__remove_ProgressChanged_fn(VideoContainer* __this, uDelegate* value);
void VideoContainer__Reset_fn(VideoContainer* __this);
void VideoContainer__Resume_fn(VideoContainer* __this);
void VideoContainer__SetPlayer_fn(VideoContainer* __this, uObject* player);
void VideoContainer__get_Size_fn(VideoContainer* __this, ::g::Uno::Int2* __retval);
void VideoContainer__add_Started_fn(VideoContainer* __this, uDelegate* value);
void VideoContainer__remove_Started_fn(VideoContainer* __this, uDelegate* value);
void VideoContainer__Stop_fn(VideoContainer* __this);
void VideoContainer__add_Stopped_fn(VideoContainer* __this, uDelegate* value);
void VideoContainer__remove_Stopped_fn(VideoContainer* __this, uDelegate* value);
void VideoContainer__Update_fn(VideoContainer* __this);
void VideoContainer__set_Url_fn(VideoContainer* __this, uString* value);
void VideoContainer__get_VideoTexture_fn(VideoContainer* __this, ::g::Uno::Graphics::VideoTexture** __retval);
void VideoContainer__get_Volume_fn(VideoContainer* __this, float* __retval);
void VideoContainer__set_Volume_fn(VideoContainer* __this, float* value);

struct VideoContainer : uObject
{
    bool _autoPlay;
    uStrong< ::g::Fuse::Video::CancellationTokenSource*> _cancellationTokenSource;
    bool _isLooping;
    uStrong<uObject*> _player;
    float _volume;
    uStrong<uDelegate*> Completed1;
    uStrong<uDelegate*> Error1;
    uStrong<uDelegate*> FrameAvailable1;
    uStrong<uDelegate*> Loading1;
    uStrong<uDelegate*> Paused1;
    uStrong<uDelegate*> Prepared1;
    uStrong<uDelegate*> ProgressChanged1;
    uStrong<uDelegate*> Started1;
    uStrong<uDelegate*> Stopped1;

    void ctor_();
    bool AutoPlay();
    void AutoPlay(bool value);
    void Cancel();
    bool CanPause();
    bool CanPlayTo();
    bool CanResume();
    bool CanStop();
    void add_Completed(uDelegate* value);
    void remove_Completed(uDelegate* value);
    void DisposePlayer();
    double Duration();
    void add_Error(uDelegate* value);
    void remove_Error(uDelegate* value);
    void File(::g::Uno::UX::FileSource* value);
    bool Flip();
    void add_FrameAvailable(uDelegate* value);
    void remove_FrameAvailable(uDelegate* value);
    bool IsLooping();
    void IsLooping(bool value);
    bool IsPlaying();
    void Load(uString* url);
    void Load1(::g::Uno::UX::FileSource* fileSource);
    void add_Loading(uDelegate* value);
    void remove_Loading(uDelegate* value);
    void OnCompleted(uObject* sender, ::g::Uno::EventArgs* args);
    void OnError(uObject* sender, uString* msg);
    void OnFrameAvailable(uObject* sender, ::g::Uno::EventArgs* args);
    void OnLoadedHandler(::g::Fuse::Video::LoadResult* result);
    void OnLoading();
    void OnParamChanged();
    void OnPaused();
    void OnPrepared();
    void OnStarted();
    void OnStopped();
    void Pause();
    void add_Paused(uDelegate* value);
    void remove_Paused(uDelegate* value);
    void Play();
    void PlayTo(double progress);
    double Position();
    void Position(double value);
    void add_Prepared(uDelegate* value);
    void remove_Prepared(uDelegate* value);
    double Progress();
    void Progress(double value);
    void add_ProgressChanged(uDelegate* value);
    void remove_ProgressChanged(uDelegate* value);
    void Reset();
    void Resume();
    void SetPlayer(uObject* player);
    ::g::Uno::Int2 Size();
    void add_Started(uDelegate* value);
    void remove_Started(uDelegate* value);
    void Stop();
    void add_Stopped(uDelegate* value);
    void remove_Stopped(uDelegate* value);
    void Update();
    void Url(uString* value);
    ::g::Uno::Graphics::VideoTexture* VideoTexture();
    float Volume();
    void Volume(float value);
    static VideoContainer* New1();
};
// }

}}} // ::g::Fuse::Video


text:
namespace halfling
{

    class Fontmap
    {
        public:
            Fontmap();
            Fontmap(SDL_Renderer* ren, std::string fname, int num_horiz, int num_vert);
            ~Fontmap();

            bool load(SDL_Renderer* ren, std::string fname, int num_horiz, int num_vert);

            const Size& get_glyph_size() const;
            SDL_Texture* get_font_texture();
            bool is_valid() const;
            Rect operator[](unsigned char ch) const;

        private:
            SDL_Texture* font;

            int num_horiz, num_vert;
            Size glyph_size;
    };

};

#endif

redpajama_set_name: RedPajamaGithub


text:
<?php

/**
 * Virtualmin Password Driver
 *
 * Driver that adds functionality to change the users Virtualmin password.
 * The code is derrived from the Squirrelmail "Change Cyrus/SASL Password" Plugin
 * by Thomas Bruederli.
 *
 * It only works with virtualmin on the same host where Roundcube runs
 * and requires shell access and gcc in order to compile the binary.
 *
 * @version 3.0
 * @author Martijn de Munnik
 */

class rcube_virtualmin_password
{
    function save($currpass, $newpass)
    {
        $rcmail   = rcmail::get_instance();
        $format   = $rcmail->config->get('password_virtualmin_format', 0);
        $username = $_SESSION['username'];

        switch ($format) {
        case 1: // username%domain
            $domain = substr(strrchr($username, "%"), 1);
            break;
        case 2: // username.domain (could be bogus)
            $pieces = explode(".", $username);
            $domain = $pieces[count($pieces)-2]. "." . end($pieces);
            break;
        case 3: // domain.username (could be bogus)
            $pieces = explode(".", $username);
            $domain = $pieces[0]. "." . $pieces[1];
            break;
        case 4: // username-domain
            $domain = substr(strrchr($username, "-"), 1);
            break;
        case 5: // domain-username
            $domain = str_replace(strrchr($username, "-"), "", $username);
            break;
        case 6: // username_domain
            $domain = substr(strrchr($username, "_"), 1);
            break;
        case 7: // domain_username
            $pieces = explode("_", $username);
            $domain = $pieces[0];
            break;
        default: // username@domain
            $domain = substr(strrchr($username, "@"), 1);
        }

        if (!$domain) {
            $domain = $rcmail->user->get_username('domain');
        }

        $username = escapeshellcmd($username);
        $domain   = escapeshellcmd($domain);
        $newpass  = escapeshellcmd($newpass);
        $curdir   = RCUBE_PLUGINS_DIR . 'password/helpers';

        exec("$curdir/chgvirtualminpasswd modify-user --domain $domain --user $username --pass $newpass", $output, $returnvalue);

        if ($returnvalue == 0) {
            return PASSWORD_SUCCESS;
        }
        else {
            rcube::raise_error(array(
                'code' => 600,
                'type' => 'php',
                'file' => __FILE__, 'line' => __LINE__,
                'message' => "Password plugin: Unable to execute $curdir/chgvirtualminpasswd"
                ), true, false);
        }

        return PASSWORD_ERROR;
    }
}


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
Beitr. Kryptfl. Schweiz 5(4): 170 (1923)

#### Original name
Peronospora lithospermi Gäum.

### Remarks
null


text:
package com.linecorp.armeria.common.stream;

import static com.linecorp.armeria.common.stream.SubscriptionOption.WITH_POOLED_OBJECTS;
import static org.assertj.core.api.Assertions.assertThat;

import javax.annotation.Nullable;

import org.junit.jupiter.api.Test;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;

import com.linecorp.armeria.common.util.EventLoopGroups;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.util.ReferenceCountUtil;

class TwoElementFixedStreamMessageTest {

    @Test
    void cancelOnFirstElement() {
        final ByteBuf obj1 = newBuffer("obj1");
        final ByteBuf obj2 = newBuffer("obj2");
        final TwoElementFixedStreamMessage<ByteBuf> streamMessage =
                new TwoElementFixedStreamMessage<>(obj1, obj2);
        streamMessage.subscribe(new CancelSubscriber(1), EventLoopGroups.directEventLoop(),
                                WITH_POOLED_OBJECTS);

        assertThat(obj1.refCnt()).isZero();
        assertThat(obj2.refCnt()).isZero();
    }

    @Test
    void cancelOnSecondElement() {
        final ByteBuf obj1 = newBuffer("obj1");
        final ByteBuf obj2 = newBuffer("obj2");
        final TwoElementFixedStreamMessage<ByteBuf> streamMessage =
                new TwoElementFixedStreamMessage<>(obj1, obj2);
        streamMessage.subscribe(new CancelSubscriber(2), EventLoopGroups.directEventLoop(),
                                WITH_POOLED_OBJECTS);

        assertThat(obj1.refCnt()).isZero();
        assertThat(obj2.refCnt()).isZero();
    }

    private static ByteBuf newBuffer(String content) {
        return ByteBufAllocator.DEFAULT.buffer().writeBytes(content.getBytes());
    }

    private static class CancelSubscriber implements Subscriber<ByteBuf> {
        private final int cancelCallingSequence;
        private int currentSequence = 1;

        @Nullable
        private Subscription subscription;

        CancelSubscriber(int cancelCallingSequence) {
            this.cancelCallingSequence = cancelCallingSequence;
        }

        @Override
        public void onSubscribe(Subscription s) {
            subscription = s;
            s.request(Long.MAX_VALUE);
        }

        @Override
        public void onNext(ByteBuf byteBuf) {
            ReferenceCountUtil.safeRelease(byteBuf);
            if (currentSequence++ == cancelCallingSequence) {
                subscription.cancel();
            }
        }

        @Override
        public void onError(Throwable t) {}

        @Override
        public void onComplete() {}
    }
}


text:
namespace blink {

class FontVariantLigaturesParser {
  STACK_ALLOCATED();

 public:
  FontVariantLigaturesParser()
      : saw_common_ligatures_value_(false),
        saw_discretionary_ligatures_value_(false),
        saw_historical_ligatures_value_(false),
        saw_contextual_ligatures_value_(false),
        result_(CSSValueList::CreateSpaceSeparated()) {}

  enum class ParseResult { kConsumedValue, kDisallowedValue, kUnknownValue };

  ParseResult ConsumeLigature(CSSParserTokenRange& range) {
    CSSValueID value_id = range.Peek().Id();
    switch (value_id) {
      case CSSValueID::kNoCommonLigatures:
      case CSSValueID::kCommonLigatures:
        if (saw_common_ligatures_value_)
          return ParseResult::kDisallowedValue;
        saw_common_ligatures_value_ = true;
        break;
      case CSSValueID::kNoDiscretionaryLigatures:
      case CSSValueID::kDiscretionaryLigatures:
        if (saw_discretionary_ligatures_value_)
          return ParseResult::kDisallowedValue;
        saw_discretionary_ligatures_value_ = true;
        break;
      case CSSValueID::kNoHistoricalLigatures:
      case CSSValueID::kHistoricalLigatures:
        if (saw_historical_ligatures_value_)
          return ParseResult::kDisallowedValue;
        saw_historical_ligatures_value_ = true;
        break;
      case CSSValueID::kNoContextual:
      case CSSValueID::kContextual:
        if (saw_contextual_ligatures_value_)
          return ParseResult::kDisallowedValue;
        saw_contextual_ligatures_value_ = true;
        break;
      default:
        return ParseResult::kUnknownValue;
    }
    result_->Append(*css_parsing_utils::ConsumeIdent(range));
    return ParseResult::kConsumedValue;
  }

  CSSValue* FinalizeValue() {
    if (!result_->length())
      return CSSIdentifierValue::Create(CSSValueID::kNormal);
    CSSValue* result = result_;
    result_ = nullptr;
    return result;
  }

 private:
  bool saw_common_ligatures_value_;
  bool saw_discretionary_ligatures_value_;
  bool saw_historical_ligatures_value_;
  bool saw_contextual_ligatures_value_;
  CSSValueList* result_;
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_PARSER_FONT_VARIANT_LIGATURES_PARSER_H_


text:
<?php

namespace Evozon\TranslatrBundle\Command;

use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

/**
 * Class ExtractTranslationsCommand
 *
 * @package     Evozon\TranslatrBundle\Command
 * @author      Ovidiu Enache <i.ovidiuenache@yahoo.com>
 */
class ExtractTranslationsCommand extends AbstractCommand
{
    /**
     * Configure command
     */
    protected function configure()
    {
        $this
            ->setName('evozon:translatr:extract')
            ->setDescription('Extract translations from the application')
            ->addArgument(
                'languages',
                InputArgument::OPTIONAL,
                'Languages to be extracted'
            );
    }

    /**
     * @param InputInterface  $input
     * @param OutputInterface $output
     *
     * @return void
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $io = new SymfonyStyle($input, $output);
        $errorsFound = false;

        $io->success('Extracting translations from the application!');

        $availableLocales = $this->getContainer()->getParameter('available_locales');
        $availableLocales = array_map(
            function ($locale) {
                return strtolower(substr($locale, 0, 2));
            },
            $availableLocales
        );

        $inputLanguages = explode(',', $input->getArgument('languages'));
        $filteredInput = array();

        if (empty($inputLanguages[0])) {
            $filteredInput = $availableLocales;
            $io->warning('No language found! Will extract all available languages!');
        } else {
            foreach ($inputLanguages as $language) {
                if (in_array($language, $availableLocales)) {
                    $filteredInput[] = $language;
                } else {
                    $io->error("Language $language is not available!");
                    $errorsFound = true;
                }
            }
        }

        $commandName = 'translation:update';
        $command = $this->getApplication()->find($commandName);

        foreach ($filteredInput as $locale) {
            $command->run(
                new ArrayInput([
                    'command' => $commandName,
                    'locale' => $locale,
                    '--force' => true,
                    '--output-format' => 'po']),
                $output
            );
        }

        if (!$errorsFound) {
            $io->success('Translations successfully extracted');
        } else {
            $io->warning('Some errors have occured!');
        }
    }
}


text:
/*
Sort: 1
*/

If your app's build and test requires a piece of software that is not pre-installed on our builders, there is an easy way for you to get it installed.

When you are configuring a Job, set the up the first Build Step as a Shell Script. From here you can write a Bash script where you can customize the build environment. This is how you can install any required software.

Our builder machines are running OSX, and you have Administrator privileges, so you can use [Homebrew](http://brew.sh/) to install many packages. If Homebrew does not offer it, you can put the install steps in a Shell Script and it will be available by the time your build and test phases start.


text:
package org.kuali.kpme.tklm.leave.accrual.service;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.joda.time.DateTime;
import org.joda.time.DateTimeConstants;
import org.joda.time.Interval;
import org.joda.time.LocalDate;
import org.kuali.kpme.core.api.accrualcategory.AccrualCategory;
import org.kuali.kpme.core.api.accrualcategory.AccrualCategoryContract;
import org.kuali.kpme.core.api.accrualcategory.AccrualEarnInterval;
import org.kuali.kpme.core.api.accrualcategory.rule.AccrualCategoryRule;
import org.kuali.kpme.core.api.accrualcategory.rule.AccrualCategoryRuleContract;
import org.kuali.kpme.core.api.assignment.Assignment;
import org.kuali.kpme.core.api.calendar.Calendar;
import org.kuali.kpme.core.api.calendar.entry.CalendarEntry;
import org.kuali.kpme.core.api.earncode.EarnCodeContract;
import org.kuali.kpme.core.api.job.Job;
import org.kuali.kpme.core.api.job.JobContract;
import org.kuali.kpme.core.api.leaveplan.LeavePlan;
import org.kuali.kpme.core.api.leaveplan.LeavePlanContract;
import org.kuali.kpme.core.api.principal.PrincipalHRAttributes;
import org.kuali.kpme.core.service.HrServiceLocator;
import org.kuali.kpme.core.util.HrConstants;
import org.kuali.kpme.core.util.HrContext;
import org.kuali.kpme.core.util.TKUtils;
import org.kuali.kpme.tklm.api.leave.accrual.AccrualService;
import org.kuali.kpme.tklm.api.leave.accrual.PrincipalAccrualRanContract;
import org.kuali.kpme.tklm.api.leave.accrual.RateRangeContract;
import org.kuali.kpme.tklm.api.leave.block.LeaveBlock;
import org.kuali.kpme.tklm.api.leave.timeoff.SystemScheduledTimeOffContract;
import org.kuali.kpme.tklm.common.LMConstants;
import org.kuali.kpme.tklm.leave.accrual.RateRange;
import org.kuali.kpme.tklm.leave.accrual.RateRangeAggregate;
import org.kuali.kpme.tklm.leave.block.LeaveBlockBo;
import org.kuali.kpme.tklm.leave.service.LmServiceLocator;
import org.kuali.kpme.tklm.leave.workflow.LeaveCalendarDocumentHeader;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class AccrualServiceImpl implements AccrualService {
    private static final Logger LOG = Logger.getLogger(AccrualServiceImpl.class);

	@Override
	public void runAccrual(String principalId) {
		DateTime startDate = getStartAccrualDate(principalId);
		DateTime endDate = getEndAccrualDate(principalId);

		LOG.info("AccrualServiceImpl.runAccrual() STARTED with Principal: "+principalId);
		runAccrual(principalId,startDate,endDate, true);

	}

	@Override
	public void runAccrual(String principalId, DateTime startDate, DateTime endDate, boolean recordRanData) {
		runAccrual(principalId, startDate, endDate, recordRanData, HrContext.getPrincipalId());
	}

	@SuppressWarnings("unchecked")
	@Override
	public void runAccrual(String principalId, DateTime startDate, DateTime endDate, boolean recordRanData, String runAsPrincipalId) {
		List<LeaveBlock> accrualLeaveBlocks = new ArrayList<LeaveBlock>();
		Map<String, BigDecimal> accumulatedAccrualCatToAccrualAmounts = new HashMap<String,BigDecimal>();
		Map<String, BigDecimal> accumulatedAccrualCatToNegativeAccrualAmounts = new HashMap<String,BigDecimal>();

		if (startDate != null && endDate != null) {
            LOG.info("AccrualServiceImpl.runAccrual() STARTED with Principal: "+principalId+" Start: "+startDate.toString()+" End: "+endDate.toString());
		}
		if(startDate.isAfter(endDate)) {
			LOG.error("Start Date " + startDate.toString() + " should not be later than End Date " + endDate.toString());
			return;
//			throw new RuntimeException("Start Date " + startDate.toString() + " should not be later than End Date " + endDate.toString());
		}
		//Inactivate all previous accrual-generated entries for this span of time
		deactivateOldAccruals(principalId, startDate, endDate, runAsPrincipalId);

		//Build a rate range aggregate with appropriate information for this period of time detailing Rate Ranges for job
		//entries for this range of time
		RateRangeAggregate rrAggregate = this.buildRateRangeAggregate(principalId, startDate, endDate);
		PrincipalHRAttributes phra = null;
		PrincipalHRAttributes endPhra = null;
		LeavePlanContract lp = null;
		List<? extends AccrualCategoryContract> accrCatList = null;

		//Iterate over every day in span
		DateTime currentDate = startDate;
		while (!currentDate.isAfter(endDate)) {
			RateRange currentRange = rrAggregate.getRateOnDate(currentDate);
			if(currentRange == null) {
				currentDate = currentDate.plusDays(1);
				continue;
			}

			phra = currentRange.getPrincipalHRAttributes();
			if(phra == null || currentDate.toLocalDate().isBefore(phra.getServiceLocalDate())) {
				currentDate = currentDate.plusDays(1);
				continue;
			}

	// use the effectiveDate of this principalHRAttribute to search for inactive entries for this principalId
	// If there's an inactive entry, it means the job is going to end on the effectiveDate of the inactive entry
	// used for minimumPercentage and proration
			endPhra = currentRange.getEndPrincipalHRAttributes();
			if(endPhra != null && currentDate.toLocalDate().isAfter(endPhra.getEffectiveLocalDate())) {
				currentDate = currentDate.plusDays(1);
				continue;
			}

	// if the date range is before the service date of this employee, do not calculate accrual
			if(endDate.toLocalDate().isBefore(phra.getServiceLocalDate())) {
				return;
			}
			lp = currentRange.getLeavePlan();
			accrCatList = currentRange.getAcList();
			// if the employee status is changed, create an empty leave block on the currentDate
			if(currentRange.isStatusChanged()) {
				this.createEmptyLeaveBlockForStatusChange(principalId, accrualLeaveBlocks, currentDate.toLocalDate());
			}
			// if no job found for the employee on the currentDate, do nothing
			if(CollectionUtils.isEmpty(currentRange.getJobs())) {
				currentDate = currentDate.plusDays(1);
				continue;
			}

			BigDecimal ftePercentage = currentRange.getAccrualRatePercentageModifier();
			BigDecimal totalOfStandardHours = currentRange.getStandardHours();
			boolean fullFteGranted = false;
			for(AccrualCategoryContract anAC : accrCatList) {
				if(anAC == null)
					continue;

				fullFteGranted = false;
				if(!currentDate.toLocalDate().isBefore(phra.getEffectiveLocalDate()) && !anAC.getAccrualEarnInterval().equals("N")) {   	// "N" means no accrual
					boolean prorationFlag = this.isProrationFlag(anAC.getProration());
					// get the accrual rule
					AccrualCategoryRuleContract currentAcRule = this.getRuleForAccrualCategory(currentRange.getAcRuleList(), anAC);

					// check if accrual category rule changed
					if(currentAcRule != null) {
						DateTime ruleStartDate = getRuleStartDate(currentAcRule.getServiceUnitOfTime(), phra.getServiceLocalDate(), currentAcRule.getStart());
						DateTime previousIntervalDay = this.getPrevIntervalDate(ruleStartDate, anAC.getAccrualEarnInterval(), phra.getPayCalendar(), rrAggregate.getCalEntryMap());
						DateTime nextIntervalDay = this.getNextIntervalDate(ruleStartDate, anAC.getAccrualEarnInterval(), phra.getPayCalendar(), rrAggregate.getCalEntryMap());

						RateRangeContract previousRange = rrAggregate.getRateOnDate(previousIntervalDay);
						AccrualCategoryRuleContract previousAcRule = null;
						if(previousRange != null) {
							previousAcRule = this.getRuleForAccrualCategory(previousRange.getAcRuleList(), anAC);
						}
						// rule changed
						if(previousAcRule != null && !previousAcRule.getLmAccrualCategoryRuleId().equals(currentAcRule.getLmAccrualCategoryRuleId())) {
							if(currentDate.toLocalDate().compareTo(previousIntervalDay.toLocalDate()) >= 0
									&& currentDate.toLocalDate().compareTo(nextIntervalDay.toLocalDate()) <= 0) {
								int workDaysInBetween = TKUtils.getWorkDays(ruleStartDate, nextIntervalDay);
								boolean minReachedFlag = minimumPercentageReachedForPayPeriod(anAC.getMinPercentWorked(),
												anAC.getAccrualEarnInterval(), workDaysInBetween, nextIntervalDay,
												phra.getPayCalendar(), rrAggregate.getCalEntryMap());
								if(prorationFlag) {
									if(minReachedFlag) {
										// min reached, proration=true, rule changed, then use actual work days of currentRule for calculation
										// so nothing special needs to be done here
									} else {
										//minimum percentage NOT reached, proration = true, rule changed, then use previousRule for the whole pay period
										currentAcRule = previousAcRule;
									}
								} else {
									if(minReachedFlag) {
										// min reached, proration = false, rule changed, then accrual the whole fte of the new rule for this pay interval
										accumulatedAccrualCatToAccrualAmounts.put(anAC.getLmAccrualCategoryId(), currentAcRule.getAccrualRate());
										fullFteGranted = true;
									} else {
										//min NOT reached, proration = false, rule changed, then accrual the whole fte of the previous rule for this pay interval
										accumulatedAccrualCatToAccrualAmounts.put(anAC.getLmAccrualCategoryId(), previousAcRule.getAccrualRate());
										fullFteGranted = true;
									}
								}
							}
						}
					}

					// check for first pay period of principal attributes considering minimum percentage and proration
					DateTime firstIntervalDate = this.getNextIntervalDate(phra.getEffectiveLocalDate().toDateTimeAtStartOfDay(), anAC.getAccrualEarnInterval(), phra.getPayCalendar(), rrAggregate.getCalEntryMap());
					if(!currentDate.toLocalDate().isBefore(phra.getEffectiveLocalDate())
							&& !currentDate.toLocalDate().isAfter(firstIntervalDate.toLocalDate())) {
						int workDaysInBetween = TKUtils.getWorkDays(phra.getEffectiveLocalDate().toDateTimeAtStartOfDay(), firstIntervalDate);
						boolean minReachedFlag = minimumPercentageReachedForPayPeriod(anAC.getMinPercentWorked(),  anAC.getAccrualEarnInterval(),
									workDaysInBetween, firstIntervalDate,
									phra.getPayCalendar(), rrAggregate.getCalEntryMap());

						if(prorationFlag) {
							if(minReachedFlag) {
								// minimum reached, proration = true, first pay period, then use actual work days of currentRule for calculation
								// so nothing special needs to be done here
							} else {
								// min NOT reached, proration = true, first pay period, then no accrual for this pay period
								accumulatedAccrualCatToAccrualAmounts.remove(anAC.getLmAccrualCategoryId());
								accumulatedAccrualCatToNegativeAccrualAmounts.remove(anAC.getLmAccrualCategoryId());
								continue;
							}
						} else {
							if(minReachedFlag && currentAcRule != null) {
								//  minimum reached, proration = false, first pay period, then accrual the whole fte of current AC rule for this pay interval
								accumulatedAccrualCatToAccrualAmounts.put(anAC.getLmAccrualCategoryId(), currentAcRule.getAccrualRate());
								fullFteGranted = true;
							} else {
								// min NOT reached, proration = false, first pay period, then no accrual for this pay period
								accumulatedAccrualCatToAccrualAmounts.remove(anAC.getLmAccrualCategoryId());
								accumulatedAccrualCatToNegativeAccrualAmounts.remove(anAC.getLmAccrualCategoryId());
								continue;
							}
						}
					}
					// last accrual interval
					if(endPhra != null) {	// the employment is going to end on the effectiveDate of enPhra
						DateTime previousIntervalDate = this.getPrevIntervalDate(endPhra.getEffectiveLocalDate().toDateTimeAtStartOfDay(), anAC.getAccrualEarnInterval(), phra.getPayCalendar(), rrAggregate.getCalEntryMap());
						// currentDate is between the end date and the last interval date, so we are in the last interval
						if(!currentDate.toLocalDate().isAfter(endPhra.getEffectiveLocalDate())
								&& currentDate.toLocalDate().isAfter(previousIntervalDate.toLocalDate())) {
							DateTime lastIntervalDate = this.getNextIntervalDate(endPhra.getEffectiveLocalDate().toDateTimeAtStartOfDay(), anAC.getAccrualEarnInterval(),  phra.getPayCalendar(), rrAggregate.getCalEntryMap());
							int workDaysInBetween = TKUtils.getWorkDays(previousIntervalDate, endPhra.getEffectiveLocalDate().toDateTimeAtStartOfDay());
							boolean minReachedFlag = minimumPercentageReachedForPayPeriod(anAC.getMinPercentWorked(),  anAC.getAccrualEarnInterval(),
										workDaysInBetween, lastIntervalDate,
										phra.getPayCalendar(), rrAggregate.getCalEntryMap());
							if(prorationFlag) {
								if(minReachedFlag) {
									// minimum reached, proration = true, first pay period, then use actual work days of currentRule for calculation
									// so nothing special needs to be done here
								} else {
									// min NOT reached, proration = true, first pay period, then no accrual for this pay period
									accumulatedAccrualCatToAccrualAmounts.remove(anAC.getLmAccrualCategoryId());
									accumulatedAccrualCatToNegativeAccrualAmounts.remove(anAC.getLmAccrualCategoryId());
									continue;
								}
							} else {
								if(minReachedFlag) {
									//  minimum reached, proration = false, first pay period, then accrual the whole fte of current AC rule for this pay interval
									accumulatedAccrualCatToAccrualAmounts.put(anAC.getLmAccrualCategoryId(), currentAcRule.getAccrualRate());
									fullFteGranted = true;
								} else {
									// min NOT reached, proration = false, first pay period, then no accrual for this pay period
									accumulatedAccrualCatToAccrualAmounts.remove(anAC.getLmAccrualCategoryId());
									accumulatedAccrualCatToNegativeAccrualAmounts.remove(anAC.getLmAccrualCategoryId());
									continue;
								}
							}
						}
					}

					if(currentAcRule == null) {
						accumulatedAccrualCatToAccrualAmounts.remove(anAC.getLmAccrualCategoryId());
						accumulatedAccrualCatToNegativeAccrualAmounts.remove(anAC.getLmAccrualCategoryId());
						continue;
					}

					//Fetch the accrual rate based on rate range for today(Rate range is the accumulated list of jobs and accrual rate for today)
					BigDecimal accrualRate = currentAcRule.getAccrualRate();
					int numberOfWorkDays = this.getWorkDaysInInterval(currentDate, anAC.getAccrualEarnInterval(), phra.getPayCalendar(), rrAggregate.getCalEntryMap());
					BigDecimal dayRate = numberOfWorkDays > 0 ? accrualRate.divide(new BigDecimal(numberOfWorkDays), 6, BigDecimal.ROUND_HALF_UP) : new BigDecimal(0);

					//get not eligible for accrual hours based on leave block on this day
					BigDecimal noAccrualHours = getNotEligibleForAccrualHours(principalId, currentDate.toLocalDate());
					if(noAccrualHours != null && noAccrualHours.compareTo(BigDecimal.ZERO) != 0 && totalOfStandardHours.compareTo(BigDecimal.ZERO) != 0) {
						BigDecimal dayHours = totalOfStandardHours.divide(new BigDecimal(5), 6, BigDecimal.ROUND_HALF_UP);
						// if leave hours on the day is more than the standard hours, use the standard hour to calculate the adjustment
						if(noAccrualHours.abs().compareTo(dayHours.abs()) == 1) {
							noAccrualHours = dayHours.abs().negate();
						}
						BigDecimal noAccrualRate = dayRate.multiply(noAccrualHours.divide(dayHours));
						this.calculateHours(anAC.getLmAccrualCategoryId(), ftePercentage, noAccrualRate, accumulatedAccrualCatToNegativeAccrualAmounts);
					}

					// only accrual on work days
					if(!TKUtils.isWeekend(currentDate) && !fullFteGranted) {
						//Add to total accumulatedAccrualCatToAccrualAmounts
						//use rule and ftePercentage to calculate the hours
						this.calculateHours(anAC.getLmAccrualCategoryId(), ftePercentage, dayRate, accumulatedAccrualCatToAccrualAmounts);
					}
					//Determine if we are at the accrual earn interval in the span, if so add leave block for accumulated accrual amount to list
					//and reset accumulatedAccrualCatToAccrualAmounts and accumulatedAccrualCatToNegativeAccrualAmounts for this accrual category
					if(this.isDateAnIntervalDate(currentDate.toLocalDate(), anAC.getAccrualEarnInterval(), phra.getPayCalendar(), rrAggregate.getCalEntryMap())) {
						BigDecimal acHours = accumulatedAccrualCatToAccrualAmounts.get(anAC.getLmAccrualCategoryId());

						if(acHours != null) {
							createLeaveBlock(principalId, accrualLeaveBlocks, currentDate.toLocalDate(), acHours, anAC, null, true, currentRange.getLeaveCalendarDocumentId(), null);
							accumulatedAccrualCatToAccrualAmounts.remove(anAC.getLmAccrualCategoryId());	// reset accumulatedAccrualCatToAccrualAmounts
							fullFteGranted = false;
						}

						BigDecimal adjustmentHours = accumulatedAccrualCatToNegativeAccrualAmounts.get(anAC.getLmAccrualCategoryId());
						if(adjustmentHours != null && adjustmentHours.compareTo(BigDecimal.ZERO) != 0) {
							// do not create leave block if the ajustment amount is 0
							createLeaveBlock(principalId, accrualLeaveBlocks, currentDate.toLocalDate(), adjustmentHours, anAC, null, false, currentRange.getLeaveCalendarDocumentId(), null);
							accumulatedAccrualCatToNegativeAccrualAmounts.remove(anAC.getLmAccrualCategoryId());	// reset accumulatedAccrualCatToNegativeAccrualAmounts
						}
					}
				}
			}
			//Determine if today is a system scheduled time off and accrue holiday if so.
			SystemScheduledTimeOffContract ssto = currentRange.getSysScheTimeOff();
			if(ssto != null) {
				AccrualCategory anAC = HrServiceLocator.getAccrualCategoryService().getAccrualCategory(ssto.getAccrualCategory(), ssto.getEffectiveLocalDate());
				if(anAC == null) {
					LOG.error("Cannot find Accrual Category for system scheduled time off " + ssto.getLmSystemScheduledTimeOffId());
					return;
//					throw new RuntimeException("Cannot find Accrual Category for system scheduled time off " + ssto.getLmSystemScheduledTimeOffId());
				}
				BigDecimal hrs = ssto.getAmountofTime().multiply(ftePercentage);
				// system scheduled time off leave block
				createLeaveBlock(principalId, accrualLeaveBlocks, currentDate.toLocalDate(), hrs, anAC, ssto.getLmSystemScheduledTimeOffId(), true, currentRange.getLeaveCalendarDocumentId(), null);
				// we only need to create usage leave block for ssto if there is a scheduled time off date
				if(ssto.getScheduledTimeOffDate() != null) {
					// usage leave block with negative amount. Assign primary leave assignment information to ssto usage leave block
					createLeaveBlock(principalId, accrualLeaveBlocks, ssto.getScheduledTimeOffLocalDate(),
								hrs.negate(), anAC, ssto.getLmSystemScheduledTimeOffId(), true, currentRange.getLeaveCalendarDocumentId(), currentRange.getPrimaryLeaveAssignmentId());
				}
			}
			// if today is the last day of the employment, create leave blocks if there's any hours available
			if(endPhra != null && currentDate.toLocalDate().equals(endPhra.getEffectiveLocalDate())){
				// accumulated accrual amount
				if(!accumulatedAccrualCatToAccrualAmounts.isEmpty()) {
					for(Map.Entry<String, BigDecimal> entry : accumulatedAccrualCatToAccrualAmounts.entrySet()) {
						if(entry.getValue() != null && entry.getValue().compareTo(BigDecimal.ZERO) != 0) {
							AccrualCategory anAC = HrServiceLocator.getAccrualCategoryService().getAccrualCategory(entry.getKey());
							createLeaveBlock(principalId, accrualLeaveBlocks, currentDate.toLocalDate(), entry.getValue(), anAC, null, true, currentRange.getLeaveCalendarDocumentId(), null);
						}
					}
					accumulatedAccrualCatToAccrualAmounts = new HashMap<String,BigDecimal>();	// reset accumulatedAccrualCatToAccrualAmounts
				}
				// negative/adjustment accrual amount
				if(!accumulatedAccrualCatToNegativeAccrualAmounts.isEmpty()) {
					for(Map.Entry<String, BigDecimal> entry : accumulatedAccrualCatToNegativeAccrualAmounts.entrySet()) {
						if(entry.getValue() != null && entry.getValue().compareTo(BigDecimal.ZERO) != 0) {
							AccrualCategory anAC = HrServiceLocator.getAccrualCategoryService().getAccrualCategory(entry.getKey());
							createLeaveBlock(principalId, accrualLeaveBlocks, currentDate.toLocalDate(), entry.getValue(), anAC, null, true, currentRange.getLeaveCalendarDocumentId(), null);
						}
					}
					accumulatedAccrualCatToNegativeAccrualAmounts = new HashMap<String,BigDecimal>();	// reset accumulatedAccrualCatToNegativeAccrualAmounts
				}
				phra = null;	// reset principal attribute so new value will be retrieved
				endPhra = null;	// reset end principal attribute so new value will be retrieved
			}

			currentDate = currentDate.plusDays(1);
		}

		//Save accrual leave blocks at the very end
		LmServiceLocator.getLeaveBlockService().saveLeaveBlocks(accrualLeaveBlocks);

		// record timestamp of this accrual run in database
		if(recordRanData) {
			LmServiceLocator.getPrincipalAccrualRanService().updatePrincipalAccrualRanInfo(principalId);
		}

	}

	private void deactivateOldAccruals(String principalId, DateTime startDate, DateTime endDate, String runAsPrincipalId) {
		List<LeaveBlock> previousLB = LmServiceLocator.getLeaveBlockService().getAccrualGeneratedLeaveBlocks(principalId, startDate.toLocalDate(), endDate.toLocalDate());
		List<LeaveBlock> sstoAccrualList = new ArrayList<LeaveBlock>();
		List<LeaveBlock> sstoUsageList = new ArrayList<LeaveBlock>();

		for(LeaveBlock lb : previousLB) {
			if(StringUtils.isNotEmpty(lb.getScheduleTimeOffId())) {
				if(lb.getLeaveAmount().compareTo(BigDecimal.ZERO) > 0) {
					sstoAccrualList.add(lb);
				} else if(lb.getLeaveAmount().compareTo(BigDecimal.ZERO) < 0) {
					sstoUsageList.add(lb);
				}
			} else {
				if(!(StringUtils.equals(lb.getLeaveBlockType(),LMConstants.LEAVE_BLOCK_TYPE.BALANCE_TRANSFER) ||
								StringUtils.equals(lb.getLeaveBlockType(),LMConstants.LEAVE_BLOCK_TYPE.LEAVE_PAYOUT))) {
					LmServiceLocator.getLeaveBlockService().deleteLeaveBlock(lb.getLmLeaveBlockId(), runAsPrincipalId);
                }
			}
		}

		for(LeaveBlock accrualLb : sstoAccrualList) {
			for(LeaveBlock usageLb : sstoUsageList) {
				// both usage and accrual ssto leave blocks are there, so the ssto accural is not banked, removed both leave blocks
				// if this is no ssto usage leave block, it means the user has banked this ssto hours. Don't delete this ssto accrual leave block
				if(accrualLb.getScheduleTimeOffId().equals(usageLb.getScheduleTimeOffId())) {
					LmServiceLocator.getLeaveBlockService().deleteLeaveBlock(accrualLb.getLmLeaveBlockId(), runAsPrincipalId);
					LmServiceLocator.getLeaveBlockService().deleteLeaveBlock(usageLb.getLmLeaveBlockId(), runAsPrincipalId);
				}
			}
		}

	}

	private BigDecimal getNotEligibleForAccrualHours(String principalId, LocalDate currentDate) {
		BigDecimal hours = BigDecimal.ZERO;
		// check if there's any manual not-eligible-for-accrual leave blocks, use the hours of the leave block to adjust accrual calculation
		List<LeaveBlock> lbs = LmServiceLocator.getLeaveBlockService().getNotAccrualGeneratedLeaveBlocksForDate(principalId, currentDate);
		for(LeaveBlock lb : lbs) {
			EarnCodeContract ec = HrServiceLocator.getEarnCodeService().getEarnCode(lb.getEarnCode(), currentDate);
			if(ec == null) {
				LOG.error("Cannot find Earn Code for Leave block " + lb.getLmLeaveBlockId());
				return null;
//				throw new RuntimeException("Cannot find Earn Code for Leave block " + lb.getLmLeaveBlockId());
			}
			if(ec.getEligibleForAccrual().equals("N")
					&& ec.getAccrualBalanceAction().equals(HrConstants.ACCRUAL_BALANCE_ACTION.USAGE)
					&& lb.getLeaveAmount().compareTo(BigDecimal.ZERO) != 0) {
				hours = hours.add(lb.getLeaveAmount());
			}
		}
		return hours;
	}

	private void createLeaveBlock(String principalId, List<LeaveBlock> accrualLeaveBlocks,
			LocalDate leaveDate, BigDecimal hrs, AccrualCategoryContract anAC, String sysSchTimeOffId,
			boolean createZeroLeaveBlock, String leaveDocId, String primaryAssignmentId) {
		// Replacing Leave Code to earn code - KPME 1634
		EarnCodeContract ec = HrServiceLocator.getEarnCodeService().getEarnCode(anAC.getEarnCode(), anAC.getEffectiveLocalDate());
		if(ec == null) {
//			throw new RuntimeException("Cannot find Earn Code for Accrual category " + anAC.getAccrualCategory());
			LOG.error("Cannot find Earn Code for Accrual category " + anAC.getAccrualCategory());
			return;
		}
		// use rounding option and fract time allowed of Leave Code to round the leave block hours
		BigDecimal roundedHours = HrServiceLocator.getEarnCodeService().roundHrsWithEarnCode(hrs, ec);
		if(!createZeroLeaveBlock && roundedHours.compareTo(BigDecimal.ZERO) == 0) {
			return;	// do not create leave block with zero amount
		}
		LeaveBlockBo aLeaveBlock = new LeaveBlockBo();
		aLeaveBlock.setAccrualCategory(anAC.getAccrualCategory());
		aLeaveBlock.setLeaveLocalDate(leaveDate);
		aLeaveBlock.setPrincipalId(principalId);
		//More than one earn code can be associated with an accrual category. Which one does this get?
		aLeaveBlock.setEarnCode(anAC.getEarnCode());
		aLeaveBlock.setAccrualGenerated(true);
		aLeaveBlock.setBlockId(0L);
		aLeaveBlock.setScheduleTimeOffId(sysSchTimeOffId);
		aLeaveBlock.setLeaveAmount(roundedHours);
		aLeaveBlock.setLeaveBlockType(LMConstants.LEAVE_BLOCK_TYPE.ACCRUAL_SERVICE);
		aLeaveBlock.setRequestStatus(HrConstants.REQUEST_STATUS.APPROVED);
		aLeaveBlock.setDocumentId(leaveDocId);

		if(StringUtils.isNotBlank(primaryAssignmentId)) {
            Assignment primAssignment = HrServiceLocator.getAssignmentService().getAssignment(primaryAssignmentId);
			if(primAssignment != null) {
                aLeaveBlock.setGroupKeyCode(primAssignment.getGroupKeyCode());
				aLeaveBlock.setWorkArea(primAssignment.getWorkArea());
				aLeaveBlock.setJobNumber(primAssignment.getJobNumber());
		        aLeaveBlock.setTask(primAssignment.getTask());
			}
		}

		accrualLeaveBlocks.add(LeaveBlockBo.to(aLeaveBlock));

	}

	private void createEmptyLeaveBlockForStatusChange(String principalId, List<LeaveBlock> accrualLeaveBlocks, LocalDate leaveDate) {
		LeaveBlockBo aLeaveBlock = new LeaveBlockBo();
		aLeaveBlock.setAccrualCategory(null);
		aLeaveBlock.setLeaveLocalDate(leaveDate);
		aLeaveBlock.setPrincipalId(principalId);
		aLeaveBlock.setEarnCode(LMConstants.STATUS_CHANGE_EARN_CODE);	// fake leave code
		aLeaveBlock.setAccrualGenerated(true);
		aLeaveBlock.setBlockId(0L);
		aLeaveBlock.setScheduleTimeOffId(null);
		aLeaveBlock.setLeaveAmount(BigDecimal.ZERO);
		aLeaveBlock.setLeaveBlockType(LMConstants.LEAVE_BLOCK_TYPE.ACCRUAL_SERVICE);
		aLeaveBlock.setRequestStatus(HrConstants.REQUEST_STATUS.APPROVED);

		accrualLeaveBlocks.add(LeaveBlockBo.to(aLeaveBlock));

	}

	private void calculateHours(String accrualCategoryId, BigDecimal fte, BigDecimal rate, Map<String, BigDecimal> accumulatedAmounts ) {
		BigDecimal hours = rate.multiply(fte);
		BigDecimal oldHours = accumulatedAmounts.get(accrualCategoryId);
		BigDecimal newHours = oldHours == null ? hours : hours.add(oldHours);
		accumulatedAmounts.put(accrualCategoryId, newHours);
	}

	public DateTime getStartAccrualDate(String principalId){
		return null;
	}

	public DateTime getEndAccrualDate(String principalId){
		return null;
	}

	@Override
	public void runAccrual(List<String> principalIds) {
		for(String principalId : principalIds){
			runAccrual(principalId);
		}
	}

	private boolean isDateAnIntervalDate(LocalDate aDate, String earnInterval, String payCalName,  Map<String, List<CalendarEntry>> aMap) {
		if(earnInterval.equals(AccrualEarnInterval.PAY_CAL.getCode())) {
			return isDateAtPayCalInterval(aDate, earnInterval, payCalName, aMap);
		} else {
			return this.isDateAtEarnInterval(aDate, earnInterval);
		}
	}

	private boolean isDateAtPayCalInterval(LocalDate aDate, String earnInterval, String payCalName,  Map<String, List<CalendarEntry>> aMap) {
		if(StringUtils.isNotEmpty(payCalName)
				&& !aMap.isEmpty()
				&& earnInterval.equals(AccrualEarnInterval.PAY_CAL.getCode())) {	// only used for ac earn interval == pay calendar
			List<CalendarEntry> entryList = aMap.get(payCalName);
			if(CollectionUtils.isNotEmpty(entryList)) {
				for(CalendarEntry anEntry : entryList) {
					// endPeriodDate of calendar entry is the beginning hour of the next day, so we need to substract one day from it to get the real end date
					LocalDate endDate = anEntry.getEndPeriodFullDateTime().toLocalDate().minusDays(1);
					if(aDate.compareTo(endDate) == 0) {
						return true;
					}
				}
			}
		}
		return false;
	}

	@Override
	public boolean isDateAtEarnInterval(LocalDate aDate, String earnInterval) {
		boolean atEarnInterval = false;
        AccrualEarnInterval accrualEarnInterval = AccrualEarnInterval.fromCode(earnInterval);
		if (accrualEarnInterval != null) {
			if (AccrualEarnInterval.DAILY.equals(accrualEarnInterval)) {
				atEarnInterval = true;
			} else if(AccrualEarnInterval.WEEKLY.equals(accrualEarnInterval)) {
				// figure out if the day is a Saturday
				if (aDate.getDayOfWeek() == DateTimeConstants.SATURDAY) {
					atEarnInterval = true;
				}
			} else if (AccrualEarnInterval.SEMI_MONTHLY.equals(accrualEarnInterval)) {
				// either the 15th or the last day of the month
				if (aDate.getDayOfMonth() == 15 || aDate.getDayOfMonth() == aDate.dayOfMonth().getMaximumValue()) {
					atEarnInterval = true;
				}
			} else if (AccrualEarnInterval.MONTHLY.equals(accrualEarnInterval)) {
				// the last day of the month
				if (aDate.getDayOfMonth() == aDate.dayOfMonth().getMaximumValue()) {
					atEarnInterval = true;
				}
			} else if (AccrualEarnInterval.YEARLY.equals(accrualEarnInterval)) {
				// the last day of the year
				if (aDate.getDayOfYear() == aDate.dayOfYear().getMaximumValue()) {
					atEarnInterval = true;
				}
			} else if (AccrualEarnInterval.NO_ACCRUAL.equals(accrualEarnInterval)) {
				// no calculation
			}
		}
		return atEarnInterval;
	}

	@Override
	public RateRangeAggregate buildRateRangeAggregate(String principalId, DateTime startDate, DateTime endDate) {
		RateRangeAggregate rrAggregate = new RateRangeAggregate();
		List<RateRange> rateRangeList = new ArrayList<RateRange>();
		// get all active jobs that are effective before the endDate
		List<Job> activeJobs = HrServiceLocator.getJobService().getAllActiveLeaveJobs(principalId, endDate.toLocalDate());
		List<Job> inactiveJobs = HrServiceLocator.getJobService().getAllInActiveLeaveJobsInRange(principalId, endDate.toLocalDate());

		List<PrincipalHRAttributes> phaList = HrServiceLocator.getPrincipalHRAttributeService().getAllActivePrincipalHrAttributesForPrincipalId(principalId, endDate.toLocalDate());
		List<PrincipalHRAttributes> inactivePhaList = HrServiceLocator.getPrincipalHRAttributeService().getAllInActivePrincipalHrAttributesForPrincipalId(principalId, endDate.toLocalDate());

		if(activeJobs.isEmpty() || phaList.isEmpty()) {
			return rrAggregate;
		}

		Set<String> phaLpSet = new HashSet<String>();
		Set<String> calNameSet = new HashSet<String>();
		if(CollectionUtils.isNotEmpty(phaList)) {
			for(PrincipalHRAttributes pha : phaList) {
				phaLpSet.add(pha.getLeavePlan());
				calNameSet.add(pha.getPayCalendar());
			}
		}

		List<LeavePlan> activeLpList = new ArrayList<LeavePlan> ();
		List<LeavePlan> inactiveLpList = new ArrayList<LeavePlan> ();
		for(String lpString : phaLpSet) {
			List<LeavePlan> aList = HrServiceLocator.getLeavePlanService().getAllActiveLeavePlan(lpString, endDate.toLocalDate());
			activeLpList.addAll(aList);

			aList = HrServiceLocator.getLeavePlanService().getAllInActiveLeavePlan(lpString, endDate.toLocalDate());
			inactiveLpList.addAll(aList);
		}

		// get all pay calendar entries for this employee. used to determine interval dates
		Map<String, List<CalendarEntry>> calEntryMap = new HashMap<String, List<CalendarEntry>>();
		for(String calName : calNameSet) {
            Calendar aCal = HrServiceLocator.getCalendarService().getCalendarByGroup(calName);
			if(aCal != null) {
				List<CalendarEntry> aList = HrServiceLocator.getCalendarEntryService().getAllCalendarEntriesForCalendarId(aCal.getHrCalendarId());
				Collections.sort(aList);
				calEntryMap.put(calName, aList);
			}
		}
		rrAggregate.setCalEntryMap(calEntryMap);

		Set<String> lpStringSet = new HashSet<String>();
		if(CollectionUtils.isNotEmpty(activeLpList)) {
			for(LeavePlan lp : activeLpList) {
				lpStringSet.add(lp.getLeavePlan());
			}
		}
		List<SystemScheduledTimeOffContract> sstoList = new ArrayList<SystemScheduledTimeOffContract>();
		for(String lpString : lpStringSet) {
			List<? extends SystemScheduledTimeOffContract> aList =LmServiceLocator.getSysSchTimeOffService().getSystemScheduledTimeOffsForLeavePlan(startDate.toLocalDate(), endDate.toLocalDate(), lpString);
			if(CollectionUtils.isNotEmpty(aList)) {
				sstoList.addAll(aList);
			}
		}

		List<AccrualCategory> activeAccrCatList = new ArrayList<AccrualCategory>();
		List<AccrualCategory> inactiveAccrCatList = new ArrayList<AccrualCategory>();
		for(String lpString : lpStringSet) {
			List<AccrualCategory> aList = HrServiceLocator.getAccrualCategoryService().getActiveLeaveAccrualCategoriesForLeavePlan(lpString, endDate.toLocalDate());
			if(CollectionUtils.isNotEmpty(aList)) {
				activeAccrCatList.addAll(aList);
			}

			aList = HrServiceLocator.getAccrualCategoryService().getInActiveLeaveAccrualCategoriesForLeavePlan(lpString, endDate.toLocalDate());
			if(CollectionUtils.isNotEmpty(aList)) {
				inactiveAccrCatList.addAll(aList);
			}
		}

		List<AccrualCategoryRule> activeRuleList = new ArrayList<AccrualCategoryRule>();
		List<AccrualCategoryRule> inactiveRuleList = new ArrayList<AccrualCategoryRule>();
		for(AccrualCategory ac : activeAccrCatList) {
			List<AccrualCategoryRule> aRuleList = HrServiceLocator.getAccrualCategoryRuleService().getActiveRulesForAccrualCategoryId(ac.getLmAccrualCategoryId());
			activeRuleList.addAll(aRuleList);

			aRuleList = HrServiceLocator.getAccrualCategoryRuleService().getInActiveRulesForAccrualCategoryId(ac.getLmAccrualCategoryId());
			inactiveRuleList.addAll(aRuleList);
		}

		List<LeaveCalendarDocumentHeader> lcDocList = LmServiceLocator.getLeaveCalendarDocumentHeaderService().getAllDocumentHeadersInRangeForPricipalId(principalId, startDate, endDate);

		BigDecimal previousFte = null;
		List<Job> jobs;

		DateTime currentDate = startDate;
	    while (!currentDate.isAfter(endDate)) {
	    	RateRange rateRange = new RateRange();

	    	jobs = this.getJobsForDate(activeJobs, inactiveJobs, currentDate.toLocalDate());
	    	if(jobs.isEmpty()) {	// no jobs found for this day
	    		currentDate = currentDate.plusDays(1);
	    		continue;
	    	}
			rateRange.setJobs(jobs);

			// detect if there's a status change
			BigDecimal fteSum = HrServiceLocator.getJobService().getFteSumForJobs(jobs);
			rateRange.setAccrualRatePercentageModifier(fteSum);
			BigDecimal standardHours = HrServiceLocator.getJobService().getStandardHoursSumForJobs(jobs);
			rateRange.setStandardHours(standardHours);

			if(previousFte != null && !previousFte.equals(fteSum)) {
				rateRange.setStatusChanged(true);
				rrAggregate.setRateRangeChanged(true);
			}
			previousFte = fteSum;

			// figure out the PrincipalHRAttributes for this day
			PrincipalHRAttributes phra = this.getPrincipalHrAttributesForDate(phaList, currentDate.toLocalDate());
			rateRange.setPrincipalHRAttributes(phra);

			if(rateRange.getPrincipalHRAttributes() != null) {
				// figure out if there's an end principalHrAttributes for the initial principalHRAttributes
				PrincipalHRAttributes endPhra = this.getInactivePrincipalHrAttributesForDate(inactivePhaList, rateRange.getPrincipalHRAttributes().getEffectiveLocalDate(), currentDate.toLocalDate());
				rateRange.setEndPrincipalHRAttributes(endPhra);
			}

			// get leave plan for this day
			if(rateRange.getPrincipalHRAttributes()!= null) {
				rateRange.setLeavePlan(this.getLeavePlanForDate(activeLpList, inactiveLpList, rateRange.getPrincipalHRAttributes().getLeavePlan(), currentDate.toLocalDate()));
			}

			if(rateRange.getLeavePlan() != null) {
				// get accrual category list for this day
				List<AccrualCategory> acsForDay = this.getAccrualCategoriesForDate(activeAccrCatList, inactiveAccrCatList, rateRange.getLeavePlan().getLeavePlan(), currentDate.toLocalDate());
				rateRange.setAcList(acsForDay);

				// get System scheduled time off for this day
				for(SystemScheduledTimeOffContract ssto : sstoList) {
					if(ssto.getAccruedLocalDate().equals(currentDate.toLocalDate())
							&& ssto.getLeavePlan().equals(rateRange.getLeavePlan().getLeavePlan())) {

						// figure out the primary leave assignment to use for ssto usage leave blocks
						if(CollectionUtils.isNotEmpty(jobs) && StringUtils.isBlank(rateRange.getPrimaryLeaveAssignmentId())) {
							for(Job aJob : jobs) {
								if(aJob.isEligibleForLeave() && aJob.isPrimaryJob()) {
									List<Assignment> assignmentList = HrServiceLocator.getAssignmentService().getActiveAssignmentsForJob(principalId, aJob.getJobNumber(), currentDate.toLocalDate());
									for(Assignment anAssignment : assignmentList) {
										if(anAssignment != null && anAssignment.isPrimaryAssign()) {
											rateRange.setPrimaryLeaveAssignmentId(anAssignment.getTkAssignmentId());
											break;
										}
									}
								}
							}
						}

						// if there exists a ssto accrualed leave block with this ssto id, it means the ssto hours has been banked or transferred by the employee
						// this logic depends on the deactivateOldAccruals() runs before buildRateRangeAggregate()
						// because deactivateOldAccruals() removes accrued ssto leave blocks unless they are banked/transferred
						List<LeaveBlock> sstoLbList = LmServiceLocator.getLeaveBlockService().getSSTOLeaveBlocks(principalId, ssto.getLmSystemScheduledTimeOffId(), ssto.getAccruedLocalDate());
						if(CollectionUtils.isEmpty(sstoLbList)) {
							rateRange.setSysScheTimeOff(ssto);
						}
					}
				}
			}
			// set accrual category rules for the day
			if(CollectionUtils.isNotEmpty(rateRange.getAcList())) {
				List<AccrualCategoryRule> rulesForDay = new ArrayList<AccrualCategoryRule>();
				for(AccrualCategory ac : rateRange.getAcList()) {
					rulesForDay.addAll(this.getAccrualCategoryRulesForDate
											(activeRuleList, ac.getLmAccrualCategoryId(), currentDate.toLocalDate(), rateRange.getPrincipalHRAttributes().getServiceLocalDate()));
				}
				rateRange.setAcRuleList(rulesForDay);

			}

			Interval range = new Interval(currentDate, currentDate.plusDays(1));
			rateRange.setRange(range);
			// assign leave document id to range if there is an existing leave doc for currentDate.
			// The doc Id will be assigned to leave blocks created at this rate range
			rateRange.setLeaveCalendarDocumentId(this.getLeaveDocumentForDate(lcDocList, currentDate));
			rateRangeList.add(rateRange);

			currentDate = currentDate.plusDays(1);
	    }
		rrAggregate.setRateRanges(rateRangeList);
		rrAggregate.setCurrentRate(null);
		return rrAggregate;
	}

	private String getLeaveDocumentForDate(List<LeaveCalendarDocumentHeader> lcDocList, DateTime currentDate) {
		for(LeaveCalendarDocumentHeader lcdh : lcDocList) {
			if(!lcdh.getBeginDateTime().isAfter(currentDate) && lcdh.getEndDateTime().isAfter(currentDate)) {
				return lcdh.getDocumentId();
			}
		}
		return "";
	}

	public List<Job> getJobsForDate(List<Job> activeJobs, List<Job> inactiveJobs, LocalDate currentDate) {
		List<Job> jobs = new ArrayList<Job>();
    	for(Job aJob : activeJobs) {
    		if(!aJob.getEffectiveLocalDate().isAfter(currentDate)) {
    			jobs.add(aJob);
    		}
    	}
    	if(CollectionUtils.isNotEmpty(jobs)) {
	    	List<Job> tempList = new ArrayList<Job>();
	    	tempList.addAll(jobs);
	    	for(Job aJob : tempList) {
	    		for(Job inactiveJob : inactiveJobs) {
	    			if(inactiveJob.getJobNumber().equals(aJob.getJobNumber())
	    				&& inactiveJob.getEffectiveLocalDate().isAfter(aJob.getEffectiveLocalDate())
	    				&& !inactiveJob.getEffectiveLocalDate().isAfter(currentDate)) {
	    					// remove inactive job from list
	    					jobs.remove(aJob);
	    			}
	    		}
	    	}
    	}
    	return jobs;
	}

	public PrincipalHRAttributes getPrincipalHrAttributesForDate(List<PrincipalHRAttributes> activeList, LocalDate currentDate) {
		List<PrincipalHRAttributes> phasForDay = new ArrayList<PrincipalHRAttributes>();
		for(PrincipalHRAttributes pha : activeList) {
			if(pha != null && pha.getEffectiveLocalDate() != null && pha.getServiceLocalDate() != null
					&& !pha.getEffectiveLocalDate().isAfter(currentDate) && !pha.getServiceLocalDate().isAfter(currentDate)) {
    			phasForDay.add(pha);
    		}
		}
		if(CollectionUtils.isNotEmpty(phasForDay)) {
			PrincipalHRAttributes pha = phasForDay.get(0);
			int indexOfMaxEffDt = 0;
			if(phasForDay.size() > 1) {
				for(int i = 1; i < phasForDay.size(); i++) {
					if( (phasForDay.get(i).getEffectiveLocalDate().isAfter(phasForDay.get(indexOfMaxEffDt).getEffectiveLocalDate()))
							||(phasForDay.get(i).getEffectiveLocalDate().equals(phasForDay.get(indexOfMaxEffDt).getEffectiveLocalDate())
									&& phasForDay.get(i).getCreateTime().isAfter(phasForDay.get(indexOfMaxEffDt).getCreateTime()))) {
						indexOfMaxEffDt = i;
					}
				}
				pha = phasForDay.get(indexOfMaxEffDt);
			}
			return pha;
		}
		return null;
	}

	public PrincipalHRAttributes getInactivePrincipalHrAttributesForDate(List<PrincipalHRAttributes> inactiveList, LocalDate activeDate, LocalDate currentDate) {
		List<PrincipalHRAttributes> inactivePhasForDay = new ArrayList<PrincipalHRAttributes>();
		for(PrincipalHRAttributes pha : inactiveList) {
			if( pha.getEffectiveLocalDate().isAfter(activeDate) && !pha.getServiceLocalDate().isAfter(currentDate)) {
				inactivePhasForDay.add(pha);
    		}
		}
		if(CollectionUtils.isNotEmpty(inactivePhasForDay)) {
			PrincipalHRAttributes pha = inactivePhasForDay.get(0);
			int indexOfMaxEffDt = 0;
			if(inactivePhasForDay.size() > 1) {
				for(int i = 1; i < inactivePhasForDay.size(); i++) {
					if( (inactivePhasForDay.get(i).getEffectiveLocalDate().isAfter(inactivePhasForDay.get(indexOfMaxEffDt).getEffectiveLocalDate()))
							||(inactivePhasForDay.get(i).getEffectiveLocalDate().equals(inactivePhasForDay.get(indexOfMaxEffDt).getEffectiveLocalDate())
									&& inactivePhasForDay.get(i).getCreateTime().isAfter(inactivePhasForDay.get(indexOfMaxEffDt).getCreateTime()))) {
						indexOfMaxEffDt = i;
					}
				}
				pha = inactivePhasForDay.get(indexOfMaxEffDt);
			}
			return pha;
		}
		return null;
	}

	public LeavePlan getLeavePlanForDate(List<LeavePlan> activeLpList, List<LeavePlan> inactiveLpList, String leavePlan, LocalDate currentDate) {
		List<LeavePlan> lpsForDay = new ArrayList<LeavePlan>();
		for(LeavePlan lp : activeLpList) {
			if(lp.getLeavePlan().equals(leavePlan) && !lp.getEffectiveLocalDate().isAfter(currentDate)) {
				lpsForDay.add(lp);
			}
		}
		List<LeavePlan> aList = new ArrayList<LeavePlan>();
		aList.addAll(lpsForDay);
    	for(LeavePlan lp : aList) {
    		for(LeavePlan inactiveLp : inactiveLpList) {
    			if(inactiveLp.getLeavePlan().equals(lp.getLeavePlan())
    				&& inactiveLp.getEffectiveLocalDate().isAfter(lp.getEffectiveLocalDate())
    				&& !inactiveLp.getEffectiveLocalDate().isAfter(currentDate)) {
    					// remove inactive leave plan from list
    					lpsForDay.remove(lp);
    			}
    		}
    	}
		if(CollectionUtils.isNotEmpty(lpsForDay)) {
			LeavePlan aLp = lpsForDay.get(0);
			int indexOfMaxEffDt = 0;
			if(lpsForDay.size() > 1) {
				for(int i = 1; i < lpsForDay.size(); i++) {
					if( (lpsForDay.get(i).getEffectiveLocalDate().isAfter(lpsForDay.get(indexOfMaxEffDt).getEffectiveLocalDate()))
							||(lpsForDay.get(i).getEffectiveLocalDate().compareTo(lpsForDay.get(indexOfMaxEffDt).getEffectiveLocalDate()) == 0
									&& lpsForDay.get(i).getCreateTime().isAfter(lpsForDay.get(indexOfMaxEffDt).getCreateTime()))) {
						indexOfMaxEffDt = i;
					}
				}
				aLp = lpsForDay.get(indexOfMaxEffDt);
			}
			return aLp;
		}
		return null;
	}

	public List<AccrualCategory> getAccrualCategoriesForDate(List<AccrualCategory> activeAccrCatList, List<AccrualCategory> inactiveAccrCatList, String leavePlan, LocalDate currentDate) {
		Set<AccrualCategory> aSet = new HashSet<AccrualCategory>();
		for(AccrualCategory ac : activeAccrCatList) {
			if(ac.getLeavePlan().equals(leavePlan) && !ac.getEffectiveLocalDate().isAfter(currentDate)) {
				aSet.add(ac);
			}
		}
		List<AccrualCategory> list1 = new ArrayList<AccrualCategory>();
		list1.addAll(aSet);
    	for(AccrualCategory ac : list1) {
    		for(AccrualCategory inactiveAc : inactiveAccrCatList) {
    			if(inactiveAc.getAccrualCategory().equals(ac.getAccrualCategory())
    				&& inactiveAc.getEffectiveLocalDate().isAfter(ac.getEffectiveLocalDate())
    				&& !inactiveAc.getEffectiveLocalDate().isAfter(currentDate)) {
    					// remove inactive accrual category from list
    				aSet.remove(ac);
    			}
    		}
    	}
    	List<AccrualCategory> acsForDay = new ArrayList<AccrualCategory>();
    	acsForDay.addAll(aSet);
    	return acsForDay;
	}

	@Override
	public boolean isEmpoyeementFutureStatusChanged(String principalId, DateTime startDate, DateTime endDate) {
		if(endDate.isAfter(LocalDate.now().toDateTimeAtStartOfDay())) {
			RateRangeAggregate rrAggregate = this.buildRateRangeAggregate(principalId, startDate, endDate);
			if(rrAggregate.isRateRangeChanged()) {
				return true;
			}
		}
		return false;
	}

	@Override
	public void calculateFutureAccrualUsingPlanningMonth(String principalId, LocalDate asOfDate, String runAsPrincipalId) {
		PrincipalHRAttributes phra = HrServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(principalId, asOfDate);
		if(phra != null) {
			// use the date from pay period to get the leave plan
			LeavePlanContract lp = HrServiceLocator.getLeavePlanService().getLeavePlan(phra.getLeavePlan(), asOfDate);
			if(lp != null && StringUtils.isNotEmpty(lp.getPlanningMonths())) {
				// go back a year
				LocalDate startDate = asOfDate.minusYears(1);
				if(startDate.getDayOfMonth() > startDate.dayOfMonth().getMaximumValue()) {
					startDate = startDate.withDayOfMonth(startDate.dayOfMonth().getMaximumValue());
				}
				// go forward using planning months
				LocalDate endDate = asOfDate.plusMonths(Integer.parseInt(lp.getPlanningMonths()));
				// max days in months differ, if the date is bigger than the max day, set it to the max day of the month
				if(endDate.getDayOfMonth() > endDate.dayOfMonth().getMaximumValue()) {
					endDate = endDate.withDayOfMonth(endDate.dayOfMonth().getMaximumValue());
				}
				runAccrual(principalId, startDate.toDateTimeAtStartOfDay(), endDate.toDateTimeAtStartOfDay(), true, runAsPrincipalId);

			}
		}
	}

	private boolean minimumPercentageReachedForPayPeriod(BigDecimal min, String earnInterval, int workDays, DateTime intervalDate, String payCalName,  Map<String, List<CalendarEntry>> aMap) {
		if(min == null || min.compareTo(BigDecimal.ZERO) == 0) {
			return true;
		}
		int daysInInterval = this.getWorkDaysInInterval(intervalDate, earnInterval, payCalName, aMap);
		if(daysInInterval == 0) {
			return true;
		}
		BigDecimal actualPercentage =  new BigDecimal(workDays).divide(new BigDecimal(daysInInterval), 2, BigDecimal.ROUND_HALF_EVEN);
		if(actualPercentage.compareTo(min) >= 0) {
			return true;
		}

		return false;
	}

	private DateTime getPrevIntervalDate(DateTime aDate, String earnInterval, String payCalName,  Map<String, List<CalendarEntry>> aMap) {
		if(earnInterval.equals(AccrualEarnInterval.PAY_CAL.getCode())) {
			return this.getPrevPayCalIntervalDate(aDate, earnInterval, payCalName, aMap);
		} else {
			return this.getPreviousAccrualIntervalDate(earnInterval, aDate);
		}
	}

	@Override
	public DateTime getPreviousAccrualIntervalDate(String earnInterval, DateTime aDate) {
		DateTime previousAccrualIntervalDate = null;
        AccrualEarnInterval accrualEarnInterval = AccrualEarnInterval.fromCode(earnInterval);
		if (AccrualEarnInterval.DAILY.equals(accrualEarnInterval)) {
			previousAccrualIntervalDate = aDate.minusDays(1);
		} else if(AccrualEarnInterval.WEEKLY.equals(accrualEarnInterval)) {
			previousAccrualIntervalDate = aDate.minusWeeks(1).withDayOfWeek(DateTimeConstants.SATURDAY);
		} else if (AccrualEarnInterval.SEMI_MONTHLY.equals(accrualEarnInterval)) {
			previousAccrualIntervalDate = aDate.minusDays(15);
			if (previousAccrualIntervalDate.getDayOfMonth() <= 15) {
				previousAccrualIntervalDate = previousAccrualIntervalDate.withDayOfMonth(15);
			} else {
				previousAccrualIntervalDate = previousAccrualIntervalDate.withDayOfMonth(previousAccrualIntervalDate.dayOfMonth().getMaximumValue());
			}
		} else if (AccrualEarnInterval.MONTHLY.equals(accrualEarnInterval)) {
			previousAccrualIntervalDate = aDate.minusMonths(1);
			previousAccrualIntervalDate = previousAccrualIntervalDate.withDayOfMonth(previousAccrualIntervalDate.dayOfMonth().getMaximumValue());
		} else if (AccrualEarnInterval.YEARLY.equals(accrualEarnInterval)) {
			previousAccrualIntervalDate = aDate.minusYears(1);
			previousAccrualIntervalDate = previousAccrualIntervalDate.withDayOfYear(previousAccrualIntervalDate.dayOfYear().getMaximumValue());
		} else if (AccrualEarnInterval.NO_ACCRUAL.equals(accrualEarnInterval)) {
			previousAccrualIntervalDate = aDate;
		}

		return previousAccrualIntervalDate;
	}

	private DateTime getPrevPayCalIntervalDate(DateTime aDate, String earnInterval, String payCalName,  Map<String, List<CalendarEntry>> aMap) {
		if(StringUtils.isNotEmpty(payCalName)
				&& !aMap.isEmpty()
				&& earnInterval.equals(AccrualEarnInterval.PAY_CAL.getCode())) {	// only used for ac earn interval == pay calendar
			List<CalendarEntry> entryList = aMap.get(payCalName);
			if(CollectionUtils.isNotEmpty(entryList)) {
				for(CalendarEntry anEntry : entryList) {
					// endPeriodDate of calendar entry is the beginning hour of the next day, so we need to substract one day from it to get the real end date
					DateTime endDate = anEntry.getEndPeriodFullDateTime().minusDays(1);
					if(anEntry.getBeginPeriodFullDateTime().compareTo(aDate) <= 0 && endDate.compareTo(aDate) >= 0) {
						// the day before the beginning date of the cal entry that contains the passed in date is the endDate of previous calendar entry
						DateTime prevIntvDate = anEntry.getBeginPeriodFullDateTime().minusDays(1);
						return prevIntvDate;
					}
				}
			}
		}
		return aDate;
	}

    @Override
	public DateTime getNextIntervalDate(DateTime aDate, String earnInterval, String payCalName, Map<String, List<CalendarEntry>> aMap) {
		if(earnInterval.equals(AccrualEarnInterval.PAY_CAL.getCode())) {
			return this.getNextPayCalIntervalDate(aDate, earnInterval, payCalName, aMap);
		} else {
			return this.getNextAccrualIntervalDate(earnInterval, aDate);
		}
	}

	private DateTime getNextPayCalIntervalDate(DateTime aDate, String earnInterval, String payCalName,  Map<String, List<CalendarEntry>> aMap) {
		if(StringUtils.isNotEmpty(payCalName)
				&& !aMap.isEmpty()
				&& earnInterval.equals(AccrualEarnInterval.PAY_CAL.getCode())) {	// only used for ac earn interval == pay calendar
			List<CalendarEntry> entryList = aMap.get(payCalName);
			if(CollectionUtils.isNotEmpty(entryList)) {
				for(CalendarEntry anEntry : entryList) {
					// endPeriodDate of calendar entry is the beginning hour of the next day, so we need to substract one day from it to get the real end date
					DateTime endDate = anEntry.getEndPeriodFullDateTime().minusDays(1);
					if(anEntry.getBeginPeriodFullDateTime().compareTo(aDate) <= 0 && endDate.compareTo(aDate) >= 0) {
						// the endDate of the cal entry that contains the passed in date is the next pay calendar interval date
						return endDate;
					}
				}
			}
		}
		return aDate;
	}

	@Override
	public DateTime getNextAccrualIntervalDate(String earnInterval, DateTime aDate) {
		DateTime nextAccrualIntervalDate = null;
        AccrualEarnInterval accrualEarnInterval = AccrualEarnInterval.fromCode(earnInterval);
		if (AccrualEarnInterval.DAILY.equals(accrualEarnInterval)) {
			nextAccrualIntervalDate = aDate;
		} else if(AccrualEarnInterval.WEEKLY.equals(accrualEarnInterval)) {
			if (aDate.getDayOfWeek() != DateTimeConstants.SATURDAY) {
				nextAccrualIntervalDate = aDate.withDayOfWeek(DateTimeConstants.SATURDAY);
			} else {
				nextAccrualIntervalDate = aDate.withWeekOfWeekyear(1);
			}
		} else if (AccrualEarnInterval.SEMI_MONTHLY.equals(accrualEarnInterval)) {
			if(aDate.getDayOfMonth() <= 15) {
				nextAccrualIntervalDate = aDate.withDayOfMonth(15);
			} else {
				nextAccrualIntervalDate = aDate.withDayOfMonth(aDate.dayOfMonth().getMaximumValue());
			}
		} else if (AccrualEarnInterval.MONTHLY.equals(accrualEarnInterval)) {
			nextAccrualIntervalDate = aDate.withDayOfMonth(aDate.dayOfMonth().getMaximumValue());
		} else if (AccrualEarnInterval.YEARLY.equals(accrualEarnInterval)) {
			nextAccrualIntervalDate = aDate.withDayOfYear(aDate.dayOfYear().getMaximumValue());
		} else if (AccrualEarnInterval.NO_ACCRUAL.equals(accrualEarnInterval)) {
			nextAccrualIntervalDate = aDate;
		} else if (AccrualEarnInterval.PAY_CAL.equals(accrualEarnInterval)) {
			LOG.error("Accrual Earn Interval of Pay CAL is not valid for AccrualServiceImpl:getNextAccrualIntervalDate");
            nextAccrualIntervalDate = null;
		}

		return nextAccrualIntervalDate;
	}

	private int getWorkDaysInInterval(DateTime aDate, String earnInterval, String payCalName,  Map<String, List<CalendarEntry>> aMap) {
		if(earnInterval.equals(AccrualEarnInterval.PAY_CAL.getCode())) {
			return this.getWorkDaysInPayCalInterval(aDate, earnInterval, payCalName, aMap);
		} else {
			return this.getWorkDaysInAccrualInterval(earnInterval, aDate);
		}
	}

	private int getWorkDaysInPayCalInterval(DateTime aDate, String earnInterval, String payCalName,  Map<String, List<CalendarEntry>> aMap) {
		if(StringUtils.isNotEmpty(payCalName)
				&& !aMap.isEmpty()
				&& earnInterval.equals(AccrualEarnInterval.PAY_CAL.getCode())) {	// only used for ac earn interval == pay calendar
			List<CalendarEntry> entryList = aMap.get(payCalName);
			if(CollectionUtils.isNotEmpty(entryList)) {
				for(CalendarEntry anEntry : entryList) {
					// endPeriodDate of calendar entry is the beginning hour of the next day, so we need to substract one day from it to get the real end date
					DateTime endDate = anEntry.getEndPeriodFullDateTime().minusDays(1);
					if(anEntry.getBeginPeriodFullDateTime().compareTo(aDate) <= 0 && endDate.compareTo(aDate) >= 0) {
						return TKUtils.getWorkDays(anEntry.getBeginPeriodFullDateTime(), endDate);
					}
				}
			}
		}
		return 0;
	}

	@Override
	public int getWorkDaysInAccrualInterval(String earnInterval, DateTime aDate) {
        AccrualEarnInterval accrualEarnInterval = AccrualEarnInterval.fromCode(earnInterval);
        if (accrualEarnInterval != null) {
            if(AccrualEarnInterval.DAILY.equals(accrualEarnInterval)) {
                return 1;
            } else if(AccrualEarnInterval.WEEKLY.equals(accrualEarnInterval)) {
                return 5;
            } else if (AccrualEarnInterval.SEMI_MONTHLY.equals(accrualEarnInterval)) {
                if(aDate.getDayOfMonth() <= 15) {
                    return TKUtils.getWorkDays(aDate.withDayOfMonth(1), aDate.withDayOfMonth(15));
                } else {
                    return TKUtils.getWorkDays(aDate.withDayOfMonth(16), aDate.withDayOfMonth(aDate.dayOfMonth().getMaximumValue()));
                }
            } else if (AccrualEarnInterval.MONTHLY.equals(accrualEarnInterval)) {
                return TKUtils.getWorkDays(aDate.withDayOfMonth(1), aDate.withDayOfMonth(aDate.dayOfMonth().getMaximumValue()));
            } else if (AccrualEarnInterval.YEARLY.equals(accrualEarnInterval)) {
                return TKUtils.getWorkDays(aDate.withDayOfYear(1), aDate.withDayOfYear(aDate.dayOfYear().getMaximumValue()));
            } else if (AccrualEarnInterval.NO_ACCRUAL.equals(accrualEarnInterval)) {
                return 0;
            }
        }
		return 0;
	}

	public DateTime getRuleStartDate(String earnInterval, LocalDate serviceDate, Long startAcc) {
		DateTime ruleStartDate = null;

		String intervalValue = HrConstants.SERVICE_UNIT_OF_TIME.get(earnInterval);

        switch (intervalValue) {
            case "Months":
                ruleStartDate = serviceDate.toDateTimeAtStartOfDay().plusMonths(startAcc.intValue());
                if (ruleStartDate.getDayOfMonth() > ruleStartDate.dayOfMonth().getMaximumValue()) {
                    ruleStartDate = ruleStartDate.withDayOfMonth(ruleStartDate.dayOfMonth().getMaximumValue());
                }
                break;
            case "Years":
                ruleStartDate = serviceDate.toDateTimeAtStartOfDay().withYear(startAcc.intValue());
                break;
            default:
                ruleStartDate = serviceDate.toDateTimeAtStartOfDay();
                break;
        }

		return ruleStartDate;
	}

	public boolean isProrationFlag(String proration) {
		if(proration == null) {
			return true;
		}
		return proration.equals("Y") ? true : false;
	}

	@Override
	public boolean statusChangedSinceLastRun(String principalId) {
		PrincipalAccrualRanContract par = LmServiceLocator.getPrincipalAccrualRanService().getLastPrincipalAccrualRan(principalId);
		if(par == null) {
			return true;
		}
		JobContract aJob = HrServiceLocator.getJobService().getMaxTimestampJob(principalId);

		if(aJob != null && aJob.getCreateTime().isAfter(new DateTime(par.getLastRanTs().getTime()))) {
			return true;
		}

        Assignment anAssign = HrServiceLocator.getAssignmentService().getMaxTimestampAssignment(principalId);
		if(anAssign != null && anAssign.getCreateTime().isAfter(new DateTime(par.getLastRanTs().getTime()))) {
			return true;
		}

		PrincipalHRAttributes pha = HrServiceLocator.getPrincipalHRAttributeService().getMaxTimeStampPrincipalHRAttributes(principalId);
		if(pha != null && pha.getCreateTime().isAfter(par.getLastRanDateTime())) {
			return true;
		}
		// if there are leave blocks created for earn codes with eligible-for-accrual = no since the last accrual run, it should trigger recalculation
		List<LeaveBlock> lbList = LmServiceLocator.getLeaveBlockService().getABELeaveBlocksSinceTime(principalId, par.getLastRanDateTime());
        return CollectionUtils.isNotEmpty(lbList);
    }

    public List<AccrualCategoryRule> getAccrualCategoryRulesForDate(List<AccrualCategoryRule> acrList, String accrualCategoryId, LocalDate currentDate, LocalDate serviceDate) {
    	List<AccrualCategoryRule> aList = new ArrayList<AccrualCategoryRule>();
    	if(CollectionUtils.isNotEmpty(acrList)) {
	    	for(AccrualCategoryRule acr : acrList) {
	    		if(acr.getLmAccrualCategoryId().equals(accrualCategoryId)) {
		    		String uot = acr.getServiceUnitOfTime();
		    		int startTime = acr.getStart().intValue();
					int endTime = acr.getEnd().intValue();

					LocalDate startDate = serviceDate;
					LocalDate endDate = serviceDate;
		    		if(uot.equals("M")) {		// monthly
		    			startDate = startDate.plusMonths(startTime);
		    			endDate = endDate.plusMonths(endTime).minusDays(1);
		    		} else if(uot.endsWith("Y")) { // yearly
		    			startDate = startDate.plusYears(startTime);
		    			endDate = endDate.plusYears(endTime).minusDays(1);
		    		}

		    		// max days in months differ, if the date is bigger than the max day, set it to the max day of the month
					if(startDate.getDayOfMonth() > startDate.dayOfMonth().getMaximumValue()) {
						startDate = startDate.withDayOfMonth(startDate.dayOfMonth().getMaximumValue());
					}
					if(endDate.getDayOfMonth() > endDate.dayOfMonth().getMaximumValue()) {
						endDate = endDate.withDayOfMonth(endDate.dayOfMonth().getMaximumValue());
					}

		    		if(currentDate.compareTo(startDate) >= 0 && currentDate.compareTo(endDate) <=0 ) {
		    			aList.add(acr);
		    		}
	    		}
	    	}
    	}
    	return aList;
	}

    public AccrualCategoryRuleContract getRuleForAccrualCategory(List<AccrualCategoryRule> acrList, AccrualCategoryContract ac) {
    	if(CollectionUtils.isNotEmpty(acrList)) {
	    	for(AccrualCategoryRuleContract acr : acrList) {
	    		if(acr.getLmAccrualCategoryId().equals(ac.getLmAccrualCategoryId())) {
	    			return acr;
	    		}
	    	}
	    }
    	return null;
    }

    @Override
	public BigDecimal getAccruedBalanceForPrincipal(String principalId,
			AccrualCategoryContract accrualCategory, LocalDate asOfDate) {
    	BigDecimal balance = new BigDecimal(0);
    	PrincipalHRAttributes pha = HrServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(principalId, asOfDate);
    	if(pha == null)
    		return BigDecimal.ZERO;

    	List<LeaveBlock> leaveBlocks = LmServiceLocator.getLeaveBlockService().getLeaveBlocksWithAccrualCategory(principalId, pha.getServiceLocalDate(), asOfDate, accrualCategory.getAccrualCategory());
    	for(LeaveBlock block : leaveBlocks) {
    		if(!(StringUtils.equals(block.getRequestStatus(),HrConstants.REQUEST_STATUS.DEFERRED)
    				|| StringUtils.equals(block.getRequestStatus(),HrConstants.REQUEST_STATUS.DISAPPROVED))) {
    			balance = balance.add(block.getLeaveAmount());
/*    			EarnCode code = accrualCategory.getEarnCodeObj();
    			if(StringUtils.equals(HrConstants.ACCRUAL_BALANCE_ACTION_MAP.get(code.getAccrualBalanceAction()), "Usage"))
    				balance = balance.subtract(block.getLeaveAmount().abs());
    			if(StringUtils.equals(HrConstants.ACCRUAL_BALANCE_ACTION_MAP.get(code.getAccrualBalanceAction()), "Adjustment"))
    				balance = balance.add(block.getLeaveAmount());*/
    		}
    	}
		return balance;
	}

	@Override
	public BigDecimal getApprovedBalanceForPrincipal(String principalId,
			AccrualCategoryContract accrualCategory, LocalDate asOfDate) {
    	BigDecimal balance = new BigDecimal(0);
    	PrincipalHRAttributes pha = HrServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(principalId, asOfDate);
    	List<LeaveBlock> leaveBlocks = LmServiceLocator.getLeaveBlockService().getLeaveBlocksWithAccrualCategory(principalId, pha.getServiceLocalDate(), asOfDate, accrualCategory.getAccrualCategory());
    	for(LeaveBlock block : leaveBlocks) {
    		if(StringUtils.equals(block.getRequestStatus(),HrConstants.REQUEST_STATUS.APPROVED)) {
				balance = balance.add(block.getLeaveAmount());
/*    			EarnCode code = accrualCategory.getEarnCodeObj();
    			if(StringUtils.equals(HrConstants.ACCRUAL_BALANCE_ACTION_MAP.get(code.getAccrualBalanceAction()), "Usage"))
    				balance = balance.subtract(block.getLeaveAmount().abs());
    			if(StringUtils.equals(HrConstants.ACCRUAL_BALANCE_ACTION_MAP.get(code.getAccrualBalanceAction()), "Adjustment"))
    				balance = balance.add(block.getLeaveAmount());*/
    		}
    	}
		return balance;
	}

	@Override
	public void runAccrualForLeavePlan(LeavePlanContract aLeavePlan, DateTime startDate, DateTime endDate, boolean recordRanData) {
		if(aLeavePlan != null) {
			List<PrincipalHRAttributes> phaList = HrServiceLocator.getPrincipalHRAttributeService().getActiveEmployeesForLeavePlan(aLeavePlan.getLeavePlan(), aLeavePlan.getEffectiveLocalDate());
			for(PrincipalHRAttributes aPHA : phaList) {
				String anId = aPHA.getPrincipalId();
				if(LmServiceLocator.getLeaveAccrualService().statusChangedSinceLastRun(anId)) {
					DateTime startDT = startDate == null ? getStartAccrualDate(anId) : startDate;
					DateTime endDT = endDate == null ? getEndAccrualDate(anId) : endDate;
					if(startDT != null && endDT != null) {
						this.runAccrual(anId, startDT, endDT, recordRanData);
					}
				}
			}
		}
	}
}


text:
package org.apache.distributedlog.service;

import org.apache.distributedlog.DistributedLogConfiguration;
import org.apache.distributedlog.LocalDLMEmulator;
import org.apache.distributedlog.client.routing.SingleHostRoutingService;
import org.apache.distributedlog.impl.metadata.BKDLConfig;
import org.apache.distributedlog.metadata.DLMetadata;
import org.apache.distributedlog.service.placement.EqualLoadAppraiser;
import org.apache.distributedlog.service.streamset.IdentityStreamPartitionConverter;
import com.twitter.finagle.builder.Server;
import java.io.File;
import java.net.BindException;
import java.net.InetSocketAddress;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.bookkeeper.conf.ServerConfiguration;
import org.apache.bookkeeper.shims.zk.ZooKeeperServerShim;
import org.apache.bookkeeper.stats.NullStatsProvider;
import org.apache.bookkeeper.util.IOUtils;
import org.apache.bookkeeper.util.LocalBookKeeper;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * DistributedLog Cluster is an emulator to run distributedlog components.
 */
public class DistributedLogCluster {

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

    public static Builder newBuilder() {
        return new Builder();
    }

    /**
     * Builder to build distributedlog cluster.
     */
    public static class Builder {

        int numBookies = 3;
        boolean shouldStartZK = true;
        String zkHost = "127.0.0.1";
        int zkPort = 0;
        boolean shouldStartProxy = true;
        int proxyPort = 7000;
        boolean thriftmux = false;
        DistributedLogConfiguration dlConf = new DistributedLogConfiguration()
                .setLockTimeout(10)
                .setOutputBufferSize(0)
                .setImmediateFlushEnabled(true);
        ServerConfiguration bkConf = new ServerConfiguration();

        private Builder() {}

        /**
         * How many bookies to run. By default is 3.
         *
         * @return builder
         */
        public Builder numBookies(int numBookies) {
            this.numBookies = numBookies;
            return this;
        }

        /**
         * Whether to start zookeeper? By default is true.
         *
         * @param startZK
         *          flag to start zookeeper?
         * @return builder
         */
        public Builder shouldStartZK(boolean startZK) {
            this.shouldStartZK = startZK;
            return this;
        }

        /**
         * ZooKeeper server to run. By default it runs locally on '127.0.0.1'.
         *
         * @param zkServers
         *          zk servers
         * @return builder
         */
        public Builder zkServers(String zkServers) {
            this.zkHost = zkServers;
            return this;
        }

        /**
         * ZooKeeper server port to listen on. By default it listens on 2181.
         *
         * @param zkPort
         *          zookeeper server port.
         * @return builder.
         */
        public Builder zkPort(int zkPort) {
            this.zkPort = zkPort;
            return this;
        }

        /**
         * Whether to start proxy or not. By default is true.
         *
         * @param startProxy
         *          whether to start proxy or not.
         * @return builder
         */
        public Builder shouldStartProxy(boolean startProxy) {
            this.shouldStartProxy = startProxy;
            return this;
        }

        /**
         * Port that proxy server to listen on. By default is 7000.
         *
         * @param proxyPort
         *          port that proxy server to listen on.
         * @return builder
         */
        public Builder proxyPort(int proxyPort) {
            this.proxyPort = proxyPort;
            return this;
        }

        /**
         * Set the distributedlog configuration.
         *
         * @param dlConf
         *          distributedlog configuration
         * @return builder
         */
        public Builder dlConf(DistributedLogConfiguration dlConf) {
            this.dlConf = dlConf;
            return this;
        }

        /**
         * Set the Bookkeeper server configuration.
         *
         * @param bkConf
         *          bookkeeper server configuration
         * @return builder
         */
        public Builder bkConf(ServerConfiguration bkConf) {
            this.bkConf = bkConf;
            return this;
        }

        /**
         * Enable thriftmux for the dl server.
         *
         * @param enabled flag to enable thriftmux
         * @return builder
         */
        public Builder thriftmux(boolean enabled) {
            this.thriftmux = enabled;
            return this;
        }

        public DistributedLogCluster build() throws Exception {
            // build the cluster
            return new DistributedLogCluster(
                dlConf,
                bkConf,
                numBookies,
                shouldStartZK,
                zkHost,
                zkPort,
                shouldStartProxy,
                proxyPort,
                thriftmux);
        }
    }

    /**
     * Run a distributedlog proxy server.
     */
    public static class DLServer {

        static final int MAX_RETRIES = 20;
        static final int MIN_PORT = 1025;
        static final int MAX_PORT = 65535;

        int proxyPort;

        public final InetSocketAddress address;
        public final Pair<DistributedLogServiceImpl, Server> dlServer;
        private final SingleHostRoutingService routingService = SingleHostRoutingService.of(null);

        protected DLServer(DistributedLogConfiguration dlConf,
                           URI uri,
                           int basePort,
                           boolean thriftmux) throws Exception {
            proxyPort = basePort;

            boolean success = false;
            int retries = 0;
            Pair<DistributedLogServiceImpl, Server> serverPair = null;
            while (!success) {
                try {
                    org.apache.distributedlog.service.config.ServerConfiguration serverConf =
                            new org.apache.distributedlog.service.config.ServerConfiguration();
                    serverConf.loadConf(dlConf);
                    serverConf.setServerShardId(proxyPort);
                    serverPair = DistributedLogServer.runServer(
                            serverConf,
                            dlConf,
                            uri,
                            new IdentityStreamPartitionConverter(),
                            routingService,
                            new NullStatsProvider(),
                            proxyPort,
                            thriftmux,
                            new EqualLoadAppraiser());
                    routingService.setAddress(DLSocketAddress.getSocketAddress(proxyPort));
                    routingService.startService();
                    serverPair.getLeft().startPlacementPolicy();
                    success = true;
                } catch (BindException be) {
                    retries++;
                    if (retries > MAX_RETRIES) {
                        throw be;
                    }
                    proxyPort++;
                    if (proxyPort > MAX_PORT) {
                        proxyPort = MIN_PORT;
                    }
                }
            }

            LOG.info("Running DL on port {}", proxyPort);

            dlServer = serverPair;
            address = DLSocketAddress.getSocketAddress(proxyPort);
        }

        public InetSocketAddress getAddress() {
            return address;
        }

        public void shutdown() {
            DistributedLogServer.closeServer(dlServer, 0, TimeUnit.MILLISECONDS);
            routingService.stopService();
        }
    }

    private final DistributedLogConfiguration dlConf;
    private final ZooKeeperServerShim zks;
    private final LocalDLMEmulator dlmEmulator;
    private DLServer dlServer;
    private final boolean shouldStartProxy;
    private final int proxyPort;
    private final boolean thriftmux;
    private final List<File> tmpDirs = new ArrayList<File>();

    private DistributedLogCluster(DistributedLogConfiguration dlConf,
                                  ServerConfiguration bkConf,
                                  int numBookies,
                                  boolean shouldStartZK,
                                  String zkServers,
                                  int zkPort,
                                  boolean shouldStartProxy,
                                  int proxyPort,
                                  boolean thriftmux) throws Exception {
        this.dlConf = dlConf;
        if (shouldStartZK) {
            File zkTmpDir = IOUtils.createTempDir("zookeeper", "distrlog");
            tmpDirs.add(zkTmpDir);
            if (0 == zkPort) {
                Pair<ZooKeeperServerShim, Integer> serverAndPort = LocalDLMEmulator.runZookeeperOnAnyPort(zkTmpDir);
                this.zks = serverAndPort.getLeft();
                zkPort = serverAndPort.getRight();
            } else {
                this.zks = LocalBookKeeper.runZookeeper(1000, zkPort, zkTmpDir);
            }
        } else {
            this.zks = null;
        }
        this.dlmEmulator = LocalDLMEmulator.newBuilder()
                .numBookies(numBookies)
                .zkHost(zkServers)
                .zkPort(zkPort)
                .serverConf(bkConf)
                .shouldStartZK(false)
                .build();
        this.shouldStartProxy = shouldStartProxy;
        this.proxyPort = proxyPort;
        this.thriftmux = thriftmux;
    }

    public void start() throws Exception {
        this.dlmEmulator.start();
        BKDLConfig bkdlConfig = new BKDLConfig(this.dlmEmulator.getZkServers(), "/ledgers").setACLRootPath(".acl");
        DLMetadata.create(bkdlConfig).update(this.dlmEmulator.getUri());
        if (shouldStartProxy) {
            this.dlServer = new DLServer(
                    dlConf,
                    this.dlmEmulator.getUri(),
                    proxyPort,
                    thriftmux);
        } else {
            this.dlServer = null;
        }
    }

    public void stop() throws Exception {
        if (null != dlServer) {
            this.dlServer.shutdown();
        }
        this.dlmEmulator.teardown();
        if (null != this.zks) {
            this.zks.stop();
        }
        for (File dir : tmpDirs) {
            FileUtils.forceDeleteOnExit(dir);
        }
    }

    public URI getUri() {
        return this.dlmEmulator.getUri();
    }

    public String getZkServers() {
        return this.dlmEmulator.getZkServers();
    }

    public String getProxyFinagleStr() {
        return "inet!" + (dlServer == null ? "127.0.0.1:" + proxyPort : dlServer.getAddress().toString());
    }

}


text:
SauceJs Demo

            <form ng-submit="loadBoard(boardName, boards)">
            <input type="text" placeholder="Board Name" ng-model="boardName" / >   <button class="btn btn-success" >Load Idea List</button>
          </form>

 Start by typing a name for a new or existing Todo list.

{{boards[board].name}} Board <button class="btn btn-xs " ng-click="clearBoard()">change board</button>

          share link : http://{{host}}/#/{{boards[board].name}}
          <form ng-submit="addItem(board, boards, newItem)">
            <input type="text" class="input-lg col-lg-12" placeholder="Type an idea. Press [ENTER]" ng-model="newItem" maxlength="40">
          </form>

              <div class="items" ng-class="{itemstop: $index < itemTop}">

{{$index + 1}}. {{item.name}}
                  {{item.vote}}

        Test : 1 + 2 = {{sum}}


text:
package org.elasticsearch.client.ml.job.process;

import org.elasticsearch.client.ml.job.config.Job;
import org.elasticsearch.xcontent.ConstructingObjectParser;
import org.elasticsearch.xcontent.ObjectParser.ValueType;
import org.elasticsearch.xcontent.ParseField;
import org.elasticsearch.xcontent.ToXContentObject;
import org.elasticsearch.xcontent.XContentBuilder;

import java.io.IOException;
import java.util.Date;
import java.util.Objects;

/**
 * Quantiles Result POJO
 */
public class Quantiles implements ToXContentObject {

    /**
     * Field Names
     */
    public static final ParseField TIMESTAMP = new ParseField("timestamp");
    public static final ParseField QUANTILE_STATE = new ParseField("quantile_state");

    public static final ConstructingObjectParser<Quantiles, Void> PARSER = new ConstructingObjectParser<>(
        "quantiles",
        true,
        a -> new Quantiles((String) a[0], (Date) a[1], (String) a[2])
    );

    static {
        PARSER.declareString(ConstructingObjectParser.constructorArg(), Job.ID);
        PARSER.declareField(ConstructingObjectParser.optionalConstructorArg(), p -> new Date(p.longValue()), TIMESTAMP, ValueType.LONG);
        PARSER.declareString(ConstructingObjectParser.constructorArg(), QUANTILE_STATE);
    }

    private final String jobId;
    private final Date timestamp;
    private final String quantileState;

    public Quantiles(String jobId, Date timestamp, String quantileState) {
        this.jobId = jobId;
        this.timestamp = Objects.requireNonNull(timestamp);
        this.quantileState = Objects.requireNonNull(quantileState);
    }

    @Override
    public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
        builder.startObject();
        builder.field(Job.ID.getPreferredName(), jobId);
        if (timestamp != null) {
            builder.field(TIMESTAMP.getPreferredName(), timestamp.getTime());
        }
        if (quantileState != null) {
            builder.field(QUANTILE_STATE.getPreferredName(), quantileState);
        }
        builder.endObject();
        return builder;
    }

    public String getJobId() {
        return jobId;
    }

    public Date getTimestamp() {
        return timestamp;
    }

    public String getQuantileState() {
        return quantileState;
    }

    @Override
    public int hashCode() {
        return Objects.hash(jobId, timestamp, quantileState);
    }

    /**
     * Compare all the fields.
     */
    @Override
    public boolean equals(Object other) {
        if (this == other) {
            return true;
        }

        if (other == null || getClass() != other.getClass()) {
            return false;
        }

        Quantiles that = (Quantiles) other;

        return Objects.equals(this.jobId, that.jobId)
            && Objects.equals(this.timestamp, that.timestamp)
            && Objects.equals(this.quantileState, that.quantileState);
    }
}


text:
<?php

namespace Symfony\Component\Process\Pipes;

/**
 * PipesInterface manages descriptors and pipes for the use of proc_open.
 *
 * @author Romain Neutron <imprec@gmail.com>
 *
 * @internal
 */
interface PipesInterface
{
    public const CHUNK_SIZE = 16384;

    /**
     * Returns an array of descriptors for the use of proc_open.
     */
    public function getDescriptors(): array;

    /**
     * Returns an array of filenames indexed by their related stream in case these pipes use temporary files.
     *
     * @return string[]
     */
    public function getFiles(): array;

    /**
     * Reads data in file handles and pipes.
     *
     * @param bool $blocking Whether to use blocking calls or not
     * @param bool $close    Whether to close pipes if they've reached EOF
     *
     * @return string[] An array of read data indexed by their fd
     */
    public function readAndWrite(bool $blocking, bool $close = false): array;

    /**
     * Returns if the current state has open file handles or pipes.
     */
    public function areOpen(): bool;

    /**
     * Returns if pipes are able to read output.
     */
    public function haveReadSupport(): bool;

    /**
     * Closes file handles and pipes.
     */
    public function close();
}