/*
 * Copyright 2017, TeamDev Ltd. All rights reserved.
 *
 * Redistribution and use in source and/or binary forms, with or without
 * modification, must retain the above copyright notice and the following
 * disclaimer.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package io.spine.server.integration;

import com.google.protobuf.Message;
import io.spine.core.AbstractMessageEnvelope;
import io.spine.core.ActorContext;
import io.spine.core.EventContext;
import io.spine.type.MessageClass;

import static com.google.common.base.Preconditions.checkNotNull;
import static io.spine.util.Exceptions.newIllegalStateException;

/**
 * An envelope for the messages, produced outside of the current bounded context.
 *
 * @author Alex Tymchenko
 */
public final class ExternalMessageEnvelope
        extends AbstractMessageEnvelope<Message, ExternalMessage, ActorContext> {

    /** An identifier of the original message (e.g. event ID). */
    private final Message id;

    /** An original message (e.g. instance of {@code io.spine.sample.TaskCreated}). */
    private final Message message;

    /** A message class of the original message (e.g. {@code io.spine.sample.TaskCreated} class). */
    private final MessageClass messageClass;

    /** An actor context representing the environment in which the original message was created. */
    private final ActorContext actorContext;

    private ExternalMessageEnvelope(ExternalMessage externalMessage,
                                    Message originalMessage) {
        super(externalMessage);

        this.id = externalMessage.getId();
        this.message = originalMessage;
        this.messageClass = ExternalMessageClass.of(this.message.getClass());
        this.actorContext = externalMessage.getActorContext();

    }

    public static ExternalMessageEnvelope of(ExternalMessage externalMessage,
                                             Message originalMessage) {
        checkNotNull(externalMessage);
        return new ExternalMessageEnvelope(externalMessage, originalMessage);
    }

    @Override
    public Message getId() {
        return id;
    }

    @Override
    public Message getMessage() {
        return message;
    }

    @Override
    public MessageClass getMessageClass() {
        return messageClass;
    }

    @Override
    public ActorContext getMessageContext() {
        return actorContext;
    }

    @Override
    public void setOriginContext(EventContext.Builder builder) {
        /*
         * This should never happen, as no event is caused directly by an {@code ExternalMessage}.
         *
         * Instead, the external messages are consumed by an anti-corruption layer, such as
         * external reactor or subscriber methods in the destination bounded context.
         */
        throw newIllegalStateException(
                "An external message like this (%s) may not be a direct origin of any event.",
                this);
    }
}

@@ -2517,24 +2517,825 @@
 ();%0A%0A    %7D%0A%0A
+    /**%0A     * Creates a new instance of %7B@code ExternalMessageEnvelope%7D from the %7B@link ExternalMessage%7D%0A     * instance and the message transferred inside the %7B@code ExternalMessage%7D, such as%0A     * a %7B@code io.spine.sample.TaskCreated%7D event message.%0A     *%0A     * %3Cp%3EThis factory method provides an optimal performance of%0A     * the %7B@code ExternalMessageEnvelope%7D creation. It allows to avoid unpacking the original%0A     * message from the %7B@code ExternalMessage%7D instance.%0A     *%0A     * @param externalMessage the instance of %7B@code ExternalMessage%7D to wrap into an envelope%0A     * @param originalMessage the message instance, which was originally transferred inside the%0A     *                        %7B@code externalMessage%7D%0A     * @return the new instance of external message envelope.%0A     */%0A
     public s

Document the factory method of `ExternalMessageEnvelope`.