text:
package org.elasticsearch.cluster.metadata;

import com.carrotsearch.hppc.ObjectArrayList;
import com.carrotsearch.hppc.ObjectHashSet;
import com.carrotsearch.hppc.cursors.ObjectCursor;
import com.carrotsearch.hppc.cursors.ObjectObjectCursor;
import com.google.common.base.Predicate;
import com.google.common.collect.*;

import org.apache.lucene.util.CollectionUtil;
import org.elasticsearch.cluster.*;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.cluster.DiffableUtils.KeyedReader;
import org.elasticsearch.cluster.block.ClusterBlock;
import org.elasticsearch.cluster.block.ClusterBlockLevel;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.HppcMaps;
import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.regex.Regex;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.loader.SettingsLoader;
import org.elasticsearch.common.xcontent.*;
import org.elasticsearch.index.Index;
import org.elasticsearch.indices.IndexClosedException;
import org.elasticsearch.indices.IndexMissingException;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.warmer.IndexWarmersMetaData;

import java.io.IOException;
import java.util.*;

import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Maps.newHashMap;
import static org.elasticsearch.common.settings.Settings.*;

/**
 *
 */
public class MetaData implements Iterable<IndexMetaData>, Diffable<MetaData> {

    public static final MetaData PROTO = builder().build();

    public static final String ALL = "_all";

    public enum XContentContext {
        /* Custom metadata should be returns as part of API call */
        API,

        /* Custom metadata should be stored as part of the persistent cluster state */
        GATEWAY,

        /* Custom metadata should be stored as part of a snapshot */
        SNAPSHOT
    }

    public static EnumSet<XContentContext> API_ONLY = EnumSet.of(XContentContext.API);
    public static EnumSet<XContentContext> API_AND_GATEWAY = EnumSet.of(XContentContext.API, XContentContext.GATEWAY);
    public static EnumSet<XContentContext> API_AND_SNAPSHOT = EnumSet.of(XContentContext.API, XContentContext.SNAPSHOT);

    public interface Custom extends Diffable<Custom>, ToXContent {

        String type();

        Custom fromXContent(XContentParser parser) throws IOException;

        EnumSet<XContentContext> context();
    }

    public static Map<String, Custom> customPrototypes = new HashMap<>();

    static {
        // register non plugin custom metadata
        registerPrototype(RepositoriesMetaData.TYPE, RepositoriesMetaData.PROTO);
        registerPrototype(SnapshotMetaData.TYPE, SnapshotMetaData.PROTO);
        registerPrototype(RestoreMetaData.TYPE, RestoreMetaData.PROTO);
    }

    /**
     * Register a custom index meta data factory. Make sure to call it from a static block.
     */
    public static void registerPrototype(String type, Custom proto) {
        customPrototypes.put(type, proto);
    }

    @Nullable
    public static <T extends Custom> T lookupPrototype(String type) {
        //noinspection unchecked
        return (T) customPrototypes.get(type);
    }

    public static <T extends Custom> T lookupPrototypeSafe(String type) {
        //noinspection unchecked
        T proto = (T) customPrototypes.get(type);
        if (proto == null) {
            throw new IllegalArgumentException("No custom metadata prototype registered for type [" + type + "]");
        }
        return proto;
    }

    public static final String SETTING_READ_ONLY = "cluster.blocks.read_only";

    public static final ClusterBlock CLUSTER_READ_ONLY_BLOCK = new ClusterBlock(6, "cluster read-only (api)", false, false, RestStatus.FORBIDDEN, EnumSet.of(ClusterBlockLevel.WRITE, ClusterBlockLevel.METADATA_WRITE));

    public static final MetaData EMPTY_META_DATA = builder().build();

    public static final String CONTEXT_MODE_PARAM = "context_mode";

    public static final String CONTEXT_MODE_SNAPSHOT = XContentContext.SNAPSHOT.toString();

    public static final String CONTEXT_MODE_GATEWAY = XContentContext.GATEWAY.toString();

    private final String uuid;
    private final long version;

    private final Settings transientSettings;
    private final Settings persistentSettings;
    private final Settings settings;
    private final ImmutableOpenMap<String, IndexMetaData> indices;
    private final ImmutableOpenMap<String, IndexTemplateMetaData> templates;
    private final ImmutableOpenMap<String, Custom> customs;

    private final transient int totalNumberOfShards; // Transient ? not serializable anyway?
    private final int numberOfShards;

    private final String[] allIndices;
    private final String[] allOpenIndices;
    private final String[] allClosedIndices;

    private final ImmutableOpenMap<String, ImmutableOpenMap<String, AliasMetaData>> aliases;
    private final ImmutableOpenMap<String, String[]> aliasAndIndexToIndexMap;

    @SuppressWarnings("unchecked")
    MetaData(String uuid, long version, Settings transientSettings, Settings persistentSettings, ImmutableOpenMap<String, IndexMetaData> indices, ImmutableOpenMap<String, IndexTemplateMetaData> templates, ImmutableOpenMap<String, Custom> customs) {
        this.uuid = uuid;
        this.version = version;
        this.transientSettings = transientSettings;
        this.persistentSettings = persistentSettings;
        this.settings = Settings.settingsBuilder().put(persistentSettings).put(transientSettings).build();
        this.indices = indices;
        this.customs = customs;
        this.templates = templates;
        int totalNumberOfShards = 0;
        int numberOfShards = 0;
        int numAliases = 0;
        for (ObjectCursor<IndexMetaData> cursor : indices.values()) {
            totalNumberOfShards += cursor.value.totalNumberOfShards();
            numberOfShards += cursor.value.numberOfShards();
            numAliases += cursor.value.aliases().size();
        }
        this.totalNumberOfShards = totalNumberOfShards;
        this.numberOfShards = numberOfShards;

        // build all indices map
        List<String> allIndicesLst = Lists.newArrayList();
        for (ObjectCursor<IndexMetaData> cursor : indices.values()) {
            allIndicesLst.add(cursor.value.index());
        }
        allIndices = allIndicesLst.toArray(new String[allIndicesLst.size()]);
        int numIndices = allIndicesLst.size();

        List<String> allOpenIndices = Lists.newArrayList();
        List<String> allClosedIndices = Lists.newArrayList();
        for (ObjectCursor<IndexMetaData> cursor : indices.values()) {
            IndexMetaData indexMetaData = cursor.value;
            if (indexMetaData.state() == IndexMetaData.State.OPEN) {
                allOpenIndices.add(indexMetaData.index());
            } else if (indexMetaData.state() == IndexMetaData.State.CLOSE) {
                allClosedIndices.add(indexMetaData.index());
            }
        }
        this.allOpenIndices = allOpenIndices.toArray(new String[allOpenIndices.size()]);
        this.allClosedIndices = allClosedIndices.toArray(new String[allClosedIndices.size()]);

        // build aliases map
        ImmutableOpenMap.Builder<String, Object> tmpAliases = ImmutableOpenMap.builder(numAliases);
        for (ObjectCursor<IndexMetaData> cursor : indices.values()) {
            IndexMetaData indexMetaData = cursor.value;
            String index = indexMetaData.index();
            for (ObjectCursor<AliasMetaData> aliasCursor : indexMetaData.aliases().values()) {
                AliasMetaData aliasMd = aliasCursor.value;
                ImmutableOpenMap.Builder<String, AliasMetaData> indexAliasMap = (ImmutableOpenMap.Builder<String, AliasMetaData>) tmpAliases.get(aliasMd.alias());
                if (indexAliasMap == null) {
                    indexAliasMap = ImmutableOpenMap.builder(1); // typically, there is 1 alias pointing to an index
                    tmpAliases.put(aliasMd.alias(), indexAliasMap);
                }
                indexAliasMap.put(index, aliasMd);
            }
        }

        for (ObjectCursor<String> cursor : tmpAliases.keys()) {
            String alias = cursor.value;
            // if there is access to the raw values buffer of the map that the immutable maps wraps, then we don't need to use put, and just set array slots
            ImmutableOpenMap<String, AliasMetaData> map = ((ImmutableOpenMap.Builder) tmpAliases.get(alias)).cast().build();
            tmpAliases.put(alias, map);
        }

        this.aliases = tmpAliases.<String, ImmutableOpenMap<String, AliasMetaData>>cast().build();
        ImmutableOpenMap.Builder<String, Object> aliasAndIndexToIndexMap = ImmutableOpenMap.builder(numAliases + numIndices);
        for (ObjectCursor<IndexMetaData> cursor : indices.values()) {
            IndexMetaData indexMetaData = cursor.value;
            ObjectArrayList<String> indicesLst = (ObjectArrayList<String>) aliasAndIndexToIndexMap.get(indexMetaData.index());
            if (indicesLst == null) {
                indicesLst = new ObjectArrayList<>();
                aliasAndIndexToIndexMap.put(indexMetaData.index(), indicesLst);
            }
            indicesLst.add(indexMetaData.index());

            for (ObjectCursor<String> cursor1 : indexMetaData.aliases().keys()) {
                String alias = cursor1.value;
                indicesLst = (ObjectArrayList<String>) aliasAndIndexToIndexMap.get(alias);
                if (indicesLst == null) {
                    indicesLst = new ObjectArrayList<>();
                    aliasAndIndexToIndexMap.put(alias, indicesLst);
                }
                indicesLst.add(indexMetaData.index());
            }
        }

        for (ObjectObjectCursor<String, Object> cursor : aliasAndIndexToIndexMap) {
            String[] indicesLst = ((ObjectArrayList<String>) cursor.value).toArray(String.class);
            aliasAndIndexToIndexMap.put(cursor.key, indicesLst);
        }

        this.aliasAndIndexToIndexMap = aliasAndIndexToIndexMap.<String, String[]>cast().build();
    }

    public long version() {
        return this.version;
    }

    public String uuid() {
        return this.uuid;
    }

    /**
     * Returns the merges transient and persistent settings.
     */
    public Settings settings() {
        return this.settings;
    }

    public Settings transientSettings() {
        return this.transientSettings;
    }

    public Settings persistentSettings() {
        return this.persistentSettings;
    }

    public ImmutableOpenMap<String, ImmutableOpenMap<String, AliasMetaData>> aliases() {
        return this.aliases;
    }

    public ImmutableOpenMap<String, ImmutableOpenMap<String, AliasMetaData>> getAliases() {
        return aliases();
    }

    /**
     * Finds the specific index aliases that match with the specified aliases directly or partially via wildcards and
     * that point to the specified concrete indices or match partially with the indices via wildcards.
     *
     * @param aliases         The names of the index aliases to find
     * @param concreteIndices The concrete indexes the index aliases must point to order to be returned.
     * @return the found index aliases grouped by index
     */
    public ImmutableOpenMap<String, ImmutableList<AliasMetaData>> findAliases(final String[] aliases, String[] concreteIndices) {
        assert aliases != null;
        assert concreteIndices != null;
        if (concreteIndices.length == 0) {
            return ImmutableOpenMap.of();
        }

        boolean matchAllAliases = matchAllAliases(aliases);
        ImmutableOpenMap.Builder<String, ImmutableList<AliasMetaData>> mapBuilder = ImmutableOpenMap.builder();
        Iterable<String> intersection = HppcMaps.intersection(ObjectHashSet.from(concreteIndices), indices.keys());
        for (String index : intersection) {
            IndexMetaData indexMetaData = indices.get(index);
            List<AliasMetaData> filteredValues = Lists.newArrayList();
            for (ObjectCursor<AliasMetaData> cursor : indexMetaData.getAliases().values()) {
                AliasMetaData value = cursor.value;
                if (matchAllAliases || Regex.simpleMatch(aliases, value.alias())) {
                    filteredValues.add(value);
                }
            }

            if (!filteredValues.isEmpty()) {
                // Make the list order deterministic
                CollectionUtil.timSort(filteredValues, new Comparator<AliasMetaData>() {
                    @Override
                    public int compare(AliasMetaData o1, AliasMetaData o2) {
                        return o1.alias().compareTo(o2.alias());
                    }
                });
                mapBuilder.put(index, ImmutableList.copyOf(filteredValues));
            }
        }
        return mapBuilder.build();
    }

    private static boolean matchAllAliases(final String[] aliases) {
        for (String alias : aliases) {
            if (alias.equals(ALL)) {
                return true;
            }
        }
        return aliases.length == 0;
    }

    /**
     * Checks if at least one of the specified aliases exists in the specified concrete indices. Wildcards are supported in the
     * alias names for partial matches.
     *
     * @param aliases         The names of the index aliases to find
     * @param concreteIndices The concrete indexes the index aliases must point to order to be returned.
     * @return whether at least one of the specified aliases exists in one of the specified concrete indices.
     */
    public boolean hasAliases(final String[] aliases, String[] concreteIndices) {
        assert aliases != null;
        assert concreteIndices != null;
        if (concreteIndices.length == 0) {
            return false;
        }

        Iterable<String> intersection = HppcMaps.intersection(ObjectHashSet.from(concreteIndices), indices.keys());
        for (String index : intersection) {
            IndexMetaData indexMetaData = indices.get(index);
            List<AliasMetaData> filteredValues = Lists.newArrayList();
            for (ObjectCursor<AliasMetaData> cursor : indexMetaData.getAliases().values()) {
                AliasMetaData value = cursor.value;
                if (Regex.simpleMatch(aliases, value.alias())) {
                    filteredValues.add(value);
                }
            }
            if (!filteredValues.isEmpty()) {
                return true;
            }
        }
        return false;
    }

    /*
     * Finds all mappings for types and concrete indices. Types are expanded to
     * include all types that match the glob patterns in the types array. Empty
     * types array, null or {"_all"} will be expanded to all types available for
     * the given indices.
     */
    public ImmutableOpenMap<String, ImmutableOpenMap<String, MappingMetaData>> findMappings(String[] concreteIndices, final String[] types) {
        assert types != null;
        assert concreteIndices != null;
        if (concreteIndices.length == 0) {
            return ImmutableOpenMap.of();
        }

        ImmutableOpenMap.Builder<String, ImmutableOpenMap<String, MappingMetaData>> indexMapBuilder = ImmutableOpenMap.builder();
        Iterable<String> intersection = HppcMaps.intersection(ObjectHashSet.from(concreteIndices), indices.keys());
        for (String index : intersection) {
            IndexMetaData indexMetaData = indices.get(index);
            ImmutableOpenMap.Builder<String, MappingMetaData> filteredMappings;
            if (isAllTypes(types)) {
                indexMapBuilder.put(index, indexMetaData.getMappings()); // No types specified means get it all

            } else {
                filteredMappings = ImmutableOpenMap.builder();
                for (ObjectObjectCursor<String, MappingMetaData> cursor : indexMetaData.mappings()) {
                    if (Regex.simpleMatch(types, cursor.key)) {
                        filteredMappings.put(cursor.key, cursor.value);
                    }
                }
                if (!filteredMappings.isEmpty()) {
                    indexMapBuilder.put(index, filteredMappings.build());
                }
            }
        }
        return indexMapBuilder.build();
    }

    public ImmutableOpenMap<String, ImmutableList<IndexWarmersMetaData.Entry>> findWarmers(String[] concreteIndices, final String[] types, final String[] uncheckedWarmers) {
        assert uncheckedWarmers != null;
        assert concreteIndices != null;
        if (concreteIndices.length == 0) {
            return ImmutableOpenMap.of();
        }
        // special _all check to behave the same like not specifying anything for the warmers (not for the indices)
        final String[] warmers = Strings.isAllOrWildcard(uncheckedWarmers) ? Strings.EMPTY_ARRAY : uncheckedWarmers;

        ImmutableOpenMap.Builder<String, ImmutableList<IndexWarmersMetaData.Entry>> mapBuilder = ImmutableOpenMap.builder();
        Iterable<String> intersection = HppcMaps.intersection(ObjectHashSet.from(concreteIndices), indices.keys());
        for (String index : intersection) {
            IndexMetaData indexMetaData = indices.get(index);
            IndexWarmersMetaData indexWarmersMetaData = indexMetaData.custom(IndexWarmersMetaData.TYPE);
            if (indexWarmersMetaData == null || indexWarmersMetaData.entries().isEmpty()) {
                continue;
            }

            Collection<IndexWarmersMetaData.Entry> filteredWarmers = Collections2.filter(indexWarmersMetaData.entries(), new Predicate<IndexWarmersMetaData.Entry>() {

                @Override
                public boolean apply(IndexWarmersMetaData.Entry warmer) {
                    if (warmers.length != 0 && types.length != 0) {
                        return Regex.simpleMatch(warmers, warmer.name()) && Regex.simpleMatch(types, warmer.types());
                    } else if (warmers.length != 0) {
                        return Regex.simpleMatch(warmers, warmer.name());
                    } else if (types.length != 0) {
                        return Regex.simpleMatch(types, warmer.types());
                    } else {
                        return true;
                    }
                }

            });
            if (!filteredWarmers.isEmpty()) {
                mapBuilder.put(index, ImmutableList.copyOf(filteredWarmers));
            }
        }
        return mapBuilder.build();
    }

    /**
     * Returns all the concrete indices.
     */
    public String[] concreteAllIndices() {
        return allIndices;
    }

    public String[] getConcreteAllIndices() {
        return concreteAllIndices();
    }

    public String[] concreteAllOpenIndices() {
        return allOpenIndices;
    }

    public String[] getConcreteAllOpenIndices() {
        return allOpenIndices;
    }

    public String[] concreteAllClosedIndices() {
        return allClosedIndices;
    }

    public String[] getConcreteAllClosedIndices() {
        return allClosedIndices;
    }

    /**
     * Returns indexing routing for the given index.
     */
    public String resolveIndexRouting(@Nullable String routing, String aliasOrIndex) {
        // Check if index is specified by an alias
        ImmutableOpenMap<String, AliasMetaData> indexAliases = aliases.get(aliasOrIndex);
        if (indexAliases == null || indexAliases.isEmpty()) {
            return routing;
        }
        if (indexAliases.size() > 1) {
            throw new IllegalArgumentException("Alias [" + aliasOrIndex + "] has more than one index associated with it [" + Arrays.toString(indexAliases.keys().toArray(String.class)) + "], can't execute a single index op");
        }
        AliasMetaData aliasMd = indexAliases.values().iterator().next().value;
        if (aliasMd.indexRouting() != null) {
            if (routing != null) {
                if (!routing.equals(aliasMd.indexRouting())) {
                    throw new IllegalArgumentException("Alias [" + aliasOrIndex + "] has index routing associated with it [" + aliasMd.indexRouting() + "], and was provided with routing value [" + routing + "], rejecting operation");
                }
            }
            routing = aliasMd.indexRouting();
        }
        if (routing != null) {
            if (routing.indexOf(',') != -1) {
                throw new IllegalArgumentException("index/alias [" + aliasOrIndex + "] provided with routing value [" + routing + "] that resolved to several routing values, rejecting operation");
            }
        }
        return routing;
    }

    public Map<String, Set<String>> resolveSearchRouting(@Nullable String routing, String aliasOrIndex) {
        return resolveSearchRouting(routing, convertFromWildcards(new String[]{aliasOrIndex}, IndicesOptions.lenientExpandOpen()));
    }

    public Map<String, Set<String>> resolveSearchRouting(@Nullable String routing, String[] aliasesOrIndices) {
        if (isAllIndices(aliasesOrIndices)) {
            return resolveSearchRoutingAllIndices(routing);
        }

        aliasesOrIndices = convertFromWildcards(aliasesOrIndices, IndicesOptions.lenientExpandOpen());

        if (aliasesOrIndices.length == 1) {
            return resolveSearchRoutingSingleValue(routing, aliasesOrIndices[0]);
        }

        Map<String, Set<String>> routings = null;
        Set<String> paramRouting = null;
        // List of indices that don't require any routing
        Set<String> norouting = new HashSet<>();
        if (routing != null) {
            paramRouting = Strings.splitStringByCommaToSet(routing);
        }

        for (String aliasOrIndex : aliasesOrIndices) {
            ImmutableOpenMap<String, AliasMetaData> indexToRoutingMap = aliases.get(aliasOrIndex);
            if (indexToRoutingMap != null && !indexToRoutingMap.isEmpty()) {
                for (ObjectObjectCursor<String, AliasMetaData> indexRouting : indexToRoutingMap) {
                    if (!norouting.contains(indexRouting.key)) {
                        if (!indexRouting.value.searchRoutingValues().isEmpty()) {
                            // Routing alias
                            if (routings == null) {
                                routings = newHashMap();
                            }
                            Set<String> r = routings.get(indexRouting.key);
                            if (r == null) {
                                r = new HashSet<>();
                                routings.put(indexRouting.key, r);
                            }
                            r.addAll(indexRouting.value.searchRoutingValues());
                            if (paramRouting != null) {
                                r.retainAll(paramRouting);
                            }
                            if (r.isEmpty()) {
                                routings.remove(indexRouting.key);
                            }
                        } else {
                            // Non-routing alias
                            if (!norouting.contains(indexRouting.key)) {
                                norouting.add(indexRouting.key);
                                if (paramRouting != null) {
                                    Set<String> r = new HashSet<>(paramRouting);
                                    if (routings == null) {
                                        routings = newHashMap();
                                    }
                                    routings.put(indexRouting.key, r);
                                } else {
                                    if (routings != null) {
                                        routings.remove(indexRouting.key);
                                    }
                                }
                            }
                        }
                    }
                }
            } else {
                // Index
                if (!norouting.contains(aliasOrIndex)) {
                    norouting.add(aliasOrIndex);
                    if (paramRouting != null) {
                        Set<String> r = new HashSet<>(paramRouting);
                        if (routings == null) {
                            routings = newHashMap();
                        }
                        routings.put(aliasOrIndex, r);
                    } else {
                        if (routings != null) {
                            routings.remove(aliasOrIndex);
                        }
                    }
                }
            }

        }
        if (routings == null || routings.isEmpty()) {
            return null;
        }
        return routings;
    }

    private Map<String, Set<String>> resolveSearchRoutingSingleValue(@Nullable String routing, String aliasOrIndex) {
        Map<String, Set<String>> routings = null;
        Set<String> paramRouting = null;
        if (routing != null) {
            paramRouting = Strings.splitStringByCommaToSet(routing);
        }

        ImmutableOpenMap<String, AliasMetaData> indexToRoutingMap = aliases.get(aliasOrIndex);
        if (indexToRoutingMap != null && !indexToRoutingMap.isEmpty()) {
            // It's an alias
            for (ObjectObjectCursor<String, AliasMetaData> indexRouting : indexToRoutingMap) {
                if (!indexRouting.value.searchRoutingValues().isEmpty()) {
                    // Routing alias
                    Set<String> r = new HashSet<>(indexRouting.value.searchRoutingValues());
                    if (paramRouting != null) {
                        r.retainAll(paramRouting);
                    }
                    if (!r.isEmpty()) {
                        if (routings == null) {
                            routings = newHashMap();
                        }
                        routings.put(indexRouting.key, r);
                    }
                } else {
                    // Non-routing alias
                    if (paramRouting != null) {
                        Set<String> r = new HashSet<>(paramRouting);
                        if (routings == null) {
                            routings = newHashMap();
                        }
                        routings.put(indexRouting.key, r);
                    }
                }
            }
        } else {
            // It's an index
            if (paramRouting != null) {
                routings = ImmutableMap.of(aliasOrIndex, paramRouting);
            }
        }
        return routings;
    }

    /**
     * Sets the same routing for all indices
     */
    private Map<String, Set<String>> resolveSearchRoutingAllIndices(String routing) {
        if (routing != null) {
            Set<String> r = Strings.splitStringByCommaToSet(routing);
            Map<String, Set<String>> routings = newHashMap();
            String[] concreteIndices = concreteAllIndices();
            for (String index : concreteIndices) {
                routings.put(index, r);
            }
            return routings;
        }
        return null;
    }

    /**
     * Translates the provided indices or aliases, eventually containing wildcard expressions, into actual indices.
     *
     * @param indicesOptions   how the aliases or indices need to be resolved to concrete indices
     * @param aliasesOrIndices the aliases or indices to be resolved to concrete indices
     * @return the obtained concrete indices
     * @throws IndexMissingException if one of the aliases or indices is missing and the provided indices options
     * don't allow such a case, or if the final result of the indices resolution is no indices and the indices options
     * don't allow such a case.
     * @throws IllegalArgumentException if one of the aliases resolve to multiple indices and the provided
     * indices options don't allow such a case.
     */
    public String[] concreteIndices(IndicesOptions indicesOptions, String... aliasesOrIndices) throws IndexMissingException, IllegalArgumentException {
        if (indicesOptions.expandWildcardsOpen() || indicesOptions.expandWildcardsClosed()) {
            if (isAllIndices(aliasesOrIndices)) {
                String[] concreteIndices;
                if (indicesOptions.expandWildcardsOpen() && indicesOptions.expandWildcardsClosed()) {
                    concreteIndices = concreteAllIndices();
                } else if (indicesOptions.expandWildcardsOpen()) {
                    concreteIndices = concreteAllOpenIndices();
                } else {
                    concreteIndices = concreteAllClosedIndices();
                }

                if (!indicesOptions.allowNoIndices() && concreteIndices.length == 0) {
                    throw new IndexMissingException(new Index("_all"));
                }
                return concreteIndices;
            }

            aliasesOrIndices = convertFromWildcards(aliasesOrIndices, indicesOptions);
        }

        if (aliasesOrIndices == null || aliasesOrIndices.length == 0) {
            if (!indicesOptions.allowNoIndices()) {
                throw new IllegalArgumentException("no indices were specified and wildcard expansion is disabled.");
            } else {
                return Strings.EMPTY_ARRAY;
            }
        }

        boolean failClosed = indicesOptions.forbidClosedIndices() && !indicesOptions.ignoreUnavailable();

        // optimize for single element index (common case)
        if (aliasesOrIndices.length == 1) {
            return concreteIndices(aliasesOrIndices[0], indicesOptions, !indicesOptions.allowNoIndices());
        }

        // check if its a possible aliased index, if not, just return the passed array
        boolean possiblyAliased = false;
        boolean closedIndices = false;
        for (String index : aliasesOrIndices) {
            IndexMetaData indexMetaData = indices.get(index);
            if (indexMetaData == null) {
                possiblyAliased = true;
                break;
            } else {
                if (indicesOptions.forbidClosedIndices() && indexMetaData.getState() == IndexMetaData.State.CLOSE) {
                    if (failClosed) {
                        throw new IndexClosedException(new Index(index));
                    } else {
                        closedIndices = true;
                    }
                }
            }
        }
        if (!possiblyAliased) {
            if (closedIndices) {
                Set<String> actualIndices = new HashSet<>(Arrays.asList(aliasesOrIndices));
                actualIndices.retainAll(new HashSet<Object>(Arrays.asList(allOpenIndices)));
                return actualIndices.toArray(new String[actualIndices.size()]);
            } else {
                return aliasesOrIndices;
            }
        }

        Set<String> actualIndices = new HashSet<>();
        for (String aliasOrIndex : aliasesOrIndices) {
            String[] indices = concreteIndices(aliasOrIndex, indicesOptions, !indicesOptions.ignoreUnavailable());
            Collections.addAll(actualIndices, indices);
        }

        if (!indicesOptions.allowNoIndices() && actualIndices.isEmpty()) {
            throw new IndexMissingException(new Index(Arrays.toString(aliasesOrIndices)));
        }
        return actualIndices.toArray(new String[actualIndices.size()]);
    }

    /**
     * Utility method that allows to resolve an index or alias to its corresponding single concrete index.
     * Callers should make sure they provide proper {@link org.elasticsearch.action.support.IndicesOptions}
     * that require a single index as a result. The indices resolution must in fact return a single index when
     * using this method, an {@link IllegalArgumentException} gets thrown otherwise.
     *
     * @param indexOrAlias   the index or alias to be resolved to concrete index
     * @param indicesOptions the indices options to be used for the index resolution
     * @return the concrete index obtained as a result of the index resolution
     * @throws IndexMissingException                 if the index or alias provided doesn't exist
     * @throws IllegalArgumentException if the index resolution lead to more than one index
     */
    public String concreteSingleIndex(String indexOrAlias, IndicesOptions indicesOptions) throws IndexMissingException, IllegalArgumentException {
        String[] indices = concreteIndices(indicesOptions, indexOrAlias);
        if (indices.length != 1) {
            throw new IllegalArgumentException("unable to return a single index as the index and options provided got resolved to multiple indices");
        }
        return indices[0];
    }

    private String[] concreteIndices(String aliasOrIndex, IndicesOptions options, boolean failNoIndices) throws IndexMissingException, IllegalArgumentException {
        boolean failClosed = options.forbidClosedIndices() && !options.ignoreUnavailable();

        // a quick check, if this is an actual index, if so, return it
        IndexMetaData indexMetaData = indices.get(aliasOrIndex);
        if (indexMetaData != null) {
            if (indexMetaData.getState() == IndexMetaData.State.CLOSE) {
                if (failClosed) {
                    throw new IndexClosedException(new Index(aliasOrIndex));
                } else {
                    return options.forbidClosedIndices() ? Strings.EMPTY_ARRAY : new String[]{aliasOrIndex};
                }
            } else {
                return new String[]{aliasOrIndex};
            }
        }
        // not an actual index, fetch from an alias
        String[] indices = aliasAndIndexToIndexMap.getOrDefault(aliasOrIndex, Strings.EMPTY_ARRAY);
        if (indices.length == 0 && failNoIndices) {
            throw new IndexMissingException(new Index(aliasOrIndex));
        }
        if (indices.length > 1 && !options.allowAliasesToMultipleIndices()) {
            throw new IllegalArgumentException("Alias [" + aliasOrIndex + "] has more than one indices associated with it [" + Arrays.toString(indices) + "], can't execute a single index op");
        }

        // No need to check whether indices referred by aliases are closed, because there are no closed indices.
        if (allClosedIndices.length == 0) {
            return indices;
        }

        switch (indices.length) {
            case 0:
                return indices;
            case 1:
                indexMetaData = this.indices.get(indices[0]);
                if (indexMetaData != null && indexMetaData.getState() == IndexMetaData.State.CLOSE) {
                    if (failClosed) {
                        throw new IndexClosedException(new Index(indexMetaData.getIndex()));
                    } else {
                        if (options.forbidClosedIndices()) {
                            return Strings.EMPTY_ARRAY;
                        }
                    }
                }
                return indices;
            default:
                ObjectArrayList<String> concreteIndices = new ObjectArrayList<>();
                for (String index : indices) {
                    indexMetaData = this.indices.get(index);
                    if (indexMetaData != null) {
                        if (indexMetaData.getState() == IndexMetaData.State.CLOSE) {
                            if (failClosed) {
                                throw new IndexClosedException(new Index(indexMetaData.getIndex()));
                            } else if (!options.forbidClosedIndices()) {
                                concreteIndices.add(index);
                            }
                        } else if (indexMetaData.getState() == IndexMetaData.State.OPEN) {
                            concreteIndices.add(index);
                        } else {
                            throw new IllegalStateException("index state [" + indexMetaData.getState() + "] not supported");
                        }
                    }
                }
                return concreteIndices.toArray(String.class);
        }
    }

    /**
     * Converts a list of indices or aliases wildcards, and special +/- signs, into their respective full matches. It
     * won't convert only to indices, but also to aliases. For example, alias_* will expand to alias_1 and alias_2, not
     * to the respective indices those aliases point to.
     */
    public String[] convertFromWildcards(String[] aliasesOrIndices, IndicesOptions indicesOptions) {
        if (aliasesOrIndices == null) {
            return null;
        }
        Set<String> result = null;
        for (int i = 0; i < aliasesOrIndices.length; i++) {
            String aliasOrIndex = aliasesOrIndices[i];
            if (aliasAndIndexToIndexMap.containsKey(aliasOrIndex)) {
                if (result != null) {
                    result.add(aliasOrIndex);
                }
                continue;
            }
            boolean add = true;
            if (aliasOrIndex.charAt(0) == '+') {
                // if its the first, add empty result set
                if (i == 0) {
                    result = new HashSet<>();
                }
                add = true;
                aliasOrIndex = aliasOrIndex.substring(1);
            } else if (aliasOrIndex.charAt(0) == '-') {
                // if its the first, fill it with all the indices...
                if (i == 0) {
                    String[] concreteIndices;
                    if (indicesOptions.expandWildcardsOpen() && indicesOptions.expandWildcardsClosed()) {
                        concreteIndices = concreteAllIndices();
                    } else if (indicesOptions.expandWildcardsOpen()) {
                        concreteIndices = concreteAllOpenIndices();
                    } else if (indicesOptions.expandWildcardsClosed()) {
                        concreteIndices = concreteAllClosedIndices();
                    } else {
                        assert false : "Shouldn't end up here";
                        concreteIndices = Strings.EMPTY_ARRAY;
                    }
                    result = new HashSet<>(Arrays.asList(concreteIndices));
                }
                add = false;
                aliasOrIndex = aliasOrIndex.substring(1);
            }
            if (!Regex.isSimpleMatchPattern(aliasOrIndex)) {
                if (!indicesOptions.ignoreUnavailable() && !aliasAndIndexToIndexMap.containsKey(aliasOrIndex)) {
                    throw new IndexMissingException(new Index(aliasOrIndex));
                }
                if (result != null) {
                    if (add) {
                        result.add(aliasOrIndex);
                    } else {
                        result.remove(aliasOrIndex);
                    }
                }
                continue;
            }
            if (result == null) {
                // add all the previous ones...
                result = new HashSet<>();
                result.addAll(Arrays.asList(aliasesOrIndices).subList(0, i));
            }
            String[] indices;
            if (indicesOptions.expandWildcardsOpen() && indicesOptions.expandWildcardsClosed()) {
                indices = concreteAllIndices();
            } else if (indicesOptions.expandWildcardsOpen()) {
                indices = concreteAllOpenIndices();
            } else if (indicesOptions.expandWildcardsClosed()) {
                indices = concreteAllClosedIndices();
            } else {
                assert false : "convertFromWildcards shouldn't get called if wildcards expansion is disabled";
                indices = Strings.EMPTY_ARRAY;
            }
            boolean found = false;
            // iterating over all concrete indices and see if there is a wildcard match
            for (String index : indices) {
                if (Regex.simpleMatch(aliasOrIndex, index)) {
                    found = true;
                    if (add) {
                        result.add(index);
                    } else {
                        result.remove(index);
                    }
                }
            }
            // iterating over all aliases and see if there is a wildcard match
            for (ObjectCursor<String> cursor : aliases.keys()) {
                String alias = cursor.value;
                if (Regex.simpleMatch(aliasOrIndex, alias)) {
                    found = true;
                    if (add) {
                        result.add(alias);
                    } else {
                        result.remove(alias);
                    }
                }
            }
            if (!found && !indicesOptions.allowNoIndices()) {
                throw new IndexMissingException(new Index(aliasOrIndex));
            }
        }
        if (result == null) {
            return aliasesOrIndices;
        }
        if (result.isEmpty() && !indicesOptions.allowNoIndices()) {
            throw new IndexMissingException(new Index(Arrays.toString(aliasesOrIndices)));
        }
        return result.toArray(new String[result.size()]);
    }

    public boolean hasIndex(String index) {
        return indices.containsKey(index);
    }

    public boolean hasConcreteIndex(String index) {
        return aliasAndIndexToIndexMap.containsKey(index);
    }

    public IndexMetaData index(String index) {
        return indices.get(index);
    }

    public ImmutableOpenMap<String, IndexMetaData> indices() {
        return this.indices;
    }

    public ImmutableOpenMap<String, IndexMetaData> getIndices() {
        return indices();
    }

    public ImmutableOpenMap<String, IndexTemplateMetaData> templates() {
        return this.templates;
    }

    public ImmutableOpenMap<String, IndexTemplateMetaData> getTemplates() {
        return this.templates;
    }

    public ImmutableOpenMap<String, Custom> customs() {
        return this.customs;
    }

    public ImmutableOpenMap<String, Custom> getCustoms() {
        return this.customs;
    }

    public <T extends Custom> T custom(String type) {
        return (T) customs.get(type);
    }

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

    public int getTotalNumberOfShards() {
        return totalNumberOfShards();
    }

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

    public int getNumberOfShards() {
        return numberOfShards();
    }

    /**
     * Iterates through the list of indices and selects the effective list of filtering aliases for the
     * given index.
     * <p/>
     * <p>Only aliases with filters are returned. If the indices list contains a non-filtering reference to
     * the index itself - null is returned. Returns <tt>null</tt> if no filtering is required.</p>
     */
    public String[] filteringAliases(String index, String... indicesOrAliases) {
        // expand the aliases wildcard
        indicesOrAliases = convertFromWildcards(indicesOrAliases, IndicesOptions.lenientExpandOpen());

        if (isAllIndices(indicesOrAliases)) {
            return null;
        }
        // optimize for the most common single index/alias scenario
        if (indicesOrAliases.length == 1) {
            String alias = indicesOrAliases[0];
            IndexMetaData indexMetaData = this.indices.get(index);
            if (indexMetaData == null) {
                // Shouldn't happen
                throw new IndexMissingException(new Index(index));
            }
            AliasMetaData aliasMetaData = indexMetaData.aliases().get(alias);
            boolean filteringRequired = aliasMetaData != null && aliasMetaData.filteringRequired();
            if (!filteringRequired) {
                return null;
            }
            return new String[]{alias};
        }
        List<String> filteringAliases = null;
        for (String alias : indicesOrAliases) {
            if (alias.equals(index)) {
                return null;
            }

            IndexMetaData indexMetaData = this.indices.get(index);
            if (indexMetaData == null) {
                // Shouldn't happen
                throw new IndexMissingException(new Index(index));
            }

            AliasMetaData aliasMetaData = indexMetaData.aliases().get(alias);
            // Check that this is an alias for the current index
            // Otherwise - skip it
            if (aliasMetaData != null) {
                boolean filteringRequired = aliasMetaData.filteringRequired();
                if (filteringRequired) {
                    // If filtering required - add it to the list of filters
                    if (filteringAliases == null) {
                        filteringAliases = newArrayList();
                    }
                    filteringAliases.add(alias);
                } else {
                    // If not, we have a non filtering alias for this index - no filtering needed
                    return null;
                }
            }
        }
        if (filteringAliases == null) {
            return null;
        }
        return filteringAliases.toArray(new String[filteringAliases.size()]);
    }

    /**
     * Identifies whether the array containing index names given as argument refers to all indices
     * The empty or null array identifies all indices
     *
     * @param aliasesOrIndices the array containing index names
     * @return true if the provided array maps to all indices, false otherwise
     */
    public static boolean isAllIndices(String[] aliasesOrIndices) {
        return aliasesOrIndices == null || aliasesOrIndices.length == 0 || isExplicitAllPattern(aliasesOrIndices);
    }

    /**
     * Identifies whether the array containing type names given as argument refers to all types
     * The empty or null array identifies all types
     *
     * @param types the array containing index names
     * @return true if the provided array maps to all indices, false otherwise
     */
    public static boolean isAllTypes(String[] types) {
        return types == null || types.length == 0 || isExplicitAllPattern(types);
    }

    /**
     * Identifies whether the array containing index names given as argument explicitly refers to all indices
     * The empty or null array doesn't explicitly map to all indices
     *
     * @param aliasesOrIndices the array containing index names
     * @return true if the provided array explicitly maps to all indices, false otherwise
     */
    public static boolean isExplicitAllPattern(String[] aliasesOrIndices) {
        return aliasesOrIndices != null && aliasesOrIndices.length == 1 && ALL.equals(aliasesOrIndices[0]);
    }

    /**
     * Identifies whether the first argument (an array containing index names) is a pattern that matches all indices
     *
     * @param indicesOrAliases the array containing index names
     * @param concreteIndices  array containing the concrete indices that the first argument refers to
     * @return true if the first argument is a pattern that maps to all available indices, false otherwise
     */
    public boolean isPatternMatchingAllIndices(String[] indicesOrAliases, String[] concreteIndices) {
        // if we end up matching on all indices, check, if its a wildcard parameter, or a "-something" structure
        if (concreteIndices.length == concreteAllIndices().length && indicesOrAliases.length > 0) {

            //we might have something like /-test1,+test1 that would identify all indices
            //or something like /-test1 with test1 index missing and IndicesOptions.lenient()
            if (indicesOrAliases[0].charAt(0) == '-') {
                return true;
            }

            //otherwise we check if there's any simple regex
            for (String indexOrAlias : indicesOrAliases) {
                if (Regex.isSimpleMatchPattern(indexOrAlias)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * @param concreteIndex The concrete index to check if routing is required
     * @param type          The type to check if routing is required
     * @return Whether routing is required according to the mapping for the specified index and type
     */
    public boolean routingRequired(String concreteIndex, String type) {
        IndexMetaData indexMetaData = indices.get(concreteIndex);
        if (indexMetaData != null) {
            MappingMetaData mappingMetaData = indexMetaData.getMappings().get(type);
            if (mappingMetaData != null) {
                return mappingMetaData.routing().required();
            }
        }
        return false;
    }

    @Override
    public UnmodifiableIterator<IndexMetaData> iterator() {
        return indices.valuesIt();
    }

    public static boolean isGlobalStateEquals(MetaData metaData1, MetaData metaData2) {
        if (!metaData1.persistentSettings.equals(metaData2.persistentSettings)) {
            return false;
        }
        if (!metaData1.templates.equals(metaData2.templates())) {
            return false;
        }
        // Check if any persistent metadata needs to be saved
        int customCount1 = 0;
        for (ObjectObjectCursor<String, Custom> cursor : metaData1.customs) {
            if (customPrototypes.get(cursor.key).context().contains(XContentContext.GATEWAY)) {
                if (!cursor.value.equals(metaData2.custom(cursor.key))) return false;
                customCount1++;
            }
        }
        int customCount2 = 0;
        for (ObjectObjectCursor<String, Custom> cursor : metaData2.customs) {
            if (customPrototypes.get(cursor.key).context().contains(XContentContext.GATEWAY)) {
                customCount2++;
            }
        }
        if (customCount1 != customCount2) return false;
        return true;
    }

    @Override
    public Diff<MetaData> diff(MetaData previousState) {
        return new MetaDataDiff(previousState, this);
    }

    @Override
    public Diff<MetaData> readDiffFrom(StreamInput in) throws IOException {
        return new MetaDataDiff(in);
    }

    private static class MetaDataDiff implements Diff<MetaData> {

        private long version;

        private String uuid;

        private Settings transientSettings;
        private Settings persistentSettings;
        private Diff<ImmutableOpenMap<String, IndexMetaData>> indices;
        private Diff<ImmutableOpenMap<String, IndexTemplateMetaData>> templates;
        private Diff<ImmutableOpenMap<String, Custom>> customs;

        public MetaDataDiff(MetaData before, MetaData after) {
            uuid = after.uuid;
            version = after.version;
            transientSettings = after.transientSettings;
            persistentSettings = after.persistentSettings;
            indices = DiffableUtils.diff(before.indices, after.indices);
            templates = DiffableUtils.diff(before.templates, after.templates);
            customs = DiffableUtils.diff(before.customs, after.customs);
        }

        public MetaDataDiff(StreamInput in) throws IOException {
            uuid = in.readString();
            version = in.readLong();
            transientSettings = Settings.readSettingsFromStream(in);
            persistentSettings = Settings.readSettingsFromStream(in);
            indices = DiffableUtils.readImmutableOpenMapDiff(in, IndexMetaData.PROTO);
            templates = DiffableUtils.readImmutableOpenMapDiff(in, IndexTemplateMetaData.PROTO);
            customs = DiffableUtils.readImmutableOpenMapDiff(in, new KeyedReader<Custom>() {
                @Override
                public Custom readFrom(StreamInput in, String key) throws IOException {
                    return lookupPrototypeSafe(key).readFrom(in);
                }

                @Override
                public Diff<Custom> readDiffFrom(StreamInput in, String key) throws IOException {
                    return lookupPrototypeSafe(key).readDiffFrom(in);
                }
            });
        }

        @Override
        public void writeTo(StreamOutput out) throws IOException {
            out.writeString(uuid);
            out.writeLong(version);
            Settings.writeSettingsToStream(transientSettings, out);
            Settings.writeSettingsToStream(persistentSettings, out);
            indices.writeTo(out);
            templates.writeTo(out);
            customs.writeTo(out);
        }

        @Override
        public MetaData apply(MetaData part) {
            Builder builder = builder();
            builder.uuid(uuid);
            builder.version(version);
            builder.transientSettings(transientSettings);
            builder.persistentSettings(persistentSettings);
            builder.indices(indices.apply(part.indices));
            builder.templates(templates.apply(part.templates));
            builder.customs(customs.apply(part.customs));
            return builder.build();
        }
    }

    @Override
    public MetaData readFrom(StreamInput in) throws IOException {
        Builder builder = new Builder();
        builder.version = in.readLong();
        builder.uuid = in.readString();
        builder.transientSettings(readSettingsFromStream(in));
        builder.persistentSettings(readSettingsFromStream(in));
        int size = in.readVInt();
        for (int i = 0; i < size; i++) {
            builder.put(IndexMetaData.Builder.readFrom(in), false);
        }
        size = in.readVInt();
        for (int i = 0; i < size; i++) {
            builder.put(IndexTemplateMetaData.Builder.readFrom(in));
        }
        int customSize = in.readVInt();
        for (int i = 0; i < customSize; i++) {
            String type = in.readString();
            Custom customIndexMetaData = lookupPrototypeSafe(type).readFrom(in);
            builder.putCustom(type, customIndexMetaData);
        }
        return builder.build();
    }

    @Override
    public void writeTo(StreamOutput out) throws IOException {
        out.writeLong(version);
        out.writeString(uuid);
        writeSettingsToStream(transientSettings, out);
        writeSettingsToStream(persistentSettings, out);
        out.writeVInt(indices.size());
        for (IndexMetaData indexMetaData : this) {
            indexMetaData.writeTo(out);
        }
        out.writeVInt(templates.size());
        for (ObjectCursor<IndexTemplateMetaData> cursor : templates.values()) {
            cursor.value.writeTo(out);
        }
        out.writeVInt(customs.size());
        for (ObjectObjectCursor<String, Custom> cursor : customs) {
            out.writeString(cursor.key);
            cursor.value.writeTo(out);
        }
    }

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

    public static Builder builder(MetaData metaData) {
        return new Builder(metaData);
    }

    public static class Builder {

        private String uuid;
        private long version;

        private Settings transientSettings = Settings.Builder.EMPTY_SETTINGS;
        private Settings persistentSettings = Settings.Builder.EMPTY_SETTINGS;

        private final ImmutableOpenMap.Builder<String, IndexMetaData> indices;
        private final ImmutableOpenMap.Builder<String, IndexTemplateMetaData> templates;
        private final ImmutableOpenMap.Builder<String, Custom> customs;

        public Builder() {
            uuid = "_na_";
            indices = ImmutableOpenMap.builder();
            templates = ImmutableOpenMap.builder();
            customs = ImmutableOpenMap.builder();
        }

        public Builder(MetaData metaData) {
            this.uuid = metaData.uuid;
            this.transientSettings = metaData.transientSettings;
            this.persistentSettings = metaData.persistentSettings;
            this.version = metaData.version;
            this.indices = ImmutableOpenMap.builder(metaData.indices);
            this.templates = ImmutableOpenMap.builder(metaData.templates);
            this.customs = ImmutableOpenMap.builder(metaData.customs);
        }

        public Builder put(IndexMetaData.Builder indexMetaDataBuilder) {
            // we know its a new one, increment the version and store
            indexMetaDataBuilder.version(indexMetaDataBuilder.version() + 1);
            IndexMetaData indexMetaData = indexMetaDataBuilder.build();
            indices.put(indexMetaData.index(), indexMetaData);
            return this;
        }

        public Builder put(IndexMetaData indexMetaData, boolean incrementVersion) {
            if (indices.get(indexMetaData.index()) == indexMetaData) {
                return this;
            }
            // if we put a new index metadata, increment its version
            if (incrementVersion) {
                indexMetaData = IndexMetaData.builder(indexMetaData).version(indexMetaData.version() + 1).build();
            }
            indices.put(indexMetaData.index(), indexMetaData);
            return this;
        }

        public IndexMetaData get(String index) {
            return indices.get(index);
        }

        public Builder remove(String index) {
            indices.remove(index);
            return this;
        }

        public Builder removeAllIndices() {
            indices.clear();
            return this;
        }

        public Builder indices(ImmutableOpenMap<String, IndexMetaData> indices) {
            this.indices.putAll(indices);
            return this;
        }

        public Builder put(IndexTemplateMetaData.Builder template) {
            return put(template.build());
        }

        public Builder put(IndexTemplateMetaData template) {
            templates.put(template.name(), template);
            return this;
        }

        public Builder removeTemplate(String templateName) {
            templates.remove(templateName);
            return this;
        }

        public Builder templates(ImmutableOpenMap<String, IndexTemplateMetaData> templates) {
            this.templates.putAll(templates);
            return this;
        }

        public Custom getCustom(String type) {
            return customs.get(type);
        }

        public Builder putCustom(String type, Custom custom) {
            customs.put(type, custom);
            return this;
        }

        public Builder removeCustom(String type) {
            customs.remove(type);
            return this;
        }

        public Builder customs(ImmutableOpenMap<String, Custom> customs) {
            this.customs.putAll(customs);
            return this;
        }

        public Builder updateSettings(Settings settings, String... indices) {
            if (indices == null || indices.length == 0) {
                indices = this.indices.keys().toArray(String.class);
            }
            for (String index : indices) {
                IndexMetaData indexMetaData = this.indices.get(index);
                if (indexMetaData == null) {
                    throw new IndexMissingException(new Index(index));
                }
                put(IndexMetaData.builder(indexMetaData)
                        .settings(settingsBuilder().put(indexMetaData.settings()).put(settings)));
            }
            return this;
        }

        public Builder updateNumberOfReplicas(int numberOfReplicas, String... indices) {
            if (indices == null || indices.length == 0) {
                indices = this.indices.keys().toArray(String.class);
            }
            for (String index : indices) {
                IndexMetaData indexMetaData = this.indices.get(index);
                if (indexMetaData == null) {
                    throw new IndexMissingException(new Index(index));
                }
                put(IndexMetaData.builder(indexMetaData).numberOfReplicas(numberOfReplicas));
            }
            return this;
        }

        public Settings transientSettings() {
            return this.transientSettings;
        }

        public Builder transientSettings(Settings settings) {
            this.transientSettings = settings;
            return this;
        }

        public Settings persistentSettings() {
            return this.persistentSettings;
        }

        public Builder persistentSettings(Settings settings) {
            this.persistentSettings = settings;
            return this;
        }

        public Builder version(long version) {
            this.version = version;
            return this;
        }

        public Builder uuid(String uuid) {
            this.uuid = uuid;
            return this;
        }

        public Builder generateUuidIfNeeded() {
            if (uuid.equals("_na_")) {
                uuid = Strings.randomBase64UUID();
            }
            return this;
        }

        public MetaData build() {
            return new MetaData(uuid, version, transientSettings, persistentSettings, indices.build(), templates.build(), customs.build());
        }

        public static String toXContent(MetaData metaData) throws IOException {
            XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON);
            builder.startObject();
            toXContent(metaData, builder, ToXContent.EMPTY_PARAMS);
            builder.endObject();
            return builder.string();
        }

        public static void toXContent(MetaData metaData, XContentBuilder builder, ToXContent.Params params) throws IOException {
            XContentContext context = XContentContext.valueOf(params.param(CONTEXT_MODE_PARAM, "API"));

            builder.startObject("meta-data");

            builder.field("version", metaData.version());
            builder.field("uuid", metaData.uuid);

            if (!metaData.persistentSettings().getAsMap().isEmpty()) {
                builder.startObject("settings");
                for (Map.Entry<String, String> entry : metaData.persistentSettings().getAsMap().entrySet()) {
                    builder.field(entry.getKey(), entry.getValue());
                }
                builder.endObject();
            }

            if (context == XContentContext.API && !metaData.transientSettings().getAsMap().isEmpty()) {
                builder.startObject("transient_settings");
                for (Map.Entry<String, String> entry : metaData.transientSettings().getAsMap().entrySet()) {
                    builder.field(entry.getKey(), entry.getValue());
                }
                builder.endObject();
            }

            builder.startObject("templates");
            for (ObjectCursor<IndexTemplateMetaData> cursor : metaData.templates().values()) {
                IndexTemplateMetaData.Builder.toXContent(cursor.value, builder, params);
            }
            builder.endObject();

            if (context == XContentContext.API && !metaData.indices().isEmpty()) {
                builder.startObject("indices");
                for (IndexMetaData indexMetaData : metaData) {
                    IndexMetaData.Builder.toXContent(indexMetaData, builder, params);
                }
                builder.endObject();
            }

            for (ObjectObjectCursor<String, Custom> cursor : metaData.customs()) {
                Custom proto = lookupPrototypeSafe(cursor.key);
                if (proto.context().contains(context)) {
                    builder.startObject(cursor.key);
                    cursor.value.toXContent(builder, params);
                    builder.endObject();
                }
            }
            builder.endObject();
        }

        public static MetaData fromXContent(XContentParser parser) throws IOException {
            Builder builder = new Builder();

            // we might get here after the meta-data element, or on a fresh parser
            XContentParser.Token token = parser.currentToken();
            String currentFieldName = parser.currentName();
            if (!"meta-data".equals(currentFieldName)) {
                token = parser.nextToken();
                if (token == XContentParser.Token.START_OBJECT) {
                    // move to the field name (meta-data)
                    token = parser.nextToken();
                    // move to the next object
                    token = parser.nextToken();
                }
                currentFieldName = parser.currentName();
                if (token == null) {
                    // no data...
                    return builder.build();
                }
            }

            while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
                if (token == XContentParser.Token.FIELD_NAME) {
                    currentFieldName = parser.currentName();
                } else if (token == XContentParser.Token.START_OBJECT) {
                    if ("settings".equals(currentFieldName)) {
                        builder.persistentSettings(Settings.settingsBuilder().put(SettingsLoader.Helper.loadNestedFromMap(parser.mapOrdered())).build());
                    } else if ("indices".equals(currentFieldName)) {
                        while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
                            builder.put(IndexMetaData.Builder.fromXContent(parser), false);
                        }
                    } else if ("templates".equals(currentFieldName)) {
                        while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
                            builder.put(IndexTemplateMetaData.Builder.fromXContent(parser, parser.currentName()));
                        }
                    } else {
                        // check if its a custom index metadata
                        Custom proto = lookupPrototype(currentFieldName);
                        if (proto == null) {
                            //TODO warn
                            parser.skipChildren();
                        } else {
                            Custom custom = proto.fromXContent(parser);
                            builder.putCustom(custom.type(), custom);
                        }
                    }
                } else if (token.isValue()) {
                    if ("version".equals(currentFieldName)) {
                        builder.version = parser.longValue();
                    } else if ("uuid".equals(currentFieldName)) {
                        builder.uuid = parser.text();
                    }
                }
            }
            return builder.build();
        }

        public static MetaData readFrom(StreamInput in) throws IOException {
            return PROTO.readFrom(in);
        }
    }
}


text:
STUDIES ON THE NATURE OF PLASMIDS ARISING FROM CONJUGATION IN THE HUMAN GASTRO-INTESTINAL TRACT
J. D. ANDERSON, L. C. INGRAM, M. H. RICHMOND and B. WIEDEMANN
First Published: 01 November 1973 https://doi.org/10.1099/00222615-6-4-475
/recommendto/form?webId=%2Fcontent%2Fjournal%2Fjmm&title=Journal+of+Medical+Microbiology&issn=0022-2615&eissn=1473-5644
Journal of Medical Microbiology — Recommend this title to your library
In the studies described in the preceding paper, circumstantial evidence was found for transfer of antibiotic resistance from an ingested strain of Escherichia coli carrying an R factor, R-1, which determined resistance to ampicillin (A), chloramphenicol (C), kanamycin (K), streptomycin (S) and sulphonamide (Su). Resistant organisms isolated from the faeces of a single individual were examined in detail to prove conclusively that the DNA of the ingested plasmid had transferred to other organisms.
The O antigens of the resistant faecal isolates were the same as those of two organisms present before the beginning of the experiment, and these strains were resistant to all the determinants of R-1. The levels of resistance of the isolates to these antibiotics were quantitatively consistent with transfer of the plasmid R-1; and the β-lactamase conferring ampicillin resistance was of the same antigenic type.
The predominant resistant organism isolated from the faeces transferred resistance to ACKSSu to laboratory recipients, and plasmid DNA isolated from such strains had the same molecular weight as R-1 and gave 100 per cent. DNA hybridisation with DNA from R-1. Small populations of another strain were also isolated which transferred resistance to ACKSSu and to tetracycline, and this plasmid contained all of the DNA base sequence of R-1 plus additional DNA. The serotype of this strain was the same as that of a strain already resistant to tetracycline before the beginning of the experiment.
These results prove that R-factor transfer must have occurred during or after antibiotic therapy and illustrates possible dangers of chemotherapy.
© 1973 The Pathological Society of Great Britain and Ireland
/content/journal/jmm/10.1099/00222615-6-4-475
http://instance.metastore.ingenta.com/content/journal/jmm/10.1099/00222615-6-4-475
content/journal/jmm
Candida species: current epidemiology, pathogenicity, biofilm formation, natural antifungal products and new therapeutic options
J. C. O. Sardi, L. Scorzoni, T. Bernardi, A. M. Fusco-Almeida and M. J. S. Mendes Giannini
The Microbial Ecology of the Large Bowel of Breastfed and Formula-fed Infants During the First Year of Life
P. L. Stark and A. Lee
Antimicrobial activities of silver dressings: an in vitro comparison
Margaret Ip, Sau Lai Lui, Vincent K. M. Poon, Ivan Lung and Andrew Burd
Cytotoxic activity in broth-culture filtrates of Campylobacter pylori
R. D. Leunk, P. T. Johnson, B. C. David, W. G. Kraft and D. R. Morgan
Differences between the gut microflora of children with autistic spectrum disorders and that of healthy children
Helena MRT Parracho, Max O Bingham, Glenn R Gibson and Anne L McCartney
Pseudomonas aeruginosa – a phenomenon of bacterial resistance
Tanya Strateva and Daniel Yordanov
THE MICROBIAL CONTRIBUTION TO HUMAN FAECAL MASS
Alison M. Stephen and J. H. Cummings
Serratia marcescens
A. HEJAZI and F. R. FALKINER
Biofilm matrix of Candida albicans and Candida tropicalis: chemical composition and role in drug resistance
Mohammed A. Al-Fattani and L. Julia Douglas
Invasive fungal infections: a review of epidemiology and management options
D. A. Enoch, H. A. Ludlam and N. M. Brown
10.1099/00222615-6-4-475

redpajama_set_name: RedPajamaCommonCrawl


text:
ticanpemo
Movie! Streaming Download 123MOVIE The Offering Full
19 secs ago -!Streaming The Offering 2022 Movie The Offering 2022 Movie Warner THE OFFERING Pictures! Are you looking to download or watch the new The Offering online? #TheOffering is available for Free Streaming 123movies & Reddit, including where to watch the Action movie at home. Express
➤ ► 🌍📺📱👉 Stream and Watch Online
➤ ► 🌍📺📱👉 Stream and Watch Online Download
Now Is The Offering available to stream? Is watching THE OFFERING on Disney Plus, HBO Max, Netflix, or Amazon Prime? Yes, we have found an authentic streaming option/service. A 1950s housewife The Offering with her husband in a utopian experimental community begins to worry that his glamorous company could be hiding disturbing secrets.
Showcase Cinema Warwick you'll want to make sure you're one of the first people to see it! So mark your calendars and get ready for a The Offering movie experience like never before. of our other Marvel movies available to watch online. We're sure you'll find something to your liking. Thanks for reading, and we'll see you soon! The Offering is available on our website for free streaming. Details on how you can watch The Offering for free throughout the year are described
If you're a fan of the comics, you won't want to miss this one! The storyline follows THE OFFERING as he tries to find his way home after being stranded on an alien The Offeringt. The Offering is definitely a The Offering movie you don't want to miss with stunning visuals and an action-packed plot! Plus, The Offering online streaming is available on our website. The Offering online is free, which includes streaming options such as 123movies, Reddit, or TV shows from HBO Max or Netflix!
THE OFFERING Release in the US
The Offering hits theaters on January 21, 2022. Tickets to see the film at your local movie theater are available online here. The film is being released in a wide release so you can watch it in person.
How to Watch THE OFFERING for Free
Where to Watch The Offering?
There are currently no platforms that have the rights to Watch The Offering Movie Online.MAPPA has decided to air the movie only in theaters because it has been a huge success.The studio , on the other hand, does not wish to divert revenue Streaming the movie would only slash the profits, not increase them.
As a result, no streaming services are authorized to offer The Offering Movie for free. The film would, however, very definitely be acquired by services like Funimation , Netflix, and Crunchyroll. As a last consideration, which of these outlets will likely distribute the film worldwide?
Is The Offering on Netflix?
The streaming giant has a massive catalog of television shows and movies, but it does not include 'The Offering.' We recommend our readers watch other dark fantasy films like 'The Witcher: Nightmare of the Wolf.'
Is The Offering on Crunchyroll?
Crunchyroll, along with Funimation, has acquired the rights to the film and will be responsible for its distribution in North America.Therefore, we recommend our readers to look for the movie on the streamer in the coming months. subscribers can also watch dark fantasy shows like 'Jujutsu Kaisen.'


Catholic mates is your 100% free catholic singles online dating site create your profile for free and find a friend or the possible love of your life. Browse photo profiles & contact who are catholic, religion on australia's #1 dating site rsvp free to browse & join. That non-white women power of twitter and all notified speed dating in nc by e-mail if anyone modified to single parent catholic young adults of the lehigh. You will be happy to know that you can actively seek to date a catholic woman online free catholic chat rooms provide you with catholic dating is all.
Meet catholic singles in swedesboro, new jersey online & connect in the chat rooms dhu is a 100% free dating site to find single catholics. Devout catholic women on secular dating sites men and women are utilizing the popular dating sites realm of catholic dating between people 18-32, women have. Are you over 40 and back in the dating game meet an attractive woman today on these 7 best online dating sites for men the 7 best dating sites for men in. List of top websites like stbrigidparish swedesboro, new jersey, parishes online, site men and single catholic women in our community for catholic dating.
Dating in swedesboro in swedesboro catholic dating in swedesboro jewish dating in swedesboro dating site for single women in swedesboro. Catholicmatchcom is the best place for catholic singles to meet online find single catholic men and single catholic women in our community for catholic dating, catholic friendship and catholic marriage.
Catholic dating that's focused most dating sites view online dating at catholic singles is one of my favorite questions to ask the single women in my. In terms of catholic sites, catholic match says it has served almost 1 million people since its founding in 1999 three other catholic sites — avemariasinglescom, catholicsinglescom and catholicminglecom (catholic mingle is part of the christian mingle conglomerate (aka spark network) that operates other sites for jewish and. Woman man seeking a but it's much more difficult to find catholic singles with whom you share the key ingredient unlike other catholic dating sites. Are you a single man in swedesboro, nj local dating service for men at idating4youcom find women without partners incredibly easy & fast.
Catholic dating: want to meet catholic girls, catholic women, or catholic men for genuine relationships and catholic friendships this is the catholic online dating site. Singles over 60 - the best over 60 dating site singles over 60 is a dedicated senior dating site for single men and women over 60 to find activity partners, travel companions or your dream lover with your children grown up and left home, you have more spare time at home it's now time to live for yourself find that special one, start dating over.
Catholic singles for over a decade 36, charlotte catholic women in north carolina, united states looking for a: man aged 29 to 99 ready to love again and.
As a catholic single catholic singles millions of men and women have turned to online dating to meet like-minded singles. Someone you can love is nearby browse profiles & photos of single women in swedesboro, nj join matchcom, the leader in online dating with more dates, more relationships and more marriages than any other dating site. Our members prefer courtship and romance to casual dating and take the time to i am looking for a traditional catholic , fit and active woman who fears god. On dating nice catholic girls february 28 and who use humanae vitae as a dating guide: this is a woman both socially conservative and attractive.


Youtube. She has been with us for so long. It doesn't matter if you are 35 right now, or 15 – a significant part of the current younger generations has grown up with Youtube as their main source for music, short movies for every genre, trailers, funny compilations, books, tutorials, best of's – it's all on there. Even though suggestive content sources like Spotify have gained a substantial global audience over the years. Its user-numbers are still no match for the most popular media content provider in the world; Youtube.
Besides its obvious volume in video content (for pretty much every interest), the Youtube community is also considered powerful. At this very moment, hundreds – if not thousands – of people are arguing and 'fighting' in the comment section of particular content. It's even known that influencers hired by governments are splashing their opinion around in the Youtube comment sections. Based on its sheer volume Youtube is viewed upon by many marketers as one of the 3 leading pillars of internet activity; that would be Google, Facebook, and Youtube.
New days are arriving and while advertising on Youtube was already evident for big brands, medium-sized and smaller brands/product owners are finding their way to Youtube as well. Around 5-6 advertising formats can be served before, on, in, during or around Youtube content. The most obvious format being - of course – the video format. Youtube describes it's advertising options as follows: Display Ads, Overlay Ads, Skippable Video Ads, Non-Skippable Video Ads, Bumper Ads and Sponsored Cards.
Recently, Youtube has also allowed its advertiser to serve ads – in Youtube – based on previous Google searches. You could say some technical aspects/functions of Youtube and Google have merged, offering an ever stronger marketing tool.
Then there is the Targeting. Offering a wide selection of targeting variables Youtube – technically speaking – has similar attributes/functions compared to a normal Demand Side Platform. It has a huge amount of reach and tools to target a specific audience within that reach; all based on the single product that Youtube is. Youtube offers targeting on Demographics; for example; age and gender. But also certain interests can be targeted based on past activity of users. Video Remarketing offers a similar tool that has some trades of traditional retargeting. Also, Youtube offers to target based on placement, topics, and even keywords.
Costs; Cost Per Mille (CPM) or Cost Per View (CPV) is higher than the linear serving of video's using thousands of video publishers (which a good DSP can offer). However; its effects (or conversions) are usually and on average – higher than normal video advertising achieves. Hence the higher pricing is – in most cases – justified.
Do you need a video to do Youtube Advertising? No; several ad formats Youtube can serve can be static images or just text. It is – however – recommended to serve an actual video when advertising on Youtube. Why? Because hundreds of campaigns have taught us that – in comparison to budget spend – video ads have the highest ROI (although there are exceptions). This creates a problem for small business owners. Simply put most of them don't have the resources or knowledge to produce a cheap but professional appearing video. Luckily the internet is here to help. Google for 'Cheap Video Production' or 'Low-cost tutorial video' and you will find plenty of vendors who are able to produce a professional video (in most cases being an animation). Secondarily; honest appearing video's – made by a business owner him/herself (for example showing the workplace or store) – usually are appreciated by the right audience and also have a positive ROI.
In any case; low fee specialists are here to help. You have found one.


It was an everyday thing to do. Stacy Dunbar popped into another room, leaving her eight-week-old baby Eve alone for a second in her bouncer. But suddenly, realising where she'd left Eve, panic seized her.
The little room they were in might look innocent enough to anyone else.
A pale yellow colour on the walls, a change table, a few toys and clothes strewn around. But horrendously, it held the memory of where Stacy's eight-month-old son Nate was horrifically killed in his cot when a drunk driver ploughed through the wall of their Perth home five years ago.
Back in January 2013, Stacy and her husband Justin were awoken at 2.30am by what sounded like an explosion in Nate's nursery.
'The whole room was floodlit and I suddenly realised there was a car, with its headlights still on, in the middle of my son's bedroom,' Stacy told New Idea at the time.
A Toyota HiLux had smashed through the wall, destroying the cot, and had come to rest on Nate's tiny chest.
As his parents sat in the rubble of their home, trying to comprehend what had just happened, the driver of the car, 35-year-old Melissa Ann Waters, stepped over them, climbed out of the hole she'd created and walked off into the night. Waters was later found to have a blood alcohol reading of more than three times the legal limit, and she pleaded guilty to dangerous driving occasioning death and driving under the influence of alcohol.
Handed a jail sentence of three years and eight months, she was out on parole after just one year and 10 months.
'The original sentence was hard enough to stomach, but when she got out the wound was ripped open again,' Stacy says. 'My son is dead and we have to live our life without him, but she gets to walk free.' Despite this, Stacy tries not to focus on Waters or her early release from prison. 'Forgiveness isn't something she deserves from me, but I don't spend my time hating her, as that just destroys my peace,' she sighs.
Besides, Stacy has her hands full with her 12-year-old son Kai and the little whirlwind of a daughter, who came along in the wake of Nate's death.
'Eve has helped our healing so much,' Stacy says of their now three-year-old girl.
Nate is never far from Stacy's thoughts and she admits it was very hard when Eve hit milestones Nate never would.
'Before that we could compare them, but then there was nothing to compare,' Stacy says. On Eve's first birthday, while a happy occasion, both Justin and Stacy keenly felt their loss.
'For the first two years, we couldn't afford to move out of the house where it happened,' Stacy says. 'I felt so unsafe there, I hardly ever went into Nate's room and there was no way I'd let Eve sleep there.
'The Pledge For Nate campaign we ran after his death, where people promised not to drink and drive, has literally saved lives,' Stacy smiles proudly.
The Dunbars received hundreds of heartfelt messages from people saying they would never drink and drive after hearing Nate's story.
'Drink-driving fatalities in WA dropped to their lowest since records began 60 years ago, as a direct result of that campaign,' Stacy says.
Five years on, in the party season, Stacy wants to remind people of Nate's story.
'The only thing every angel mum and dad wants is for people to remember their child, and for me, if with that remembering comes life-saving action, there's a positive out of all this,' Stacy says.
But the anniversary will signal another year without little Nate, and Stacy and her family plan to mark it quietly together.


text:
Home/Cars & Motorcycles/Trains
Trains January 2022
TRAINS IS THE #1 MAGAZINE AMONG RAILROAD ENTHUSIASTS! EACH ISSUE IS PACKED WITH PROBING FEATURES, RAILROAD NEWS, EXPERT COMMENTARY, CUTTING-EDGE INDUSTRY REPORTS, DETAILED MAPS AND SPECTACULAR PHOTOGRAPHY COVERING RAILROADING'S INFLUENTIAL HISTORY AND EXCITING FUTURE.
Kalmbach Publishing Co. - Magazines
SPECIAL: Get 40% OFF with code: START40
$10.65(Incl. tax)
jwrinn@kalmbach.com @TrainsMagazine @trains_magazine There is a lot to like in this issue, from our cover story, "Winter in Coal Country," to a short line worth knowing, and my story about planning trips for the world's largest operating steam locomotive. If I had to pick a favorite, though, I'd direct you to pages 22 to 29, where David Lustig and associates have news you can use: Our guide to the rare, the interesting, and the fleeting that are worth your time visiting in 2022. It's a guide to the locomotives, railroads, and places that you should seek out in person. I've delighted in my visits to the Iowa Traction electrics, and street running in Michigan City calls me across Lake Michigan. Enjoy these opportunities to visit something truly remarkable. Let's get busy livin'!…
canadian national ceo to retire as railroad faces proxy fight
JJ RUEST'S TENURE as Canadian National's chief executive will end the way it began: In the middle of a crisis. Ruest replaced Luc Jobin as CEO in 2018 when CN struggled with traffic in Western Canada. Ruest will retire in January, the railroad announced in October amid an ongoing proxy fight launched by activist investor TCI Fund Management. No successor was named. CN's announcement came a day after TCI released its plan touting former CN Chief Operating Officer Jim Vena as its CEO candidate. TCI has been critical of CN's financial and operational performance as well as its failed pursuit of Kansas City Southern. TCI founder Chris Hohn said Ruest's retirement was "a clear admission by the board that change is needed." TCI urged the CN board to meet with Vena and appoint…
UNION PACIFIC and NORFOLK SOUTHERN mandated COVID-19 vaccinations for employees in October, effective Dec. 8, citing an executive order covering federal contractors. Both railroads filed lawsuits against unions indicating opposition to the requirement, saying it should be subject to negotiation. NS contended the matter is subject to arbitration because it involves interpretation of an existing agreement. BNSF RAILWAY later added its own mandate, effective Jan. 4. After a pandemic-spurred shutdown of more than 20 months, BRIGHTLINE resumed service between Miami and West Palm Beach, Fla., on Nov. 8, and announced it would offer door-to-door service to and from its stations. In October, the company received the first of the new SIEMENS trainsets for its coming expansion to Orlando, shown en route at Hopkinsville, Ky. Jim Pearson A TRANSPORTATION SAFETY BOARD OF CANADA…
infrastructure package to help freight railroads
PRESIDENT JOE BIDEN'S $1.2 trillion infrastructure package, signed into law in November, includes significant spending for rail-related projects through 2026, from grants to shore up short line track to a study of Class I railroads' use of long trains. Amtrak will receive the majority of the rail money; Trains will address that in the February issue. But freight railroads are not left out of the five-year Infrastructure Investment and Jobs Act. The Consolidated Rail Infrastructure and Safety Improvement grant program, or CRISI, will get a big funding boost. The bill provides $1 billion per year, up from $362 million in fiscal 2021. The grants support a range of programs, including regional and short line track and infrastructure projects, grade crossing elimination and improvement efforts, and research and development. Regional and short line railroads…
cp-kcs merger has all the right stuff
bybillstephens@gmail.com @bybillstephens Analysis: Trains.com The proposed merger of Canadian Pacific and Kansas City Southern — the first combination of Class I systems in two decades, and likely the last — should win favor in Washington. After all, their comprehensive merger application checks all of the Surface Transportation Board's boxes. More rail competition? Canadian Pacific Kansas City has that in spades, since much of the forecast growth will come at the expense of other railroads. More trucks off the highway? You bet! Environmental benefits, like reduced greenhouse gas emissions? Yup, by the ton! Support from shippers? Nearly universal! More jobs for labor? Yes, since you need more people to move and maintain more trains. And, finally, a focus on growth, backed by capital spending? CPKC is putting its money where its mouth is, judging from…
guru of the steam safari
briansolomon.author@gmail.com @briansolomon.author Blog: briansolomon.com/trackingthelight/ Podcast: Trains.com Recently, I met with Peter Lerro, who had arranged to visit the Conway Scenic Railroad in New Hampshire to scout locations for his January photo charter. Lerro has established a reputation for his professionally organized steam photo charters, and I was curious to learn first hand about his approach and planning. Many years ago, I discovered that I could always improve my technique by spending time with other photographers because every photographer goes about the process of making pictures in their own way. In my photography, I put time and thought into finding the best locations. Typically, this involves lots of map study, walking to inspect places at various times of day and during different seasons, and when possible from locomotive cabs. To obtain the most effective photo, I…


text:
Protests continue in TN over 'The Family Man 2' web series
MDMK leader Vaiko. (Photo: IANS)
Chennai, June 8 (IANS) Protests surrounding the "The Family Man 2" continued in Tamil Nadu with MDMK leader and Member of Parliament, Vaiko demanding Amazon Prime to stop screening of the web series, starring Manoj Bajpai, Priyamani and Samantha in the leading roles.
The MDMK leader said that several scenes in the series are portraying Tamils in poor light, and sought immediate ban on the series.
Tamil Nadu Minister for Information Technology, Mano Thangaraj had written a letter to Union minister for Information and Broadcasting, Prakash Javedkar on May 24 calling for the banning of the web series from the OTT platform. However the producers of the web series, Amazon Prime had commenced streaming the series from June 4.
In the letter, the Tamil Nadu Minister Mano Thangaraj had said, "the series had depicted the Eelam Tamil's in a highly objectionable manner and that if allowed to stream it would be prejudicial to the maintenance of harmony in the state".
One of the most popular filmmakers of Tamil Nadu, Bharathi Raja in a tweet on Monday called upon the producers of the web series, 'The Family Man 2' to ban it.
He said, "the visuals in the show reveal that the series has been made by the people who don't know the history of Tamil Eelam fighters. I condemn the show that insults the rebellion, which was filled with good intentions, valor as well as sacrifices."
Bharathi Raja has also urged the Union Minister for Information and Broadcasting, Prakash Javedkar immediately stops the streaming of the show.
He had also warned Amazon that if they continue streaming the series, Tamilian's across the world will be forced to stop supporting Amazon and stop other businesses and services that are associated with it.
Earlier Naam Tamil Katchi's (NTK) leader and actor Seeman had issued a letter to Aparna Purohit, Head of India Originals, Amazon Prime Video to stop streaming the series. He said," Stop Streaming the Family Man 2 web series which misrepresents the Tamizhs and the valourous Eelam Liberation struggle of Tamizhs". He also said that if the web series continues to stream, then Tamil people would be forced to boycott Amazon and its products globally.
With Amazon Prime Video's continuing to stream the web series, protests are bound to increase in the state and it is to be seen as to how other mainstream political parties will act in the matter.
Previous articleWorld Bank cuts India's growth forecast for FY22 to 8.3%
Next articleYour Stars – June 11- June 24


Question: Where does on find molds (forms)?
After reading a number of the questions and answers on this forum, I purchased my lamp stand first. Now I need to find the perfect shade to fit upon it.
I've seen the forms at Odyssey and Worden is out of business.
Ideally, I would like to find a mold of my desired shape, and then a pattern to fit that shape.
However, since I have never done this before, I am looking forward to learning from all of you what is available, and what to expect.
Even though Worden is out of business, some online stores still have a few of the forms. If you are interested in that, you have to begin searching.
@WayneFL, Thank you for the information.
re Worden and Odyssey the only solutions out there? It seems that they are the only two (now one) solution(s). I find that odd, but as I stated, I am new here.
There used to me a bunch of foreign shade/mold makers. Over time, as the popularity of cold glass declined, the popularity of shades declined as well but even faster. There are some who make Tiffany reproduction molds, besides Odyssey, but they are expensive and shipping to the US is costly.
Bill, Wayne is a great source of information on lamps!
Several years ago, the market was filled with import stained glass lamps & very realistic imitation glass lamp shades which sold for much less then one could buy the supplies to make one for. This plus the fact the molds can be reused lead to a very low demand & a drying up of the availability of molds & patterns.
Worden-20-P and several places will come up. If you look on Ebay or a similar site, click on the item and check the description to make sure of the mold the pattern is designed for.
Thank you for the kind offer. I found a Worden acorn mold and pattern that will work wonderfully for me. I just hope I will work wonderfully for it.
It does seem as though find molds and patterns is a rather difficult task.
Once again, thank you for your insights and offer. It is quite kind.


text:
DEALERS, RESTORERS & COLLECTORS OF FINE ANTIQUE INSTRUMENTS & THEIR BOWS
York Violins
'Cello Bows
Restoration and Repair
Instrument Hire
Expertise, Valuations & Insurance
Materials Declarations
Instrument Photography
York Violins was first established in 2012 when Adam was reading Chemistry at the University of York (although he spent most of his time in the music department!). He would spend the holidays learning about and examining the 40+ year old instrument collection of his Father and Grandfather, Ian and Robert, while occasionally supplying violins to his friends in various York based ensembles and to the wider public.
Upon completing his degree the business grew to serve the whole country and even overseas, and so UK Violins was born.
Today we maintain very close links with the City of York and the surrounding areas. Despite our headquarters being in Lancashire, we regularly travel to York, usually on a weekly basis to see clients on a by-appointment basis. We are available for home visits where customers can try an instrument in the comfort of their own home, in their own time, and are of course welcome to trial instruments for a few days at their leisure.
We can also advise on restorations, valuations, expertise, set ups and all other enquiries requiring a face to face meeting by appointment.
To set up a meeting and to find out when we are next in the York area please get in touch by contacting us.
© 2023 UK Violins. All rights reserved. | 726 Preston Old Road, Feniscowles, Blackburn, Lancashire, United Kingdom, BB2 5EP |
Tel: +44 (0)7947492014 | Email: info@ukviolins.com


text:
from tests import requires_twisted
import unittest
try:
    from twisted.internet import reactor
    from twisted.internet.error import DNSLookupError
    from twisted.internet import defer
    from twisted.python.failure import Failure
    from eventlet.twistedutil import block_on
except ImportError:
    pass

class Test(unittest.TestCase):
    @requires_twisted
    def test_block_on_success(self):
        from twisted.internet import reactor
        d = reactor.resolver.getHostByName('www.google.com')
        ip = block_on(d)
        assert len(ip.split('.'))==4, ip
        ip2 = block_on(d)
        assert ip == ip2, (ip, ip2)

    @requires_twisted
    def test_block_on_fail(self):
        from twisted.internet import reactor
        d = reactor.resolver.getHostByName('xxx')
        self.assertRaises(DNSLookupError, block_on, d)

    @requires_twisted
    def test_block_on_already_succeed(self):
        d = defer.succeed('hey corotwine')
        res = block_on(d)
        assert res == 'hey corotwine', `res`

    @requires_twisted
    def test_block_on_already_failed(self):
        d = defer.fail(Failure(ZeroDivisionError()))
        self.assertRaises(ZeroDivisionError, block_on, d)

if __name__=='__main__':
    unittest.main()

redpajama_set_name: RedPajamaGithub


Baroque means fancy, a bit strange. No wonder in our age of fantasy novels the Baroque music is so popular. It would seem that of all the countries famous for their Baroque heritage, Germany with its mentality is the worst match of the Baroque aesthetics. Indeed the Germans are known as lovers of order, a logical and practical nation. However it was in Germany that Bach and Handel were born, the greatest composers of the Baroque era. Paradoxically enough, unity of opposites sometimes brings amazing results! The outstanding Russian organist Alexey Parshin will help us to compare the fantasy capacities of German, Italian and French composers.


Hi Fidayers lovely to be here!
Do I really have the strength?
New to FITDAY, NEED HELP!!
Any Anchorage-ALASKA Trail-walkers using FitDay?
hi, say big hello to all of you.
I am a planner! Some background info and some tips that I'm currently using.
Newbie: Net Calories or Food Calories?
not a diet just a new lifestyle.
Trying to stick with it!
Need help shedding these last few...23 pounds!
Need help to reach my goal!
what does "calories lifestyle" mean?
how to add foods to log ?
New to FitDay - How do you count "activity"?
Newcomer in Need of Support!
Here I go; new to site and wanting support!
New to site, could use some help understanding using fitday log.
Happy Thursday..I am new to Fit Day!
New to fitday ready to change!!
Started FitDay 1/25/13, but need clarification about calories lifestyle.
Hi, Just signed up today and now I see all the cool profile names..
New member, Hi, advice and tips welcomed.
Well, new of forum but not to fit day.
Newbie needs help with Atkins Induction, veterans apply within!
New to FitDay! looking for a some support and advise.
Just joined...looking for someone to hold me accountable!
Need to lose the baby weight and more!
Feeling down - Need weight loss motivation and advice!
Newcomer from South Africa - diet buddy?
Is a single day of pigging out that bad?