text:
package org.apache.flink.table.calcite.rules;

import org.apache.calcite.plan.Contexts;
import org.apache.calcite.plan.RelOptCluster;
import org.apache.calcite.plan.RelOptRule;
import org.apache.calcite.plan.RelOptRuleCall;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.Aggregate;
import org.apache.calcite.rel.core.AggregateCall;
import org.apache.calcite.rel.core.JoinRelType;
import org.apache.calcite.rel.core.RelFactories;
import org.apache.calcite.rel.logical.LogicalAggregate;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rel.type.RelDataTypeField;
import org.apache.calcite.rex.RexBuilder;
import org.apache.calcite.rex.RexInputRef;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.sql.SqlAggFunction;
import org.apache.calcite.sql.fun.SqlCountAggFunction;
import org.apache.calcite.sql.fun.SqlMinMaxAggFunction;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.fun.SqlSumAggFunction;
import org.apache.calcite.sql.fun.SqlSumEmptyIsZeroAggFunction;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.tools.RelBuilder;
import org.apache.calcite.tools.RelBuilderFactory;
import org.apache.calcite.util.ImmutableBitSet;
import org.apache.calcite.util.ImmutableIntList;
import org.apache.calcite.util.Pair;
import org.apache.calcite.util.Util;

import org.apache.flink.util.Preconditions;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

/**
 Copy calcite's AggregateExpandDistinctAggregatesRule to Flink project,
 and do a quick fix to avoid some bad case mentioned in CALCITE-1558.
 Should drop it and use calcite's AggregateExpandDistinctAggregatesRule
 when we upgrade to calcite 1.12(above)
 */

/**
 * Planner rule that expands distinct aggregates
 * (such as {@code COUNT(DISTINCT x)}) from a
 * {@link org.apache.calcite.rel.logical.LogicalAggregate}.
 *
 *
How this is done depends upon the arguments to the function. If all
 * functions have the same argument
 * (e.g. {@code COUNT(DISTINCT x), SUM(DISTINCT x)} both have the argument
 * {@code x}) then one extra {@link org.apache.calcite.rel.core.Aggregate} is
 * sufficient.
 *
 *
If there are multiple arguments
 * (e.g. {@code COUNT(DISTINCT x), COUNT(DISTINCT y)})
 * the rule creates separate {@code Aggregate}s and combines using a
 * {@link org.apache.calcite.rel.core.Join}.
 */
public final class FlinkAggregateExpandDistinctAggregatesRule extends RelOptRule {
	//~ Static fields/initializers ---------------------------------------------

	/** The default instance of the rule; operates only on logical expressions. */
	public static final FlinkAggregateExpandDistinctAggregatesRule INSTANCE =
			new FlinkAggregateExpandDistinctAggregatesRule(LogicalAggregate.class, true,
					RelFactories.LOGICAL_BUILDER);

	/** Instance of the rule that operates only on logical expressions and
	 * generates a join. */
	public static final FlinkAggregateExpandDistinctAggregatesRule JOIN =
			new FlinkAggregateExpandDistinctAggregatesRule(LogicalAggregate.class, false,
					RelFactories.LOGICAL_BUILDER);

	private static final BigDecimal TWO = BigDecimal.valueOf(2L);

	public final boolean useGroupingSets;

	//~ Constructors -----------------------------------------------------------

	public FlinkAggregateExpandDistinctAggregatesRule(
			Class<? extends LogicalAggregate> clazz,
			boolean useGroupingSets,
			RelBuilderFactory relBuilderFactory) {
		super(operand(clazz, any()), relBuilderFactory, null);
		this.useGroupingSets = useGroupingSets;
	}

	/**
	 * @deprecated to be removed before 2.0
	 */
	@Deprecated
	public FlinkAggregateExpandDistinctAggregatesRule(
			Class<? extends LogicalAggregate> clazz,
			boolean useGroupingSets,
			RelFactories.JoinFactory joinFactory) {
		this(clazz, useGroupingSets, RelBuilder.proto(Contexts.of(joinFactory)));
	}

	/**
	 * @deprecated to be removed before 2.0
	 */
	@Deprecated
	public FlinkAggregateExpandDistinctAggregatesRule(
			Class<? extends LogicalAggregate> clazz,
			RelFactories.JoinFactory joinFactory) {
		this(clazz, false, RelBuilder.proto(Contexts.of(joinFactory)));
	}

	//~ Methods ----------------------------------------------------------------

	public void onMatch(RelOptRuleCall call) {
		final Aggregate aggregate = call.rel(0);
		if (!aggregate.containsDistinctCall()) {
			return;
		}

		// Find all of the agg expressions. We use a LinkedHashSet to ensure
		// determinism.
		int nonDistinctCount = 0;
		int distinctCount = 0;
		int filterCount = 0;
		int unsupportedAggCount = 0;
		final Set<Pair<List<Integer>, Integer>> argLists = new LinkedHashSet<>();
		for (AggregateCall aggCall : aggregate.getAggCallList()) {
			if (aggCall.filterArg >= 0) {
				++filterCount;
			}
			if (!aggCall.isDistinct()) {
				++nonDistinctCount;
				if (!(aggCall.getAggregation() instanceof SqlCountAggFunction
						|| aggCall.getAggregation() instanceof SqlSumAggFunction
						|| aggCall.getAggregation() instanceof SqlMinMaxAggFunction)) {
					++unsupportedAggCount;
				}
				continue;
			}
			++distinctCount;
			argLists.add(Pair.of(aggCall.getArgList(), aggCall.filterArg));
		}
		Preconditions.checkState(argLists.size() > 0, "containsDistinctCall lied");

		// If all of the agg expressions are distinct and have the same
		// arguments then we can use a more efficient form.
		if (nonDistinctCount == 0 && argLists.size() == 1) {
			final Pair<List<Integer>, Integer> pair =
					Iterables.getOnlyElement(argLists);
			final RelBuilder relBuilder = call.builder();
			convertMonopole(relBuilder, aggregate, pair.left, pair.right);
			call.transformTo(relBuilder.build());
			return;
		}

		if (useGroupingSets) {
			rewriteUsingGroupingSets(call, aggregate, argLists);
			return;
		}

		// If only one distinct aggregate and one or more non-distinct aggregates,
		// we can generate multi-phase aggregates
		if (distinctCount == 1 // one distinct aggregate
				&& filterCount == 0 // no filter
				&& unsupportedAggCount == 0 // sum/min/max/count in non-distinct aggregate
				&& nonDistinctCount > 0) { // one or more non-distinct aggregates
			final RelBuilder relBuilder = call.builder();
			convertSingletonDistinct(relBuilder, aggregate, argLists);
			call.transformTo(relBuilder.build());
			return;
		}

		// Create a list of the expressions which will yield the final result.
		// Initially, the expressions point to the input field.
		final List<RelDataTypeField> aggFields =
				aggregate.getRowType().getFieldList();
		final List<RexInputRef> refs = new ArrayList<>();
		final List<String> fieldNames = aggregate.getRowType().getFieldNames();
		final ImmutableBitSet groupSet = aggregate.getGroupSet();
		final int groupAndIndicatorCount =
				aggregate.getGroupCount() + aggregate.getIndicatorCount();
		for (int i : Util.range(groupAndIndicatorCount)) {
			refs.add(RexInputRef.of(i, aggFields));
		}

		// Aggregate the original relation, including any non-distinct aggregates.
		final List<AggregateCall> newAggCallList = new ArrayList<>();
		int i = -1;
		for (AggregateCall aggCall : aggregate.getAggCallList()) {
			++i;
			if (aggCall.isDistinct()) {
				refs.add(null);
				continue;
			}
			refs.add(
					new RexInputRef(
							groupAndIndicatorCount + newAggCallList.size(),
							aggFields.get(groupAndIndicatorCount + i).getType()));
			newAggCallList.add(aggCall);
		}

		// In the case where there are no non-distinct aggregates (regardless of
		// whether there are group bys), there's no need to generate the
		// extra aggregate and join.
		final RelBuilder relBuilder = call.builder();
		relBuilder.push(aggregate.getInput());
		int n = 0;
		if (!newAggCallList.isEmpty()) {
			final RelBuilder.GroupKey groupKey =
					relBuilder.groupKey(groupSet, aggregate.indicator, aggregate.getGroupSets());
			relBuilder.aggregate(groupKey, newAggCallList);
			++n;
		}

		// For each set of operands, find and rewrite all calls which have that
		// set of operands.
		for (Pair<List<Integer>, Integer> argList : argLists) {
			doRewrite(relBuilder, aggregate, n++, argList.left, argList.right, refs);
		}

		relBuilder.project(refs, fieldNames);
		call.transformTo(relBuilder.build());
	}

	/**
	 * Converts an aggregate with one distinct aggregate and one or more
	 * non-distinct aggregates to multi-phase aggregates (see reference example
	 * below).
	 *
	 * @param relBuilder Contains the input relational expression
	 * @param aggregate  Original aggregate
	 * @param argLists   Arguments and filters to the distinct aggregate function
	 *
	 */
	private RelBuilder convertSingletonDistinct(RelBuilder relBuilder,
											Aggregate aggregate, Set<Pair<List<Integer>, Integer>> argLists) {
		// For example,
		//	SELECT deptno, COUNT(*), SUM(bonus), MIN(DISTINCT sal)
		//	FROM emp
		//	GROUP BY deptno
		//
		// becomes
		//
		//	SELECT deptno, SUM(cnt), SUM(bonus), MIN(sal)
		//	FROM (
		//		  SELECT deptno, COUNT(*) as cnt, SUM(bonus), sal
		//		  FROM EMP
		//		  GROUP BY deptno, sal)			// Aggregate B
		//	GROUP BY deptno						// Aggregate A
		relBuilder.push(aggregate.getInput());
		final List<Pair<RexNode, String>> projects = new ArrayList<>();
		final Map<Integer, Integer> sourceOf = new HashMap<>();
		SortedSet<Integer> newGroupSet = new TreeSet<>();
		final List<RelDataTypeField> childFields =
				relBuilder.peek().getRowType().getFieldList();
		final boolean hasGroupBy = aggregate.getGroupSet().size() > 0;

		SortedSet<Integer> groupSet = new TreeSet<>(aggregate.getGroupSet().asList());

		// Add the distinct aggregate column(s) to the group-by columns,
		// if not already a part of the group-by
		newGroupSet.addAll(aggregate.getGroupSet().asList());
		for (Pair<List<Integer>, Integer> argList : argLists) {
			newGroupSet.addAll(argList.getKey());
		}

		// Re-map the arguments to the aggregate A. These arguments will get
		// remapped because of the intermediate aggregate B generated as part of the
		// transformation.
		for (int arg : newGroupSet) {
			sourceOf.put(arg, projects.size());
			projects.add(RexInputRef.of2(arg, childFields));
		}
		// Generate the intermediate aggregate B
		final List<AggregateCall> aggCalls = aggregate.getAggCallList();
		final List<AggregateCall> newAggCalls = new ArrayList<>();
		final List<Integer> fakeArgs = new ArrayList<>();
		final Map<AggregateCall, Integer> callArgMap = new HashMap<>();
		// First identify the real arguments, then use the rest for fake arguments
		// e.g. if real arguments are 0, 1, 3. Then the fake arguments will be 2, 4
		for (final AggregateCall aggCall : aggCalls) {
			if (!aggCall.isDistinct()) {
				for (int arg : aggCall.getArgList()) {
					if (!groupSet.contains(arg)) {
						sourceOf.put(arg, projects.size());
					}
				}
			}
		}
		int fakeArg0 = 0;
		for (final AggregateCall aggCall : aggCalls) {
			// We will deal with non-distinct aggregates below
			if (!aggCall.isDistinct()) {
				boolean isGroupKeyUsedInAgg = false;
				for (int arg : aggCall.getArgList()) {
					if (groupSet.contains(arg)) {
						isGroupKeyUsedInAgg = true;
						break;
					}
				}
				if (aggCall.getArgList().size() == 0 || isGroupKeyUsedInAgg) {
					while (sourceOf.get(fakeArg0) != null) {
						++fakeArg0;
					}
					fakeArgs.add(fakeArg0);
					++fakeArg0;
				}
			}
		}
		for (final AggregateCall aggCall : aggCalls) {
			if (!aggCall.isDistinct()) {
				for (int arg : aggCall.getArgList()) {
					if (!groupSet.contains(arg)) {
						sourceOf.remove(arg);
					}
				}
			}
		}
		// Compute the remapped arguments using fake arguments for non-distinct
		// aggregates with no arguments e.g. count(*).
		int fakeArgIdx = 0;
		for (final AggregateCall aggCall : aggCalls) {
			// Project the column corresponding to the distinct aggregate. Project
			// as-is all the non-distinct aggregates
			if (!aggCall.isDistinct()) {
				final AggregateCall newCall =
						AggregateCall.create(aggCall.getAggregation(), false,
								aggCall.getArgList(), -1,
								ImmutableBitSet.of(newGroupSet).cardinality(),
								relBuilder.peek(), null, aggCall.name);
				newAggCalls.add(newCall);
				if (newCall.getArgList().size() == 0) {
					int fakeArg = fakeArgs.get(fakeArgIdx);
					callArgMap.put(newCall, fakeArg);
					sourceOf.put(fakeArg, projects.size());
					projects.add(
							Pair.of((RexNode) new RexInputRef(fakeArg, newCall.getType()),
									newCall.getName()));
					++fakeArgIdx;
				} else {
					for (int arg : newCall.getArgList()) {
						if (groupSet.contains(arg)) {
							int fakeArg = fakeArgs.get(fakeArgIdx);
							callArgMap.put(newCall, fakeArg);
							sourceOf.put(fakeArg, projects.size());
							projects.add(
									Pair.of((RexNode) new RexInputRef(fakeArg, newCall.getType()),
											newCall.getName()));
							++fakeArgIdx;
						} else {
							sourceOf.put(arg, projects.size());
							projects.add(
									Pair.of((RexNode) new RexInputRef(arg, newCall.getType()),
											newCall.getName()));
						}
					}
				}
			}
		}
		// Generate the aggregate B (see the reference example above)
		relBuilder.push(
				aggregate.copy(
						aggregate.getTraitSet(), relBuilder.build(),
						false, ImmutableBitSet.of(newGroupSet), null, newAggCalls));
		// Convert the existing aggregate to aggregate A (see the reference example above)
		final List<AggregateCall> newTopAggCalls =
				Lists.newArrayList(aggregate.getAggCallList());
		// Use the remapped arguments for the (non)distinct aggregate calls
		for (int i = 0; i < newTopAggCalls.size(); i++) {
			// Re-map arguments.
			final AggregateCall aggCall = newTopAggCalls.get(i);
			final int argCount = aggCall.getArgList().size();
			final List<Integer> newArgs = new ArrayList<>(argCount);
			final AggregateCall newCall;

			for (int j = 0; j < argCount; j++) {
				final Integer arg = aggCall.getArgList().get(j);
				if (callArgMap.containsKey(aggCall)) {
					newArgs.add(sourceOf.get(callArgMap.get(aggCall)));
				}
				else {
					newArgs.add(sourceOf.get(arg));
				}
			}
			if (aggCall.isDistinct()) {
				newCall =
						AggregateCall.create(aggCall.getAggregation(), false, newArgs,
								-1, aggregate.getGroupSet().cardinality(), relBuilder.peek(),
								aggCall.getType(), aggCall.name);
			} else {
				// If aggregate B had a COUNT aggregate call the corresponding aggregate at
				// aggregate A must be SUM. For other aggregates, it remains the same.
				if (aggCall.getAggregation() instanceof SqlCountAggFunction) {
					if (aggCall.getArgList().size() == 0) {
						newArgs.add(sourceOf.get(callArgMap.get(aggCall)));
					}
					if (hasGroupBy) {
						SqlSumAggFunction sumAgg = new SqlSumAggFunction(null);
						newCall =
								AggregateCall.create(sumAgg, false, newArgs, -1,
										aggregate.getGroupSet().cardinality(), relBuilder.peek(),
										aggCall.getType(), aggCall.getName());
					} else {
						SqlSumEmptyIsZeroAggFunction sumAgg = new SqlSumEmptyIsZeroAggFunction();
						newCall =
								AggregateCall.create(sumAgg, false, newArgs, -1,
										aggregate.getGroupSet().cardinality(), relBuilder.peek(),
										aggCall.getType(), aggCall.getName());
					}
				} else {
					newCall =
							AggregateCall.create(aggCall.getAggregation(), false, newArgs, -1,
									aggregate.getGroupSet().cardinality(),
									relBuilder.peek(), aggCall.getType(), aggCall.name);
				}
			}
			newTopAggCalls.set(i, newCall);
		}
		// Populate the group-by keys with the remapped arguments for aggregate A
		newGroupSet.clear();
		for (int arg : aggregate.getGroupSet()) {
			newGroupSet.add(sourceOf.get(arg));
		}
		relBuilder.push(
				aggregate.copy(aggregate.getTraitSet(),
						relBuilder.build(), aggregate.indicator,
						ImmutableBitSet.of(newGroupSet), null, newTopAggCalls));
		return relBuilder;
	}
	/*
	public RelBuilder convertSingletonDistinct(RelBuilder relBuilder,
											   Aggregate aggregate, Set<Pair<List<Integer>, Integer>> argLists) {
		// For example,
		//	SELECT deptno, COUNT(*), SUM(bonus), MIN(DISTINCT sal)
		//	FROM emp
		//	GROUP BY deptno
		//
		// becomes
		//
		//	SELECT deptno, SUM(cnt), SUM(bonus), MIN(sal)
		//	FROM (
		//		  SELECT deptno, COUNT(*) as cnt, SUM(bonus), sal
		//		  FROM EMP
		//		  GROUP BY deptno, sal)			// Aggregate B
		//	GROUP BY deptno						// Aggregate A
		relBuilder.push(aggregate.getInput());
		final List<Pair<RexNode, String>> projects = new ArrayList<>();
		final Map<Integer, Integer> sourceOf = new HashMap<>();
		SortedSet<Integer> newGroupSet = new TreeSet<>();
		final List<RelDataTypeField> childFields =
				relBuilder.peek().getRowType().getFieldList();
		final boolean hasGroupBy = aggregate.getGroupSet().size() > 0;

		// Add the distinct aggregate column(s) to the group-by columns,
		// if not already a part of the group-by
		newGroupSet.addAll(aggregate.getGroupSet().asList());
		for (Pair<List<Integer>, Integer> argList : argLists) {
			newGroupSet.addAll(argList.getKey());
		}

		// Re-map the arguments to the aggregate A. These arguments will get
		// remapped because of the intermediate aggregate B generated as part of the
		// transformation.
		for (int arg : newGroupSet) {
			sourceOf.put(arg, projects.size());
			projects.add(RexInputRef.of2(arg, childFields));
		}
		// Generate the intermediate aggregate B
		final List<AggregateCall> aggCalls = aggregate.getAggCallList();
		final List<AggregateCall> newAggCalls = new ArrayList<>();
		final List<Integer> fakeArgs = new ArrayList<>();
		final Map<AggregateCall, Integer> callArgMap = new HashMap<>();
		// First identify the real arguments, then use the rest for fake arguments
		// e.g. if real arguments are 0, 1, 3. Then the fake arguments will be 2, 4
		for (final AggregateCall aggCall : aggCalls) {
			if (!aggCall.isDistinct()) {
				for (int arg : aggCall.getArgList()) {
					if (!sourceOf.containsKey(arg)) {
						sourceOf.put(arg, projects.size());
					}
				}
			}
		}
		int fakeArg0 = 0;
		for (final AggregateCall aggCall : aggCalls) {
			// We will deal with non-distinct aggregates below
			if (!aggCall.isDistinct()) {
				boolean isGroupKeyUsedInAgg = false;
				for (int arg : aggCall.getArgList()) {
					if (sourceOf.containsKey(arg)) {
						isGroupKeyUsedInAgg = true;
						break;
					}
				}
				if (aggCall.getArgList().size() == 0 || isGroupKeyUsedInAgg) {
					while (sourceOf.get(fakeArg0) != null) {
						++fakeArg0;
					}
					fakeArgs.add(fakeArg0);
				}
			}
		}
		for (final AggregateCall aggCall : aggCalls) {
			if (!aggCall.isDistinct()) {
				for (int arg : aggCall.getArgList()) {
					if (!sourceOf.containsKey(arg)) {
						sourceOf.remove(arg);
					}
				}
			}
		}
		// Compute the remapped arguments using fake arguments for non-distinct
		// aggregates with no arguments e.g. count(*).
		int fakeArgIdx = 0;
		for (final AggregateCall aggCall : aggCalls) {
			// Project the column corresponding to the distinct aggregate. Project
			// as-is all the non-distinct aggregates
			if (!aggCall.isDistinct()) {
				final AggregateCall newCall =
						AggregateCall.create(aggCall.getAggregation(), false,
								aggCall.getArgList(), -1,
								ImmutableBitSet.of(newGroupSet).cardinality(),
								relBuilder.peek(), null, aggCall.name);
				newAggCalls.add(newCall);
				if (newCall.getArgList().size() == 0) {
					int fakeArg = fakeArgs.get(fakeArgIdx);
					callArgMap.put(newCall, fakeArg);
					sourceOf.put(fakeArg, projects.size());
					projects.add(
							Pair.of((RexNode) new RexInputRef(fakeArg, newCall.getType()),
									newCall.getName()));
					++fakeArgIdx;
				} else {
					for (int arg : newCall.getArgList()) {
						if (sourceOf.containsKey(arg)) {
							int fakeArg = fakeArgs.get(fakeArgIdx);
							callArgMap.put(newCall, fakeArg);
							sourceOf.put(fakeArg, projects.size());
							projects.add(
									Pair.of((RexNode) new RexInputRef(fakeArg, newCall.getType()),
											newCall.getName()));
							++fakeArgIdx;
						} else {
							sourceOf.put(arg, projects.size());
							projects.add(
									Pair.of((RexNode) new RexInputRef(arg, newCall.getType()),
											newCall.getName()));
						}
					}
				}
			}
		}
		// Generate the aggregate B (see the reference example above)
		relBuilder.push(
				aggregate.copy(
						aggregate.getTraitSet(), relBuilder.build(),
						false, ImmutableBitSet.of(newGroupSet), null, newAggCalls));
		// Convert the existing aggregate to aggregate A (see the reference example above)
		final List<AggregateCall> newTopAggCalls =
				Lists.newArrayList(aggregate.getAggCallList());
		// Use the remapped arguments for the (non)distinct aggregate calls
		for (int i = 0; i < newTopAggCalls.size(); i++) {
			// Re-map arguments.
			final AggregateCall aggCall = newTopAggCalls.get(i);
			final int argCount = aggCall.getArgList().size();
			final List<Integer> newArgs = new ArrayList<>(argCount);
			final AggregateCall newCall;

			for (int j = 0; j < argCount; j++) {
				final Integer arg = aggCall.getArgList().get(j);
				if (callArgMap.containsKey(aggCall)) {
					newArgs.add(sourceOf.get(callArgMap.get(aggCall)));
				}
				else {
					newArgs.add(sourceOf.get(arg));
				}
			}
			if (aggCall.isDistinct()) {
				newCall =
						AggregateCall.create(aggCall.getAggregation(), false, newArgs,
								-1, aggregate.getGroupSet().cardinality(), relBuilder.peek(),
								aggCall.getType(), aggCall.name);
			} else {
				// If aggregate B had a COUNT aggregate call the corresponding aggregate at
				// aggregate A must be SUM. For other aggregates, it remains the same.
				if (aggCall.getAggregation() instanceof SqlCountAggFunction) {
					if (aggCall.getArgList().size() == 0) {
						newArgs.add(sourceOf.get(callArgMap.get(aggCall)));
					}
					if (hasGroupBy) {
						SqlSumAggFunction sumAgg = new SqlSumAggFunction(null);
						newCall =
								AggregateCall.create(sumAgg, false, newArgs, -1,
										aggregate.getGroupSet().cardinality(), relBuilder.peek(),
										aggCall.getType(), aggCall.getName());
					} else {
						SqlSumEmptyIsZeroAggFunction sumAgg = new SqlSumEmptyIsZeroAggFunction();
						newCall =
								AggregateCall.create(sumAgg, false, newArgs, -1,
										aggregate.getGroupSet().cardinality(), relBuilder.peek(),
										aggCall.getType(), aggCall.getName());
					}
				} else {
					newCall =
							AggregateCall.create(aggCall.getAggregation(), false, newArgs, -1,
									aggregate.getGroupSet().cardinality(),
									relBuilder.peek(), aggCall.getType(), aggCall.name);
				}
			}
			newTopAggCalls.set(i, newCall);
		}
		// Populate the group-by keys with the remapped arguments for aggregate A
		newGroupSet.clear();
		for (int arg : aggregate.getGroupSet()) {
			newGroupSet.add(sourceOf.get(arg));
		}
		relBuilder.push(
				aggregate.copy(aggregate.getTraitSet(),
						relBuilder.build(), aggregate.indicator,
						ImmutableBitSet.of(newGroupSet), null, newTopAggCalls));
		return relBuilder;
	}
	*/

	@SuppressWarnings("DanglingJavadoc")
	private void rewriteUsingGroupingSets(RelOptRuleCall call,
										Aggregate aggregate, Set<Pair<List<Integer>, Integer>> argLists) {
		final Set<ImmutableBitSet> groupSetTreeSet =
				new TreeSet<>(ImmutableBitSet.ORDERING);
		groupSetTreeSet.add(aggregate.getGroupSet());
		for (Pair<List<Integer>, Integer> argList : argLists) {
			groupSetTreeSet.add(
					ImmutableBitSet.of(argList.left)
							.setIf(argList.right, argList.right >= 0)
							.union(aggregate.getGroupSet()));
		}

		final ImmutableList<ImmutableBitSet> groupSets =
				ImmutableList.copyOf(groupSetTreeSet);
		final ImmutableBitSet fullGroupSet = ImmutableBitSet.union(groupSets);

		final List<AggregateCall> distinctAggCalls = new ArrayList<>();
		for (Pair<AggregateCall, String> aggCall : aggregate.getNamedAggCalls()) {
			if (!aggCall.left.isDistinct()) {
				distinctAggCalls.add(aggCall.left.rename(aggCall.right));
			}
		}

		final RelBuilder relBuilder = call.builder();
		relBuilder.push(aggregate.getInput());
		relBuilder.aggregate(relBuilder.groupKey(fullGroupSet, groupSets.size() > 1, groupSets),
				distinctAggCalls);
		final RelNode distinct = relBuilder.peek();
		final int groupCount = fullGroupSet.cardinality();
		final int indicatorCount = groupSets.size() > 1 ? groupCount : 0;

		final RelOptCluster cluster = aggregate.getCluster();
		final RexBuilder rexBuilder = cluster.getRexBuilder();
		final RelDataTypeFactory typeFactory = cluster.getTypeFactory();
		final RelDataType booleanType =
				typeFactory.createTypeWithNullability(
						typeFactory.createSqlType(SqlTypeName.BOOLEAN), false);
		final List<Pair<RexNode, String>> predicates = new ArrayList<>();
		final Map<ImmutableBitSet, Integer> filters = new HashMap<>();

		/** Function to register a filter for a group set. */
		class Registrar {
			RexNode group = null;

			private int register(ImmutableBitSet groupSet) {
				if (group == null) {
					group = makeGroup(groupCount - 1);
				}
				final RexNode node =
						rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, group,
								rexBuilder.makeExactLiteral(
										toNumber(remap(fullGroupSet, groupSet))));
				predicates.add(Pair.of(node, toString(groupSet)));
				return groupCount + indicatorCount + distinctAggCalls.size()
						+ predicates.size() - 1;
			}

			private RexNode makeGroup(int i) {
				final RexInputRef ref =
						rexBuilder.makeInputRef(booleanType, groupCount + i);
				final RexNode kase =
						rexBuilder.makeCall(SqlStdOperatorTable.CASE, ref,
								rexBuilder.makeExactLiteral(BigDecimal.ZERO),
								rexBuilder.makeExactLiteral(TWO.pow(i)));
				if (i == 0) {
					return kase;
				} else {
					return rexBuilder.makeCall(SqlStdOperatorTable.PLUS,
							makeGroup(i - 1), kase);
				}
			}

			private BigDecimal toNumber(ImmutableBitSet bitSet) {
				BigDecimal n = BigDecimal.ZERO;
				for (int key : bitSet) {
					n = n.add(TWO.pow(key));
				}
				return n;
			}

			private String toString(ImmutableBitSet bitSet) {
				final StringBuilder buf = new StringBuilder("$i");
				for (int key : bitSet) {
					buf.append(key).append('_');
				}
				return buf.substring(0, buf.length() - 1);
			}
		}
		final Registrar registrar = new Registrar();
		for (ImmutableBitSet groupSet : groupSets) {
			filters.put(groupSet, registrar.register(groupSet));
		}

		if (!predicates.isEmpty()) {
			List<Pair<RexNode, String>> nodes = new ArrayList<>();
			for (RelDataTypeField f : relBuilder.peek().getRowType().getFieldList()) {
				final RexNode node = rexBuilder.makeInputRef(f.getType(), f.getIndex());
				nodes.add(Pair.of(node, f.getName()));
			}
			nodes.addAll(predicates);
			relBuilder.project(Pair.left(nodes), Pair.right(nodes));
		}

		int x = groupCount + indicatorCount;
		final List<AggregateCall> newCalls = new ArrayList<>();
		for (AggregateCall aggCall : aggregate.getAggCallList()) {
			final int newFilterArg;
			final List<Integer> newArgList;
			final SqlAggFunction aggregation;
			if (!aggCall.isDistinct()) {
				aggregation = SqlStdOperatorTable.MIN;
				newArgList = ImmutableIntList.of(x++);
				newFilterArg = filters.get(aggregate.getGroupSet());
			} else {
				aggregation = aggCall.getAggregation();
				newArgList = remap(fullGroupSet, aggCall.getArgList());
				newFilterArg =
						filters.get(
								ImmutableBitSet.of(aggCall.getArgList())
										.setIf(aggCall.filterArg, aggCall.filterArg >= 0)
										.union(aggregate.getGroupSet()));
			}
			final AggregateCall newCall =
					AggregateCall.create(aggregation, false, newArgList, newFilterArg,
							aggregate.getGroupCount(), distinct, null, aggCall.name);
			newCalls.add(newCall);
		}

		relBuilder.aggregate(
				relBuilder.groupKey(
						remap(fullGroupSet, aggregate.getGroupSet()),
						aggregate.indicator,
						remap(fullGroupSet, aggregate.getGroupSets())),
				newCalls);
		relBuilder.convert(aggregate.getRowType(), true);
		call.transformTo(relBuilder.build());
	}

	private static ImmutableBitSet remap(ImmutableBitSet groupSet,
										ImmutableBitSet bitSet) {
		final ImmutableBitSet.Builder builder = ImmutableBitSet.builder();
		for (Integer bit : bitSet) {
			builder.set(remap(groupSet, bit));
		}
		return builder.build();
	}

	private static ImmutableList<ImmutableBitSet> remap(ImmutableBitSet groupSet,
														Iterable<ImmutableBitSet> bitSets) {
		final ImmutableList.Builder<ImmutableBitSet> builder =
				ImmutableList.builder();
		for (ImmutableBitSet bitSet : bitSets) {
			builder.add(remap(groupSet, bitSet));
		}
		return builder.build();
	}

	private static List<Integer> remap(ImmutableBitSet groupSet,
									List<Integer> argList) {
		ImmutableIntList list = ImmutableIntList.of();
		for (int arg : argList) {
			list = list.append(remap(groupSet, arg));
		}
		return list;
	}

	private static int remap(ImmutableBitSet groupSet, int arg) {
		return arg < 0 ? -1 : groupSet.indexOf(arg);
	}

	/**
	 * Converts an aggregate relational expression that contains just one
	 * distinct aggregate function (or perhaps several over the same arguments)
	 * and no non-distinct aggregate functions.
	 */
	private RelBuilder convertMonopole(RelBuilder relBuilder, Aggregate aggregate,
									List<Integer> argList, int filterArg) {
		// For example,
		//	SELECT deptno, COUNT(DISTINCT sal), SUM(DISTINCT sal)
		//	FROM emp
		//	GROUP BY deptno
		//
		// becomes
		//
		//	SELECT deptno, COUNT(distinct_sal), SUM(distinct_sal)
		//	FROM (
		//	  SELECT DISTINCT deptno, sal AS distinct_sal
		//	  FROM EMP GROUP BY deptno)
		//	GROUP BY deptno

		// Project the columns of the GROUP BY plus the arguments
		// to the agg function.
		final Map<Integer, Integer> sourceOf = new HashMap<>();
		createSelectDistinct(relBuilder, aggregate, argList, filterArg, sourceOf);

		// Create an aggregate on top, with the new aggregate list.
		final List<AggregateCall> newAggCalls =
				Lists.newArrayList(aggregate.getAggCallList());
		rewriteAggCalls(newAggCalls, argList, sourceOf);
		final int cardinality = aggregate.getGroupSet().cardinality();
		relBuilder.push(
				aggregate.copy(aggregate.getTraitSet(), relBuilder.build(),
						aggregate.indicator, ImmutableBitSet.range(cardinality), null,
						newAggCalls));
		return relBuilder;
	}

	/**
	 * Converts all distinct aggregate calls to a given set of arguments.
	 *
	 *
This method is called several times, one for each set of arguments.
	 * Each time it is called, it generates a JOIN to a new SELECT DISTINCT
	 * relational expression, and modifies the set of top-level calls.
	 *
	 * @param aggregate Original aggregate
	 * @param n		 Ordinal of this in a join. {@code relBuilder} contains the
	 *				  input relational expression (either the original
	 *				  aggregate, the output from the previous call to this
	 *				  method. {@code n} is 0 if we're converting the
	 *				  first distinct aggregate in a query with no non-distinct
	 *				  aggregates)
	 * @param argList   Arguments to the distinct aggregate function
	 * @param filterArg Argument that filters input to aggregate function, or -1
	 * @param refs	  Array of expressions which will be the projected by the
	 *				  result of this rule. Those relating to this arg list will
	 *				  be modified  @return Relational expression
	 */
	private void doRewrite(RelBuilder relBuilder, Aggregate aggregate, int n,
						List<Integer> argList, int filterArg, List<RexInputRef> refs) {
		final RexBuilder rexBuilder = aggregate.getCluster().getRexBuilder();
		final List<RelDataTypeField> leftFields;
		if (n == 0) {
			leftFields = null;
		} else {
			leftFields = relBuilder.peek().getRowType().getFieldList();
		}

		// LogicalAggregate(
		//	 child,
		//	 {COUNT(DISTINCT 1), SUM(DISTINCT 1), SUM(2)})
		//
		// becomes
		//
		// LogicalAggregate(
		//	 LogicalJoin(
		//		 child,
		//		 LogicalAggregate(child, < all columns > {}),
		//		 INNER,
		//		 <f2 = f5>))
		//
		// E.g.
		//   SELECT deptno, SUM(DISTINCT sal), COUNT(DISTINCT gender), MAX(age)
		//   FROM Emps
		//   GROUP BY deptno
		//
		// becomes
		//
		//   SELECT e.deptno, adsal.sum_sal, adgender.count_gender, e.max_age
		//   FROM (
		//	 SELECT deptno, MAX(age) as max_age
		//	 FROM Emps GROUP BY deptno) AS e
		//   JOIN (
		//	 SELECT deptno, COUNT(gender) AS count_gender FROM (
		//	   SELECT DISTINCT deptno, gender FROM Emps) AS dgender
		//	 GROUP BY deptno) AS adgender
		//	 ON e.deptno = adgender.deptno
		//   JOIN (
		//	 SELECT deptno, SUM(sal) AS sum_sal FROM (
		//	   SELECT DISTINCT deptno, sal FROM Emps) AS dsal
		//	 GROUP BY deptno) AS adsal
		//   ON e.deptno = adsal.deptno
		//   GROUP BY e.deptno
		//
		// Note that if a query contains no non-distinct aggregates, then the
		// very first join/group by is omitted.  In the example above, if
		// MAX(age) is removed, then the sub-select of "e" is not needed, and
		// instead the two other group by's are joined to one another.

		// Project the columns of the GROUP BY plus the arguments
		// to the agg function.
		final Map<Integer, Integer> sourceOf = new HashMap<>();
		createSelectDistinct(relBuilder, aggregate, argList, filterArg, sourceOf);

		// Now compute the aggregate functions on top of the distinct dataset.
		// Each distinct agg becomes a non-distinct call to the corresponding
		// field from the right; for example,
		//   "COUNT(DISTINCT e.sal)"
		// becomes
		//   "COUNT(distinct_e.sal)".
		final List<AggregateCall> aggCallList = new ArrayList<>();
		final List<AggregateCall> aggCalls = aggregate.getAggCallList();

		final int groupAndIndicatorCount =
				aggregate.getGroupCount() + aggregate.getIndicatorCount();
		int i = groupAndIndicatorCount - 1;
		for (AggregateCall aggCall : aggCalls) {
			++i;

			// Ignore agg calls which are not distinct or have the wrong set
			// arguments. If we're rewriting aggs whose args are {sal}, we will
			// rewrite COUNT(DISTINCT sal) and SUM(DISTINCT sal) but ignore
			// COUNT(DISTINCT gender) or SUM(sal).
			if (!aggCall.isDistinct()) {
				continue;
			}
			if (!aggCall.getArgList().equals(argList)) {
				continue;
			}

			// Re-map arguments.
			final int argCount = aggCall.getArgList().size();
			final List<Integer> newArgs = new ArrayList<>(argCount);
			for (int j = 0; j < argCount; j++) {
				final Integer arg = aggCall.getArgList().get(j);
				newArgs.add(sourceOf.get(arg));
			}
			final int newFilterArg =
					aggCall.filterArg >= 0 ? sourceOf.get(aggCall.filterArg) : -1;
			final AggregateCall newAggCall =
					AggregateCall.create(aggCall.getAggregation(), false, newArgs,
							newFilterArg, aggCall.getType(), aggCall.getName());
			assert refs.get(i) == null;
			if (n == 0) {
				refs.set(i,
						new RexInputRef(groupAndIndicatorCount + aggCallList.size(),
								newAggCall.getType()));
			} else {
				refs.set(i,
						new RexInputRef(leftFields.size() + groupAndIndicatorCount
								+ aggCallList.size(), newAggCall.getType()));
			}
			aggCallList.add(newAggCall);
		}

		final Map<Integer, Integer> map = new HashMap<>();
		for (Integer key : aggregate.getGroupSet()) {
			map.put(key, map.size());
		}
		final ImmutableBitSet newGroupSet = aggregate.getGroupSet().permute(map);
		assert newGroupSet
				.equals(ImmutableBitSet.range(aggregate.getGroupSet().cardinality()));
		ImmutableList<ImmutableBitSet> newGroupingSets = null;
		if (aggregate.indicator) {
			newGroupingSets =
					ImmutableBitSet.ORDERING.immutableSortedCopy(
							ImmutableBitSet.permute(aggregate.getGroupSets(), map));
		}

		relBuilder.push(
				aggregate.copy(aggregate.getTraitSet(), relBuilder.build(),
						aggregate.indicator, newGroupSet, newGroupingSets, aggCallList));

		// If there's no left child yet, no need to create the join
		if (n == 0) {
			return;
		}

		// Create the join condition. It is of the form
		//  'left.f0 = right.f0 and left.f1 = right.f1 and ...'
		// where {f0, f1, ...} are the GROUP BY fields.
		final List<RelDataTypeField> distinctFields =
				relBuilder.peek().getRowType().getFieldList();
		final List<RexNode> conditions = Lists.newArrayList();
		for (i = 0; i < groupAndIndicatorCount; ++i) {
			// null values form its own group
			// use "is not distinct from" so that the join condition
			// allows null values to match.
			conditions.add(
					rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_DISTINCT_FROM,
							RexInputRef.of(i, leftFields),
							new RexInputRef(leftFields.size() + i,
									distinctFields.get(i).getType())));
		}

		// Join in the new 'select distinct' relation.
		relBuilder.join(JoinRelType.INNER, conditions);
	}

	private static void rewriteAggCalls(
			List<AggregateCall> newAggCalls,
			List<Integer> argList,
			Map<Integer, Integer> sourceOf) {
		// Rewrite the agg calls. Each distinct agg becomes a non-distinct call
		// to the corresponding field from the right; for example,
		// "COUNT(DISTINCT e.sal)" becomes   "COUNT(distinct_e.sal)".
		for (int i = 0; i < newAggCalls.size(); i++) {
			final AggregateCall aggCall = newAggCalls.get(i);

			// Ignore agg calls which are not distinct or have the wrong set
			// arguments. If we're rewriting aggregates whose args are {sal}, we will
			// rewrite COUNT(DISTINCT sal) and SUM(DISTINCT sal) but ignore
			// COUNT(DISTINCT gender) or SUM(sal).
			if (!aggCall.isDistinct()) {
				continue;
			}
			if (!aggCall.getArgList().equals(argList)) {
				continue;
			}

			// Re-map arguments.
			final int argCount = aggCall.getArgList().size();
			final List<Integer> newArgs = new ArrayList<>(argCount);
			for (int j = 0; j < argCount; j++) {
				final Integer arg = aggCall.getArgList().get(j);
				newArgs.add(sourceOf.get(arg));
			}
			final AggregateCall newAggCall =
					AggregateCall.create(aggCall.getAggregation(), false, newArgs, -1,
							aggCall.getType(), aggCall.getName());
			newAggCalls.set(i, newAggCall);
		}
	}

	/**
	 * Given an {@link org.apache.calcite.rel.logical.LogicalAggregate}
	 * and the ordinals of the arguments to a
	 * particular call to an aggregate function, creates a 'select distinct'
	 * relational expression which projects the group columns and those
	 * arguments but nothing else.
	 *
	 *
For example, given
	 *
	 *

	 *
select f0, count(distinct f1), count(distinct f2)
	 * from t group by f0

	 *

	 *
	 * and the argument list
	 *
	 *
{2}

	 *
	 * returns
	 *
	 *

	 *
select distinct f0, f2 from t

	 *

	 *
	 * '
	 *
	 *
The sourceOf map is populated with the source of each
	 * column; in this case sourceOf.get(0) = 0, and sourceOf.get(1) = 2.

	 *
	 * @param relBuilder Relational expression builder
	 * @param aggregate Aggregate relational expression
	 * @param argList   Ordinals of columns to make distinct
	 * @param filterArg Ordinal of column to filter on, or -1
	 * @param sourceOf  Out parameter, is populated with a map of where each
	 *				  output field came from
	 * @return Aggregate relational expression which projects the required
	 * columns
	 */
	private RelBuilder createSelectDistinct(RelBuilder relBuilder,
											Aggregate aggregate, List<Integer> argList, int filterArg,
											Map<Integer, Integer> sourceOf) {
		relBuilder.push(aggregate.getInput());
		final List<Pair<RexNode, String>> projects = new ArrayList<>();
		final List<RelDataTypeField> childFields =
				relBuilder.peek().getRowType().getFieldList();
		for (int i : aggregate.getGroupSet()) {
			sourceOf.put(i, projects.size());
			projects.add(RexInputRef.of2(i, childFields));
		}
		for (Integer arg : argList) {
			if (filterArg >= 0) {
				// Implement
				//   agg(DISTINCT arg) FILTER $f
				// by generating
				//   SELECT DISTINCT ... CASE WHEN $f THEN arg ELSE NULL END AS arg
				// and then applying
				//   agg(arg)
				// as usual.
				//
				// It works except for (rare) agg functions that need to see null
				// values.
				final RexBuilder rexBuilder = aggregate.getCluster().getRexBuilder();
				final RexInputRef filterRef = RexInputRef.of(filterArg, childFields);
				final Pair<RexNode, String> argRef = RexInputRef.of2(arg, childFields);
				RexNode condition =
						rexBuilder.makeCall(SqlStdOperatorTable.CASE, filterRef,
								argRef.left,
								rexBuilder.ensureType(argRef.left.getType(),
										rexBuilder.constantNull(), true));
				sourceOf.put(arg, projects.size());
				projects.add(Pair.of(condition, "i$" + argRef.right));
				continue;
			}
			if (sourceOf.get(arg) != null) {
				continue;
			}
			sourceOf.put(arg, projects.size());
			projects.add(RexInputRef.of2(arg, childFields));
		}
		relBuilder.project(Pair.left(projects), Pair.right(projects));

		// Get the distinct values of the GROUP BY fields and the arguments
		// to the agg functions.
		relBuilder.push(
				aggregate.copy(aggregate.getTraitSet(), relBuilder.build(), false,
						ImmutableBitSet.range(projects.size()),
						null, ImmutableList.<AggregateCall>of()));
		return relBuilder;
	}
}

// End AggregateExpandDistinctAggregatesRule.java


You might have heard of Dholavira in Gujarat. It is a site that belongs to Indus Valley Civilization (which also includes the very famous Harappa & Mohenjadaro). What is to be understood is that the split of countries and states happened very recently. In Indus Valley Civilization era, India or Pakistan or Afghanistan and Rajasthan or Gujarat or Punjab were not there! It was all the same region! A portion of civilization also scatters over today's Rajasthan as well!
One such site is Kalibangan. Today the site is in ruins just like Lothal or Dholavira. With citadels made of bricks, the town plan is similar to that of other Indus Valley sites. Quite amusingly, this site pre-dates Harappa. Kalibangan belongs to 3500-2500 BCE. Another amusing factor is that, this very site, shows signs of the first ever cultivation (ploughed land) anywhere in the world! Excavations here has also brought out pottery & jewelry similar to other sites. Today the ruins and a museum that houses the excavated items are here to see.
As a contemporary to Indus Valley Civilization, here in Rajasthan was the Ahar - Banas Culture, happening around the same time. As the name suggests, it's the civilization that happened in the banks of river Banas & Ahar. These rivers flow in the south of Rajasthan while portions of Indus flow in the north where Kalibangan is situated. Being a smaller river, this civilization isn't as huge as Indus Valley! One of the sites where Ahar culture flourished was Ojiyana in Bilwara. Quite unusually this site is located in the hill top unlike other civilization sites that are located in the valleys.
Excavation in Ojiyana reveal the town planning and growth that has happened in phases. The earlier houses were made of mud bricks (see similar in Lothal). However being on a sloppy terrain it proved futile and the later phase show houses built of rocks! Pottery found here are the typical black & red of the Bronze Age. Apart from pottery there were also toys, figurines (esp. bulls), beads, jewelry made of copper and shells!
Pretty close to Ojiyana is another site, Lachhura. This site belongs to a later period (700 BCE - 200 CE) that includes Sunga and Kushana era. The findings through the excavations here include terracotta human and animal figurines, copper bangles, beads made of terracotta, carnelian and quartz and ofcourse pottery. This site is located in the banks of River Mansi which is a tributary to River Banas.
The findings of all these sites are in various museums including British Museum. Locally Amer Archaeological Museum in Jaipur has a good collection of various objects found in excavations all over the state.
Hotels in Jaipur are available at all price points.
Most of these sites can be done as day trips with Jaipur as base.
Cars can be hired with a driver for the trips which are usually charged on a daily basis.
Wao! I never knew about this pre-historic sites of Rajasthan. This is very intriguing and interesting to learn! The pre-historic tales of Rajasthan shines a different light on it all together.
What a very good post. Thank you so much for this post.
Interesting! I'm honestly not very well informed about travelling in India in general, so this was super helpful!
Thank you for sharing this lovely piece about the history of Rajasthan. I visited several places in the region and I just can't get enough of the rich history and fascinating architecture.
These sites does not offer much to see despite having rich history. From ASI's side also, there are not much activity and facilities. Still these are good sites for lovers of history.
The history of Indus valley civilisation always intrigued me so it was quite an interesting read for me. This is a different face to the history of Rajasthan.


Star Wars Battlefront: Outer Rim DLC comes with two new playable characters — GamingWithSwag.com - Dads By Day, Gamers By Night.
The highly anticipated first round of DLC for Star Wars: Battlefront has been announced for some time now. We know that two new levels are available, Tatooine at Jabba's Palace and the lava world of Sullust. It has been announced that it will also come with a new game play mode "Extraction" which requires Rebel players to bring shipments of materials back to the transport ship before time runs out or the Empire overruns their forces. Also, two more weapons are available, the Relby V-10 rifle and the DT-12 blaster. You can also find and increase your power with the Scatter Gun, Dioxis Grenade, and the Adrenaline Stim Star Cards. But most importantly, two new playable characters have been introduced! Greedo (He always shoots first.) and Nien Numb. I am VERY excited to hear this, and I hope they increase the number of hero tokens on the board. Having two at once on each side would make for some epic battles! The Outer Rim DLC is scheduled to release later this month on Xbox One, PlayStation 4, and PC.
Play as Greedo and Nien Numb in Outer Rim.
Jabba won't know what hit him!


text:
Doing Psychoanalysis in Tehran (Kobo eBook)
By Gohar Homayounpour, Abbas Kiarostami
A Western-trained psychoanalyst returns to her homeland and tells stories of displacement, nostalgia, love, and pain.
Is psychoanalysis possible in the Islamic Republic of Iran? This is the question that Gohar Homayounpour poses to herself, and to us, at the beginning of this memoir of displacement, nostalgia, love, and pain. Twenty years after leaving her country, Homayounpour, an Iranian, Western-trained psychoanalyst, returns to Tehran to establish a psychoanalytic practice. When an American colleague exclaims, "I do not think that Iranians can free-associate!" Homayounpour responds that in her opinion Iranians do nothing but. Iranian culture, she says, revolves around stories. Why wouldn't Freud's methods work, given Iranians' need to talk?
Thus begins a fascinating narrative of interlocking stories that resembles—more than a little—a psychoanalytic session. Homayounpour recounts the pleasure and pain of returning to her motherland, her passion for the work of Milan Kundera, her complex relationship with Kundera's Iranian translator (her father), and her own and other Iranians' anxieties of influence and disobedience. Woven throughout the narrative are glimpses of her sometimes frustrating, always candid, sessions with patients. Ms. N, a famous artist, dreams of abandonment and sits in the analyst's chair rather than on the analysand's couch; a young chador-clad woman expresses shame because she has lost her virginity; an eloquently suicidal young man cannot kill himself.
As a psychoanalyst, Homayounpour knows that behind every story told is another story that remains untold. Doing Psychoanalysis in Tehran connects the stories, spoken and unspoken, that ordinary Iranians tell about their lives before their hour is up.
Publisher: The MIT Press
Publication Date: September 14th, 2012

redpajama_set_name: RedPajamaCommonCrawl


text:
Turn-Key Framing
Atlantic Building Components
Atlantic Construction Services
© 2017 by ATLANTIC. Proudly created with Wix.com
In February 1984, Jennings R. "Bert" Hood and several family members founded Team Mates Trusses in Moncks Corner, SC. The start-up company began with 6 employees. With hard work, ingenuity, and skill, the young firm grew and by 1987 reached $1.5 million in sales. In early 1989 many of the family members decided to leave the industry and sell their portion of the business to pursue other interests.
During this same period, James H. Broach, Sr. had been managing a small rival truss plant at Monarch Lumber, a local lumber yard in Charleston, SC. After Monarch Lumber was purchased by a large regional lumber supplier in 1989 the new company decided to close the truss plant portion.
With both young leaders at turning points in their careers and both with families of their own to provide for, one phone call would set up a partnership that would change the course of both of their lives beyond even their wildest imaginations. On November 1, 1989 the two men became 50/50 partners and changed the name to Team Mates of Charleston, Inc. With fresh leadership and new purpose, the company entered a period of sustained growth. Looking for expansion opportunities, in 1991 they acquired Truss Systems Inc. in Easley, SC and later merged them into one company Truss Systems of SC.
The year 2000 brought a changing time in the truss industry and in the local market place with an increased amount of mergers and acquisitions of truss manufacturing companies. Truss Systems had successfully grown as well and was looking to step out of the shadows of being a "Mom and Pop" truss company. With a large multi-million dollar addition underway and the decision to expand into turn-key framing the team began an aggressive rebranding campaign and changed the name to Atlantic Building Components. James Broach, Jr., PE arrived in June of 2001 as vice president of operations and aggressively grew the company to the next level with sales exceeding $20 million for the first time. The great recession of 2007 proved to be very difficult times, but with great leadership Atlantic came out un-phased and stronger than ever.
Our vision since day one has always been focused on continuing to grow the company for future generations. In 2016 this continued with the acquisition of TruLine Truss in Sparta, NC. Having been in business for over 20 years, TruLine was well established with an unbelievable manufacturing facility and great staff. Adding this location gave us immediate growth into the Charlotte, NC, Raleigh, NC, and rapidly growing Roanoke, VA markets.
With 3 locations, 200 employees, and sales on track to reach $40 million, the future is bright and we remain never satisfied.


Today I am over at Woman to Woman Ministries talking about a great new investment. Click HERE.
1940. Our church marriage retreat. We had a great time as we connected with our spouse and other Christian couples.
1941. The beautiful encouragement from our speakers and dear friends.
1942. A nap on a Saturday.
1943. Lunch with family and friends.
1944. The look on the kids' faces in children's church when they finally "get it."
A blessed weekend spent with my husband. We needed to just spend nurturing our marriage & one another. God is so good, faithful & loving. He is able to redeem & restore anything if we allow Him to. Thank you God for all that you are doing in us individually & in our marriage!
I love that look on the kids' faces too!


text:
Home > ALL BLU-RAY > DVD>Blu-ray > L'argent The Criterion Collection Blu-ray 07/11/17
L'argent The Criterion Collection Blu-ray 07/11/17
In his ruthlessly clear-eyed final film, French master Robert Bresson pushed his unique blend of spiritual rumination and formal rigor to a new level of astringency. Transposing a Tolstoy novella to contemporary Paris, L argent follows a counterfeit bill as it originates as a prop in a schoolboy prank, then circulates like a virus among the corrupt and the virtuous alike before landing with a young truck driver and leading him to incarceration and violence. With brutal economy, Bresson constructs his unforgiving vision of original sin out of starkly perceived details, rooting his characters in a dehumanizing material world that withholds any hope of transcendence.
Actors: Caroline Lang, Christian Patey, Vincent Risterucci, Sylvie Van den Elsen
Directors: Robert Bresson
Format: Subtitled, Widescreen
Studio: Sony Pictures Home Entertainment
DVD Release Date: July 11, 2017
The Tree of Wooden Clogs - Ermanno Olmi, Luigi Omaghi, Teresa Brescianini, Giuseppe Brignoli (Blu-ray - 2/17/2017) [The Criterion Collection]
12 Angry Men - Ed Begley, Henry Fonda, Jack Warden and Jack Klugman (The Criterion Collection) [Blu-ray] (Blu-ray - Nov 22, 2011)
3:10 to Yuma - Starring Van Heflin and Glenn Ford (Blu-ray - 05/14/2013) [Criterion Collection]
45 Years [2015] - Andrew Haigh, Charlotte Rampling, Tom Courtenay, Dolly Wells (Blu-ray - 3/7/2017) (Criterion Collection)
A Brief History of Time (Criterion Collection) (1991) (Blu-ray/DVD - 3/18/2014)
A Brighter Summer Day [1991] - Chang Kuo-Shu, Elaine Jin, Wang Juan, Edward Yang (Blu-ray - 3/22/2016) [The Criterion Collection]
A Man Escaped - Starring Francois Leterrier (Blu-ray - 03/26/2013) [Criterion Collection]
Fantastic Planet - René Laloux, Mark Gruner, Nora Heflin (Blu-ray - 6/21/2016) [The Criterion Collection]
Fear and Loathing in Las Vegas (Blu-ray - 2011) [The Criterion Collection]
Following - Starring Alex Haw and Lucy Russell (Blu-ray - 12/11/2012) (Criterion Collection)
For All Mankind by Al Reinert Special Ed. Criterion Collection Blu-ray 07/14/09
Fox and His Friends - Rainer Werner Fassbinder, Peter Chatel, Harry Baer, Adrian Hoven (Blu-ray - 1/17/2017) [The Criterion Collection]
Frances Ha - Starring Greta Gerwig, Mickey Sumner and Adam Driver (BLU-RAY/DVD DUAL FORMAT EDITION - Nov 12, 2013) (Criterion Collection)
Gate of Hell - Starring Kazuo Hasegawa, Machiko Kyo and Yataro Kurokawa (1953) (Blu-ray - 04/09/2013) - [Criterion Collection]
A Christmas Tale - The Criterion Collection - Arnaud Desplechin [Blu-ray] (Blu-ray - Dec 1, 2009) [Special Edition]


In many countries including Uganda, supervision visits to health facilities traditionally take on an authoritarian inspection and fault-finding approach instead of problem-solving to improve staff performance. Consequently, health workers often receive little advice or guidance on how to improve their outcomes. In fact, in many settings health workers are unsupervised and have no clear work objectives.
In order to enhance quality of maternal and newborn care, the Maternal and Neonatal Implementation for Equitable Systems (MANIFEST) study team championed a support supervision programme in Kamuli, Kibuku and Pallisa Districts. This MANIFEST Issue Brief outlines the issue, the MANIFEST experience and the results.


text:
Articles tagged with: Minority Rights
08 November 2014 08:09 PM
"Nobody can guarantee we will be able to vote on November 9", states pro-independence civil society organisation
Carme Forcadell, President of the civil society organisation Catalan National Assembly (ANC), stated that if citizens are able to cast their vote on November 9, the participatory process will already be "a success". However, she warned that...
Politics Highlights
Constitutional Court will not meet before November 9 to debate Catalonia's appeal against vote suspension
The Constitutional Court rejects calling an urgent meeting to debate the appeal that the Catalan Government filed on Friday against the suspension of Sunday's participatory process, in which it asked the Court for further clarifications about...
Spanish Government pressures high-school directors, mayors and Catalan Executive over November 9's vote
The Spanish Government's Delegate in Catalonia, María de los Llanos de Luna, sent letters on Thursday to the directors of high-schools throughout Catalonia reminding them that the Constitutional Court had temporarily suspended November...
November 9 is "using freedom of expression" to say "we are looking for a new relationship" with Spain
The President of the civil society association Òmnium Cultural, Muriel Casals, stated that "the mere fact of going with a ballot to the polling station" is "already a success" and will show that "the Catalans' tenacity is stronger that...
Spain's Supreme Court rejects Catalan Government's complaint against Rajoy for violating fundamental rights
The Spanish Supreme Court has decided to reject the Catalan Government's complaint, filed on Tuesday, against the Spanish Government's appeal of the citizen participation process on independence, scheduled for the 9th of November....
Catalan President to offer Spanish PM the opportunity for dialogue after November 9's vote
The President of the Catalan Government, Artur Mas, announced on Wednesday that next Monday he will send a letter to the Spanish Prime Minister, Mariano Rajoy, to assess November 9's participatory process and to offer a negotiation for...
Catalan representatives to send a complaint to international organisations against Spanish Government for blocking self-determination
More than 200 elected members of the European, Spanish and Catalan Parliaments and municipal councils from Catalonia have presented and started to sign on Wednesday an international complaint against the Spanish Government that will be sent...
Catalan Government keeps November 9's participatory process on-going despite Constitutional Court's suspension
On Tuesday, Spain's Constitutional Court accepted to take into consideration the Spanish Government's appeal against Catalonia's participatory process about independence, which has been organised by the Catalan Executive as...
03 October 2014 09:26 PM
Parties supporting November's independence consultation agree to carry on with calling vote
The President of the Catalan Government, Artur Mas, has organised a meeting with the parties supporting the 9th of November's consultation vote on independence in order to agree the next steps to be followed after the...


With Cruz first out of the gate among Republican contenders and a long line of competitors ready to follow, will Liberty be the venue for their announcements as well? Will Rev. Jerry Falwell Jr., who has run the institution in place of his father who died in 2007, offer the mic to Hillary Clinton, Martin O'Malley, or Joe Biden should these Democratic apostates want to make their announcements there? Wouldn't you just love to see Biden's happy face in that setting?
Liberty officials have argued, as the NPQ Newswire reported, that Cruz spoke at a thrice-weekly convocation that is mandatory for all students, no matter who happens to be speaking. In fact, they said that the speaker who originally had been scheduled was Virginia Governor Terry McAuliffe, a Democrat, who withdrew in favor of some other time. However, knowing that Cruz was announcing, Liberty could have chosen a time and place at which students would not have faced fines had they chosen to skip the event and avoid having to wave the little American flags distributed by the Cruz campaign. Liberty knew what Cruz wanted and gave him the venue for maximum political effect.
If past is precedent, Koskinen is unlikely to act, or if he does, it will be when there is a new occupant in the White House after the 2016 elections. Partisan "politicking" on the part of churches and faith-based nonprofits like Liberty has become quite commonplace, to the detriment of the important nonpartisan, nonpolitical identity of the nonprofit sector.
The NPQ Newswire texted that number on March 26th and got this as its automatic response: "Thanks for opting in to get updates. More info visit tedcruz.org." The website, tedcruz.org, is the Cruz for President website.


text:
Jefferson Public Library
World War Z, Paramount Pictures and Skydance Productions present in association with Hemisphere Media Capital and GK Films a Plan B Entertainment/2Dux2 production, a Marc Forster film ; produced by Brad Pitt, Dede Gardner, Jeremy Kleiner, Ian Bryce ; screenplay by Matthew Michael Carnahan and Drew Goddard & Damon Lindelof
The Resource World War Z, Paramount Pictures and Skydance Productions present in association with Hemisphere Media Capital and GK Films a Plan B Entertainment/2Dux2 production, a Marc Forster film ; produced by Brad Pitt, Dede Gardner, Jeremy Kleiner, Ian Bryce ; screenplay by Matthew Michael Carnahan and Drew Goddard & Damon Lindelof
The item World War Z, Paramount Pictures and Skydance Productions present in association with Hemisphere Media Capital and GK Films a Plan B Entertainment/2Dux2 production, a Marc Forster film ; produced by Brad Pitt, Dede Gardner, Jeremy Kleiner, Ian Bryce ; screenplay by Matthew Michael Carnahan and Drew Goddard & Damon Lindelof represents a specific, individual, material embodiment of a distinct intellectual or artistic creation found in Chemeketa Cooperative Regional Library Service (CCRLS).
Capaldi, Peter
Fitoussi, Grégory
Bryce, Ian
Forster, Marc, 1969-
Pitt, Brad, 1963-
trueBrooks, Max
Gardner, Dede
Boeken, Ludi
trueGoddard, Drew, 1975-
Andrews, David, 1952-
Hargrove, Abigail
Skydance Productions
Jerins, Sterling
Kertesz, Daniella, 1989-
Kleiner, Jeremy
Lindelof, Damon, 1973-
Hemisphere Media Capital
Mokoena, Fana, 1971-
GK Films (Los Angeles, Calif.)
2Dux2 (Firm)
Morse, David, 1953-
Dale, James Badge, 1978-
Enos, Mireille, 1975-
Carnahan, Matthew Michael
Gerry Lane travels the globe in an effort to eliminate the zombie pandemic that is endangering the existence of humanity
Hollywood, California, Paramount Pictures, 2013
Based on the novel by Max Brooks
Special features: Behind-the-scenes featurettes
Disc 1. Blu-ray unrated feature film
Behind-the-scenes featurettes: a compelling insider's look at the creation of the WWZ apocalypse
Disc 2. Theatrical feature film
Paramount Pictures and Skydance Productions present in association with Hemisphere Media Capital and GK Films a Plan B Entertainment/2Dux2 production, a Marc Forster film ; produced by Brad Pitt, Dede Gardner, Jeremy Kleiner, Ian Bryce ; screenplay by Matthew Michael Carnahan and Drew Goddard & Damon Lindelof
Muertos -- Teatro
Virosis -- Teatro
Zombies -- Drama
trueDVDs
Zombie films
Virus diseases -- Drama
Director of photography, Ben Seresin ; editor, Roger Barton, Matt Chesse ; music, Marco Beltrami
Rating: Unrated; contains material different from the original PG-13 version shown in theaters ; theatrial version rated PG-13 for intense frightening zombie sequences, violence and disturbing images
English, French, Spanish or Portuguese dialogue; Spanish, Portuguese, French or English subtitles; subtitled for the deaf and hard of hearing
Brad Pitt, Mireille Enos, Daniella Kertesz, James Badge Dale, David Morse, Fana Mokoena, David Andrews, Sterling Jerins, Abigail Hargrove, Peter Capaldi, Pierfrancesco Favino, Ludi Boeken, Gregory Fitoussi
Forster, Marc
Goddard, Drew
Lindelof, Damon
Pitt, Brad
Enos, Mireille
Kertesz, Daniella
Dale, James Badge
Morse, David
Mokoena, Fana
Brooks, Max
Virosis
Disc 1. Blu-ray unrated feature film -- Behind-the-scenes featurettes: a compelling insider's look at the creation of the WWZ apocalypse -- Disc 2. Theatrical feature film
Blu-ray, widescreen presentation; 7.1 DTS-HD Master Audio (English), 5.1 Dolby digital (French, Spanish, Portuguese), described video; 1080p high definition; requires Blu-ray player
Blu-ray disc for use only with Blu-ray disc players, Blu-ray disc computer drives and Playstation 3 game consoles
DVD, region 1, widescreen presentation; Dolby Digital 5.1; NTSC
Jefferson Public LibraryBorrow it
128 North Main Street, Jefferson, OR, 97352, US

 Data from World War Z, Paramount Pictures and Skydance Productions present in association with Hemisphere Media Capital and GK Films a Plan B Entertainment/2Dux2 production, a Marc Forster film ; produced by Brad Pitt, Dede Gardner, Jeremy Kleiner, Ian Bryce ; screenplay by Matthew Michael Carnahan and Drew Goddard & Damon Lindelof - Chemeketa Cooperative Regional Library Service (CCRLS)

Data Citation of the Item World War Z, Paramount Pictures and Skydance Productions present in association with Hemisphere Media Capital and GK Films a Plan B Entertainment/2Dux2 production, a Marc Forster film ; produced by Brad Pitt, Dede Gardner, Jeremy Kleiner, Ian Bryce ; screenplay by Matthew Michael Carnahan and Drew Goddard & Damon Lindelof


text:
Milauna Jackson and BAM «Strike Back»!
julio 29, 2014 brian
The British action series «Strike Back» came to BAM Studios to record ADR with actress Milauna Jackson! Back in 2012, BAM worked with the creative team from «Strike Back» on a recording session with actor Eamonn Walker. It was great to work with them again! This time around, actress Milauna Jackson came to the studio to record additional dialogue for her character of Kim Martinez, in a session engineered by Philip von During. Now entering its fifth season, «Strike Back» is a military action series that follows the lives of the members of Section 20, a secret unit within British Defence Intelligence. The series is based on a semi-autobiographical novel of the same name written by former Special Air Service soldier Chris Ryan. In addition to her work with «Strike Back,» Ms. Jackson is known for her roles in projects such as «NCIS,» «Rizzoli and Isles,» «Squad 85,» «FlashForward,» «Da Brick,» and «Dexter». Other stars of the series include Philip Winchester, Sullivan Stapleton, Michelle Lukes, and Rashan Stone. «Strike Back» is currently airing on Cinemax, on Wednesdays at10/9c.
To read more about «Strike Back», click here: http://www.cinemax.com/strike-back/
To read more about Milauna Jackson, click here: http://www.imdb.com/name/nm1040389/?ref_=ttfc_fc_cl_t9
Etiquetas:ADR Recording, ADR Stage, Celebrity, Cinemax, Milauna Jackson, Philip von During, Strike Back, Television Program, TV Show, VO Recording
BAM Summer Party 2014 Photos Are Here!
In EVENTOS on julio 29, 2014
BAM "Wanders Over Yonder" with Jack McBrayer!
In NOTICIAS on julio 29, 2014
BAM Studios Is Open
A Message from the BAM Team about Delivering Serious Sound
20 Year BAM-iversary!


text:
Hatewatch is a blog that monitors and exposes the activities of the American radical right.
Miller Dismisses DACA in Emails, Mirroring Anti-Immigrant Extremists' Views
Michael Edison Hayden
White House senior policy adviser Stephen Miller went against many Republicans when siding with white nationalists and other extremists on the issue of Deferred Action for Childhood Arrivals, more commonly known as DACA, emails show.
All Ideologies Alt-Right (1) Anti-Immigrant (3) Anti-LGBT (1) Anti-Muslim (2) Antigovernment Movement (37) Black Nationalist (2) Christian Identity (3) General Hate (84) Ku Klux Klan (1) Sovereign Citizens Movement (67) White Nationalist (2)
All Groups Fundamentalist Church of Jesus Christ of Latter-Day Saints (1) Moorish Sovereign Citizens (3)
Winston Shrout, One of America's Most High-Profile 'Sovereign Citizens,' is a Fugitive
Brett Barrouquere
Winston Shrout spent years defying the federal government as one of the country's most high-profile sovereign citizens and tax dodgers.
QAnon Conspiracy Increasingly Popular with Antigovernment Extremists
Brendan Joel Kelley and Hatewatch Staff
Antigovernment extremists, including some who've committed violent acts, are increasingly subscribing to and propagating the QAnon conspiracy theory, which asserts that pro-Trump forces will soon take down the so-called deep state.
Sovereign Citizen Calls for Action on Bogus 'Indictment'
Brendan Joel Kelley
It was to have been a historic roundup of enemies of the extreme right, ending with Hillary Clinton, former FBI director James Comey, former Attorney General Loretta Lynch, former Senator Harry Reid and a slew of other politicians, jurists and law enforcement officers in the custody of those who would have them tried by "common law grand juries" for their perceived crimes.
Sovereign Citizen Threatens Police With 'Pig-Shaped' Bomb
A sovereign citizen, 42-year-old Dennis Duane Vann, threatened the lives of police officers in Maplewood, Minnesota, on Feb. 20 with a pig-shaped explosive device painted with the words "Fuck the Police," according to police and local news reports.
Patriot Movement AZ founder: Yes, I'm 'pretty hateful'
Lesa Antone, the founder of the anti-immigrant and anti-Muslim group Patriot Movement AZ (PMAZ), said this weekend on an internet radio show that she's "feeling pretty hateful right now."
Hatewatch Headlines 12/21/2018
Trump fires service members with HIV; How a revenge plot unraveled the Proud Boys; Tucker Carlson boycott having a visible effect; and more.
The Sovereign Files: 12/20/2018
In this month's Sovereign Files, the alleged Holy Fire starter pleads not guilty, it takes three officers to pull a man from his car when he refuses to move, and an accused killer says laws do not apply to him.
Facebook's moment of reckoning arrives; Advertisers abandon Tucker Carlson; ADF seeks expansion of Jim Crow-era exemption; and more.
Terror plots targeted bar, synagogue; McInnes banned from YouTube now; Miami Proud Boys hoping to take hate mainstream; and more.
Neo-Nazis create a national training network; Proud Boys cash out with Amazon; Judge blocks Trump's ban on asylum seekers at border; and more.
Are you a member of the media looking to speak with one of our experts?
Subscriptions to the Intel Report are free to law enforcement, journalists, and others.
Our investigative reporting depends on reliable sources and tips.


What is the shortest period of time that an independent country has existed?
The probable answer is a day and the country was Carpatho-Ukraine.
Following the start of the Nazi dismemberment of Czechoslavakia, on 15th March 1939 the Carpatho-Ruthenia region of Czechoslovakia declared independence. Its head of state was the Reverend Avgustyn Voloshyn and its capital was Khust. A day later Hungarian troops marched in and seized the territory, which is now part of Western Ukraine.
That is interesting! Points for that one Zebra!


The night sky is the venue for an ancient arms race. Insectivorous bats with their ultrasonic sonar exert an enormous selective pressure on nocturnal insects. In response insects have evolved the ability to hear bat cries, to evade their hunting maneuvers, and some, the tiger moths (Arctiidae), to utter an ultrasonic reply. We here determine what it is that tiger moths "say" to bats. We chose four species of arctiid moths, Cycnia tenera, Euchaetes egle, Utetheisa ornatrix, and Apantesis nais, that naturally differ in their levels of unpalatability and their ability to produce sound. Moths were tethered and offered to free-flying naïve big brown bats, Eptesicus fuscus. The ability of the bats to capture each species was compared to their ability to capture noctuid, geometrid, and wax moth controls over a learning period of 7 days. We repeated the experiment using the single arctiid species E. egle that through diet manipulation and simple surgery could be rendered palatable or unpalatable and sound producing or mute. We again compared the capture rates of these categories of E. egle to control moths. Using both novel learning approaches we have found that the bats only respond to the sounds of arctiids when they are paired with defensive chemistry. The sounds are in essence a warning to the bats that the moth is unpalatable—an aposematic signal.
N.I.H. collected the data, whereas W.E.C. helped design the experiments and supervised the project. We thank Mitch Masters and Amanda Lollar for helpful advice on how to maintain a healthy bat colony. We are grateful to Wake Forest undergraduates Sarah Ross, Payton Deal, Megan Clendenin, and Jason Davenport for assistance with the learning experiments. Anna Price, Rebecca Cooke, and Hugh Labusohr reared many of the insects. Jesse Barber, Susan Fahrbach, and two anonymous reviewers greatly improved a previous version of this manuscript and Jesse assisted with the bat experiments. Mindy Conner provided editorial assistance and suggested the title for this article. The research was supported in part by the Science Research Fund at Wake Forest University, the Eppley Foundation of New York, and the National Science Foundation (IBN-0135825). All experiments were carried out in compliance with current laws in the United States.


text:
Coca-Cola: The Power of a Brand
Patrick Altoft
There are few images as recognizable throughout the world as the Coca-Cola brand. Travel to the furthest reaches of the globe and you will probably encounter it on a clock or a sign, if not on the drink itself. Marketers today look to the Coca-Cola brand as a model of marketing power. Its image has transcended national borders and cultural barriers to reach almost everyone on earth. How did the Coca-Cola symbol become such an omnipresent image?
Beginning in 1886, Coca-Cola president John Pemberton began traveling the country introducing pharmacists to the drink. At that time it was considered a medicinal substance that could relieve headaches and other minor woes. Candler distributed clocks, calendars and other items laden with the Coca-Cola logo as he toured the country, spreading the brand and selling his product.
From there the brand continued to penetrate further around the world. The bottling rights to Coca-Cola were sold in 1899 and in 1915 the Root family submitted a standard size bottle for distribution, but it was too fat in the middle. The Coca-Cola Company liked the bottle so much they thinned it down and has been used ever since and is called a Hobbleskirt Bottle. By 1920, with new bottlers springing up all the time, the brand had expanded into Cuba, France, Puerto Rico and other territories. Its world dominance would increase further with World War II, when Coca-Cola promised that "every man in uniform gets a bottle of Coca-Cola for 5 cents, wherever he is, and whatever it costs the company." Suddenly Coca-Cola could be found throughout Europe as American GIs carried it with them, and by 1960 the number of countries with Coke bottling plants had doubled.
Today Coke remains a powerful brand with over a century of history behind it. As a result, items featuring previous incarnations of the Coke image have become classic pieces of Americana. The success of the Coca-Cola brand has made it an icon not just in the world of brand marketing but of American history. It symbolizes the popularity of a soft drink as well as the dominance of American entrepreneurialism in the twentieth century and beyond.
Bob Zurn and his wife Joyce own and operate Cola Corner, the leading online provider of Coca-Cola collectibles. Cola Corner provides a wide selection of Coca-Cola posters, novelties, clothing, and furniture. Visit them online today at http://www.colacorner.com/novelties.html to view their classic collection.
marketing power world war ii man in uniform brand marketing number of countries national borders classic pieces incarnations coca cola company coca cola brand john pemberton coca cola logo coke bottling world dominance bottling plants medicinal substance root family american gis bottlers president john
Related Articles about marketing power,world war ii,man in uniform,brand marketing,number of countries,national borders,classic pieces,incarnations,coca cola company,coca cola brand,john pemberton,coca cola logo,coke bottling,world dominance,bottling plants,medicinal substance,root family,american gis,bottlers,president john
The Reality of Arranged Marriages
0 0 0 11 min read
Types of Sport
More Articles From Patrick Altoft
The Perfect Sandwich Label
History of the scarf


Brazilian brand Cravvo has released a new t-shirt for their first season, limited to 50 pieces.
The shirt has been made for the fans who live and breathe football with the number 10 on the shirt paying homage to the game's best ever players.
Cravvo is a brand based in São Paulo and is inspired by the combination of street football and the world's biggest leagues. The products they will release, including this one, are inspired by worldwide clubs, players' lifestyles and football fanatics.
The brand takes football beyond just the white lines on the field. Check them out here.


text:
The Aurora Warnings
James Holmes' psychiatrist told campus police he was homicidal. Why wasn't the warning passed on?
By William Saletan
James Holmes appears in district court in Centennial, Colo. for his arraignment on March 12, 2013
Photo by RJ Sangosti/Denver Post/AP/Pool
What did police at the University of Colorado know about the homicidal intent of James Holmes, the Aurora, Colo., theater shooter? When did they know it? Did they share this information with police outside the university? If not, why not?
These are some of the questions provoked by court documents unsealed yesterday, a week after similar documents were released in the Tucson and Sandy Hook massacres. The Colorado records, related to early information and warrants, include some eyebrow-raising details. Images on Holmes' phone show how carefully he scouted the theater weeks in advance, taking pictures of the door jamb. In addition to the propane tanks and other explosive items in his apartment, investigators found 50 containers of an unspecified liquid. Denver news station CALL7 notes that testimony at a January hearing "revealed many of the canisters contained layered combinations of improvised napalm, thermite and/or black powder." But the number of containers, previously unreported, suggests he may have purchased ingredients in quantities that should have triggered alarms.
The clearest warning, however, came from Dr. Lynne Fenton, a psychiatrist at the university. At a hearing last August, Fenton confirmed that she had met with Holmes before the shooting. She testified that on June 11, a month before the tragedy, she contacted a university police officer, Lynn Whitten, about a patient. Fenton, asserting confidentiality, didn't name the patient in court. She testified that "I communicated with Officer Whitten to gather more information about this case and to communicate my concerns." According to a Denver Post account of the hearing, when Fenton "was asked in court whether she had ever contacted authorities for reasons required by the state law that mandates psychiatrists report specific threats of violence made by their patients, Fenton said she had not."
The Post also reports that officials at the university "have denied that Holmes was banned from campus for making threats, saying instead that his key card was deactivated as part of a normal process when a student withdraws from school."
But the newly released documents tell a different story. A July 23 police affidavit says that shortly after the shooting, Whitten told an Aurora police officer that Fenton had been much more explicit in their June conversations. According to the affidavit,
"Dr. Fenton advised that through her contact with James Holmes she was reporting, per her requirement, his danger to the public due to homicidal statements he had made. Additionally, Dr. Fenton was advising that she had been treating Holmes, and that Holmes had stopped seeing her and had begun threatening her via text messages."
A July 24 affidavit says that on July 21, Whitten told investigators
"that Lynne Fenton had contacted Officer Whitten [regarding] James E. Holmes on June 12, 2012. Lynne Fenton described James E. Holmes as having Homicidal thoughts and also stated that James E. Holmes had threatened and harassed her via e-mail/text messages. Officer Whitten Advised Sergeant Wesner that she had deactivated James E. Holmes' I.D. on June 12, 2012 due to that complaint."
Threats. Harassment. Homicidal statements. Danger to the public. These were explicit warnings, conveyed to a police officer. Based on these warnings, the university police cut off Holmes' access to campus facilities.
What did the university do to protect the broader public? We don't know. The Post reports that "the documents don't reveal what—if anything—campus authorities did to investigate Holmes" after barring him from their own facilities. CALL7 stands by its report that "neither Fenton nor the CU threat assessment team took action because Holmes had made it known he was going to leave the university." CALL7 has also reported that according to its sources, university officials "never contacted Aurora police with Fenton's concerns."
As further evidence is unsealed in this case, we may learn more about what Fenton knew and disclosed. CALL7 says that according to testimony at the August hearing, "She wrote a four-page summary of her meeting with Holmes on June 11, but left blank a section designated for the treatment plan." The search warrant records also show that at Holmes' apartment, police found clonazepam, a psychiatric drug, as well as sedatives and sertraline (generic Zoloft).
What we know so far is that the public statements attributed to Fenton and university officials don't match what's in the police affidavits. And if the affidavits are correct, information about Holmes' homicidal statements and danger to the public were deemed sufficient to trigger a warning to the university police, but not to the police who protect the rest of us. Why not?


Don�t leave something as important as your water supply, your comfort and your safety to just anyone. Let the professionals at Wragg Brothers help you with any of your well or pump needs.
When you need a water system, geothermal well, cameral inspection, pump installation, pump service or hydrofracking, know that you can depend on us to get the job right the first time.


text:
<?php
/**
 * Loads the WordPress environment and template.
 *
 * @package WordPress
 */

if ( ! isset( $wp_did_header ) ) {

	$wp_did_header = true;

	// Load the WordPress library.
	require_once __DIR__ . '/wp-load.php';

	// Set up the WordPress query.
	wp();

	// Load the theme template.
	require_once ABSPATH . WPINC . '/template-loader.php';

}

redpajama_set_name: RedPajamaGithub


text:
Tag: Lusail Stadium
Wednesday, March 11th 2015 - 02:08 UTC
British architects will design Lusail stadium, master piece of the Qatar 2022 World Cup
British architects Foster & Partners has been appointed to design Qatar's Lusail Stadium, venue for the Qatar 2022 World Cup opening match and final. The London-based firm won the international tender competition for the project, Qatar's Supreme Committee for Delivery & Legacy announced on Monday.