text:
namespace blink {

void MultiColumnSetPainter::paintObject(const PaintInfo& paintInfo,
                                        const LayoutPoint& paintOffset) {
  if (m_layoutMultiColumnSet.style()->visibility() != EVisibility::kVisible)
    return;

  BlockPainter(m_layoutMultiColumnSet).paintObject(paintInfo, paintOffset);

  // FIXME: Right now we're only painting in the foreground phase.
  // Columns should technically respect phases and allow for
  // background/float/foreground overlap etc., just like LayoutBlocks do. Note
  // this is a pretty minor issue, since the old column implementation clipped
  // columns anyway, thus making it impossible for them to overlap one another.
  // It's also really unlikely that the columns would overlap another block.
  if (!m_layoutMultiColumnSet.flowThread() ||
      (paintInfo.phase != PaintPhaseForeground &&
       paintInfo.phase != PaintPhaseSelection))
    return;

  paintColumnRules(paintInfo, paintOffset);
}

void MultiColumnSetPainter::paintColumnRules(const PaintInfo& paintInfo,
                                             const LayoutPoint& paintOffset) {
  Vector<LayoutRect> columnRuleBounds;
  if (!m_layoutMultiColumnSet.computeColumnRuleBounds(paintOffset,
                                                      columnRuleBounds))
    return;

  if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(
          paintInfo.context, m_layoutMultiColumnSet, DisplayItem::kColumnRules))
    return;

  LayoutRect paintRect = m_layoutMultiColumnSet.visualOverflowRect();
  paintRect.moveBy(paintOffset);
  LayoutObjectDrawingRecorder drawingRecorder(
      paintInfo.context, m_layoutMultiColumnSet, DisplayItem::kColumnRules,
      paintRect);

  const ComputedStyle& blockStyle =
      m_layoutMultiColumnSet.multiColumnBlockFlow()->styleRef();
  EBorderStyle ruleStyle = blockStyle.columnRuleStyle();
  bool leftToRight = m_layoutMultiColumnSet.style()->isLeftToRightDirection();
  BoxSide boxSide = m_layoutMultiColumnSet.isHorizontalWritingMode()
                        ? leftToRight ? BSLeft : BSRight
                        : leftToRight ? BSTop : BSBottom;
  const Color& ruleColor = m_layoutMultiColumnSet.resolveColor(
      blockStyle, CSSPropertyColumnRuleColor);

  for (auto& bound : columnRuleBounds) {
    IntRect pixelSnappedRuleRect = pixelSnappedIntRect(bound);
    ObjectPainter::drawLineForBoxSide(
        paintInfo.context, pixelSnappedRuleRect.x(), pixelSnappedRuleRect.y(),
        pixelSnappedRuleRect.maxX(), pixelSnappedRuleRect.maxY(), boxSide,
        ruleColor, ruleStyle, 0, 0, true);
  }
}

}  // namespace blink

redpajama_set_name: RedPajamaGithub


2 available flavours in 1 kg doypack bag.
Made by cooking of cane sugar, "décuit" with milk, cream and fresh salted butter.
Made by mixing pure cocoa butter, vanilla bourbon in pod and cane sugar. Without soya, no added flavours.


text:
package org.axonframework.commandhandling.gateway;

import org.axonframework.commandhandling.CommandBus;
import org.axonframework.commandhandling.CommandCallback;
import org.axonframework.commandhandling.CommandExecutionException;
import org.axonframework.commandhandling.CommandMessage;
import org.axonframework.commandhandling.CommandResultMessage;
import org.axonframework.common.lock.DeadlockException;
import org.axonframework.messaging.MetaData;
import org.axonframework.messaging.annotation.MetaDataValue;
import org.axonframework.messaging.responsetypes.ResponseTypes;
import org.axonframework.messaging.unitofwork.DefaultUnitOfWork;
import org.axonframework.messaging.unitofwork.UnitOfWork;
import org.junit.jupiter.api.*;
import org.mockito.*;
import org.mockito.invocation.*;
import org.mockito.stubbing.*;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.Nonnull;

import static java.util.Collections.singletonMap;
import static org.axonframework.commandhandling.GenericCommandResultMessage.asCommandResultMessage;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentCaptor.*;
import static org.mockito.Mockito.*;

/**
 * Test class validating the {@link CommandGatewayFactory}.
 *
 * @author Allard Buijze
 * @author Nakul Mishra
 */
@SuppressWarnings({"unchecked", "ThrowableResultOfMethodCallIgnored"})
class CommandGatewayFactoryTest {

    private CommandBus mockCommandBus;
    private RetryScheduler mockRetryScheduler;
    private CompleteGateway gateway;
    @SuppressWarnings("rawtypes")
    private CommandCallback callback;

    private CommandGatewayFactory testSubject;

    @BeforeEach
    void setUp() {
        mockCommandBus = mock(CommandBus.class);
        mockRetryScheduler = mock(RetryScheduler.class);
        testSubject = CommandGatewayFactory.builder()
                                           .commandBus(mockCommandBus)
                                           .retryScheduler(mockRetryScheduler)
                                           .build();
        callback = spy(new StringCommandCallback());

        testSubject.registerCommandCallback(
                (commandMessage, commandResultMessage) -> {
                },
                ResponseTypes.instanceOf(String.class)
        );
        testSubject.registerCommandCallback(callback, ResponseTypes.instanceOf(String.class));
        gateway = testSubject.createGateway(CompleteGateway.class);
    }

    @Test
    @Timeout(value = 2)
    void gatewayFireAndForget() {
        final Object metaTest = new Object();

        doAnswer(new Success(asCommandResultMessage(null)))
                .when(mockCommandBus).dispatch(isA(CommandMessage.class), isA(CommandCallback.class));
        testSubject.registerCommandCallback(callback, ResponseTypes.instanceOf(Void.class));

        gateway.fireAndForget("Command", null, metaTest, "value");

        verify(mockCommandBus).dispatch(
                argThat(x -> x.getMetaData().get("test") == metaTest && "value".equals(x.getMetaData().get("key"))),
                isA(RetryingCallback.class)
        );

        // Check that the callback is invoked, despite the null return value,
        //  as we have registered it under Void response type
        verify(callback).onResult(isA(CommandMessage.class), any());
    }

    @Test
    @Timeout(value = 2)
    void gatewayFireAndForgetWithoutRetryScheduler() {
        final Object metaTest = new Object();

        CommandGatewayFactory testSubject = CommandGatewayFactory.builder().commandBus(mockCommandBus).build();
        CompleteGateway gateway = testSubject.createGateway(CompleteGateway.class);

        gateway.fireAndForget("Command", MetaData.from(singletonMap("otherKey", "otherVal")), metaTest, "value");

        verify(mockCommandBus).dispatch(argThat(
                x -> x.getMetaData().get("test") == metaTest
                        && "otherVal".equals(x.getMetaData().get("otherKey"))
                        && "value".equals(x.getMetaData().get("key"))
        ));
    }

    @Test
    @Timeout(value = 2)
    void gatewayTimeout() throws InterruptedException {
        final CountDownLatch latch = new CountDownLatch(1);
        doAnswer(new CountDown(latch))
                .when(mockCommandBus).dispatch(isA(CommandMessage.class), isA(CommandCallback.class));

        Thread t = new Thread(() -> gateway.fireAndWait("Command"));
        t.start();
        assertTrue(latch.await(1, TimeUnit.SECONDS), "Expected command bus to be invoked");
        assertTrue(t.isAlive());
        t.interrupt();
    }

    @Test
    @Timeout(value = 2)
    void gatewayWithReturnValueReturns() throws InterruptedException {
        String expectedReturnValue = "ReturnValue";
        CommandResultMessage<String> returnValue = asCommandResultMessage(expectedReturnValue);
        final CountDownLatch latch = new CountDownLatch(1);
        final AtomicReference<String> result = new AtomicReference<>();

        doAnswer(new Success(latch, returnValue))
                .when(mockCommandBus).dispatch(isA(CommandMessage.class), isA(CommandCallback.class));

        Thread t = new Thread(() -> result.set(gateway.waitForReturnValue("Command")));
        t.start();
        assertTrue(latch.await(1, TimeUnit.SECONDS), "Expected command bus to be invoked");
        t.join();
        assertEquals(expectedReturnValue, result.get());
        verify(callback).onResult(any(), eq(returnValue));
    }

    @Test
    @Timeout(value = 2)
    void gatewayWithReturnValueUndeclaredException() throws InterruptedException {
        final CountDownLatch latch = new CountDownLatch(1);
        final AtomicReference<String> result = new AtomicReference<>();
        final AtomicReference<Throwable> error = new AtomicReference<>();

        doAnswer(new Failure(latch, new ExpectedException()))
                .when(mockCommandBus).dispatch(isA(CommandMessage.class), isA(CommandCallback.class));

        Thread t = new Thread(() -> {
            try {
                result.set(gateway.waitForReturnValue("Command"));
            } catch (Throwable e) {
                error.set(e);
            }
        });

        t.start();
        assertTrue(latch.await(1, TimeUnit.SECONDS), "Expected command bus to be invoked");
        t.join();

        assertNull(result.get(), "Did not expect ReturnValue");
        assertTrue(error.get() instanceof CommandExecutionException);
        assertTrue(error.get().getCause() instanceof ExpectedException);

        ArgumentCaptor<CommandResultMessage<?>> commandResultMessageCaptor = forClass(CommandResultMessage.class);
        verify(callback).onResult(any(), commandResultMessageCaptor.capture());
        assertTrue(commandResultMessageCaptor.getValue().isExceptional());
        assertEquals(ExpectedException.class, commandResultMessageCaptor.getValue().exceptionResult().getClass());
    }

    @Test
    @Timeout(value = 2)
    void gatewayWithReturnValueInterrupted() throws InterruptedException {
        final AtomicReference<String> result = new AtomicReference<>();
        final AtomicReference<Throwable> error = new AtomicReference<>();

        Thread t = new Thread(() -> {
            try {
                result.set(gateway.waitForReturnValue("Command"));
            } catch (Throwable e) {
                error.set(e);
            }
        });

        t.start();
        t.interrupt();
        t.join();

        assertNull(result.get(), "Did not expect ReturnValue");
        assertTrue(error.get() instanceof CommandExecutionException, "Expected CommandExecutionException");
        assertTrue(error.get().getCause() instanceof InterruptedException, "Expected wrapped InterruptedException");
    }

    @Test
    void gatewayWithReturnValueRuntimeException() {
        final AtomicReference<String> result = new AtomicReference<>();
        final AtomicReference<Throwable> error = new AtomicReference<>();
        RuntimeException runtimeException = new RuntimeException();

        doAnswer(new Failure(null, runtimeException))
                .when(mockCommandBus).dispatch(isA(CommandMessage.class), isA(CommandCallback.class));

        try {
            result.set(gateway.waitForReturnValue("Command"));
        } catch (Throwable e) {
            error.set(e);
        }

        assertNull(result.get(), "Did not expect ReturnValue");
        assertSame(runtimeException, error.get(), "Expected exact instance of RunTimeException being propagated");

        ArgumentCaptor<CommandResultMessage<?>> commandResultMessageCaptor = forClass(CommandResultMessage.class);
        verify(callback).onResult(any(), commandResultMessageCaptor.capture());
        assertEquals(RuntimeException.class, commandResultMessageCaptor.getValue().exceptionResult().getClass());
    }

    @Test
    @Timeout(value = 2)
    void gatewayWaitForExceptionInterrupted() throws InterruptedException {
        final AtomicReference<String> result = new AtomicReference<>();
        final AtomicReference<Throwable> error = new AtomicReference<>();

        Thread t = new Thread(() -> {
            try {
                gateway.waitForException("Command");
            } catch (Throwable e) {
                error.set(e);
            }
        });

        t.start();
        t.interrupt();
        t.join();

        assertNull(result.get(), "Did not expect ReturnValue");
        assertTrue(error.get() instanceof InterruptedException);
    }

    @Test
    @Timeout(value = 2)
    void gatewayWaitForUndeclaredInterruptedException() throws InterruptedException {
        final AtomicReference<String> result = new AtomicReference<>();
        final AtomicReference<Throwable> error = new AtomicReference<>();

        Thread t = new Thread(() -> {
            try {
                gateway.waitForReturnValue("Command");
            } catch (Throwable e) {
                error.set(e);
            }
        });

        t.start();
        t.interrupt();
        t.join();

        assertNull(result.get(), "Did not expect ReturnValue");
        assertTrue(error.get() instanceof CommandExecutionException);
    }

    @Test
    @Timeout(value = 2)
    void fireAndWaitWithTimeoutParameterReturns() throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(1);
        final AtomicReference<String> result = new AtomicReference<>();
        final AtomicReference<Throwable> error = new AtomicReference<>();

        doAnswer(new Success(latch, asCommandResultMessage("OK!")))
                .when(mockCommandBus).dispatch(isA(CommandMessage.class), isA(CommandCallback.class));

        Thread t = new Thread(() -> {
            try {
                gateway.fireAndWaitWithTimeoutParameter("Command", 1, TimeUnit.MILLISECONDS);
            } catch (Throwable e) {
                error.set(e);
            }
        });

        t.start();
        assertTrue(latch.await(1, TimeUnit.SECONDS));
        t.interrupt();

        // The return type of `fireAndWaitWithTimeoutParameter` is void, so return value is ignored
        assertNull(result.get(), "Did not expect ReturnValue");
        assertNull(error.get(), "Did not expect exception");
    }

    @Test
    @Timeout(value = 2)
    void fireAndWaitWithTimeoutParameterTimeout() throws InterruptedException {
        final AtomicReference<String> result = new AtomicReference<>();
        final AtomicReference<Throwable> error = new AtomicReference<>();

        Thread t = new Thread(() -> {
            try {
                gateway.fireAndWaitWithTimeoutParameter("Command", 1, TimeUnit.MILLISECONDS);
            } catch (Throwable e) {
                error.set(e);
            }
        });

        t.start();
        t.join();

        assertNull(result.get(), "Did not expect ReturnValue");
        assertTrue(error.get() instanceof CommandExecutionException, "Expected CommandExecutionException");
        assertTrue(error.get().getCause() instanceof TimeoutException, "Expected wrapped InterruptedException");
    }

    @Test
    @Timeout(value = 2)
    void fireAndWaitWithTimeoutParameterTimeoutException() throws InterruptedException {
        final AtomicReference<String> result = new AtomicReference<>();
        final AtomicReference<Throwable> error = new AtomicReference<>();

        Thread t = new Thread(() -> {
            try {
                gateway.fireAndWaitWithTimeoutParameterAndException("Command", 1, TimeUnit.MILLISECONDS);
            } catch (Throwable e) {
                error.set(e);
            }
        });

        t.start();
        t.join();

        assertNull(result.get(), "Did not expect ReturnValue");
        assertTrue(error.get() instanceof TimeoutException);
    }

    @Test
    @Timeout(value = 2)
    void fireAndWaitWithTimeoutParameterInterrupted() throws InterruptedException {
        final AtomicReference<String> result = new AtomicReference<>();
        final AtomicReference<Throwable> error = new AtomicReference<>();

        Thread t = new Thread(() -> {
            try {
                gateway.fireAndWaitWithTimeoutParameter("Command", 1, TimeUnit.SECONDS);
            } catch (Throwable e) {
                error.set(e);
            }
        });

        t.start();
        t.interrupt();
        t.join();

        assertNull(result.get(), "Did not expect ReturnValue");
        assertTrue(error.get() instanceof CommandExecutionException, "Expected CommandExecutionException");
        assertTrue(error.get().getCause() instanceof InterruptedException, "Expected wrapped InterruptedException");
    }

    @Test
    @Timeout(value = 2)
    void fireAndWaitForCheckedException() throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(1);
        final AtomicReference<String> result = new AtomicReference<>();
        final AtomicReference<Throwable> error = new AtomicReference<>();

        doAnswer(new Failure(latch, new ExpectedException()))
                .when(mockCommandBus).dispatch(isA(CommandMessage.class), isA(CommandCallback.class));

        Thread t = new Thread(() -> {
            try {
                gateway.fireAndWaitForCheckedException("Command");
            } catch (Throwable e) {
                error.set(e);
            }
        });

        t.start();
        assertTrue(latch.await(1, TimeUnit.SECONDS));
        t.join();

        assertNull(result.get(), "Did not expect ReturnValue");
        assertTrue(error.get() instanceof ExpectedException);

        ArgumentCaptor<CommandResultMessage<?>> commandResultMessageCaptor = forClass(CommandResultMessage.class);
        verify(callback).onResult(any(), commandResultMessageCaptor.capture());
        assertTrue(commandResultMessageCaptor.getValue().isExceptional());
        assertEquals(ExpectedException.class, commandResultMessageCaptor.getValue().exceptionResult().getClass());
    }

    @Test
    @Timeout(value = 2)
    void fireAndGetFuture() throws InterruptedException {
        final AtomicReference<Future<Object>> result = new AtomicReference<>();
        final AtomicReference<Throwable> error = new AtomicReference<>();

        Thread t = new Thread(() -> {
            try {
                result.set(gateway.fireAndGetFuture("Command"));
            } catch (Throwable e) {
                error.set(e);
            }
        });

        t.start();
        t.join();

        assertNotNull(result.get(), "Expected to get a Future return value");
        assertNull(error.get());
    }

    @Test
    @Timeout(value = 2)
    void fireAndGetCompletableFuture() throws InterruptedException {
        final AtomicReference<CompletableFuture<Object>> result = new AtomicReference<>();
        final AtomicReference<Throwable> error = new AtomicReference<>();

        Thread t = new Thread(() -> {
            try {
                result.set(gateway.fireAndGetCompletableFuture("Command"));
            } catch (Throwable e) {
                error.set(e);
            }
        });

        t.start();
        t.join();

        assertNotNull(result.get(), "Expected to get a Future return value");
        assertNull(error.get());
    }

    @Test
    @Timeout(value = 2)
    void fireAndGetFutureWithTimeout() throws Throwable {
        final AtomicReference<Future<Object>> result = new AtomicReference<>();
        final AtomicReference<Throwable> error = new AtomicReference<>();

        Thread t = new Thread(() -> {
            try {
                result.set(gateway.futureWithTimeout("Command", 100, TimeUnit.SECONDS));
            } catch (Throwable e) {
                error.set(e);
            }
        });

        t.start();
        t.join();

        assertNotNull(result.get(), "Expected to get a Future return value");
        assertNull(error.get());
    }

    @Test
    @Timeout(value = 2)
    void fireAndGetCompletionStageWithTimeout() throws Throwable {
        final AtomicReference<CompletionStage<Object>> result = new AtomicReference<>();
        final AtomicReference<Throwable> error = new AtomicReference<>();

        Thread t = new Thread(() -> {
            try {
                result.set(gateway.fireAndGetCompletionStage("Command"));
            } catch (Throwable e) {
                error.set(e);
            }
        });

        t.start();
        t.join();

        assertNotNull(result.get(), "Expected to get a CompletionStage return value");
        assertNull(error.get());
    }

    @Test
    @Timeout(value = 2)
    void retrySchedulerInvokedOnFailure() throws Throwable {
        final AtomicReference<Object> result = new AtomicReference<>();
        final AtomicReference<Throwable> error = new AtomicReference<>();

        doAnswer(new Failure(new SomeRuntimeException()))
                .when(mockCommandBus).dispatch(isA(CommandMessage.class), isA(CommandCallback.class));

        Thread t = new Thread(() -> {
            try {
                result.set(gateway.waitForReturnValue("Command"));
            } catch (Throwable e) {
                error.set(e);
            }
        });

        t.start();
        t.join();

        verify(mockRetryScheduler).scheduleRetry(isA(CommandMessage.class),
                                                 isA(SomeRuntimeException.class),
                                                 anyList(),
                                                 any(Runnable.class));
        assertNotNull(error.get());
        assertNull(result.get(), "Did not Expect to get a Future return value");
    }

    @Test
    @Timeout(value = 2)
    void retrySchedulerNotInvokedOnCheckedException() throws Throwable {
        final AtomicReference<Object> result = new AtomicReference<>();
        final AtomicReference<Throwable> error = new AtomicReference<>();

        doAnswer(new Failure(new ExpectedException()))
                .when(mockCommandBus).dispatch(isA(CommandMessage.class), isA(CommandCallback.class));

        Thread t = new Thread(() -> {
            try {
                result.set(gateway.waitForReturnValue("Command"));
            } catch (Throwable e) {
                error.set(e);
            }
        });

        t.start();
        t.join();

        verify(mockRetryScheduler, never()).scheduleRetry(isA(CommandMessage.class),
                                                          any(RuntimeException.class),
                                                          anyList(),
                                                          any(Runnable.class));
        assertNotNull(error.get());
        assertNull(result.get(), "Did not Expect to get a Future return value");
    }

    @Test
    @Timeout(value = 2)
    void retrySchedulerInvokedOnExceptionCausedByDeadlock() {
        final AtomicReference<Object> result = new AtomicReference<>();
        final AtomicReference<Throwable> error = new AtomicReference<>();

        doAnswer(new Failure(new RuntimeException(new DeadlockException("Mock"))))
                .when(mockCommandBus).dispatch(isA(CommandMessage.class), isA(CommandCallback.class));

        try {
            result.set(gateway.waitForReturnValue("Command"));
        } catch (Exception e) {
            error.set(e);
        }

        verify(mockRetryScheduler).scheduleRetry(isA(CommandMessage.class),
                                                 any(RuntimeException.class),
                                                 anyList(),
                                                 any(Runnable.class));
        assertNotNull(error.get());
        assertNull(result.get(), "Did not Expect to get a Future return value");
    }

    @Test
    @Timeout(value = 2)
    void createGatewayWaitForResultAndInvokeCallbacksSuccess() {
        CountDownLatch latch = new CountDownLatch(1);
        CommandResultMessage<String> resultMessage = asCommandResultMessage("OK");
        final CommandCallback<Object, String> callback1 = mock(CommandCallback.class);
        final CommandCallback<Object, String> callback2 = mock(CommandCallback.class);

        doAnswer(new Success(latch, resultMessage))
                .when(mockCommandBus).dispatch(isA(CommandMessage.class), isA(CommandCallback.class));

        Object result = gateway.fireAndWaitAndInvokeCallbacks("Command", callback1, callback2);
        assertEquals(0, latch.getCount());

        assertNotNull(result);
        verify(callback1).onResult(any(), eq(resultMessage));
        verify(callback2).onResult(any(), eq(resultMessage));
    }

    @Test
    @Timeout(value = 2)
    void createGatewayWaitForResultAndInvokeCallbacksFailure() {
        final RuntimeException exception = new RuntimeException();
        final CommandCallback<Object, ?> callback1 = mock(CommandCallback.class);
        final CommandCallback<Object, ?> callback2 = mock(CommandCallback.class);

        doAnswer(new Failure(exception))
                .when(mockCommandBus).dispatch(isA(CommandMessage.class), isA(CommandCallback.class));

        try {
            gateway.fireAndWaitAndInvokeCallbacks("Command", callback1, callback2);
            fail("Expected exception");
        } catch (RuntimeException e) {
            //noinspection rawtypes
            ArgumentCaptor<CommandResultMessage> commandResultMessageCaptor = forClass(CommandResultMessage.class);
            verify(callback1).onResult(any(), commandResultMessageCaptor.capture());
            verify(callback2).onResult(any(), commandResultMessageCaptor.capture());

            assertEquals(2, commandResultMessageCaptor.getAllValues().size());
            assertEquals(exception, commandResultMessageCaptor.getAllValues().get(0).exceptionResult());
            assertEquals(exception, commandResultMessageCaptor.getAllValues().get(1).exceptionResult());
        }
    }

    @Test
    @Timeout(value = 2)
    void createGatewayAsyncWithCallbacksSuccess() {
        CountDownLatch latch = new CountDownLatch(1);
        CommandResultMessage<String> resultMessage = asCommandResultMessage("OK");
        final CommandCallback<Object, String> callback1 = mock(CommandCallback.class);
        final CommandCallback<Object, String> callback2 = mock(CommandCallback.class);

        doAnswer(new Success(latch, resultMessage))
                .when(mockCommandBus).dispatch(isA(CommandMessage.class), isA(CommandCallback.class));

        gateway.fireAsyncWithCallbacks("Command", callback1, callback2);
        assertEquals(0, latch.getCount());

        verify(callback1).onResult(any(), eq(resultMessage));
        verify(callback2).onResult(any(), eq(resultMessage));
    }

    @Test
    @Timeout(value = 2)
    void createGatewayAsyncWithCallbacksSuccessButReturnTypeDoesNotMatchCallback() {
        CountDownLatch latch = new CountDownLatch(1);
        CommandResultMessage<Object> resultMessage = asCommandResultMessage(42);
        final CommandCallback<Object, Object> callback1 = mock(CommandCallback.class);
        final CommandCallback<Object, Object> callback2 = mock(CommandCallback.class);

        doAnswer(new Success(latch, resultMessage))
                .when(mockCommandBus).dispatch(isA(CommandMessage.class), isA(CommandCallback.class));

        gateway.fireAsyncWithCallbacks("Command", callback1, callback2);
        assertEquals(0, latch.getCount());

        verify(callback1).onResult(any(), eq(resultMessage));
        verify(callback2).onResult(any(), eq(resultMessage));
        verify(callback, never()).onResult(any(), any());
    }

    @Test
    @Timeout(value = 2)
    void createGatewayAsyncWithCallbacksFailure() {
        final RuntimeException exception = new RuntimeException();
        final CommandCallback<Object, ?> callback1 = mock(CommandCallback.class);
        final CommandCallback<Object, ?> callback2 = mock(CommandCallback.class);

        doAnswer(new Failure(exception))
                .when(mockCommandBus).dispatch(isA(CommandMessage.class), isA(CommandCallback.class));

        gateway.fireAsyncWithCallbacks("Command", callback1, callback2);

        //noinspection rawtypes
        ArgumentCaptor<CommandResultMessage> commandResultMessageCaptor =
                forClass(CommandResultMessage.class);
        verify(callback1).onResult(any(), commandResultMessageCaptor.capture());
        verify(callback2).onResult(any(), commandResultMessageCaptor.capture());
        assertEquals(2, commandResultMessageCaptor.getAllValues().size());
        assertEquals(exception, commandResultMessageCaptor.getAllValues().get(0).exceptionResult());
        assertEquals(exception, commandResultMessageCaptor.getAllValues().get(1).exceptionResult());
    }

    @Test
    @Timeout(value = 2)
    void createGatewayCompletableFutureFailure() {
        final RuntimeException exception = new RuntimeException();

        doAnswer(new Failure(exception))
                .when(mockCommandBus).dispatch(isA(CommandMessage.class), isA(CommandCallback.class));

        CompletableFuture<Object> future = gateway.fireAndGetCompletableFuture("Command");

        assertTrue(future.isDone());
        assertTrue(future.isCompletedExceptionally());
    }

    @Test
    @Timeout(value = 2)
    void createGatewayCompletableFutureSuccessfulResult() throws Throwable {
        String expectedReturnValue = "returnValue";

        doAnswer(new Success(asCommandResultMessage(expectedReturnValue)))
                .when(mockCommandBus).dispatch(isA(CommandMessage.class), isA(CommandCallback.class));

        CompletableFuture<Object> future = gateway.fireAndGetCompletableFuture("Command");

        assertTrue(future.isDone());
        assertEquals(expectedReturnValue, future.get());
    }

    @Test
    @Timeout(value = 2)
    void createGatewayFutureSuccessfulResult() throws Throwable {
        String expectedReturnValue = "returnValue";

        doAnswer(new Success(asCommandResultMessage(expectedReturnValue)))
                .when(mockCommandBus).dispatch(isA(CommandMessage.class), isA(CommandCallback.class));

        Future<Object> future = gateway.fireAndGetFuture("Command");

        assertTrue(future.isDone());
        assertEquals("returnValue", future.get());
    }

    @Test
    @Timeout(value = 2)
    void retrySchedulerNotInvokedOnExceptionCausedByDeadlockAndActiveUnitOfWork() {
        final AtomicReference<Object> result = new AtomicReference<>();
        final AtomicReference<Throwable> error = new AtomicReference<>();
        UnitOfWork<CommandMessage<?>> uow = DefaultUnitOfWork.startAndGet(null);

        doAnswer(new Failure(new RuntimeException(new DeadlockException("Mock"))))
                .when(mockCommandBus).dispatch(isA(CommandMessage.class), isA(CommandCallback.class));

        try {
            result.set(gateway.waitForReturnValue("Command"));
        } catch (Exception e) {
            error.set(e);
        } finally {
            uow.rollback();
        }

        verify(mockRetryScheduler, never()).scheduleRetry(isA(CommandMessage.class),
                                                          any(RuntimeException.class),
                                                          anyList(),
                                                          any(Runnable.class));
        assertNotNull(error.get());
        assertNull(result.get(), "Did not Expect to get a Future return value");
    }

    @Test
    @Timeout(value = 2)
    void createGatewayEqualsAndHashCode() {
        CompleteGateway gateway2 = testSubject.createGateway(CompleteGateway.class);

        assertNotSame(gateway, gateway2);
        assertNotEquals(gateway, gateway2);
    }

    @Test
    void differentCommandCallbackResultTypesInvocationsAreAllInvoked() {
        String expectedResult = "OK";
        AtomicBoolean stringCallbackInvocation = new AtomicBoolean(false);
        AtomicBoolean integerCallbackInvocation = new AtomicBoolean(false);

        CommandResultMessage<String> resultMessage = asCommandResultMessage(expectedResult);
        CommandCallback<Object, String> stringCallback = (command, result) -> stringCallbackInvocation.set(true);
        CommandCallback<Object, Integer> integerCallback = (command, result) -> integerCallbackInvocation.set(true);

        doAnswer(new Success(resultMessage))
                .when(mockCommandBus).dispatch(isA(CommandMessage.class), isA(CommandCallback.class));

        Object result = gateway.fireAsyncWithCallbacksOfSpecificResultType("Command", stringCallback, integerCallback);

        assertNotNull(result);
        assertEquals(expectedResult, result);
        assertTrue(stringCallbackInvocation.get());
        assertTrue(integerCallbackInvocation.get());
    }

    @SuppressWarnings("UnusedReturnValue")
    private interface CompleteGateway {

        void fireAndForget(Object command, MetaData meta,
                           @MetaDataValue("test") Object metaTest, @MetaDataValue("key") Object metaKey);

        String waitForReturnValue(Object command);

        void waitForException(Object command) throws InterruptedException;

        @Timeout(value = 1, unit = TimeUnit.SECONDS)
        void fireAndWait(Object command);

        void fireAndWaitWithTimeoutParameter(Object command, long timeout, TimeUnit unit);

        Object fireAndWaitWithTimeoutParameterAndException(Object command, long timeout, TimeUnit unit)
                throws TimeoutException;

        Object fireAndWaitForCheckedException(Object command) throws ExpectedException;

        Future<Object> fireAndGetFuture(Object command);

        CompletableFuture<Object> fireAndGetCompletableFuture(Object command);

        CompletionStage<Object> fireAndGetCompletionStage(Object command);

        CompletableFuture<Object> futureWithTimeout(Object command, int timeout, TimeUnit unit);

        Object fireAndWaitAndInvokeCallbacks(Object command,
                                             CommandCallback<Object, ?> first,
                                             CommandCallback<Object, ?> second);

        void fireAsyncWithCallbacks(Object command,
                                    CommandCallback<Object, ?> first,
                                    CommandCallback<Object, ?> second);

        Object fireAsyncWithCallbacksOfSpecificResultType(Object command,
                                                          CommandCallback<Object, String> stringCallback,
                                                          CommandCallback<Object, Integer> integerCallback);
    }

    private static class StringCommandCallback implements CommandCallback<Object, String> {

        @Override
        public void onResult(@Nonnull CommandMessage<?> commandMessage,
                             @Nonnull CommandResultMessage<? extends String> commandResultMessage) {
        }
    }

    private static class SomeRuntimeException extends RuntimeException {

    }

    private static class ExpectedException extends Exception {

    }

    private static class Success implements Answer<Object> {

        private final CountDownLatch latch;
        private final CommandResultMessage<?> returnValue;

        Success(CommandResultMessage<?> returnValue) {
            this(new CountDownLatch(1), returnValue);
        }

        Success(CountDownLatch latch, CommandResultMessage<?> returnValue) {
            this.latch = latch;
            this.returnValue = returnValue;
        }

        @Override
        public Object answer(InvocationOnMock invocation) {
            latch.countDown();
            //noinspection rawtypes
            ((CommandCallback) invocation.getArguments()[1])
                    .onResult((CommandMessage) invocation.getArguments()[0], returnValue);
            return null;
        }
    }

    private static class Failure implements Answer<Object> {

        private final CountDownLatch latch;
        private final Exception e;

        Failure(CountDownLatch latch, Exception e) {
            this.latch = latch;
            this.e = e;
        }

        Failure(Exception e) {
            this(null, e);
        }

        @Override
        public Object answer(InvocationOnMock invocation) {
            if (latch != null) {
                latch.countDown();
            }
            //noinspection rawtypes
            ((CommandCallback) invocation.getArguments()[1])
                    .onResult((CommandMessage) invocation.getArguments()[0], asCommandResultMessage(e));
            return null;
        }
    }

    private static class CountDown implements Answer<Object> {

        private final CountDownLatch cdl;

        CountDown(CountDownLatch cdl) {
            this.cdl = cdl;
        }

        @Override
        public Object answer(InvocationOnMock invocation) {
            cdl.countDown();
            return null;
        }
    }
}


Pack up all your gear in an Adidas Stadium II backpack for only $42 today. The main and front mesh pockets are both big enough to fit a regulation size soccer ball, and the bottom zippered compartment is designed to keep dirty cleats or sneakers away from the rest of your stuff. Today's price is the best we've ever seen on Amazon, and you'll have a whole bunch of colors to pick from.


Mortensen is justly celebrated in Hollywood for how he telegraphs both, which are reading in his face right now.
A face rendered (almost) unrecognizable with that distracting droop of a Wild West mustache, the familiar starburst cleft in his chin forested over by a neat beard.
The frostbite-blue eyes snap onto mine for a split second.
NY-Lon nexus: from left, Lauren Santo Domingo, Kristina O'Neill, Dasha Zhukova and Derek Blasberg at a party this week to toast Dasha's Wall Street Journal magazine cover (Picture: Victor Boyko/Getty) In between the couture fashion shows in Paris this week, supermodels, designers and journalists made time for an elite gathering at Vogue contributing editor Lauren Santo Domingo's tasteful flat in Saint- Germain.
Santo Domingo (known as LSD to friends) co-hosted the evening with fashion editor Derek Blasberg, to "celebrate" their friend Dasha Zhukova, who wore a high-necked blood-red dress by Simone Rocha.
I also collect art you can find at flea markets, the streets of NYC, or Estate Auctions online, etc.
My last purchase was an oil painting of a little blonde boy hitchhiking with two six shooters, a lollipop, and a tear in his eye. This weekend I just played a painting party at Jim Carrey's painting studio.
The official reason for the party was the cover story she'd recently run in her New York-based title earlier this month — it centred on Zhukova, 33, and her ambitious project to give Moscow a contemporary art museum, designed by Rem Koolhaas.
A profile in such a serious New York magazine is the ultimate welcome to this famously unforgiving city.
And it marks the status of Zhukova, an art collector and philanthropist, as the latest member of the New York-London set.
Her husband, billionaire Roman Abramovich, 48, has bought a house (well, three brownstones — worth a combined million — that he plans to knock together) in the Upper East Side.
I am a poet, photographer, filmmaker, DJ/remixer and curator. I played music at the Submercer back when it was a "speakeasy". I saw the space below the hotel one day when I was touring around with Sean Mac Pherson. I've included new paintings and one more artist named Michael Tharp. I have paintings from artists/friends such as Ross Bleckner, John Newsom, Lola Schnabel and Kika Karadi.
I love the work of all the artists I've had in my shows.
Once a music photographer, Makebish dove into making music of his own, and was Andre Balazs' go to DJ for years.


Epilepsy affects nearly half a million children each year in the United States, according to recent estimates from the Centers for Disease Control and Prevention. It's one of the most common neurological disorders diagnosed in America and takes on different forms in different people. UChicago Medicine asked pediatric neurologist and epileptologist Chalongchai Phitsanuwong, MD, to explain how children with epilepsy are diagnosed and treated.
Q: How do you diagnose a child with epilepsy?
A: Looking at a patient's clinical history and conducting a thorough neurological examination are fundamentally important to diagnosing kids with epilepsy. We also use certain diagnostic tools like electroencephalography (EEG) or brain magnetic resonance imaging (MRI). To determine the cause of certain complicated cases, we may need to collect fluid from a patient's spine and analyze their blood and urine or obtain genetic testing.
Q: What are the treatment options for epilepsy patients?
A: UChicago Medicine offers comprehensive treatments of epilepsy. Some patients need anti-seizure medications, while others may not respond to medications alone. For those patients, who we identify as having drug-resistant epilepsy, we offer surgery, ketogenic diets and a neurostimulator device, which is a device that provides electrical stimulation to the brain through leads to prevent seizures. We also look at symptoms and disorders that frequently accompany epilepsy, like learning disabilities, developmental delays and attention deficit/hyperactivity disorder (ADHD). Our team uses a comprehensive approach and works closely with developmental behavior pediatricians, social workers and our colleagues in child psychiatry.
A: Ketogenic diets are special medical diets specifically used as metabolic-based therapy for epilepsy. They incorporate high fat, moderate protein and low carbohydrate foods, which induce a metabolic state called ketosis (hence, "ketogenic"). Experts do not know for certain how the ketogenic diets work to stop seizures, but they do know they are proven to work. We believe the diet has multiple mechanisms, and to put it simply, it "strengthens" the nervous system against seizures.
Q: Who qualifies for ketogenic diets?
A: Traditionally, these diets are used in patients who have failed at least two anti-seizure medications and are not deemed good surgical candidates. Ketogenic diets can be used early in some circumstances depending on clinical necessity. Although the diets have relatively low side effects, I strongly caution everybody who would like to start on the diet that it needs to be done under close supervision of a ketogenic diet-trained dietitian and neurologist. Currently at UChicago, we have a multidisciplinary ketogenic diet program with an epilepsy specialist, ketogenic dietitian, nurse and social worker that offers the dietary treatment for both children and adults with epilepsy.
Q: Do you primarily see patients on their first visit, or are you often a resource for second opinions?
A: Both. I have many patients in my practice who came to me after having a new onset seizure and even more patients who were referred or came to see me as a second or third opinion, as there are not many pediatric epilepsy specialists.
Q: What distinguishes UChicago Medicine's epilepsy treatment offerings from other hospitals?
A: We are one of few places in the state that can offer such a wide array of epilepsy treatments for children, including anti-seizure medications, ketogenic diets, neurostimulation and traditional or minimally invasive epilepsy surgery. We also have an experienced team of pediatric neurologists, epileptologists, neurosurgeons and dietitians. We also offer a wide variety of epilepsy diagnostic tools including EEG with long-term monitoring, high-resolution MRI, PET scan, functional MRI and genetic testing for epilepsy.
Pediatric neurologist and epileptologist Chalongchai Phitsanuwong, MD, specializes in the treatment of children with epilepsy, using medication and medical diets. He has unique expertise in ketogenic diets for the treatment of difficult-to-control seizures, particularly when epilepsy surgery is not deemed an option.


text:
Spiritual Accompaniment
Mission and Charism
Canadian Federation
Sisters of Service
as a Sister
as an Associate
as an Employee
Catholics Urge Prime Minister to Take Urgent and Swift Measures to Address Climate Emergency
In celebration of the 5th anniversary of Pope Francis' encyclical Laudato Si': On Care for Our Common Home, the Joint Ecological Ministry (JEM) called on Catholics across Canada to unite and demand the government "take immediate concrete actions to flatten the curve of global warming and move towards a just and sustainable future."
"As with all crises, it is those who are already marginalized and oppressed who are suffering most from the COVID-19 fallout. All of Creation is being threatened for the sake of our economy" says Leah Watkiss, the Director of the Ministry for Social Justice, Peace, and Creation Care. Following Pope Francis' appeal: "Living our vocation to be protectors of God's handiwork is … not an optional or a secondary aspect of our Christian experience," (Laudato Si' #217) Catholics have the moral obligation to protect all Creation for today -- and for future generations.
Catholics United for Climate Action was signed by 73 Catholic communities and organizations, and 551 Catholic individuals from across Canada. The petition demands that Canada's recovery:
Reject bailouts of oil and gas industries, instead urging government to implement the commitment to table and then pass in Parliament the Just Transition Act.
Implement the UN Declaration on the Rights of Indigenous Peoples (UNDRIP)
Prioritize action on multilateral debt cancellation for countries of the Global South struggling to meet the challenges of the pandemic as well as the climate emergency.
The letter was delivered today to PM Justin Trudeau. Please click here for a full list of all signatories.
Leah Watkiss
Ministry Director - Ministry for Social Justice, Peace, and Creation Care
Joe Gunn
Executive Director/Directeur général Centre Oblat – A Voice for Justice
*Joint Ecological Ministry (JEM) is a collaboration of religious communities and partners using their resources to promote caring for Creation and living within planetary limits.
Out of deep respect for those who have cared for these lands since time immemorial, we are committed to tread lightly on the land, protect water as sacred, and affirm our desire for right relations with all Indigenous Peoples. - From our CSJ Land Acknowledgement
Sisters of St. Joseph of Toronto © 2023

redpajama_set_name: RedPajamaCommonCrawl


Kholeka Engineering (Pty) Ltd is a proudly South African, Level 1 value added BEE (Black Economic Empowerment) rated company that was established in 2003. We specialise in the manufacturing of Trailers and Truck Bodies. Our BEE status qualifies us as an empowered supplier to the government and corporate clients, affording them a 135% procurement spend advantage. We are 100% owned by Black owned and managed ISIPHO CAPITAL HOLDINGS (PTY) LTD.
Our fabrication team processes large chassis, from cutting and bending through to spraying in the 3-bay spray shop.


text:
« Town Mountain's "Leave the Bottle" Releases TODAY and Debuts at #4 on Bluegrass Today's Radio Charts!
Activities, Excursions and the Theme Night Announced for Strings & Sol! »
Mike Cullison, the Roadhouse Rambler, Releases "The Barstool Monologues" on Nov 13th
September 4, 2012 by dreamspider
The Barstool Monologues
MIKE CULLISON & The Regulars
"A Honky-Tonk Canterbury Tales"
"Fans of classic country music will feel right at home with Mike Cullison."
–John Davy, No Depression
"A captivating blues rocker … soulful roadhouse songwriting." –Simon Hallett, Totnes FM (UK)
"This is what country music has been missing … [Mike] is bringing it back." –Renaldo 6, SongCritic.com
"I think music is the highway through life and I'm just rockin' and rollin' down the road." —Mike Cullison
www.theroadhouserambler.com
Singer-songwriter Mike Cullison (aka "The Roadhouse Rambler") is used to hearing his work defined in painterly terms; music journalists commonly pull out such metaphors when trying to describe songs. But with his new album, The Barstool Monologues (due out November 13th through JoeDog Records), it's almost as if he's working in the 3D style of sculptor J. Seward Johnson Jr., who turns famous Impressionist paintings into life-sized tableaux, incorporating not only the original images, but his own fanciful imaginings of what went on beyond the canvas.
Cullison takes a similar approach with The Barstool Monologues, weaving lives of bar patrons into songs, then threading them together with spoken-word narrative to create a vivid musical tableau. There's the heartbroken lover, the fracturing couple, the other woman, the lonely imbiber … each introduced by a bartender named Hollis, who sees and hears it all. Various singers (including Jon Byrd, Davis Raines, and six others) inhabit their personas, spinning musical novellas into what Cullison likes to describe as "a honky-tonk Canterbury Tales."
"It's as if you walked into a place and you took a snapshot and everybody's looking in the camera," says the Nashville resident. "What I wanted to do was place everybody in that picture into one of the songs, either as its subject or the person singing it to somebody else."
Mike Cullison. Photo by Greg Roth.
Cullison, an Oklahoma native who's honed his songwriting skills with such royalty as Don Goodman ("Ol' Red"; "Ring on Her Finger, Time on Her Hands"), Johnny Neel (the Allman Brothers) and Mike Stergis (Crosby, Stills & Nash), describes his style as "roadhouse blues and country roots-rock." But his influences are as vast as the early rock 'n' roll his mom adored and the classic country his dad preferred, and he draws deeply from that well, along with other Americana styles — from Bakersfield to hybrid zyde-Cajun blues — to create a rich aural tapestry as colorful as Johnson's art.
He considers himself a lyric writer first, however. "The story and how it is told are very important to me," Cullison says. "Some songs come at you very quickly, but most take time. There's still a lot of polishing to do even after the lightning bolts strike."
Cullison's career has taken time, too. In fact, the release party for his first album, 2004's BAC (Big American Car), was also his retirement party after 32 years with the Bell Telephone Co. Midway through his Bell Tel years, he moved to Atlanta, "because it was five hours closer to Nashville." His ultimate goal was always Music City, "because that's where the writers were."
He finally made it in 1995. Throughout his day-job years, he always wrote and performed; in Atlanta, he was in a band called Lone Walter. These days, Cullison appears solo or with a variety of friends and collaborators in the states and Europe, where he first released the EP Roadhouse Rambler in 2011, which hit #1 on the Airplay Direct radio charts. (His second CD, Blue Collar Tired, came out in 2007.)
Like most musicians, Cullison spends his share of time in bars. And like most country-influenced players, he's sung his share of "tears in beer" tunes. But one night, while performing at the late Nashville bar the Sutler (lost, sadly, to developers), a thought struck: "Instead of having somebody sitting on the customer's side of the bar crying in their beer, what if we turned it around?"
That was the genesis of the Mark Robinson-produced The Barstool Monologues.
"Songwriting is storytelling, so it kind of fit for me," says Cullison, who also has plenty of "behind the song" stories. One of his favorites involves the opening tune, "Wish I Didn't Like Whiskey" — a perfect choice to open an album set in a bar.
"I had bought a drink for a friend of mine," Cullison relates, "and as I handed her the glass, she said, 'I wish I didn't like whiskey so much.' I excused myself for a minute while I wrote that on a coaster. Turned out to be a very good song."
They've all turned out to be very good songs — vignettes, actually, sung and performed by some of Nashville's finest. If Cullison has his way, The Barstool Monologues might even turn into a musical of some sort, with actors and stage sets. Life-sized, like a Johnson tableau. Only even more real, because we can recognize the characters in Cullison's stories. They're our friends, our exes … or maybe even ourselves.
Posted in Mike Cullison | Tagged Bakersfield, bar patrons, bar stories, Barstool Monologues, blues rocker, Canterbury Tales, country, Country Music, country roots-rock, honky tonk, J. Seward Johnson Jr., Johnson tableau, lyric writer, Mark Robinson, Mike Cullison, Music, NAshville, old school country, rambler, RoadHouse, roadhouse rambler, rowdy, singer-songwriter, songwriter, story teller, storytelling, vignettes, Wish I Didn't Like Whiskey, zyde-Cajun blues | Leave a Comment


Let see how to cook authentic Tamil recipe Idli(idly) sambar recipe with step by step instructions.
Cook the red gram or Pigeon Pea with water to a paste. You can use pressure cooker also.
Cut the Shallots into small cubes, Cut the tomatoes into small pieces. cut and split the green chili.
Heat oil in a pan. When its hot add mustard seed, black gram , split Bengal gram, fenugreek seed , dry chili and curry leaves until the mustard seed splatter.
Now add add shallots and fry until golden brown. Now at the cut tomatoes and fry until oil separates.
Now add the sambar powder, asafetida and Tamarind paste, add 1/4 cup water and cook for 5 min.
Now add the cooked black gram and salt to taste. Cook for 3 min add the coriander leaves and remove from flame.


text:
Electric ferry gets off to a great start with DEIF solution
In 2021, Danish ferry operator Molslinjen added an electric ferry to its Esbjerg-Fanø route to boost service reliability and minimise environmental impact. A DEIF solution including a Delomatic 4 power and energy management system plus competent project support has helped make the switch from diesel to electric propulsion very successful. One captain considers the system very easy to use, and the project superintendent ranks the experience as the best new ship project he has been involved in.
Off the west coast of Jutland, Denmark, lies the scenic island of Fanø at the northern end of the shallow Wadden Sea. Even though Fanø is only a couple of kilometres from the busy port city of Esbjerg on the mainland, there has never been a bridge to the island; instead, its 3,500 inhabitants and thousands of annual visitors depend on a ferry service. Since 2018, the Esbjerg-Fanø crossing has been operated by Danish ferry company Molslinjen which provides reliable ferry services for daily commuters and tourists alike. The need for reliability and safety is underscored by the fact that the ferry is an integral part of the island's emergency response system, always ready to take patients to hospital on the mainland.
"Every once in a while, accidents happen, and we're constantly on standby for ambulances," says captain Iben Gejl Christensen who has sailed the route since 2003. "When the ambulance arrives, we depart immediately."
New electric ferry with DEIF system on board
In 2021, Molslinjen decided to boost the reliability of the ferry service by reducing the workload for its two existing ferries, the Fenja and Menja, and at the same time minimise its environmental impact by adding a third ferry, the electric Grotte. The batteries on the new ferry power two 375 kW electric motors that take up to 35 cars and 300 passengers across at a service speed of 11.5 knots. The Grotte recharges its batteries from a 2 x 1,250 kW shore supply during each 8-minute stay in the port of Esbjerg; this provides the necessary energy for a purely electric round trip.
The electrical installations on board were handled by installation company Vest-El who used the DEIF Delomatic 4 power and energy management system to control and coordinate the power generating equipment on board and the connection to shore. In addition, DEIF contributed technical support and know-how throughout the project to ensure successful completion.
Easy to put into service
The Grotte has been in service since 1 October 2021 and both crews and management are happy with the new ship – and its control systems. Even though sailing on electrical power is different from sailing on diesel power, Iben Gejl Christensen has not had difficulties adjusting to the new system.
"I think it's simple to work with," she says. "It's very manageable. We just need to press two buttons to start charging and two buttons to prepare for departure. I was able to learn, so I guess most other people could, too," she adds with a smile.
Superintendent Thomas Jensen from Molslinjen is responsible for daily operations on the crossing and has been involved in the Grotte project since its early stages. He agrees that putting the new ferry into service has been relatively easy. "The commissioning went without any incidents," he says. "Of course, we had to test the charging procedure at night to avoid disturbing operations. We spent three or four nights getting things ready, and I think it went well."
State-of-the-art power and energy management
The Delomatic 4 system on the Grotte is a state-of-the-art power and energy management system that can be customised and engineered to fit a wide range of specifications and requirements. It is a perfect match for marine hybrid applications such as battery solutions and DC bus solutions, and the system can be monitored and controlled from multiple operator touch screens.
These features make the system a perfect match for the Grotte with its energy storage systems and DC bus. The control system on the ferry includes features for both daily operations and maintenance and can easily be accessed from 15" touch screens mounted on the bridge and in the two engine rooms. DEIF and Molslinjen staff can also access the system remotely to carry out monitoring or troubleshooting over a secure internet connection. The system provides facility management for the battery management system and displays important battery alarms on the operator touch screens, and it allows the crew to easily switch and manage batteries and inverters.
"We use the DEIF systems for power and energy management," explains Thomas Jensen. "It's very easy to connect engines, shore power, and charging power out there. Our navigators use the DEIF setups for battery, power, and energy management, and we use them in connection with maintenance and connecting and disconnecting the engines and motors. It works well."
Thomas Jensen, Superintendent Molslinjen
Quiet and easy daily operations
On the daily crossings, the captain and first mate take turns at the controls for a round trip, alternately overseeing loading and unloading and deck operations. The crew also includes an able ship's assistant and an ordinary ship's assistant.
"We don't really notice the battery operation, except that we can't hear the engines or see any smoke from the exhaust", says Iben Gejl Christensen. "Of course, we need to keep an eye on the state of charge, but apart from that it hasn't been a big challenge to adjust to battery operations. It's quiet on board – really quiet, in fact, and our passengers notice that, too".
When the Grotte is in port in Esbjerg, the crew can easily start and stop the charging procedure by pressing buttons on the touch screen. A hatch on the side of the ship is opened, and the charging system plug is lowered towards the hatch and automatically grabbed and plugged into the ferry socket. After charging, the plug is ejected and hoisted away from the ship, the hatch closes, and the propulsion system is ready for departure. If the state of charge drops below 56% at sea, the diesel engine is started automatically to recharge the battery in order to comply with international maritime safety regulations.
A good overview with no distractions
The 12-minute crossing goes through a narrow trench with little space to give way, and deeper waters right outside the port of Esbjerg where there is often heavy traffic. To ensure safe passage, the crew needs to manoeuvre constantly during the crossing. This is one of the reasons why the Grotte was purposely designed to resemble the Fenja and the Menja.
"That's what we wanted," comments Iben Gejl Christensen. "If we were to have a new ferry, it needed to resemble the existing ones as much as possible so we could just get on board and sail off immediately". Thomas Jensen adds, "The Grotte uses the same ramp system, and it's important to us that we can use it alongside the Fenja and the Menja."
The bridge layout and instrumentation are also very similar to those found on the existing ferries, but with one key difference: The 15" touch screen provides a good overview of every important aspect of the crossing. "It took us a little while to realise that we could see everything on one screen, and that we didn't need to go down to the engine room," remarks Iben Gejl Christensen. "I think it provides a good overview, and it doesn't distract us from our operations while we're sailing back and forth."
Contributing to greener shipping
When the Grotte was put into service, Danish Minister for Transport Benny Engelbrecht was one of several guests who attended the official launch event, indicating the significance of battery-powered vessels as a means to contribute to lower carbon emissions from shipping. Similarly, the ferry is a perfect match for Molslinjen's corporate social responsibility policy which calls for responsible conduct while contributing to freedom of movement: Molslinjen is continuously working to identify, prevent, or mitigate adverse impacts on sustainable development, and the Grotte proves that this can be achieved without adversely affecting the ferry timetable, or jeopardising safety on board.
"Our primary target was to get a green solution," says Thomas Jensen. "We want to be seen as an innovative and sustainably managed transportation company. Molslinjen wants to develop battery operations on its shorter routes in western Denmark. We believe that getting this crossing to work was a good start, and everything indicates that we will succeed so we're ready to upgrade our other routes with something similar to this. Bigger, of course, but similar!"
Since 1 October 2021, the Grotte has been in operation with no significant cancellations or delays, marking a great start for the electric ferry which is now handling the passenger load alongside the Fenja and Menja and ensuring reliable, green, and safe transportation through the UNESCO world heritage waters between Esbjerg and Fanø. Despite the new propulsion solutions below deck, however, not much has changed on the bridge.
"The new world of electric operation has not changed the crossing itself," says Iben Gejl Christensen. "We're doing the same thing that we always have: We sail back and forth and make sure our customers get to and from the island. We just need to focus on some other things. I think it's really easy to use the DEIF system because we can't really make mistakes. It has to be that way – it has to be simple and easy. We shouldn't have to press all kinds of menus to charge or stop charging or check how much power we've got on the batteries. It works well!"
Good performance with competent support
Throughout the project, DEIF has supported the Delomatic 4 system with know-how and practical technical solutions based on the company's extensive experience from all types of marine power applications, including electric and hybrid propulsion solutions. These competences have contributed to a smooth project process where issues and challenges have been resolved quickly through a good and open dialogue between Molslinjen and DEIF. Speaking from a manager's perspective, Thomas Jensen is very satisfied with the overall DEIF solution.
"I think DEIF has performed well," he says. "In the project phase, the start-up phase, and the operational phase, they've been receptive to the changes we have suggested. It's important that the people who are going to use the system every day can contribute. Overall, this is one of the best projects I've been involved in. I've had four or five projects before, but this is one of the best ones". He stops briefly to think and then concludes, "It's the best one."
Download the case study as PDF
Esper Flodgaard
+45 4070 9698 |
Per Ole Sørensen
Solution Manager, Marine & Offshore and Engine MFG
Battery hybrid power in marine applications
Marine hybrid
Hybrid ferries save 65% carbon dioxide


hockey coach to both of his children's hockey teams and because of this, he decided to use his Employee-Directed Gift to support his daughter's hockey team this year. The team of girls, aged 13-14 are part of the Ottawa Girls Hockey Association (OGHA) and their team is called the Ottawa Ice. At this level, the girls are on the ice three to five times a week and the teams compete with other leagues throughout Eastern Ontario and participate in several weekend tournaments that take place throughout the province.
With a big upcoming tournament in Cambridge on the horizon, Geoff knew that he wanted to help offset some of the cost for the team by using his Employee-Directed Gift. This three day tournament was going to be significant for the team because it would give them the opportunity to face other opponents from all over Ontario not just local to the Ottawa area. These teams also play a different style of hockey which can be a bit more physical – the Ottawa Ice were also choosing to play up a division for this tournament, adding to the challenge. It was an amazing weekend for the Ottawa Ice with lots of memories and they came out of it feeling like they had really risen to the challenge facing different teams from a higher level.
Martello is proud to help these eager young athletes get a chance to compete and support local hockey associations.


text:
109 staff members at risk of losing their jobs at SOAS: students and workers unite!
Published by Marxist Student on April 1, 2019 April 1, 2019
SOAS is currently undergoing an intense re-structuring. With a £7.1m gap in the budget, the dire financial crisis at SOAS is no secret. According to a report commissioned by UNISON and UCU Execs, the school is facing "an existential crisis".
Throughout the entire restructuring process, higher management have isolated themselves. Management claim they worked closely alongside unions when working out the process. We are infuriated by these blatant lies when our staff have had no say whatsoever in the security and future of their careers at SOAS.
While cutting over £1.5 million from Professional Services staffing budgets, the new structure sees an increase in senior management roles.
The damaging restructuring plan that SOAS' higher management have presented to staff and students is an obvious example of vicious class warfare. 109 members of our professional staff – some of which have been at SOAS for decades and are integral to the running of the university – have not been "matched" to new job descriptions as the current restructuring stands. In other words: for 109 people, their jobs will no longer exist.
Over a hundred members of staff – real people, supporting real families, with real rents and mortgages to pay – will be told that SOAS can no longer give them work.
For staff members who have been "matched" to new jobs, it comes as no surprise that their new job descriptions are a complete sham. Across the school, there has been a significant 'downgrading' of jobs.
This means that many job descriptions have been altered with the sole intention of being 'worth' a lower salary. However, the changes to the job descriptions are made as minimal as possible and are often made by changing the language; for example, omitting 'higher grade' key words like 'support'. Essentially, staff will be doing the exact same work whilst their wages will be savagely slashed. This 'downgrading' of roles is perhaps most significant for library staff. All jobs in the library currently stand at grade 7 and 8, however all new library positions are now graded at 6. This is a horrendous tactic pulled by management as a means to 'cut costs'.
The Baroness herself, Lady Amos, rakes in £225,000 a year – that's two years of our tuition fees in one month. The 8 parasites who make up the higher management team suck out £1m of SOAS funds per annum in their grossly large paychecks. Higher management are completely delusional in thinking it's acceptable to shift this damaging financial burden onto 109 members of professional staff, all whilst taking absolutely no responsibility for the dire situation they have put SOAS into. We will not stand aside and let our professional staff take the bullet for higher management's incompetence.
The motion passed at the emergency UGM on Friday 22nd of March shows that this seething anger is shared across the student body. We call on all and every member of the community at SOAS to get engaged, reach out, attend any open union meetings, email your heads of department, and prepare to support any strike action in solidarity with staff. Let's continue to build pressure on the joke of a management at SOAS.
What is happening at SOAS right now is in no way an isolated incident. Other universities in Britain are facing similar or connected struggles; Reading, Swansea, Cardiff, UCL, Goldsmiths, KCL. This is a direct result of the commercialisation of Higher Education, turning our education into a commodity, profiting the fat cats at the very tops of institutions. Whilst our immediate aim is to pressure management into scrapping this failure of an OPS plan, we must point out the broader picture at a national level.
Management are far removed from the day to day life of the university. It is the students, academic staff, cleaners, security staff and all other professional staff who actually run the university.
We stand for democratic control of universities by elected representatives, not unelected management. We want elected managers to be paid the same wage as teachers and staff, not university vice-chancellors who earn six-figure salaries while staff are forced to take pay cuts, or indeed redundancies as seen here.
Capitalism is in its death agony. It can no longer provide for those outside the highest earning 1% of society. Valerie Amos and those whose huge paychecks are at stake are running amok trying to keep the situation under control, but like our disgraced Prime Minister May – they're destined to fail. The days of the fat cats raking in profits at the expense of the livelihoods of workers will come to an end within our lifetime.
Join the struggle!
Students and workers united will never be defeated!
SOAS Marxist Society executive:
Nicolas Navarro Padron, Peter Kwasiborski, Mina-Mae Alexander, Phoenix Scotney, Eric Moore.
Categories: AnalysisSOASWorkers Movement
Marxist students prepare for a red 2023!
As the new year begins, Marxist students are preparing for a busy term of activity: showing solidarity with striking workers; discussing revolutionary events past and present; and building the forces of Marxism on UK campuses. Join the MSF today!
MSF solidarity message with the masses in Peru
The Marxist Student Federation, representing students from over 50 universities and colleges across Britain, stands in full solidarity with the mass movement taking place in Peru.