text:
package reactor.core.publisher;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import java.util.stream.Stream;

import org.awaitility.Awaitility;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DynamicContainer;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestFactory;
import reactor.core.scheduler.Schedulers;
import reactor.test.StepVerifier;
import reactor.test.StepVerifierOptions;
import reactor.test.subscriber.AssertSubscriber;

import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.DynamicContainer.dynamicContainer;
import static org.junit.jupiter.api.DynamicTest.dynamicTest;
import static reactor.core.publisher.Sinks.EmitFailureHandler.FAIL_FAST;

/**
 * @author Simon Baslé
 */
class SinksTest {

	@Test
	void oneIsSerialized() {
		assertThat(Sinks.one())
				.isInstanceOf(SinksSpecs.AbstractSerializedSink.class)
				.isExactlyInstanceOf(SinkOneSerialized.class);
	}

	@Test
	void emptyIsSerialized() {
		assertThat(Sinks.empty())
				.isInstanceOf(SinksSpecs.AbstractSerializedSink.class)
				.isExactlyInstanceOf(SinkEmptySerialized.class);
	}

	@Test
	void unsafeOneIsNotSerialized() {
		assertThat(Sinks.unsafe().one()).isNotInstanceOf(SinksSpecs.AbstractSerializedSink.class);
	}

	@Test
	void unsafeEmptyIsNotSerialized() {
		assertThat(Sinks.unsafe().empty()).isNotInstanceOf(SinksSpecs.AbstractSerializedSink.class);
	}

	@Nested
	class Multicast {

		//TODO Multicast has slightly different behavior with early onNext + onError : doesn't buffer elements for benefit of 1st subscriber
		//(this is a behavioral difference in EmitterProcessor)

		final Supplier<Sinks.Many<Integer>> supplier = () -> Sinks.many().multicast().onBackpressureBuffer(10);

		@TestFactory
		Stream<DynamicContainer> checkSemantics() {
			return Stream.of(
					expectMulticast(supplier, 10),
					expectReplay(supplier, NONE),
					dynamicContainer("buffers all before 1st subscriber, except for errors",
									 expectBufferingBeforeFirstSubscriber(supplier, ALL).getChildren().filter(dn -> !dn.getDisplayName().equals("replayAndErrorFirstSubscriber")))
			);
		}

		@Test
		void noReplayBeforeFirstSubscriberIfEarlyError() {
			Sinks.Many<Integer> sink = supplier.get();
			Flux<Integer> flux = sink.asFlux();
			AssertSubscriber<Integer> first = AssertSubscriber.create();

			sink.emitNext(1, FAIL_FAST);
			sink.emitNext(2, FAIL_FAST);
			sink.emitNext(3, FAIL_FAST);
			sink.emitError(new IllegalStateException("boom"), FAIL_FAST);
			flux.subscribe(first);

			first.assertNoValues()
			     .assertErrorMessage("boom");
		}
	}

	@Nested
	class MulticastReplayAll {

		final Supplier<Sinks.Many<Integer>> supplier = () -> Sinks.many().replay().all();

		@TestFactory
		Stream<DynamicContainer> checkSemantics() {
			return Stream.of(
					expectMulticast(supplier, Integer.MAX_VALUE),
					expectReplay(supplier, ALL),
					expectBufferingBeforeFirstSubscriber(supplier, ALL)
			);
		}
	}

	@Nested
	class OptimisticEmitFailureHandlerTest {
		@Test
		void shouldRetryOptimistically() {
			Sinks.One<Object> sink = new InternalOneSinkTest.InternalOneSinkAdapter<Object>() {
				final long duration = Duration.ofMillis(1000).toNanos() + System.nanoTime();
				@Override
				public Sinks.EmitResult tryEmitValue(Object value) {
					return System.nanoTime() > duration ? Sinks.EmitResult.OK : Sinks.EmitResult.FAIL_NON_SERIALIZED;
				}

				@Override
				public Sinks.EmitResult tryEmitEmpty() {
					throw new IllegalStateException();
				}

				@Override
				public Sinks.EmitResult tryEmitError(Throwable error) {
					throw new IllegalStateException();
				}
			};
			assertThatNoException().isThrownBy(() -> {
				sink.emitValue("Hello",
						Sinks.EmitFailureHandler.busyLooping(Duration.ofMillis(1000)));
			});
		}

		@Test
		void shouldFailRetryOptimistically() {
			Sinks.One<Object> sink = new InternalOneSinkTest.InternalOneSinkAdapter<Object>() {
				final long duration = Duration.ofMillis(1000).toNanos() + System.nanoTime();
				@Override
				public Sinks.EmitResult tryEmitValue(Object value) {
					return System.nanoTime() > duration ? Sinks.EmitResult.OK : Sinks.EmitResult.FAIL_NON_SERIALIZED;
				}

				@Override
				public Sinks.EmitResult tryEmitEmpty() {
					throw new IllegalStateException();
				}

				@Override
				public Sinks.EmitResult tryEmitError(Throwable error) {
					throw new IllegalStateException();
				}
			};
			assertThatExceptionOfType(Sinks.EmissionException.class).isThrownBy(() -> {
				sink.emitValue("Hello",
						Sinks.EmitFailureHandler.busyLooping(Duration.ofMillis(100)));
			});
		}
	}

	@Nested
	class MulticastReplayN {

		@Test
		void limitZeroIsRejected() {
			assertThatIllegalArgumentException()
				.isThrownBy(() -> Sinks.many().replay().limit(0))
				.withMessage("historySize must be > 0");
		}

		@TestFactory
		Stream<DynamicContainer> checkSemanticsSize5() {
			final int historySize = 5;
			final Supplier<Sinks.Many<Integer>> supplier = () -> Sinks.many().replay().limit(historySize);

			return Stream.of(
					expectMulticast(supplier, Integer.MAX_VALUE),
					expectReplay(supplier, historySize),
					expectBufferingBeforeFirstSubscriber(supplier, historySize)
			);
		}

		@TestFactory
		Stream<DynamicContainer> checkSemanticsSize100() {
			final int historySize = 100;
			final Supplier<Sinks.Many<Integer>> supplier = () -> Sinks.many().replay().limit(historySize);

			return Stream.of(
					expectMulticast(supplier, Integer.MAX_VALUE),
					expectReplay(supplier, historySize),
					expectBufferingBeforeFirstSubscriber(supplier, historySize)
			);
		}
	}

	@Nested
	class MulticastReplayDuration {

		final Duration            duration = Duration.ofMillis(1000);
		final int 				  event = 12;
		Sinks.Many<Integer>       replaySink;
		Flux<Integer>             flux;

		@BeforeEach
		void setup() {
			replaySink = Sinks.many().replay().limit(duration);
			flux = replaySink.asFlux();
		}

		@Test
		void historySizeZeroIsRejected() {
			assertThatIllegalArgumentException()
				.isThrownBy(() -> Sinks.many().replay().limit(0, Duration.ofSeconds(1)))
				.withMessage("historySize must be > 0");

			assertThatIllegalArgumentException()
				.isThrownBy(() -> Sinks.many().replay().limit(0, Duration.ofSeconds(1), Schedulers.immediate()))
				.withMessage("historySize must be > 0");
		}

		// fixes: https://github.com/reactor/reactor-core/issues/2513
		@Test
		void lateSubscriberReceivesEventInRetentionTime() {
			replaySink.emitNext(event, FAIL_FAST);

			StepVerifier.withVirtualTime(() -> flux, 0L)
					.thenAwait(duration.minusMillis(1))
					.thenRequest(1)
					.expectNext(event)
					.thenCancel()
					.verify(Duration.ofMillis(20));
		}

		// fixes: https://github.com/reactor/reactor-core/issues/2513
		@Test
		void lateSubscriberDoesntReceiveEventOutsideRetentionTime() {
			replaySink.emitNext(event, FAIL_FAST);

			StepVerifier.withVirtualTime(() -> flux, 0L)
					.thenAwait(duration.plusMillis(1))
					.thenRequest(1)
					.expectNoEvent(Duration.ofMillis(20))
					.thenCancel()
					.verify(Duration.ofMillis(20));
		}
	}

	@Nested
	class MulticastDirectBestEffort {

		final Supplier<Sinks.Many<Integer>> supplier = () -> Sinks.many().multicast().directBestEffort();

		@TestFactory
		Stream<DynamicContainer> checkSemantics() {
			return Stream.of(
					expectMulticast(supplier, 0, true),
					expectReplay(supplier, NONE)
			);
		}
	}

	@Nested
	class MulticastDirectAllOrNothing {

		final Supplier<Sinks.Many<Integer>> supplier = () -> Sinks.many().multicast().directAllOrNothing();

		@TestFactory
		Stream<DynamicContainer> checkSemantics() {
			return Stream.of(
					expectMulticast(supplier, 0),
					expectReplay(supplier, NONE)
			);
		}
	}

	@Nested
	class Unicast {

		final Supplier<Sinks.Many<Integer>> supplier = () -> Sinks.many().unicast().onBackpressureBuffer();

		@TestFactory
		Stream<DynamicContainer> checkSemantics() {
			return Stream.of(
					expectUnicast(supplier),
					expectBufferingBeforeFirstSubscriber(supplier, ALL)
			);
		}
	}

	@Nested
	class SingleOrEmpty {

		Sinks.One<Integer> singleOrEmpty;
		Mono<Integer>      mono;

		@BeforeEach
		void createSingleOrEmpty() {
			singleOrEmpty = Sinks.one();
			mono = singleOrEmpty.asMono();
		}

		//TODO racing dual completions ?

		@Test
		void singleOrEmptyIsCompletableOnlyOnce_emptyVsValued() {
			StepVerifier.create(mono)
						.then(() -> {
							singleOrEmpty.emitValue(null, FAIL_FAST);
							singleOrEmpty.emitValue(-1, FAIL_FAST);
						})
						.expectComplete()
						.verifyThenAssertThat()
						.hasDropped(-1);
		}

		@Test
		void singleOrEmptyIsCompletableOnlyOnce_emptyVsError() {
			StepVerifier.create(mono)
						.then(() -> {
							singleOrEmpty.emitEmpty(FAIL_FAST);
							singleOrEmpty.emitError(new IllegalStateException("boom"), FAIL_FAST);
						})
						.expectComplete()
						.verifyThenAssertThat()
						.hasDroppedErrorWithMessage("boom");
		}

		@Test
		void singleOrEmptyIsCompletableOnlyOnce_valuedVsEmpty() {
			StepVerifier.create(mono)
						.then(() -> {
							singleOrEmpty.emitValue(1, FAIL_FAST);
							singleOrEmpty.emitValue(null, FAIL_FAST);
						})
						.expectNext(1)
						.expectComplete()
						.verifyThenAssertThat()
						.hasNotDroppedElements();
		}

		@Test
		void singleOrEmptyIsCompletableOnlyOnce_valuedVsError() {
			StepVerifier.create(mono)
						.then(() -> {
							singleOrEmpty.emitValue(1, FAIL_FAST);
							singleOrEmpty.emitError(new IllegalStateException("boom"), FAIL_FAST);
						})
						.expectNext(1)
						.expectComplete()
						.verifyThenAssertThat()
						.hasDroppedErrorWithMessage("boom");
		}

		@Test
		void singleOrEmptyIsCompletableOnlyOnce_errorVsValued() {
			StepVerifier.create(mono)
						.then(() -> {
							singleOrEmpty.emitError(new IllegalStateException("boom"), FAIL_FAST);
							singleOrEmpty.emitValue(-1, FAIL_FAST);
						})
						.expectErrorMessage("boom")
						.verifyThenAssertThat()
						.hasDropped(-1);
		}

		@Test
		void singleOrEmptyIsCompletableOnlyOnce_errorVsEmpty() {
			StepVerifier.create(mono)
						.then(() -> {
							singleOrEmpty.emitError(new IllegalStateException("boom"), FAIL_FAST);
							singleOrEmpty.emitEmpty(FAIL_FAST);
						})
						.expectErrorMessage("boom")
						.verifyThenAssertThat()
						.hasNotDroppedElements()
						.hasNotDroppedErrors();
		}

		@Test
		void canBeValuedEarly() {
			singleOrEmpty.emitValue(1, FAIL_FAST);

			StepVerifier.create(mono)
						.expectNext(1)
						.verifyComplete();
		}

		@Test
		void canBeCompletedEarly() {
			singleOrEmpty.emitEmpty(FAIL_FAST);

			StepVerifier.create(mono)
						.verifyComplete();
		}

		@Test
		void canBeErroredEarly() {
			singleOrEmpty.emitError(new IllegalStateException("boom"), FAIL_FAST);

			StepVerifier.create(mono)
						.verifyErrorMessage("boom");
		}

		@Test
		void canBeValuedLate() {
			StepVerifier.create(mono)
						.expectSubscription()
						.expectNoEvent(Duration.ofMillis(100))
						.then(() -> singleOrEmpty.emitValue(1, FAIL_FAST))
						.expectNext(1)
						.verifyComplete();
		}

		@Test
		void canBeCompletedLate() {
			StepVerifier.create(mono)
						.expectSubscription()
						.expectNoEvent(Duration.ofMillis(100))
						.then(() -> singleOrEmpty.emitEmpty(FAIL_FAST))
						.verifyComplete();
		}

		@Test
		void canBeErroredLate() {
			StepVerifier.create(mono)
						.expectSubscription()
						.expectNoEvent(Duration.ofMillis(100))
						.then(() -> singleOrEmpty.emitError(new IllegalStateException("boom"), FAIL_FAST))
						.verifyErrorMessage("boom");
		}

		@Test
		void replaysValuedCompletionToLateSubscribersWithBackpressure() {
			singleOrEmpty.emitValue(1, FAIL_FAST);
			mono.subscribe(); //first subscriber

			StepVerifier.create(mono, StepVerifierOptions.create()
														 .scenarioName("second subscriber, no backpressure"))
						.expectNext(1)
						.verifyComplete();

			StepVerifier.create(mono, StepVerifierOptions.create()
														 .scenarioName("third subscriber, backpressure")
														 .initialRequest(0))
						.expectSubscription()
						.expectNoEvent(Duration.ofMillis(100))
						.thenRequest(1)
						.expectNext(1)
						.verifyComplete();
		}

		@Test
		void replaysEmptyCompletionToLateSubscribersEvenWithoutRequest() {
			singleOrEmpty.emitEmpty(FAIL_FAST);
			mono.subscribe(); //first subscriber

			StepVerifier.create(mono, StepVerifierOptions.create()
														 .scenarioName("second subscriber, no backpressure"))
						.verifyComplete();

			StepVerifier.create(mono, StepVerifierOptions.create()
														 .scenarioName("third subscriber, 0 request")
														 .initialRequest(0))
						.expectSubscription()
						//notice no expectNoEvent / request here
						.verifyComplete();
		}

		@Test
		void replaysErrorCompletionToLateSubscribers() {
			singleOrEmpty.emitError(new IllegalStateException("boom"), FAIL_FAST);
			mono.subscribe(); //first subscriber

			StepVerifier.create(mono, StepVerifierOptions.create()
														 .scenarioName("second subscriber, no backpressure"))
						.verifyErrorMessage("boom");

			StepVerifier.create(mono, StepVerifierOptions.create()
														 .scenarioName("third subscriber, 0 request")
														 .initialRequest(0))
						.expectSubscription()
						//notice no expectNoEvent / request here
						.verifyErrorMessage("boom");
		}
	}

	private static final int NONE = 0;
	private static final int ALL = Integer.MAX_VALUE;

	DynamicContainer expectMulticast(Supplier<Sinks.Many<Integer>> sinkSupplier, int acceptableDifference) {
		return expectMulticast(sinkSupplier, acceptableDifference, false);
	}

	DynamicContainer expectMulticast(Supplier<Sinks.Many<Integer>> sinkSupplier, int acceptableDifference, boolean dropForSlow) {
		return dynamicContainer("multicast", Stream.of(

				dynamicTest("fluxViewReturnsSameInstance", () -> {
					Sinks.Many<Integer> sink = sinkSupplier.get();
					Flux<Integer> flux = sink.asFlux();

					assertThat(flux).isSameAs(sink.asFlux());
				}),

				dynamicTest("acceptsMoreThanOneSubscriber", () -> {
					Flux<Integer> flux = sinkSupplier.get()
													 .asFlux();
					assertThatCode(() -> {
						flux.subscribe();
						flux.subscribe();
					}).doesNotThrowAnyException();
				}),

				dynamicTest("honorsMultipleSubscribersBackpressure", () -> {
					Sinks.Many<Integer> sink = sinkSupplier.get();
					Flux<Integer> flux = sink.asFlux();
					ExecutorService es = Executors.newFixedThreadPool(2);

					try {
						CountDownLatch requestLatch = new CountDownLatch(2);
						final Future<?> f1 = es.submit(() -> {
							AssertSubscriber<Integer> test1 = AssertSubscriber.create(2);
							flux.subscribe(test1);
							test1.assertNoValues();
							requestLatch.countDown();

							int expectedCount = (dropForSlow || acceptableDifference > 0) ? 2 : 1;

							if (expectedCount == 2) {
								test1.awaitAndAssertNextValues(1, 2);
							}
							else {
								test1.awaitAndAssertNextValues(1);
							}
							try {
								Awaitility.await()
										  .atMost(2, TimeUnit.SECONDS)
										  .with()
										  .pollDelay(1, TimeUnit.SECONDS)
										  .untilAsserted(() -> test1.assertValueCount(expectedCount));
							}
							finally {
								test1.cancel();
							}
						});
						final Future<?> f2 = es.submit(() -> {
							AssertSubscriber<Integer> test2 = AssertSubscriber.create(1);
							flux.subscribe(test2);
							requestLatch.countDown();

							test2.awaitAndAssertNextValues(1);
							try {
								Awaitility.await()
										  .atMost(2, TimeUnit.SECONDS)
										  .with()
										  .pollDelay(1, TimeUnit.SECONDS)
										  .untilAsserted(() -> test2.assertValueCount(1));
							}
							finally {
								test2.cancel();
							}
						});

						requestLatch.await(1, TimeUnit.SECONDS);
						Sinks.EmitResult expectedFor2 = (!dropForSlow && acceptableDifference < 1) ?
								Sinks.EmitResult.FAIL_OVERFLOW  :
								Sinks.EmitResult.OK;
						Sinks.EmitResult expectedFor3 = acceptableDifference < 2 ?
								Sinks.EmitResult.FAIL_OVERFLOW  :
								Sinks.EmitResult.OK;
						Sinks.EmitResult expectedFor4 = acceptableDifference < 3 ?
								Sinks.EmitResult.FAIL_OVERFLOW  :
								Sinks.EmitResult.OK;

						assertThat(sink.tryEmitNext(1)).as("tryEmitNext(1)").isEqualTo(Sinks.EmitResult.OK);
						assertThat(sink.tryEmitNext(2)).as("tryEmitNext(2)").isEqualTo(expectedFor2);
						assertThat(sink.tryEmitNext(3)).as("tryEmitNext(3)").isEqualTo(expectedFor3);
						assertThat(sink.tryEmitNext(4)).as("tryEmitNext(4)").isEqualTo(expectedFor4);
						assertThat(sink.tryEmitComplete()).as("tryEmitComplete()").isEqualTo(Sinks.EmitResult.OK);

						f1.get();
						f2.get();
					}
					finally {
						es.shutdownNow();
					}
				})
		));
	}

	DynamicContainer expectUnicast(Supplier<Sinks.Many<Integer>> sinkSupplier) {
		return dynamicContainer("unicast", Stream.of(

				dynamicTest("fluxViewReturnsSameInstance", () -> {
					Sinks.Many<Integer> sink = sinkSupplier.get();
					Flux<Integer> flux = sink.asFlux();

					assertThat(flux).isSameAs(sink.asFlux());
				}),

				dynamicTest("acceptsOnlyOneSubscriber", () -> {
					Sinks.Many<Integer> sink = sinkSupplier.get();
					Flux<Integer> flux = sink.asFlux();
					sink.emitComplete(FAIL_FAST);

					assertThatCode(flux::subscribe).doesNotThrowAnyException();
					StepVerifier.create(flux)
								.verifyErrorSatisfies(e -> assertThat(e)
									.hasMessage("Sinks.many().unicast() sinks only allow a single Subscriber"));
				}),

				dynamicTest("honorsSubscriberBackpressure", () -> {
					Sinks.Many<Integer> sink = sinkSupplier.get();
					Flux<Integer> flux = sink.asFlux();
					ExecutorService es = Executors.newFixedThreadPool(2);

					try {
						CountDownLatch requestLatch = new CountDownLatch(1);
						final Future<?> future = es.submit(() -> {
							AssertSubscriber<Integer> test = AssertSubscriber.create(2);
							flux.subscribe(test);
							test.assertNoValues();
							requestLatch.countDown();

							test.awaitAndAssertNextValues(1, 2);
							try {
								Awaitility.await()
										  .atMost(2, TimeUnit.SECONDS)
										  .with()
										  .pollDelay(1, TimeUnit.SECONDS)
										  .untilAsserted(() -> test.assertValueCount(2));
							}
							finally {
								test.cancel();
							}
						});

						requestLatch.await(1, TimeUnit.SECONDS);
						sink.emitNext(1, FAIL_FAST);
						sink.emitNext(2, FAIL_FAST);
						sink.emitNext(3, FAIL_FAST);
						sink.emitNext(4, FAIL_FAST);
						sink.emitComplete(FAIL_FAST);

						future.get();
					}
					finally {
						es.shutdownNow();
					}
				})));
	}

	DynamicContainer expectReplay(Supplier<Sinks.Many<Integer>> sinkSupplier, int expectedReplay) {
		if (expectedReplay == NONE) {
			DynamicTest doesNotReplayToLateSubscribers = dynamicTest("doesNotReplayToLateSubscribers", () -> {
				Sinks.Many<Integer> sink = sinkSupplier.get();
				Flux<Integer> flux = sink.asFlux();
				AssertSubscriber<Integer> s1 = AssertSubscriber.create();
				AssertSubscriber<Integer> s2 = AssertSubscriber.create();

				flux.subscribe(s1);
				sink.emitNext(1, FAIL_FAST);
				sink.emitNext(2, FAIL_FAST);
				sink.emitNext(3, FAIL_FAST);
				s1.assertValues(1, 2, 3);

				flux.subscribe(s2);
				s2.assertNoValues()
				  .assertNotComplete();

				sink.emitComplete(FAIL_FAST);
				s1.assertValueCount(3)
				  .assertComplete();
				s2.assertNoValues()
				  .assertComplete();
			});

			DynamicTest immediatelyCompleteLateSubscriber = dynamicTest("immediatelyCompleteLateSubscriber", () -> {
				Sinks.Many<Integer> sink = sinkSupplier.get();
				Flux<Integer> flux = sink.asFlux();

				flux.subscribe(); //first subscriber
				AssertSubscriber<Integer> late = AssertSubscriber.create();

				sink.emitNext(1, FAIL_FAST);
				sink.emitComplete(FAIL_FAST);
				flux.subscribe(late);

				late.assertNoValues()
					.assertComplete();
			});

			DynamicTest immediatelyErrorLateSubscriber = dynamicTest("immediatelyErrorLateSubscriber", () -> {
				Sinks.Many<Integer> sink = sinkSupplier.get();
				Flux<Integer> flux = sink.asFlux();

				flux.onErrorReturn(-1)
					.subscribe(); //first subscriber, ignore errors
				AssertSubscriber<Integer> late = AssertSubscriber.create();

				sink.emitNext(1, FAIL_FAST);
				sink.emitError(new IllegalStateException("boom"), FAIL_FAST);
				flux.subscribe(late);

				late.assertNoValues()
					.assertErrorMessage("boom");
			});

			return dynamicContainer("no replay", Stream.of(
					doesNotReplayToLateSubscribers,
					immediatelyCompleteLateSubscriber,
					immediatelyErrorLateSubscriber
			));
		}
		else if (expectedReplay == ALL) {
			return dynamicContainer("replays all", Stream.of(dynamicTest("doesReplayAllToLateSubscribers", () -> {
																 Sinks.Many<Integer>
																		 sink = sinkSupplier.get();
																 Flux<Integer> flux = sink.asFlux();
																 AssertSubscriber<Integer> s1 = AssertSubscriber.create();
																 AssertSubscriber<Integer> s2 = AssertSubscriber.create();

																 flux.subscribe(s1);
																 sink.emitNext(1, FAIL_FAST);
																 sink.emitNext(2, FAIL_FAST);
																 sink.emitNext(3, FAIL_FAST);
																 s1.assertValues(1, 2, 3);

																 flux.subscribe(s2);
																 s2.assertValues(1, 2, 3)
																   .assertNotComplete();

																 sink.emitComplete(FAIL_FAST);
																 s1.assertValueCount(3)
																   .assertComplete();
																 s2.assertValues(1, 2, 3)
																   .assertComplete();
															 }),

															 dynamicTest("immediatelyCompleteLateSubscriber", () -> {
																 Sinks.Many<Integer>
																		 sink = sinkSupplier.get();
																 Flux<Integer> flux = sink.asFlux();
															 }),

															 dynamicTest("immediatelyErrorLateSubscriber", () -> {
																 Sinks.Many<Integer>
																		 sink = sinkSupplier.get();
																 Flux<Integer> flux = sink.asFlux();
															 })));
		}
		else {
			return dynamicContainer("replays " + expectedReplay, Stream.of(dynamicTest("doesReplay" + expectedReplay + "ToLateSubscribers", () -> {
																			   Sinks.Many<Integer>
																					   sink = sinkSupplier.get();
																			   Flux<Integer> flux = sink.asFlux();
																			   AssertSubscriber<Integer> s1 = AssertSubscriber.create();
																			   AssertSubscriber<Integer> s2 = AssertSubscriber.create();

																			   flux.subscribe(s1);
																			   List<Integer> expected = new ArrayList<>();
																			   for (int i = 0; i < expectedReplay + 10; i++) {
																				   sink.emitNext(i, FAIL_FAST);
																				   if (i >= 10)
																					   expected.add(i);
																			   }
																			   s1.assertValueCount(expectedReplay + 10);

																			   flux.subscribe(s2);
																			   s2.assertValueSequence(expected)
																				 .assertNotComplete();

																			   sink.emitComplete(FAIL_FAST);
																			   s1.assertValueCount(expectedReplay + 10)
																				 .assertComplete();
																			   s2.assertValueSequence(expected)
																				 .assertComplete();
																		   }),

																		   dynamicTest("replay" + expectedReplay + "AndCompleteLateSubscriber", () -> {
																			   Sinks.Many<Integer>
																					   sink = sinkSupplier.get();
																			   Flux<Integer> flux = sink.asFlux();
																			   flux.subscribe(); //first
																			   AssertSubscriber<Integer> late = AssertSubscriber.create();

																			   List<Integer> expected = new ArrayList<>();
																			   for (int i = 0; i < expectedReplay + 10; i++) {
																				   sink.emitNext(i, FAIL_FAST);
																				   if (i >= 10)
																					   expected.add(i);
																			   }
																			   sink.emitComplete(FAIL_FAST);
																			   flux.subscribe(late);

																			   late.assertValueSequence(expected)
																				   .assertComplete();
																		   }),

																		   dynamicTest("replay" + expectedReplay + "AndErrorLateSubscriber", () -> {
																			   Sinks.Many<Integer>
																					   sink = sinkSupplier.get();
																			   Flux<Integer> flux = sink.asFlux();
																			   flux.onErrorReturn(-1)
																				   .subscribe(); //first subscriber, ignore errors
																			   AssertSubscriber<Integer> late = AssertSubscriber.create();

																			   List<Integer> expected = new ArrayList<>();
																			   for (int i = 0; i < expectedReplay + 10; i++) {
																				   sink.emitNext(i, FAIL_FAST);
																				   if (i >= 10)
																					   expected.add(i);
																			   }
																			   sink.emitError(new IllegalStateException("boom"), FAIL_FAST);
																			   flux.subscribe(late);

																			   late.assertValueSequence(expected)
																				   .assertErrorMessage("boom");
																		   })));
		}
	}

	DynamicContainer expectBufferingBeforeFirstSubscriber(Supplier<Sinks.Many<Integer>> sinkSupplier, int expectedBuffering) {
		if (expectedBuffering == NONE) {
			return dynamicContainer("no buffering before 1st subscriber", Stream.of(dynamicTest("doesNotBufferBeforeFirstSubscriber", () -> {
				Sinks.Many<Integer> sink = sinkSupplier.get();
				Flux<Integer> flux = sink.asFlux();
				AssertSubscriber<Integer> first = AssertSubscriber.create();

				sink.emitNext(1, FAIL_FAST);
				sink.emitNext(2, FAIL_FAST);
				sink.emitNext(3, FAIL_FAST);
				flux.subscribe(first);

				first.assertNoValues()
					 .assertNotComplete();

				sink.emitComplete(FAIL_FAST);
				first.assertNoValues()
					 .assertComplete();
			}), dynamicTest("immediatelyCompleteFirstSubscriber", () -> {
				Sinks.Many<Integer> sink = sinkSupplier.get();
				Flux<Integer> flux = sink.asFlux();
				AssertSubscriber<Integer> first = AssertSubscriber.create();

				sink.emitNext(1, FAIL_FAST);
				sink.emitComplete(FAIL_FAST);
				flux.subscribe(first);

				first.assertNoValues()
					 .assertComplete();
			}), dynamicTest("immediatelyErrorFirstSubscriber", () -> {
				Sinks.Many<Integer> sink = sinkSupplier.get();
				Flux<Integer> flux = sink.asFlux();
				AssertSubscriber<Integer> first = AssertSubscriber.create();

				sink.emitNext(1, FAIL_FAST);
				sink.emitError(new IllegalStateException("boom"), FAIL_FAST);
				flux.subscribe(first);

				first.assertNoValues()
					 .assertErrorMessage("boom");
			})));
		}
		else if (expectedBuffering == ALL) {
			return dynamicContainer("buffers all before 1st subscriber", Stream.of(dynamicTest("doesBufferBeforeFirstSubscriber", () -> {
																					   Sinks.Many<Integer>
																							   sink = sinkSupplier.get();
																					   Flux<Integer> flux = sink.asFlux();
																					   AssertSubscriber<Integer> first = AssertSubscriber.create();

																					   sink.emitNext(1, FAIL_FAST);
																					   sink.emitNext(2, FAIL_FAST);
																					   sink.emitNext(3, FAIL_FAST);
																					   flux.subscribe(first);

																					   first.assertValues(1, 2, 3)
																							.assertNotComplete();

																					   sink.emitComplete(FAIL_FAST);
																					   first.assertComplete();
																				   }),

																				   dynamicTest("replayAndCompleteFirstSubscriber", () -> {
																					   Sinks.Many<Integer>
																							   sink = sinkSupplier.get();
																					   Flux<Integer> flux = sink.asFlux();
																					   AssertSubscriber<Integer> first = AssertSubscriber.create();

																					   sink.emitNext(1, FAIL_FAST);
																					   sink.emitComplete(FAIL_FAST);
																					   flux.subscribe(first);

																					   first.assertValues(1)
																							.assertComplete();
																				   }),

																				   dynamicTest("replayAndErrorFirstSubscriber", () -> {
																					   Sinks.Many<Integer>
																							   sink = sinkSupplier.get();
																					   Flux<Integer> flux = sink.asFlux();
																					   AssertSubscriber<Integer> first = AssertSubscriber.create();

																					   sink.emitNext(1, FAIL_FAST);
																					   sink.emitNext(2, FAIL_FAST);
																					   sink.emitNext(3, FAIL_FAST);
																					   sink.emitError(new IllegalStateException("boom"), FAIL_FAST);
																					   flux.subscribe(first);

																					   first.assertValues(1, 2, 3)
																							.assertErrorMessage("boom");
																				   })));
		}
		else {
			return dynamicContainer("buffers " + expectedBuffering + " before 1st subscriber", Stream.of(dynamicTest("doesBuffer" + expectedBuffering + "BeforeFirstSubscriber", () -> {
				Sinks.Many<Integer> sink = sinkSupplier.get();
				Flux<Integer> flux = sink.asFlux();
				AssertSubscriber<Integer> first = AssertSubscriber.create();

				List<Integer> expected = new ArrayList<>();
				for (int i = 0; i < 10 + expectedBuffering; i++) {
					sink.emitNext(i, FAIL_FAST);
					if (i >= 10) {
						expected.add(i);
					}
				}
				flux.subscribe(first);

				first.assertValueSequence(expected)
					 .assertNotComplete();

				sink.emitComplete(FAIL_FAST);
				first.assertValueSequence(expected)
					 .assertComplete();
			}), dynamicTest("replayLimitedHistoryAndCompleteFirstSubscriber", () -> {
				Sinks.Many<Integer> sink = sinkSupplier.get();
				Flux<Integer> flux = sink.asFlux();
				AssertSubscriber<Integer> first = AssertSubscriber.create();

				List<Integer> expected = new ArrayList<>();
				for (int i = 0; i < 10 + expectedBuffering; i++) {
					sink.emitNext(i, FAIL_FAST);
					if (i >= 10) {
						expected.add(i);
					}
				}
				sink.emitComplete(FAIL_FAST);
				flux.subscribe(first);

				first.assertValueSequence(expected)
					 .assertComplete();
			}), dynamicTest("replayLimitedHistoryAndErrorFirstSubscriber", () -> {
				Sinks.Many<Integer> sink = sinkSupplier.get();
				Flux<Integer> flux = sink.asFlux();
				AssertSubscriber<Integer> first = AssertSubscriber.create();

				List<Integer> expected = new ArrayList<>();
				for (int i = 0; i < 10 + expectedBuffering; i++) {
					sink.emitNext(i, FAIL_FAST);
					if (i >= 10) {
						expected.add(i);
					}
				}
				sink.emitError(new IllegalStateException("boom"), FAIL_FAST);
				flux.subscribe(first);

				first.assertValueSequence(expected)
					 .assertErrorMessage("boom");
			})));
		}
	}

}


text:
package ai.elimu.dao;

import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import ai.elimu.model.content.Number;
import ai.elimu.model.content.Word;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={
    "file:src/main/webapp/WEB-INF/spring/applicationContext.xml",
    "file:src/main/webapp/WEB-INF/spring/applicationContext-jpa.xml"
})
public class NumberDaoTest {

    private Logger logger = LogManager.getLogger();

    @Autowired
    private NumberDao numberDao;

    @Autowired
    private WordDao wordDao;

    @Test
    public void testCreate_multipleWords() {
        Word wordTwenty = new Word();
        wordTwenty.setText("twenty");
        wordDao.create(wordTwenty);

        Word wordFour = new Word();
        wordFour.setText("four");
        wordDao.create(wordFour);

        List<Word> numberWords = new ArrayList<>();
        numberWords.add(wordTwenty);
        numberWords.add(wordFour);

        Number number24 = new Number();
        number24.setValue(24);
        number24.setWords(numberWords);
        numberDao.create(number24);

        assertThat(numberDao.read(number24.getId()).getWords().isEmpty(), is(false));
        assertThat(numberDao.read(number24.getId()).getWords().size(), is(2));
        assertThat(numberDao.read(number24.getId()).getWords().get(0).getText(), is("twenty"));
        assertThat(numberDao.read(number24.getId()).getWords().get(1).getText(), is("four"));
    }

    @Test
    public void testReadAllOrdered() {
        numberDao.create(getNumber(22));
        numberDao.create(getNumber(1));
        numberDao.create(getNumber(100));
        numberDao.create(getNumber(23));
        numberDao.create(getNumber(90));

        List<Number> allNumbers = numberDao.readAllOrdered();
        assertThat(allNumbers.isEmpty(), is(false));
        assertThat(allNumbers.size() >= 5, is(true));
        Number previousNumber = null;
        for (Number number: allNumbers) {
            logger.info("number.getValue(): " + number.getValue());
            if (previousNumber != null) {
                assertTrue(number.getValue() > previousNumber.getValue());
            }
            previousNumber = number;
        }
    }

    @Test
    public void testReadByValue() {
        numberDao.create(getNumber(25));
        assertTrue(numberDao.readByValue(25).getValue() == 25);
        assertNull(numberDao.readByValue(11));
    }

    private Number getNumber(Integer value) {
        Number number = new Number();
        number.setValue(value);
        return number;
    }
}

redpajama_set_name: RedPajamaGithub


text:
package org.locke.superkit.ui.javafx.graphics;

import java.util.Objects;

import javafx.geometry.Insets;
import javafx.scene.layout.Border;
import javafx.scene.layout.BorderStroke;
import javafx.scene.layout.BorderStrokeStyle;
import javafx.scene.layout.BorderWidths;
import javafx.scene.layout.CornerRadii;

public class Margin
{
    public static Margin NONE = of(0);

    public static Margin bottom(final int bottom)
    {
        return new Margin(bottom, 0, 0, 0);
    }

    public static Margin horizontal(final int width)
    {
        return new Margin(0, width, 0, width);
    }

    public static Margin left(final int left)
    {
        return new Margin(0, left, 0, 0);
    }

    public static Margin of(final int width)
    {
        return new Margin(width, width, width, width);
    }

    public static Margin of(final int bottom, final int left, final int top, final int right)
    {
        return new Margin(bottom, left, top, right);
    }

    public static Margin right(final int right)
    {
        return new Margin(0, 0, 0, right);
    }

    public static Margin top(final int top)
    {
        return new Margin(0, 0, top, 0);
    }

    public static Margin vertical(final int width)
    {
        return new Margin(width, 0, width, 0);
    }

    private final int bottom;
    private final int left;
    private final int top;
    private final int right;

    public Margin(final int bottom, final int left, final int top, final int right)
    {
        this.bottom = bottom;
        this.left = left;
        this.top = top;
        this.right = right;
    }

    public Border asBorder(final Color color)
    {
        return new Border(new BorderStroke(color.asJava(), BorderStrokeStyle.SOLID, CornerRadii.EMPTY,
                new BorderWidths(this.top, this.right, this.bottom, this.left)));
    }

    public Border asEmptyBorder()
    {
        return new Border(new BorderStroke(Color.TRANSPARENT.asJava(), BorderStrokeStyle.NONE, CornerRadii.EMPTY,
                new BorderWidths(this.top, this.right, this.bottom, this.left)));
    }

    public Insets asInsets()
    {
        return new Insets(this.top, this.right, this.bottom, this.left);
    }

    public int bottom()
    {
        return this.bottom;
    }

    @Override
    public boolean equals(final Object object)
    {
        if (object instanceof Margin)
        {
            final Margin that = (Margin) object;
            return bottom() == that.bottom() && left() == that.left() && top() == that.top() && right() == that.right();
        }
        return false;
    }

    @Override
    public int hashCode()
    {
        return Objects.hash(bottom(), left(), top(), right());
    }

    public int left()
    {
        return this.left;
    }

    public int right()
    {
        return this.right;
    }

    public int top()
    {
        return this.top;
    }
}


text:
"""Kvaser USB CAN driver interface

This moduel extends the basedriver.BaseDriver class from `basedriver.py`
to provide an interface to the Kvaser CAN USB products.  Note this has
only been tested using a Kvaser Leaf Lite

Operating System:
    * Windows XP +
Hardware Requirements:
    * Kvaser (http://www.kvaser.com/en/products/can/usb.html)
Driver Requirements:
    * See Kvaser's website for the latest
"""
import sys
import Queue
import threading
import basedriver
import time
from pycan.common import CANMessage
from ctypes import *

CAN_TX_TIMEOUT = 100  # ms
CAN_RX_TIMEOUT = 100  # ms
MAX_BUFFER_SIZE = 1000
QUEUE_DELAY = 1  # second

class Kvaser(basedriver.BaseDriverAPI):
    def __init__(self, **kwargs):
        # Init the Leaf Light HS DLL
        windll.canlib32.canInitializeLibrary()

        # Open a CAN communication channel
        # TODO: Add multi channel support
        self._can_channel = windll.canlib32.canOpenChannel(c_int(0), c_int8(0))

        # Bus on and clear the hardware queues
        windll.canlib32.canBusOn(c_int(self._can_channel))
        windll.canlib32.canFlushReceiveQueue(c_int(self._can_channel))
        windll.canlib32.canFlushTransmitQueue(c_int(self._can_channel))

        # Set the default paramters
        self.update_bus_parameters()

        # Build the inbound and output buffers
        self.inbound = Queue.Queue(MAX_BUFFER_SIZE)
        self.inbound_count = 0
        self.outbound = Queue.Queue(MAX_BUFFER_SIZE)
        self.outbound_count = 0

        # Tell python to check for signals less often (default 1000)
        #   - This yeilds better threading performance for timing
        #     accuracy
        sys.setcheckinterval(10000)

        self._running = threading.Event()
        self._running.set()
        self.ob_t = self.start_daemon(self.__process_outbound_queue)
        self.ib_t = self.start_daemon(self.__process_inbound_queue)

    def update_bus_parameters(self, **kwargs):
        # Default values are setup for a 250k baud and a 75% sample point
        # Set up the timing parameters for the CAN controller
        windll.canlib32.canSetBusParams(c_int(self._can_channel),
                                        c_int(kwargs.get("baud", 250000)),
                                        c_uint(kwargs.get("tseg1", 5)),
                                        c_uint(kwargs.get("tseg2", 2)),
                                        c_uint(kwargs.get("sjw", 2)),
                                        c_uint(kwargs.get("sample_count", 1)),
                                        c_uint(0))
    def shutdown(self):
        self._running.clear()
        time.sleep(1)
        sys.exit()

    def send(self, message):
        while 1:
            try:
                self.outbound.put(message, timeout=QUEUE_DELAY)
                self.outbound_count += 1
                return True
            except Queue.Full:
                pass

    def next_message(self, timeout=None):
        if timeout is not None:
            stop = time.time() + timeout
        while 1:
            try:
                new_msg = self.inbound.get(timeout=QUEUE_DELAY)
                self.inbound_count += 1
                return new_msg
            except Queue.Empty:
                pass

            if timeout is not None:
                if time.time() > stop:
                    return None

    def life_time_sent(self):
        return self.outbound_count

    def life_time_received(self):
        return self.inbound_count

    def __process_outbound_queue(self):
        while self._running.is_set():
            try:
                can_msg = self.outbound.get(timeout=QUEUE_DELAY)
            except Queue.Empty:
                continue

            tx_data = (c_uint8 * can_msg.dlc)()
            for x in range(can_msg.dlc):
                tx_data[x] = can_msg.payload[x]

            if can_msg.extended:
                ext = 4
            else:
                ext = 2

            status = windll.canlib32.canWriteWait(c_int(self._can_channel),
                                                  c_uint32(can_msg.id),
                                                  pointer(tx_data),
                                                  c_int(can_msg.dlc),
                                                  c_int(ext),
                                                  c_uint32(CAN_TX_TIMEOUT))
        # TODO: Flag error status

    def __process_inbound_queue(self):
        while self._running.is_set():
            rx_id = c_uint(0)
            rx_dlc = c_uint(0)
            rx_flags = c_uint(0)
            rx_time = c_uint(0)
            rx_msg = (c_uint8 * 8)()

            status = windll.canlib32.canReadWait(c_int(self._can_channel),
                                                 pointer(rx_id),
                                                 pointer(rx_msg),
                                                 pointer(rx_dlc),
                                                 pointer(rx_flags),
                                                 pointer(rx_time),
                                                 c_uint32(CAN_RX_TIMEOUT))
            if status < 0:
                pass
                #TODO: Flag errors

            else:
                # Determine if it is 11bit or 29bit
                if (rx_flags.value >> 1) & 0x01:
                    rx_ext = False
                elif (rx_flags.value >> 2) & 0x01:
                    rx_ext = True
                else:
                    rx_ext = None

                if rx_ext is not None:
                    # Build the message
                    new_msg = CANMessage(rx_id.value, rx_msg, rx_ext)

                    try:
                        self.inbound.put(new_msg, timeout=QUEUE_DELAY)
                    except Queue.Full:
                        # TODO: flag error
                        pass


text:
"use static"

var gulp = require('gulp'),
    fs = require('fs'),
    babel = require('gulp-babel'),
    rename = require('gulp-rename'),
    _ = require('underscore');

// =============== file path =================
var featuresPath = './features/';
var buildPath = './build/';
var compileFiles = featuresPath + '/*.js';
var execFileName = 'index.js';

// =============== compile es6 file ================
gulp.task('es5', function(){
    var fileList = fs.readdirSync(featuresPath);

    _.each(fileList, function(v, k){
        gulp.src(featuresPath + v)
            .pipe(babel({compact:false}))
            .pipe(rename(v.replace(/\.js/, '') + '_build.js'))
            .pipe(gulp.dest(buildPath));
    });
});

// =============== default gulp task ===============
gulp.task('default', ['es5']);


text:
package dotty.tools
package dotc
package semanticdb

import core._
import Contexts._
import Symbols._
import Flags._
import Names.Name

import scala.annotation.tailrec
import scala.collection.mutable

class SemanticSymbolBuilder:
  import Scala3.{_, given}

  private var nextLocalIdx: Int = 0

  /** The index of a local symbol */
  private val locals = mutable.HashMap[Symbol, Int]()

  /** The local symbol(s) starting at given offset */
  private val symsAtOffset = new mutable.HashMap[Int, Set[Symbol]]():
    override def default(key: Int) = Set[Symbol]()

  def symbolName(sym: Symbol)(using Context): String =
    val b = StringBuilder(20)
    addSymName(b, sym)
    b.toString
  def symbolName(sym: FakeSymbol)(using Context): String =
    sym match
      case sym: WildcardTypeSymbol =>
        val b = StringBuilder(20)
        addSymName(b, sym.owner)
        b.append('['); addName(b, sym.name); b.append(']')
        b.toString
      case sym: TermParamRefSymbol =>
        val b = StringBuilder(20)
        addSymName(b, sym.owner)
        b.append('('); addName(b, sym.name); b.append(')')
        b.toString
      case sym: TypeParamRefSymbol =>
        val b = StringBuilder(20)
        addSymName(b, sym.owner)
        b.append('['); addName(b, sym.name); b.append(']')
        b.toString
      case sym: RefinementSymbol =>
        val b = StringBuilder(20)
        addLocalSymName(b)
        b.toString

  def funParamSymbol(sym: Symbol)(using Context): Name => String =
    if sym.isGlobal then
      val funSymbol = symbolName(sym)
      name => s"$funSymbol($name)"
    else
      name => locals.keys.find(local => local.isTerm && local.owner == sym && local.name == name)
                    .fold("<?>")(Symbols.LocalPrefix + locals(_))

  private def addName(b: StringBuilder, name: Name): Unit =
    val str = name.toString.unescapeUnicode
    if str.isJavaIdent then b append str
    else b append '`' append str append '`'

  private def addLocalSymName(b: StringBuilder): Unit =
    val idx = nextLocalIdx
    nextLocalIdx += 1
    b.append(Symbols.LocalPrefix).append(idx)

  /** Add semanticdb name of the given symbol to string builder */
  private def addSymName(b: StringBuilder, sym: Symbol)(using Context): Unit =

    def addOwner(owner: Symbol): Unit =
      if !owner.isRoot then addSymName(b, owner)

    def addOverloadIdx(initSym: Symbol): Unit =
      // revert from the compiler-generated overload of the signature polymorphic method
      val sym = initSym.originalSignaturePolymorphic.symbol.orElse(initSym)
      val decls =
        val decls0 = sym.owner.info.decls.lookupAll(sym.name)
        if sym.owner.isAllOf(JavaModule) then
          decls0 ++ sym.owner.companionClass.info.decls.lookupAll(sym.name)
        else
          decls0
      end decls
      val alts = decls.filter(_.isOneOf(Method | Mutable)).toList.reverse
      def find(filter: Symbol => Boolean) = alts match
        case notSym :: rest if !filter(notSym) =>
          val idx = rest.indexWhere(filter).ensuring(_ >= 0)
          b.append('+').append(idx + 1)
        case _ =>
      end find
      val sig = sym.signature
      find(_.signature == sig)

    def addDescriptor(sym: Symbol): Unit =
      if sym.is(ModuleClass) then
        addDescriptor(sym.sourceModule)
      else if sym.is(TypeParam) then
        b.append('['); addName(b, sym.name); b.append(']')
      else if sym.is(Param) then
        b.append('('); addName(b, sym.name); b.append(')')
      else if sym.isRoot then
        b.append(Symbols.RootPackage)
      else if sym.isEmptyPackage then
        b.append(Symbols.EmptyPackage)
      else if (sym.isScala2PackageObject) then
        b.append(Symbols.PackageObjectDescriptor)
      else
        addName(b, sym.name)
        if sym.is(Package) then b.append('/')
        else if sym.isType || sym.isAllOf(JavaModule) then b.append('#')
        else if sym.isOneOf(Method | Mutable)
        && (!sym.is(StableRealizable) || sym.isConstructor) then
          b.append('('); addOverloadIdx(sym); b.append(").")
        else b.append('.')

    /** The index of local symbol `sym`. Symbols with the same name and
     *  the same starting position have the same index.
     */
    def localIdx(sym: Symbol)(using Context): Int =
      val startPos =
        // assert(sym.span.exists, s"$sym should have a span")
        if (sym.span.exists) Some(sym.span.start) else None
      @tailrec
      def computeLocalIdx(sym: Symbol): Int = locals get sym match
        case Some(idx) => idx
        case None =>
          (for {
            pos <- startPos
            syms <- symsAtOffset.get(pos)
            found <- syms.find(_.name == sym.name)
          } yield found) match
            case Some(other) => computeLocalIdx(other)
            case None =>
              val idx = nextLocalIdx
              nextLocalIdx += 1
              locals(sym) = idx
              startPos.foreach(pos => symsAtOffset(pos) += sym)
              idx
      end computeLocalIdx
      computeLocalIdx(sym)
    end localIdx

    if sym.exists then
      if sym.isGlobal then
        addOwner(sym.owner); addDescriptor(sym)
      else
        b.append(Symbols.LocalPrefix).append(localIdx(sym))

  end addSymName


text:
package org.infinispan.protostream.impl;

import java.io.IOException;

import org.infinispan.protostream.Message;
import org.infinispan.protostream.MessageMarshaller;
import org.infinispan.protostream.ProtobufTagMarshaller;
import org.infinispan.protostream.UnknownFieldSet;
import org.infinispan.protostream.UnknownFieldSetHandler;
import org.infinispan.protostream.descriptors.Descriptor;
import org.infinispan.protostream.descriptors.FieldDescriptor;

/**
 * @author anistor@redhat.com
 * @since 1.0
 */
final class MessageMarshallerDelegate<T> extends BaseMarshallerDelegate<T> {

   private final MessageMarshaller<T> marshaller;

   private final Descriptor messageDescriptor;

   private final FieldDescriptor[] fieldDescriptors;

   private final UnknownFieldSetHandler<T> unknownFieldSetHandler;

   private static final UnknownFieldSetHandler<Message> legacyUnknownFieldSetHandler = new UnknownFieldSetHandler<Message>() {
      @Override
      public UnknownFieldSet getUnknownFieldSet(Message message) {
         return message.getUnknownFieldSet();
      }

      @Override
      public void setUnknownFieldSet(Message message, UnknownFieldSet unknownFieldSet) {
         message.setUnknownFieldSet(unknownFieldSet);
      }
   };

   MessageMarshallerDelegate(MessageMarshaller<T> marshaller, Descriptor messageDescriptor) {
      this.marshaller = marshaller;
      this.messageDescriptor = messageDescriptor;
      this.fieldDescriptors = messageDescriptor.getFields().toArray(new FieldDescriptor[0]);

      if (marshaller instanceof UnknownFieldSetHandler) {
         unknownFieldSetHandler = (UnknownFieldSetHandler<T>) marshaller;
      } else if (Message.class.isAssignableFrom(marshaller.getJavaClass())) {
         unknownFieldSetHandler = (UnknownFieldSetHandler<T>) legacyUnknownFieldSetHandler;
      } else {
         unknownFieldSetHandler = null;
      }
   }

   @Override
   public MessageMarshaller<T> getMarshaller() {
      return marshaller;
   }

   @Override
   public void marshall(ProtobufTagMarshaller.WriteContext ctx, FieldDescriptor fieldDescriptor, T message) throws IOException {
      ProtoStreamWriterImpl writer = ((TagWriterImpl) ctx).getProtoStreamWriter();
      ProtoStreamWriterImpl.WriteMessageContext messageContext = writer.enterContext(fieldDescriptor, messageDescriptor, (TagWriterImpl) ctx);

      marshaller.writeTo(writer, message);

      UnknownFieldSet unknownFieldSet = unknownFieldSetHandler != null ? unknownFieldSetHandler.getUnknownFieldSet(message) : null;

      if (unknownFieldSet != null && !unknownFieldSet.isEmpty()) {
         // validate that none of the unknown fields are actually declared by the known descriptor
         for (FieldDescriptor fd : fieldDescriptors) {
            if (unknownFieldSet.hasTag(fd.getWireTag())) {
               throw new IOException("Field " + fd.getFullName() + " is a known field so it is illegal to be present in the unknown field set");
            }
         }
         // write the unknown fields
         unknownFieldSet.writeTo(messageContext.out);
      }

      // validate that all the required fields were written either by the marshaller or by the UnknownFieldSet
      for (FieldDescriptor fd : fieldDescriptors) {
         if (fd.isRequired() && !messageContext.isFieldMarked(fd.getNumber())
               && (unknownFieldSet == null || !unknownFieldSet.hasTag(fd.getWireTag()))) {
            throw new IllegalStateException("Required field \"" + fd.getFullName()
                  + "\" should have been written by a calling a suitable method of "
                  + MessageMarshaller.ProtoStreamWriter.class.getCanonicalName());
         }
      }

      writer.exitContext();
   }

   @Override
   public T unmarshall(ProtobufTagMarshaller.ReadContext ctx, FieldDescriptor fieldDescriptor) throws IOException {
      ProtoStreamReaderImpl reader = ((TagReaderImpl) ctx).getProtoStreamReader();
      ProtoStreamReaderImpl.ReadMessageContext messageContext = reader.enterContext(fieldDescriptor, messageDescriptor, (TagReaderImpl) ctx);

      T message = marshaller.readFrom(reader);

      UnknownFieldSet unknownFieldSet = messageContext.unknownFieldSet;
      unknownFieldSet.readAllFields(ctx.getReader());

      if (unknownFieldSetHandler != null && !unknownFieldSet.isEmpty()) {
         unknownFieldSetHandler.setUnknownFieldSet(message, unknownFieldSet);
      }

      // check that all required fields were seen in the stream, even if not actually read (because are unknown)
      for (FieldDescriptor fd : fieldDescriptors) {
         if (fd.isRequired()
               && !messageContext.isFieldMarked(fd.getNumber())
               && !unknownFieldSet.hasTag(fd.getWireTag())) {
            throw new IOException("Required field \"" + fd.getFullName() + "\" was not encountered in the stream");
         }
      }

      reader.exitContext();
      return message;
   }
}


text:
package net.canadensys.query.sort;

import net.canadensys.query.OrderEnum;

/**
 * SearchSortPart represents the sorting part of a search query and is not tied to a specific technology.
 * The main usage is to translate a sort options of a search query received via URL parameters.
 * @author canadensys
 *
 */
public class SearchSortPart {

	private Integer pageNumber;
	private Integer pageSize;
	private String orderByColumn;
	private OrderEnum order;

	/**
	 * Page number starts at 1.
	 * First page is 1 but 0 is an accepted value.
	 * @return
	 */
	public Integer getPageNumber() {
		return pageNumber;
	}
	public void setPageNumber(Integer pageNumber) {
		this.pageNumber = pageNumber;
	}

	public Integer getPageSize() {
		return pageSize;
	}
	public void setPageSize(Integer pageSize) {
		this.pageSize = pageSize;
	}

	public String getOrderByColumn() {
		return orderByColumn;
	}
	public void setOrderByColumn(String orderByColumn) {
		this.orderByColumn = orderByColumn;
	}

	public OrderEnum getOrder() {
		return order;
	}
	public void setOrder(OrderEnum order) {
		this.order = order;
	}
}


text:
package gov.faa.ang.swac.uas.scheduler.vfr;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import gov.faa.ang.swac.common.datatypes.Altitude;
import gov.faa.ang.swac.common.datatypes.Latitude;
import gov.faa.ang.swac.common.datatypes.Longitude;
import gov.faa.ang.swac.common.datatypes.Timestamp;
import gov.faa.ang.swac.common.flightmodeling.ScheduleRecord;
import gov.faa.ang.swac.common.geometry.GCPoint;
import gov.faa.ang.swac.common.geometry.GCUtilities;
import gov.faa.ang.swac.common.flightmodeling.Aircraft.PhysicalClass;
import gov.faa.ang.swac.uas.scheduler.airport_data.AirportData;
import gov.faa.ang.swac.uas.scheduler.forecast.MissionAirportPairKey;
import gov.faa.ang.swac.uas.scheduler.input.UasVfrRecord;
import gov.faa.ang.swac.uas.scheduler.input.Waypoint;
import gov.faa.ang.swac.uas.scheduler.mathematics.statistics.HQRandom;

public class EnhancedVfrSchedRecCreator extends VfrSchedRecCreator {
	private static final Logger logger = LogManager.getLogger(EnhancedVfrSchedRecCreator.class);

	private Map<MissionAirportPairKey, List<UasVfrRecord>> vfrMap;
	private long samplingRandomSeed;
	private int idCounter;

	public EnhancedVfrSchedRecCreator(Timestamp startTime, int i, int j, double nominalTaxiTimeMinutes,
			VFRLocalTimeGenerator vfrLocalTimeGenerator, Map<MissionAirportPairKey, List<UasVfrRecord>> vfrMap, int idCounter, long samplingRandomSeed) {
		super(startTime, i, j, nominalTaxiTimeMinutes, vfrLocalTimeGenerator);
		this.vfrMap = vfrMap;
		this.idCounter = idCounter;
		this.samplingRandomSeed = samplingRandomSeed;
	}

	@Override
	public List<ScheduleRecord> populateMissionAirportPair(
        MissionAirportPairKey missionAirportPair,
        int nVfrToAdd)
    {
		List<UasVfrRecord> list = this.vfrMap.get(missionAirportPair);
		if (list == null || list.isEmpty()) {
			return super.populateMissionAirportPair(missionAirportPair, nVfrToAdd);
		}

		try {
			List<ScheduleRecord> results = new ArrayList<ScheduleRecord>();
			Sampler sampler = new Sampler(list, samplingRandomSeed);

	        for (int i = 0; i < nVfrToAdd; ++i)
	        {
	        	UasVfrRecord vfrRec = sampler.sample();
	            ScheduleRecord schedRec = createScheduleRecord(missionAirportPair, idCounter, vfrRec); // always departure so we populate arrival info
	            idCounter += this.idNumInc;

	            results.add(schedRec);
	        }

	        return results;
		} catch (Exception ex) {
			logger.error("Error trying to populate enhanced VFR records. Defaulting to normal VFR.");
			return super.populateMissionAirportPair(missionAirportPair, nVfrToAdd);
		}
    }

	private class Sampler {
		private List<UasVfrRecord> list;
		private double[] cumDistr;
		private HQRandom rand;

		public Sampler(List<UasVfrRecord> list, long seed) {
			this.list = list;
			this.cumDistr = new double[list.size()];
			this.rand = new HQRandom(seed);

			cumDistr[0] = list.get(0).fraction;
			for (int i = 1; i < cumDistr.length; i++) {
				cumDistr[i] = cumDistr[i-1] + list.get(i).fraction;
			}
		}

		public UasVfrRecord sample() {
			double draw = rand.nextDouble();
			for (int i = 0; i < cumDistr.length; i++) {
				if (draw < cumDistr[i]) {
					return list.get(i);
				}
			}
			// Whammy...return the first one by default
			return list.get(0);
		}
	}

	protected ScheduleRecord createScheduleRecord(
    		MissionAirportPairKey missionAirportPair,
        int iVfr, UasVfrRecord vfrRec)
    {
        // Odd indices = arrival, Even = departures
        AirportData departureAirport = missionAirportPair.airportPair.getOrigin();
        AirportData arrivalAirport = missionAirportPair.airportPair.getDestination();

        final ScheduleRecord schedRec = new ScheduleRecord();

        // Identification fields ------------------------------------------------------------------
        schedRec.idNum = iVfr;
        schedRec.actDate = this.localDate;
        schedRec.aircraftId = "V_" + departureAirport.getMostLikelyCode() + "_" + arrivalAirport.getMostLikelyCode() + "_" + iVfr;
        schedRec.flightIndex = iVfr;
        schedRec.flightPlanType = "VFR";

        // Time fields ----------------------------------------------------------------------------
        Timestamp localTime =
            this.vfrLocalTimeGenerator.createLocalVfrTime(this.localDate);
        Timestamp etmsTime  = localTime.hourAdd(-departureAirport.getUtcDifference());
        double taxiTimeSecs = 60 * this.nominalTaxiTimeMinutes;

        schedRec.gateOutTime = etmsTime.secondAdd(-taxiTimeSecs);
        schedRec.gateOutTimeFlag = "CREATED";
        schedRec.runwayOffTime = etmsTime;
        schedRec.runwayOffTimeFlag = "CREATED";
        schedRec.runwayOnTime = schedRec.runwayOffTime.hourAdd(vfrRec.duration);
        schedRec.runwayOnTimeFlag = "CREATED";
        schedRec.gateInTime = schedRec.runwayOnTime.secondAdd(taxiTimeSecs);

        // User-class fields ----------------------------------------------------------------------
        schedRec.userClass = "U";
        schedRec.atoUserClass = missionAirportPair.mission.userClass();

        // Airspace fields ------------------------------------------------------------------------
        //schedRec.flewFlag = null; // previous code did not set it?
        schedRec.airspaceCode = "10";
        // TODO: Center gives us the opportunity to create a VFR loiter at a random location in the center
        // TODO: not necessarily fair to bias toward the departure but most are round robin anyway
        String center = departureAirport.getCenter();
        if (center != null)
        {
            if (center.equals("ZAN"))
            { // Alaska
                schedRec.airspaceCode = "3";
            }
            else if (center.equals("ZHN"))
            { // Hawaii
                schedRec.airspaceCode = "1";
            }
            else if (center.equals("ZLB"))
            { // not real, seems to be Panama
                schedRec.airspaceCode = "-1";
            }
            else if (center.equals("ZSU"))
            { // San Juan
                schedRec.airspaceCode = "5";
            }
            else if (center.equals("ZUA"))
            { // Guam
                schedRec.airspaceCode = "1";
            }
        }

        // Airport --------------------------------------------------------------------------------

        schedRec.depAprtEtms = departureAirport.getFaaCode();
        schedRec.depAprtIcao = departureAirport.getIcaoCode();

        schedRec.depLatitude = departureAirport.getLatitude();
        schedRec.depLongitude = departureAirport.getLongitude();
        schedRec.depElevation = departureAirport.getElevation();
        schedRec.depAirportCountryCode = departureAirport.getCountryCode();

        schedRec.arrAprtEtms = arrivalAirport.getFaaCode();
        schedRec.arrAprtIcao = arrivalAirport.getIcaoCode();

        schedRec.arrLatitude = arrivalAirport.getLatitude();
        schedRec.arrLongitude = arrivalAirport.getLongitude();
        schedRec.arrElevation = arrivalAirport.getElevation();
        schedRec.arrAirportCountryCode = arrivalAirport.getCountryCode();

        // I don't know what to set the remaining fields to.
        // Is null sufficient for VF?

        // Performance info
        schedRec.filedCruiseAltitude = Altitude.valueOfFeet(vfrRec.cruiseAltitude);
        schedRec.filedSpeed = vfrRec.cruiseTas;

        schedRec.etmsAircraftType = vfrRec.badaType;
        schedRec.physicalClass = PhysicalClass.valueOf("T"); // TODO: not all will be T
        schedRec.badaAircraftType = vfrRec.badaType;
        schedRec.badaSource = "ATOP";

        schedRec.scheduledFlag = false;
        schedRec.scheduledDepTime = null;
        schedRec.scheduledArrTime = null;

        // Route Info
        schedRec.etmsFiledWaypointsRaw = Waypoint.toWaypointString(vfrRec.waypoints, calculateRepeatCount(vfrRec, departureAirport, arrivalAirport));

        schedRec.field10 = "";

        return schedRec;
    }

	public int calculateRepeatCount(UasVfrRecord rec, AirportData departureAirport, AirportData arrivalAirport) {
		if (rec.waypoints.size() < 2) {
			return 1;
		}

		double maxDistance = rec.cruiseTas * rec.duration; // nm

		GCPoint departureLocation = new GCPoint(Latitude.valueOfDegrees(departureAirport.getLatitude()), Longitude.valueOfDegrees(departureAirport.getLongitude()));
		GCPoint arrivalLocation = new GCPoint(Latitude.valueOfDegrees(arrivalAirport.getLatitude()), Longitude.valueOfDegrees(arrivalAirport.getLongitude()));

		double distanceToRendezvous = GCUtilities.gcDistance(departureLocation, rec.waypoints.get(0));
		double distanceFromRendezvous = GCUtilities.gcDistance(rec.waypoints.get(rec.waypoints.size()-1), arrivalLocation);

		double loiterDistance = maxDistance - distanceToRendezvous - distanceFromRendezvous;
		if (loiterDistance < 0) {
			return 1;
		}

		double circuitDistance = GCUtilities.gcDistance(rec.waypoints.get(0), rec.waypoints.get(1));
		for (int i = 0; i < rec.waypoints.size() - 1; i++) {
			circuitDistance += GCUtilities.gcDistance(rec.waypoints.get(i), rec.waypoints.get(i+1));
		}

		return (int)Math.max(1, loiterDistance / circuitDistance);
	}
}


text:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/course_unit_video"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    android:baselineAligned="false"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/player_container"
        android:layout_width="match_parent"
        android:layout_height="@dimen/video_player_height"
        android:clickable="true"
        android:contentDescription="@string/video_player"
        android:importantForAccessibility="no"
        android:orientation="vertical" />

    <LinearLayout
        android:id="@+id/message_container"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="@color/white"
        android:gravity="center"
        android:orientation="vertical">

        <org.edx.mobile.view.custom.IconImageViewXml
            android:layout_width="140dp"
            android:layout_height="140dp"
            android:background="@color/white"
            android:rotation="90"
            app:iconColor="@color/edx_brand_gray_back"
            app:iconName="fa-mobile-phone" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:layout_marginEnd="60dp"
            android:layout_marginLeft="60dp"
            android:layout_marginRight="60dp"
            android:layout_marginStart="60dp"
            android:background="@color/white"
            android:gravity="center_horizontal"
            android:singleLine="false"
            android:text="@string/assessment_rotate_for_fullscreen"
            android:textAlignment="center"
            android:textColor="@color/edx_brand_gray_base"
            android:textSize="16sp"
            tools:targetApi="17" />
    </LinearLayout>

</LinearLayout>


text:
'use strict';

const pathHelper = require('../path');
const targaryen = require('targaryen');

const defaultLog = require('debug')('firebase-test:context:targaryen');
let ID_COUNT = 0;

function defaultUniqID() {
  return `--firebase-test-id-${ID_COUNT++}--`;
}

function assertAllowed(result, {debug, log}) {
  if (debug) {
    log(result.info);
  }

  if (result.allowed !== true) {
    throw new Error('Operation failed');
  }

  return result.newDatabase == null ? result.database : result.newDatabase;
}

const rulesetKey = Symbol('ruleset');

/**
 * SimulatedDriver simulate firebase operations using targaryen.
 */
class SimulatedDriver {

  /**
   * Targaryen contructor.
   *
   * The options main use if for testing.
   *
   * @param  {function(): string}     options.uniqID Function returning unique ID for push operation
   * @param  {function(...any): void} options.log    Log operation debug info
   */
  constructor({uniqID = defaultUniqID, log = defaultLog} = {}) {
    this.uniqID = uniqID;
    this.log = log;
  }

  get id() {
    return 'targaryen';
  }

  /**
   * Check the rules are valid.
   *
   * @param  {Context} ctx Context to initialize
   */
  init(ctx) {
    ctx[rulesetKey] = targaryen.ruleset(ctx.rules);
  }

  /**
   * Simulate operations.
   *
   * Returns the content of the database at the end of sequence.
   *
   * @param  {Context} ctx Context holds the rules, seed and operation to simulate with
   * @return {any}
   */
  exec(ctx) {
    const {seed, ops} = ctx;
    const data = targaryen.store(seed);

    if (ops == null || ops.length == null || ops.length === 0) {
      return data.$value();
    }

    const initialDb = targaryen.database(ctx[rulesetKey], data).with({debug: true});
    const finalDb = ops.reduce(
      (database, operation) => {
        const {op, path = '/', value, auth = null, options: {debug = false} = {}} = operation;
        const db = database.as(auth);
        let result, childPath;

        switch (op) {

        case 'get':
          result = db.read(path);
          break;

        case 'push':
          childPath = pathHelper.join(path, this.uniqID());
          result = db.write(childPath, value);
          break;

        case 'set':
          result = db.write(path, value);
          break;

        case 'update':
          result = db.update(path, value);
          break;

        default:
          throw new Error(`Unknown operation type "${op}"`);

        }

        return assertAllowed(result, {debug, log: this.log});
      },
      initialDb
    );

    return finalDb.root.$value();
  }

}

/**
 * Create a driver simulating a sequence of Firebase operation.
 *
 * @param  {object} opts Driver's options
 * @return {SimulatedDriver}
 */
exports.create = function(opts) {
  return new SimulatedDriver(opts);
};


text:
package org.apache.myfaces.view.facelets.mock;

import javax.faces.context.FacesContext;
import javax.faces.view.ViewDeclarationLanguage;
import javax.faces.view.ViewDeclarationLanguageFactory;

import org.apache.myfaces.view.ViewDeclarationLanguageStrategy;
import org.apache.myfaces.view.facelets.MockFaceletViewDeclarationLanguage;

public class MockViewDeclarationLanguageFactory extends ViewDeclarationLanguageFactory
{

    private ViewDeclarationLanguageStrategy _strategy;

    public MockViewDeclarationLanguageFactory()
    {
        super();
        _strategy = new MockViewDeclarationLanguageStrategy();
    }

    @Override
    public ViewDeclarationLanguage getViewDeclarationLanguage(String viewId)
    {
        return _strategy.getViewDeclarationLanguage();
    }

    public static class MockViewDeclarationLanguageStrategy
        implements ViewDeclarationLanguageStrategy
    {
        private ViewDeclarationLanguage _language;

        public boolean handles(String viewId)
        {
            return true;
        }

        public ViewDeclarationLanguage getViewDeclarationLanguage()
        {
            if (_language == null)
            {
                _language = new MockFaceletViewDeclarationLanguage(FacesContext.getCurrentInstance());
            }
            return _language;
        }
    }
}


text:
package com.eventerzgz.presenter;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.provider.CalendarContract;
import android.util.Log;

import com.eventerzgz.interactor.DateUtilities;
import com.eventerzgz.interactor.QueryBuilder;
import com.eventerzgz.interactor.events.EventInteractor;
import com.eventerzgz.interactor.population.PopulationInteractor;
import com.eventerzgz.model.commons.Population;
import com.eventerzgz.model.event.Event;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

/**
 * Created by joseluis on 20/3/15.
 */
public abstract class BasePresenter
{
    //Preferences
    //-----
    private static final String APP_PREFERENCES                 = "eventerzgz";
    private static final String POBLATION_PREFERENCES_KEY       = "poblation";
    private static final String TUTORIAL_MADE_KEY               = "tutorialMade";
    private static final String CATEGORIES_PREFERENCES_KEY      = "categories";
    private static final String LOCATION_PUSH_PREFERENCES_KEY   = "locationPush";

    protected static String TAG = "EventerZgz";

    public <T> void observerTask(Observable.OnSubscribe<T> onSubscribe, Subscriber<T> subscriber)
    {
        Observable.create(onSubscribe)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber);

    }

    public void getPopulationinOtherThread(Subscriber<List<Population>> subscriber){
        observerTask(new Observable.OnSubscribe<List<Population>>() {
            @Override
            public void call(Subscriber<? super List<Population>> suscriber) {
                try {
                    suscriber.onNext(PopulationInteractor.getPopulations());
                } catch (Exception e) {
                    Log.e(TAG, e.getMessage(), e);
                    suscriber.onError(e);
                }
            }
        }, subscriber);
    }

    public void addCalendarEvent(Event event,Context ctx)
    {

        Calendar beginTime = Calendar.getInstance();
        if(event.getdStartDate()!=null) {
            beginTime.setTime(event.getdStartDate());
        }
        if(event.getdEndDate()!=null){
            beginTime.setTime(event.getdEndDate());
        }
        Calendar endTime = Calendar.getInstance();
        endTime.setTime(event.getdEndDate());

        String title = event.getsTitle();
        String location = (event.getSubEvent() != null && event.getSubEvent().getWhere() != null) ? event.getSubEvent().getWhere().getsAddress():"";
        String email = (event.getSubEvent() != null && event.getSubEvent().getWhere() != null) ? event.getSubEvent().getWhere().getsMail():"";

        Intent intent = new Intent(Intent.ACTION_INSERT)
                .setData(CalendarContract.Events.CONTENT_URI)
                .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis())
                .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis())
                .putExtra(CalendarContract.Events.TITLE, title)
                .putExtra(CalendarContract.Events.EVENT_LOCATION, location)
                .putExtra(CalendarContract.Events.AVAILABILITY, CalendarContract.Events.AVAILABILITY_FREE)
                .putExtra(Intent.EXTRA_EMAIL, email);

        ctx.startActivity(intent);
    }

    public static void saveTutorialMade( Context context){
        SharedPreferences prefs = context.getSharedPreferences(APP_PREFERENCES, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = prefs.edit();

        editor.putBoolean(TUTORIAL_MADE_KEY, true);
        editor.apply();

    }

    public static boolean getTutorialMade( Context context){
        SharedPreferences prefs = context.getSharedPreferences(APP_PREFERENCES, Context.MODE_PRIVATE);

        return prefs.getBoolean(TUTORIAL_MADE_KEY, false);

    }

    public static void saveCategoriesSelectedInPreferences(ArrayList<String> arrayIdsCategories, Context context){
        SharedPreferences prefs = context.getSharedPreferences(APP_PREFERENCES, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = prefs.edit();

        Set<String> set = new HashSet<>();
        set.addAll(arrayIdsCategories);

        editor.putStringSet(CATEGORIES_PREFERENCES_KEY, set);
        editor.apply();

    }

    public static void savePoblationSelectedInPreferences(ArrayList<String> arrayIdsCategories, Context context){
        SharedPreferences prefs = context.getSharedPreferences(APP_PREFERENCES, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = prefs.edit();

        Set<String> set = new HashSet<>();
        set.addAll(arrayIdsCategories);

        editor.putStringSet(POBLATION_PREFERENCES_KEY, set);
        editor.apply();

    }

    public static List<String> getPoblation(Context context)
    {
        SharedPreferences prefs = context.getSharedPreferences(APP_PREFERENCES, Context.MODE_PRIVATE);
        Set<String> stringSet = prefs.getStringSet(POBLATION_PREFERENCES_KEY, new HashSet<String>());
        return new ArrayList<>(stringSet);
    }

    public static Set<String> getPoblationInSet(Context context)
    {
        SharedPreferences prefs = context.getSharedPreferences(APP_PREFERENCES, Context.MODE_PRIVATE);
        return prefs.getStringSet(POBLATION_PREFERENCES_KEY, new HashSet<String>());
    }

    public static List<String> getCategories(Context context)
    {
        SharedPreferences prefs = context.getSharedPreferences(APP_PREFERENCES, Context.MODE_PRIVATE);
        Set<String> stringSet = prefs.getStringSet(CATEGORIES_PREFERENCES_KEY, new HashSet<String>());
        return new ArrayList<>(stringSet);
    }

    public static Set<String> getCategoriesInSet(Context context)
    {
        SharedPreferences prefs = context.getSharedPreferences(APP_PREFERENCES, Context.MODE_PRIVATE);
        return  prefs.getStringSet(CATEGORIES_PREFERENCES_KEY, new HashSet<String>());
    }

    public static void saveLocationPushInPreferences(Double latitude,Double longuitude,Context context){
        if(latitude == null || longuitude == null){
            Log.e(TAG,"latitude or longuite null");
            return;
        }

        SharedPreferences prefs = context.getSharedPreferences(APP_PREFERENCES, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = prefs.edit();

        editor.putString(LOCATION_PUSH_PREFERENCES_KEY, String.format(Locale.ENGLISH,"%f,%f",longuitude,latitude));
        editor.apply();
    }

    public static String getLocationFromPreferences(Context context){

        SharedPreferences prefs = context.getSharedPreferences(APP_PREFERENCES, Context.MODE_PRIVATE);

        return prefs.getString(LOCATION_PUSH_PREFERENCES_KEY, "");
    }

    public static void removeLocationFromPreferences(Context context){
        SharedPreferences prefs = context.getSharedPreferences(APP_PREFERENCES, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = prefs.edit();

        editor.remove(LOCATION_PUSH_PREFERENCES_KEY);
        editor.apply();
    }

    public static void getEventsByPreferencesInOtherThread (final Context context, final boolean filterByLastUpdated,Subscriber<List<Event>> subscriber){

        Observable.create(new Observable.OnSubscribe<List<Event>>() {
            @Override
            public void call(Subscriber<? super List<Event>> subscriber) {

                try
                {
                    String location = BasePresenter.getLocationFromPreferences(context);
                    List<String> categoryIds = BasePresenter.getCategories(context);
                    List<String> poblations = BasePresenter.getPoblation(context);

                    QueryBuilder queryBuilder = new QueryBuilder().isInToday();

                   // composeQueryLIst(queryBuilder,categoryIds, QueryBuilder.FIELD.CATEGORY);
                    //composeQueryLIst(queryBuilder, poblations, QueryBuilder.FIELD.POPULATION);
                    boolean isCompleteList =  categoryIds != null
                                                && poblations != null
                                                && categoryIds.size() > 0
                                                && poblations.size() > 0;

                    if(isCompleteList){
                        queryBuilder.and().group();
                        composeQueryLIst(queryBuilder,categoryIds, QueryBuilder.FIELD.CATEGORY);
                        queryBuilder.or();
                        composeQueryLIst(queryBuilder, poblations, QueryBuilder.FIELD.POPULATION);
                        queryBuilder.ungroup();
                    }else{
                        if (categoryIds != null  && categoryIds.size() > 0 ){

                            queryBuilder.and().group();
                            composeQueryLIst(queryBuilder, categoryIds, QueryBuilder.FIELD.CATEGORY);
                            queryBuilder.ungroup();

                        }else if(poblations != null  && poblations.size() > 0){
                            queryBuilder.and().group();
                            composeQueryLIst(queryBuilder, poblations, QueryBuilder.FIELD.POPULATION);
                            queryBuilder.ungroup();
                        }
                    }

                    if(filterByLastUpdated){
                        queryBuilder.and().addFilter(QueryBuilder.FIELD.LAST_UPDATED, QueryBuilder.COMPARATOR.GREATER_EQUALS,DateUtilities.getStartOfToday());
                    }

                    if(location.length() > 0){
                        subscriber.onNext(EventInteractor.getAllEvent(
                                EventInteractor.EventFilter.createFilter(EventInteractor.EventFilter.QUERY_FILTER, queryBuilder.build()),
                                EventInteractor.EventFilter.createFilter(EventInteractor.EventFilter.START, 0),
                                EventInteractor.EventFilter.createFilter(EventInteractor.EventFilter.SORT, QueryBuilder.FIELD.END_DATE + " desc"), // "desc" is optional
                                EventInteractor.EventFilter.createFilter(EventInteractor.EventFilter.ROWS, 50),
                                EventInteractor.EventFilter.createFilter(EventInteractor.EventFilter.DISTANCE, 3000), //metros
                                EventInteractor.EventFilter.createFilter(EventInteractor.EventFilter.POINT, location)));
                    }else{
                        subscriber.onNext(EventInteractor.getAllEvent(
                                EventInteractor.EventFilter.createFilter(EventInteractor.EventFilter.QUERY_FILTER, queryBuilder.build()),
                                EventInteractor.EventFilter.createFilter(EventInteractor.EventFilter.START, 0),
                                EventInteractor.EventFilter.createFilter(EventInteractor.EventFilter.SORT, QueryBuilder.FIELD.END_DATE + " desc" ), // "desc" is optional
                                EventInteractor.EventFilter.createFilter(EventInteractor.EventFilter.ROWS, 50)));
                    }

                }
                catch (Exception ex){
                    Log.e(TAG,ex.getMessage(),ex);
                    subscriber.onError(ex);
                }

            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber);

    }

    protected static QueryBuilder composeQueryLIst(QueryBuilder queryBuilder,List<String> list,QueryBuilder.FIELD field){

        if (list != null && list.size() > 0) {
            boolean first = true;
            //queryBuilder.and().group();
            for (String categoryId : list) {
                if (!first) {
                    queryBuilder.or();
                } else {
                    first = false;
                }
                queryBuilder.addFilter(field, QueryBuilder.COMPARATOR.EQUALS, categoryId);
            }
            //queryBuilder.ungroup();
        }

        return queryBuilder;
    }

    /**
     * Translate list Events into
     * @param eventList List of events
     * @return Map by dates
     */
    protected Map<Date,List<Event>> populateMapFromListEvents(List<Event> eventList)
    {
        Map<Date,List<Event>> dateListMap = new HashMap<>();
        List<Event> listAux;
        Date key;
        for(Event event:eventList)
        {

            key = event.getdEndDate();

            if(dateListMap.containsKey(key)){

                listAux = dateListMap.get(key);
                listAux.add(event);

            }else{
                listAux = Collections.emptyList();
                listAux.add(event);

                dateListMap.put(key, listAux);
            }
        }

        return dateListMap;
    }

    protected List<Event> filterListByDateBeforeToday(List<Event>eventList){

        List<Event> events = new ArrayList<>(0);

        if ( eventList == null || eventList.size() == 0)
            return  eventList;

        for (Event event:eventList){
            if(!isBeforeToday(event.getdEndDate(),event)){
                events.add(event);
            }
        }

        return events;

    }

    private boolean isBeforeToday(Date dateToCheck,Event event) {

        //Log.i(TAG,"Date To evaluate ->"+dateToCheck.toString());

        if (dateToCheck == null) {
            Log.e(TAG, "NULL date for event" + event.toString());
            return true;
        }

        Calendar c = Calendar.getInstance();

        // set the calendar to start of today
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);

        Calendar c2 = Calendar.getInstance();
        c2.setTime(dateToCheck);

        return  c.get(Calendar.ERA) < c2.get(Calendar.ERA) ||
                c.get(Calendar.ERA) > c2.get(Calendar.ERA) ||
                c.get(Calendar.YEAR) < c2.get(Calendar.YEAR) ||
                c.get(Calendar.YEAR) > c2.get(Calendar.YEAR) ||
                c.get(Calendar.DAY_OF_YEAR) > c2.get(Calendar.DAY_OF_YEAR);
    }

}