/*
 * Copyright 2019 MovingBlocks
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.terasology.gestalt.assets.management;

import com.google.common.collect.Queues;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.gestalt.naming.Name;

import java.util.Deque;

/**
 * ContextManager provides the ability to set the module context in which a thread is currently running, and this context can be checked. In the asset system this
 * is used to have the current context influence the resolution of assets.
 *
 * @author Immortius
 */
public final class ContextManager {

    private static final Logger logger = LoggerFactory.getLogger(ContextManager.class);
    private static final ThreadLocal<Deque<Name>> CONTEXT_STACK = ThreadLocal.withInitial(Queues::newArrayDeque);

    private ContextManager() {
    }

    /**
     * @return The Name of the module that is the current context of the thread. If there is no current context the result will be Name.EMPTY.
     */
    public static Name getCurrentContext() {
        Name context = CONTEXT_STACK.get().peek();
        return (context != null) ? context : Name.EMPTY;
    }

    /**
     * Sets the current context and returns a resource that should be closed when the context ends.
     *
     * @param moduleId The name of the module to make the current context
     * @return A Context object that should be closed when the context ends. This will restore the preceding context if any.
     */
    public static Context beginContext(final Name moduleId) {
        CONTEXT_STACK.get().push(moduleId);
        return new Context() {

            @Override
            public Name getContext() {
                return moduleId;
            }

            @Override
            public void close() {
                Deque<Name> stack = CONTEXT_STACK.get();
                if (!moduleId.equals(stack.pop())) {
                    logger.error("Module context ended out of sequence");
                }
                if (stack.isEmpty()) {
                    CONTEXT_STACK.remove();
                }
            }
        };
    }
}

@@ -1270,16 +1270,20 @@
 _STACK =
+ new
  ThreadL
@@ -1290,29 +1290,117 @@
 ocal
-.withInitial(
+%3CDeque%3CName%3E%3E() %7B%0A        @Override%0A        protected Deque%3CName%3E initialValue() %7B%0A            return 
 Queues
-::
+.
 newA
@@ -1408,17 +1408,35 @@
 rayDeque
-)
+();%0A        %7D%0A    %7D
 ;%0A%0A    p

remove only use of Android API 24 incompatible code