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

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import io.airlift.slice.Slice;
import io.trino.metadata.AggregationFunctionMetadata;
import io.trino.metadata.BoundSignature;
import io.trino.metadata.FunctionBinding;
import io.trino.metadata.FunctionDependencies;
import io.trino.metadata.FunctionMetadata;
import io.trino.metadata.LongVariableConstraint;
import io.trino.metadata.MetadataManager;
import io.trino.metadata.ResolvedFunction;
import io.trino.metadata.Signature;
import io.trino.metadata.SqlAggregationFunction;
import io.trino.operator.aggregation.AggregationImplementation;
import io.trino.operator.aggregation.ParametricAggregation;
import io.trino.operator.aggregation.state.LongState;
import io.trino.operator.aggregation.state.NullableDoubleState;
import io.trino.operator.aggregation.state.NullableLongState;
import io.trino.operator.aggregation.state.TriStateBooleanState;
import io.trino.operator.aggregation.state.VarianceState;
import io.trino.operator.annotations.LiteralImplementationDependency;
import io.trino.operator.annotations.OperatorImplementationDependency;
import io.trino.operator.annotations.TypeImplementationDependency;
import io.trino.spi.block.Block;
import io.trino.spi.block.BlockBuilder;
import io.trino.spi.function.AggregationFunction;
import io.trino.spi.function.AggregationState;
import io.trino.spi.function.BlockIndex;
import io.trino.spi.function.BlockPosition;
import io.trino.spi.function.CombineFunction;
import io.trino.spi.function.Convention;
import io.trino.spi.function.Description;
import io.trino.spi.function.InputFunction;
import io.trino.spi.function.LiteralParameter;
import io.trino.spi.function.LiteralParameters;
import io.trino.spi.function.OperatorDependency;
import io.trino.spi.function.OutputFunction;
import io.trino.spi.function.SqlType;
import io.trino.spi.function.TypeParameter;
import io.trino.spi.function.TypeParameterSpecialization;
import io.trino.spi.type.ArrayType;
import io.trino.spi.type.DoubleType;
import io.trino.spi.type.StandardTypes;
import io.trino.spi.type.Type;
import io.trino.spi.type.TypeSignature;
import io.trino.spi.type.TypeSignatureParameter;
import io.trino.type.Constraint;
import org.testng.annotations.Test;

import java.lang.invoke.MethodHandle;
import java.util.List;

import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.collect.Iterables.getOnlyElement;
import static io.trino.SessionTestUtils.TEST_SESSION;
import static io.trino.metadata.MetadataManager.createTestMetadataManager;
import static io.trino.metadata.Signature.typeVariable;
import static io.trino.operator.aggregation.AggregationFromAnnotationsParser.parseFunctionDefinitions;
import static io.trino.operator.aggregation.AggregationFunctionAdapter.AggregationParameterKind.BLOCK_INDEX;
import static io.trino.operator.aggregation.AggregationFunctionAdapter.AggregationParameterKind.BLOCK_INPUT_CHANNEL;
import static io.trino.operator.aggregation.AggregationFunctionAdapter.AggregationParameterKind.INPUT_CHANNEL;
import static io.trino.operator.aggregation.AggregationFunctionAdapter.AggregationParameterKind.STATE;
import static io.trino.spi.function.InvocationConvention.InvocationArgumentConvention.NEVER_NULL;
import static io.trino.spi.function.InvocationConvention.InvocationReturnConvention.FAIL_ON_NULL;
import static io.trino.spi.function.OperatorType.LESS_THAN;
import static io.trino.spi.type.StandardTypes.ARRAY;
import static io.trino.spi.type.StandardTypes.DOUBLE;
import static io.trino.spi.type.VarcharType.createVarcharType;
import static java.lang.invoke.MethodType.methodType;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;

public class TestAnnotationEngineForAggregates
        extends TestAnnotationEngine
{
    private static final MetadataManager METADATA = createTestMetadataManager();
    private static final FunctionDependencies NO_FUNCTION_DEPENDENCIES = new FunctionDependencies(METADATA, ImmutableMap.of(), ImmutableSet.of());

    @AggregationFunction("simple_exact_aggregate")
    @Description("Simple exact aggregate description")
    public static final class ExactAggregationFunction
    {
        @InputFunction
        public static void input(@AggregationState NullableDoubleState state, @SqlType(DOUBLE) double value)
        {
            // noop this is only for annotation testing puproses
        }

        @CombineFunction
        public static void combine(@AggregationState NullableDoubleState combine1, @AggregationState NullableDoubleState combine2)
        {
            // noop this is only for annotation testing puproses
        }

        @OutputFunction(DOUBLE)
        public static void output(@AggregationState NullableDoubleState state, BlockBuilder out)
        {
            // noop this is only for annotation testing puproses
        }
    }

    @Test
    public void testSimpleExactAggregationParse()
    {
        Signature expectedSignature = new Signature(
                "simple_exact_aggregate",
                DoubleType.DOUBLE.getTypeSignature(),
                ImmutableList.of(DoubleType.DOUBLE.getTypeSignature()));

        ParametricAggregation aggregation = getOnlyElement(parseFunctionDefinitions(ExactAggregationFunction.class));
        assertEquals(aggregation.getFunctionMetadata().getDescription(), "Simple exact aggregate description");
        assertTrue(aggregation.getFunctionMetadata().isDeterministic());
        assertEquals(aggregation.getFunctionMetadata().getSignature(), expectedSignature);
        ParametricImplementationsGroup<AggregationImplementation> implementations = aggregation.getImplementations();
        assertImplementationCount(implementations, 1, 0, 0);
        AggregationImplementation implementation = getOnlyElement(implementations.getExactImplementations().values());
        assertEquals(implementation.getDefinitionClass(), ExactAggregationFunction.class);
        assertDependencyCount(implementation, 0, 0, 0);
        assertFalse(implementation.hasSpecializedTypeParameters());
        assertEquals(implementation.getInputParameterKinds(), ImmutableList.of(STATE, INPUT_CHANNEL));

        BoundSignature boundSignature = new BoundSignature(expectedSignature.getName(), DoubleType.DOUBLE, ImmutableList.of(DoubleType.DOUBLE));
        AggregationFunctionMetadata aggregationMetadata = aggregation.getAggregationMetadata();
        assertFalse(aggregationMetadata.isOrderSensitive());
        assertFalse(aggregationMetadata.getIntermediateTypes().isEmpty());
        aggregation.specialize(boundSignature, NO_FUNCTION_DEPENDENCIES);
    }

    @AggregationFunction("simple_exact_aggregate_aggregation_state_moved")
    @Description("Simple exact function which has @AggregationState on different than first positions")
    public static final class StateOnDifferentThanFirstPositionAggregationFunction
    {
        @InputFunction
        public static void input(@SqlType(DOUBLE) double value, @AggregationState NullableDoubleState state)
        {
            // noop this is only for annotation testing puproses
        }

        @CombineFunction
        public static void combine(@AggregationState NullableDoubleState combine1, @AggregationState NullableDoubleState combine2)
        {
            // noop this is only for annotation testing puproses
        }

        @OutputFunction(DOUBLE)
        public static void output(BlockBuilder out, @AggregationState NullableDoubleState state)
        {
            // noop this is only for annotation testing puproses
        }
    }

    @Test
    public void testStateOnDifferentThanFirstPositionAggregationParse()
    {
        Signature expectedSignature = new Signature(
                "simple_exact_aggregate_aggregation_state_moved",
                DoubleType.DOUBLE.getTypeSignature(),
                ImmutableList.of(DoubleType.DOUBLE.getTypeSignature()));

        ParametricAggregation aggregation = getOnlyElement(parseFunctionDefinitions(StateOnDifferentThanFirstPositionAggregationFunction.class));
        assertEquals(aggregation.getFunctionMetadata().getSignature(), expectedSignature);

        AggregationImplementation implementation = getOnlyElement(aggregation.getImplementations().getExactImplementations().values());
        assertEquals(implementation.getDefinitionClass(), StateOnDifferentThanFirstPositionAggregationFunction.class);
        assertEquals(implementation.getInputParameterKinds(), ImmutableList.of(INPUT_CHANNEL, STATE));
    }

    @AggregationFunction("no_aggregation_state_aggregate")
    @Description("Aggregate with no @AggregationState annotations")
    public static final class NotAnnotatedAggregateStateAggregationFunction
    {
        @InputFunction
        public static void input(NullableDoubleState state, @SqlType(DOUBLE) double value)
        {
            // noop this is only for annotation testing puproses
        }

        @CombineFunction
        public static void combine(NullableDoubleState combine1, NullableDoubleState combine2)
        {
            // noop this is only for annotation testing puproses
        }

        @OutputFunction(DOUBLE)
        public static void output(NullableDoubleState state, BlockBuilder out)
        {
            // noop this is only for annotation testing puproses
        }
    }

    @Test
    public void testNotAnnotatedAggregateStateAggregationParse()
    {
        ParametricAggregation aggregation = getOnlyElement(parseFunctionDefinitions(NotAnnotatedAggregateStateAggregationFunction.class));

        AggregationImplementation implementation = getOnlyElement(aggregation.getImplementations().getExactImplementations().values());
        assertEquals(implementation.getInputParameterKinds(), ImmutableList.of(STATE, INPUT_CHANNEL));

        BoundSignature boundSignature = new BoundSignature(aggregation.getFunctionMetadata().getSignature().getName(), DoubleType.DOUBLE, ImmutableList.of(DoubleType.DOUBLE));
        AggregationFunctionMetadata aggregationMetadata = aggregation.getAggregationMetadata();
        assertFalse(aggregationMetadata.isOrderSensitive());
        assertFalse(aggregationMetadata.getIntermediateTypes().isEmpty());
        aggregation.specialize(boundSignature, NO_FUNCTION_DEPENDENCIES);
    }

    @AggregationFunction(value = "custom_decomposable_aggregate", decomposable = false)
    @Description("Aggregate with Decomposable=false")
    public static final class NotDecomposableAggregationFunction
    {
        @InputFunction
        public static void input(
                @AggregationState NullableDoubleState state,
                @SqlType(DOUBLE) double value)
        {
            // noop this is only for annotation testing puproses
        }

        @OutputFunction(DOUBLE)
        public static void output(
                @AggregationState NullableDoubleState state,
                BlockBuilder out)
        {
            // noop this is only for annotation testing puproses
        }
    }

    @Test
    public void testNotDecomposableAggregationParse()
    {
        Signature expectedSignature = new Signature(
                "custom_decomposable_aggregate",
                DoubleType.DOUBLE.getTypeSignature(),
                ImmutableList.of(DoubleType.DOUBLE.getTypeSignature()));

        ParametricAggregation aggregation = getOnlyElement(parseFunctionDefinitions(NotDecomposableAggregationFunction.class));
        assertEquals(aggregation.getFunctionMetadata().getDescription(), "Aggregate with Decomposable=false");
        assertTrue(aggregation.getFunctionMetadata().isDeterministic());
        assertEquals(aggregation.getFunctionMetadata().getSignature(), expectedSignature);

        BoundSignature boundSignature = new BoundSignature(aggregation.getFunctionMetadata().getSignature().getName(), DoubleType.DOUBLE, ImmutableList.of(DoubleType.DOUBLE));
        AggregationFunctionMetadata aggregationMetadata = aggregation.getAggregationMetadata();
        assertFalse(aggregationMetadata.isOrderSensitive());
        assertTrue(aggregationMetadata.getIntermediateTypes().isEmpty());
        aggregation.specialize(boundSignature, NO_FUNCTION_DEPENDENCIES);
    }

    @AggregationFunction("simple_generic_implementations")
    @Description("Simple aggregate with two generic implementations")
    public static final class GenericAggregationFunction
    {
        @InputFunction
        @TypeParameter("T")
        public static void input(
                @AggregationState NullableLongState state,
                @SqlType("T") double value)
        {
            // noop this is only for annotation testing puproses
        }

        @InputFunction
        @TypeParameter("T")
        public static void input(
                @AggregationState NullableLongState state,
                @SqlType("T") long value)
        {
            // noop this is only for annotation testing puproses
        }

        @CombineFunction
        public static void combine(
                @AggregationState NullableLongState state,
                @AggregationState NullableLongState otherState)
        {
            // noop this is only for annotation testing puproses
        }

        @OutputFunction("T")
        public static void output(
                @AggregationState NullableLongState state,
                BlockBuilder out)
        {
            // noop this is only for annotation testing puproses
        }
    }

    @Test
    public void testSimpleGenericAggregationFunctionParse()
    {
        Signature expectedSignature = new Signature(
                "simple_generic_implementations",
                ImmutableList.of(typeVariable("T")),
                ImmutableList.of(),
                new TypeSignature("T"),
                ImmutableList.of(new TypeSignature("T")),
                false);

        ParametricAggregation aggregation = getOnlyElement(parseFunctionDefinitions(GenericAggregationFunction.class));
        assertEquals(aggregation.getFunctionMetadata().getDescription(), "Simple aggregate with two generic implementations");
        assertTrue(aggregation.getFunctionMetadata().isDeterministic());
        assertEquals(aggregation.getFunctionMetadata().getSignature(), expectedSignature);
        assertEquals(aggregation.getStateClass(), NullableLongState.class);
        ParametricImplementationsGroup<AggregationImplementation> implementations = aggregation.getImplementations();
        assertImplementationCount(implementations, 0, 0, 2);
        AggregationImplementation implementationDouble = implementations.getGenericImplementations().stream()
                .filter(impl -> impl.getInputFunction().type().equals(methodType(void.class, NullableLongState.class, double.class)))
                .collect(toImmutableList())
                .get(0);
        assertEquals(implementationDouble.getDefinitionClass(), GenericAggregationFunction.class);
        assertDependencyCount(implementationDouble, 0, 0, 0);
        assertFalse(implementationDouble.hasSpecializedTypeParameters());
        assertEquals(implementationDouble.getInputParameterKinds(), ImmutableList.of(STATE, INPUT_CHANNEL));

        AggregationImplementation implementationLong = implementations.getGenericImplementations().stream()
                .filter(impl -> impl.getInputFunction().type().equals(methodType(void.class, NullableLongState.class, long.class)))
                .collect(toImmutableList())
                .get(0);
        assertEquals(implementationLong.getDefinitionClass(), GenericAggregationFunction.class);
        assertDependencyCount(implementationLong, 0, 0, 0);
        assertFalse(implementationLong.hasSpecializedTypeParameters());
        assertEquals(implementationLong.getInputParameterKinds(), ImmutableList.of(STATE, INPUT_CHANNEL));

        BoundSignature boundSignature = new BoundSignature(aggregation.getFunctionMetadata().getSignature().getName(), DoubleType.DOUBLE, ImmutableList.of(DoubleType.DOUBLE));
        AggregationFunctionMetadata aggregationMetadata = aggregation.getAggregationMetadata();
        assertFalse(aggregationMetadata.isOrderSensitive());
        assertFalse(aggregationMetadata.getIntermediateTypes().isEmpty());
        aggregation.specialize(boundSignature, NO_FUNCTION_DEPENDENCIES);
    }

    @AggregationFunction("block_input_aggregate")
    @Description("Simple aggregate with @BlockPosition usage")
    public static final class BlockInputAggregationFunction
    {
        @InputFunction
        public static void input(
                @AggregationState NullableDoubleState state,
                @BlockPosition @SqlType(DOUBLE) Block value,
                @BlockIndex int id)
        {
            // noop this is only for annotation testing puproses
        }

        @CombineFunction
        public static void combine(
                @AggregationState NullableDoubleState combine1,
                @AggregationState NullableDoubleState combine2)
        {
            // noop this is only for annotation testing puproses
        }

        @OutputFunction(DOUBLE)
        public static void output(
                @AggregationState NullableDoubleState state,
                BlockBuilder out)
        {
            // noop this is only for annotation testing puproses
        }
    }

    @Test
    public void testSimpleBlockInputAggregationParse()
    {
        Signature expectedSignature = new Signature(
                "block_input_aggregate",
                DoubleType.DOUBLE.getTypeSignature(),
                ImmutableList.of(DoubleType.DOUBLE.getTypeSignature()));

        ParametricAggregation aggregation = getOnlyElement(parseFunctionDefinitions(BlockInputAggregationFunction.class));
        assertEquals(aggregation.getFunctionMetadata().getDescription(), "Simple aggregate with @BlockPosition usage");
        assertTrue(aggregation.getFunctionMetadata().isDeterministic());
        assertEquals(aggregation.getFunctionMetadata().getSignature(), expectedSignature);
        ParametricImplementationsGroup<AggregationImplementation> implementations = aggregation.getImplementations();
        assertImplementationCount(implementations, 1, 0, 0);
        AggregationImplementation implementation = getOnlyElement(implementations.getExactImplementations().values());
        assertEquals(implementation.getDefinitionClass(), BlockInputAggregationFunction.class);
        assertDependencyCount(implementation, 0, 0, 0);
        assertFalse(implementation.hasSpecializedTypeParameters());
        assertEquals(implementation.getInputParameterKinds(), ImmutableList.of(STATE, BLOCK_INPUT_CHANNEL, BLOCK_INDEX));

        BoundSignature boundSignature = new BoundSignature(aggregation.getFunctionMetadata().getSignature().getName(), DoubleType.DOUBLE, ImmutableList.of(DoubleType.DOUBLE));
        AggregationFunctionMetadata aggregationMetadata = aggregation.getAggregationMetadata();
        assertFalse(aggregationMetadata.isOrderSensitive());
        assertFalse(aggregationMetadata.getIntermediateTypes().isEmpty());
        aggregation.specialize(boundSignature, NO_FUNCTION_DEPENDENCIES);
    }

    @AggregationFunction("implicit_specialized_aggregate")
    @Description("Simple implicit specialized aggregate")
    public static final class ImplicitSpecializedAggregationFunction
    {
        @InputFunction
        @TypeParameter("T")
        public static void input(
                @AggregationState NullableDoubleState state,
                @SqlType("array(T)") Block arrayBlock, @SqlType("T") double additionalValue)
        {
            // noop this is only for annotation testing puproses
        }

        @InputFunction
        @TypeParameter("T")
        public static void input(
                @AggregationState NullableLongState state,
                @SqlType("array(T)") Block arrayBlock, @SqlType("T") long additionalValue)
        {
            // noop this is only for annotation testing puproses
        }

        @CombineFunction
        public static void combine(
                @AggregationState NullableLongState state,
                @AggregationState NullableLongState otherState)
        {
            // noop this is only for annotation testing puproses
        }

        @CombineFunction
        public static void combine(
                @AggregationState NullableDoubleState state,
                @AggregationState NullableDoubleState otherState)
        {
            // noop this is only for annotation testing puproses
        }

        @OutputFunction("T")
        public static void output(
                @AggregationState NullableLongState state,
                BlockBuilder out)
        {
            // noop this is only for annotation testing puproses
        }

        @OutputFunction("T")
        public static void output(
                @AggregationState NullableDoubleState state,
                BlockBuilder out)
        {
            // noop this is only for annotation testing puproses
        }
    }

    @Test(enabled = false) // TODO this is not yet supported
    public void testSimpleImplicitSpecializedAggregationParse()
    {
        Signature expectedSignature = new Signature(
                "implicit_specialized_aggregate",
                ImmutableList.of(typeVariable("T")),
                ImmutableList.of(),
                new TypeSignature("T"),
                ImmutableList.of(new TypeSignature(ARRAY, TypeSignatureParameter.typeParameter(new TypeSignature("T"))), new TypeSignature("T")),
                false);

        ParametricAggregation aggregation = getOnlyElement(parseFunctionDefinitions(ImplicitSpecializedAggregationFunction.class));
        assertEquals(aggregation.getFunctionMetadata().getDescription(), "Simple implicit specialized aggregate");
        assertTrue(aggregation.getFunctionMetadata().isDeterministic());
        assertEquals(aggregation.getFunctionMetadata().getSignature(), expectedSignature);
        ParametricImplementationsGroup<AggregationImplementation> implementations = aggregation.getImplementations();
        assertImplementationCount(implementations, 0, 0, 2);

        AggregationImplementation implementation1 = implementations.getSpecializedImplementations().get(0);
        assertTrue(implementation1.hasSpecializedTypeParameters());
        assertFalse(implementation1.hasSpecializedTypeParameters());
        assertEquals(implementation1.getInputParameterKinds(), ImmutableList.of(STATE, INPUT_CHANNEL, INPUT_CHANNEL));

        AggregationImplementation implementation2 = implementations.getSpecializedImplementations().get(1);
        assertTrue(implementation2.hasSpecializedTypeParameters());
        assertFalse(implementation2.hasSpecializedTypeParameters());
        assertEquals(implementation2.getInputParameterKinds(), ImmutableList.of(STATE, INPUT_CHANNEL, INPUT_CHANNEL));

        BoundSignature boundSignature = new BoundSignature(aggregation.getFunctionMetadata().getSignature().getName(), DoubleType.DOUBLE, ImmutableList.of(new ArrayType(DoubleType.DOUBLE)));
        AggregationFunctionMetadata aggregationMetadata = aggregation.getAggregationMetadata();
        assertFalse(aggregationMetadata.isOrderSensitive());
        assertFalse(aggregationMetadata.getIntermediateTypes().isEmpty());
        aggregation.specialize(boundSignature, NO_FUNCTION_DEPENDENCIES);
    }

    @AggregationFunction("explicit_specialized_aggregate")
    @Description("Simple explicit specialized aggregate")
    public static final class ExplicitSpecializedAggregationFunction
    {
        @InputFunction
        @TypeParameterSpecialization(name = "T", nativeContainerType = double.class)
        @TypeParameter("T")
        public static void input(
                @AggregationState NullableDoubleState state,
                @SqlType("array(T)") Block arrayBlock)
        {
            // noop this is only for annotation testing puproses
        }

        @InputFunction
        @TypeParameter("T")
        public static void input(
                @AggregationState NullableLongState state,
                @SqlType("array(T)") Block arrayBlock)
        {
            // noop this is only for annotation testing puproses
        }

        @CombineFunction
        public static void combine(
                @AggregationState NullableLongState state,
                @AggregationState NullableLongState otherState)
        {
            // noop this is only for annotation testing puproses
        }

        @CombineFunction
        public static void combine(
                @AggregationState NullableDoubleState state,
                @AggregationState NullableDoubleState otherState)
        {
            // noop this is only for annotation testing puproses
        }

        @OutputFunction("T")
        public static void output(
                @AggregationState NullableLongState state,
                BlockBuilder out)
        {
            // noop this is only for annotation testing puproses
        }

        @OutputFunction("T")
        public static void output(
                @AggregationState NullableDoubleState state,
                BlockBuilder out)
        {
            // noop this is only for annotation testing puproses
        }
    }

    @Test(enabled = false) // TODO this is not yet supported
    public void testSimpleExplicitSpecializedAggregationParse()
    {
        Signature expectedSignature = new Signature(
                "explicit_specialized_aggregate",
                ImmutableList.of(typeVariable("T")),
                ImmutableList.of(),
                new TypeSignature("T"),
                ImmutableList.of(new TypeSignature(ARRAY, TypeSignatureParameter.typeParameter(new TypeSignature("T")))),
                false);

        ParametricAggregation aggregation = getOnlyElement(parseFunctionDefinitions(ExplicitSpecializedAggregationFunction.class));
        assertEquals(aggregation.getFunctionMetadata().getDescription(), "Simple explicit specialized aggregate");
        assertTrue(aggregation.getFunctionMetadata().isDeterministic());
        assertEquals(aggregation.getFunctionMetadata().getSignature(), expectedSignature);
        ParametricImplementationsGroup<AggregationImplementation> implementations = aggregation.getImplementations();
        assertImplementationCount(implementations, 0, 1, 1);
        AggregationImplementation implementation1 = implementations.getSpecializedImplementations().get(0);
        assertTrue(implementation1.hasSpecializedTypeParameters());
        assertFalse(implementation1.hasSpecializedTypeParameters());
        assertEquals(implementation1.getInputParameterKinds(), ImmutableList.of(STATE, INPUT_CHANNEL));

        AggregationImplementation implementation2 = implementations.getSpecializedImplementations().get(1);
        assertTrue(implementation2.hasSpecializedTypeParameters());
        assertFalse(implementation2.hasSpecializedTypeParameters());
        assertEquals(implementation2.getInputParameterKinds(), ImmutableList.of(STATE, INPUT_CHANNEL));

        BoundSignature boundSignature = new BoundSignature(aggregation.getFunctionMetadata().getSignature().getName(), DoubleType.DOUBLE, ImmutableList.of(new ArrayType(DoubleType.DOUBLE)));
        AggregationFunctionMetadata aggregationMetadata = aggregation.getAggregationMetadata();
        assertFalse(aggregationMetadata.isOrderSensitive());
        assertFalse(aggregationMetadata.getIntermediateTypes().isEmpty());
        aggregation.specialize(boundSignature, NO_FUNCTION_DEPENDENCIES);
    }

    @AggregationFunction("multi_output_aggregate")
    @Description("Simple multi output function aggregate generic description")
    public static final class MultiOutputAggregationFunction
    {
        @InputFunction
        public static void input(
                @AggregationState NullableDoubleState state,
                @SqlType(DOUBLE) double value)
        {
            // noop this is only for annotation testing puproses
        }

        @CombineFunction
        public static void combine(
                @AggregationState NullableDoubleState combine1,
                @AggregationState NullableDoubleState combine2)
        {
            // noop this is only for annotation testing puproses
        }

        @AggregationFunction("multi_output_aggregate_1")
        @Description("Simple multi output function aggregate specialized description")
        @OutputFunction(DOUBLE)
        public static void output1(
                @AggregationState NullableDoubleState state,
                BlockBuilder out)
        {
            // noop this is only for annotation testing puproses
        }

        @AggregationFunction("multi_output_aggregate_2")
        @OutputFunction(DOUBLE)
        public static void output2(
                @AggregationState NullableDoubleState state,
                BlockBuilder out)
        {
            // noop this is only for annotation testing puproses
        }
    }

    @Test
    public void testMultiOutputAggregationParse()
    {
        Signature expectedSignature1 = new Signature(
                "multi_output_aggregate_1",
                DoubleType.DOUBLE.getTypeSignature(),
                ImmutableList.of(DoubleType.DOUBLE.getTypeSignature()));

        Signature expectedSignature2 = new Signature(
                "multi_output_aggregate_2",
                DoubleType.DOUBLE.getTypeSignature(),
                ImmutableList.of(DoubleType.DOUBLE.getTypeSignature()));

        List<ParametricAggregation> aggregations = parseFunctionDefinitions(MultiOutputAggregationFunction.class);
        assertEquals(aggregations.size(), 2);

        ParametricAggregation aggregation1 = aggregations.stream().filter(aggregate -> aggregate.getFunctionMetadata().getSignature().getName().equals("multi_output_aggregate_1")).collect(toImmutableList()).get(0);
        assertEquals(aggregation1.getFunctionMetadata().getSignature(), expectedSignature1);
        assertEquals(aggregation1.getFunctionMetadata().getDescription(), "Simple multi output function aggregate specialized description");

        ParametricAggregation aggregation2 = aggregations.stream().filter(aggregate -> aggregate.getFunctionMetadata().getSignature().getName().equals("multi_output_aggregate_2")).collect(toImmutableList()).get(0);
        assertEquals(aggregation2.getFunctionMetadata().getSignature(), expectedSignature2);
        assertEquals(aggregation2.getFunctionMetadata().getDescription(), "Simple multi output function aggregate generic description");

        ParametricImplementationsGroup<AggregationImplementation> implementations1 = aggregation1.getImplementations();
        assertImplementationCount(implementations1, 1, 0, 0);

        ParametricImplementationsGroup<AggregationImplementation> implementations2 = aggregation2.getImplementations();
        assertImplementationCount(implementations2, 1, 0, 0);

        AggregationImplementation implementation = getOnlyElement(implementations1.getExactImplementations().values());
        assertEquals(implementation.getDefinitionClass(), MultiOutputAggregationFunction.class);
        assertDependencyCount(implementation, 0, 0, 0);
        assertFalse(implementation.hasSpecializedTypeParameters());
        assertEquals(implementation.getInputParameterKinds(), ImmutableList.of(STATE, INPUT_CHANNEL));

        BoundSignature boundSignature = new BoundSignature(aggregation1.getFunctionMetadata().getSignature().getName(), DoubleType.DOUBLE, ImmutableList.of(DoubleType.DOUBLE));
        AggregationFunctionMetadata aggregationMetadata = aggregation1.getAggregationMetadata();
        assertFalse(aggregationMetadata.isOrderSensitive());
        assertFalse(aggregationMetadata.getIntermediateTypes().isEmpty());
        aggregation1.specialize(boundSignature, NO_FUNCTION_DEPENDENCIES);
    }

    @AggregationFunction("inject_operator_aggregate")
    @Description("Simple aggregate with operator injected")
    public static final class InjectOperatorAggregateFunction
    {
        @InputFunction
        public static void input(
                @OperatorDependency(
                        operator = LESS_THAN,
                        argumentTypes = {DOUBLE, DOUBLE},
                        convention = @Convention(arguments = {NEVER_NULL, NEVER_NULL}, result = FAIL_ON_NULL))
                        MethodHandle methodHandle,
                @AggregationState NullableDoubleState state,
                @SqlType(DOUBLE) double value)
        {
            // noop this is only for annotation testing puproses
        }

        @CombineFunction
        public static void combine(
                @OperatorDependency(
                        operator = LESS_THAN,
                        argumentTypes = {DOUBLE, DOUBLE},
                        convention = @Convention(arguments = {NEVER_NULL, NEVER_NULL}, result = FAIL_ON_NULL))
                        MethodHandle methodHandle,
                @AggregationState NullableDoubleState combine1,
                @AggregationState NullableDoubleState combine2)
        {
            // noop this is only for annotation testing puproses
        }

        @OutputFunction(DOUBLE)
        public static void output(
                @OperatorDependency(
                        operator = LESS_THAN,
                        argumentTypes = {DOUBLE, DOUBLE},
                        convention = @Convention(arguments = {NEVER_NULL, NEVER_NULL}, result = FAIL_ON_NULL))
                        MethodHandle methodHandle,
                @AggregationState NullableDoubleState state,
                BlockBuilder out)
        {
            // noop this is only for annotation testing puproses
        }
    }

    @Test
    public void testInjectOperatorAggregateParse()
    {
        Signature expectedSignature = new Signature(
                "inject_operator_aggregate",
                DoubleType.DOUBLE.getTypeSignature(),
                ImmutableList.of(DoubleType.DOUBLE.getTypeSignature()));

        ParametricAggregation aggregation = getOnlyElement(parseFunctionDefinitions(InjectOperatorAggregateFunction.class));
        assertEquals(aggregation.getFunctionMetadata().getDescription(), "Simple aggregate with operator injected");
        assertTrue(aggregation.getFunctionMetadata().isDeterministic());
        assertEquals(aggregation.getFunctionMetadata().getSignature(), expectedSignature);
        ParametricImplementationsGroup<AggregationImplementation> implementations = aggregation.getImplementations();

        AggregationImplementation implementation = getOnlyElement(implementations.getExactImplementations().values());
        assertEquals(implementation.getDefinitionClass(), InjectOperatorAggregateFunction.class);
        assertDependencyCount(implementation, 1, 1, 1);

        assertTrue(implementation.getInputDependencies().get(0) instanceof OperatorImplementationDependency);
        assertTrue(implementation.getCombineDependencies().get(0) instanceof OperatorImplementationDependency);
        assertTrue(implementation.getOutputDependencies().get(0) instanceof OperatorImplementationDependency);

        assertFalse(implementation.hasSpecializedTypeParameters());
        assertEquals(implementation.getInputParameterKinds(), ImmutableList.of(STATE, INPUT_CHANNEL));

        BoundSignature boundSignature = new BoundSignature(aggregation.getFunctionMetadata().getSignature().getName(), DoubleType.DOUBLE, ImmutableList.of(DoubleType.DOUBLE));
        specializeAggregationFunction(boundSignature, aggregation);
    }

    @AggregationFunction("inject_type_aggregate")
    @Description("Simple aggregate with type injected")
    public static final class InjectTypeAggregateFunction
    {
        @InputFunction
        @TypeParameter("T")
        public static void input(
                @TypeParameter("T") Type type,
                @AggregationState NullableDoubleState state,
                @SqlType("T") double value)
        {
            // noop this is only for annotation testing puproses
        }

        @CombineFunction
        public static void combine(
                @TypeParameter("T") Type type,
                @AggregationState NullableDoubleState combine1,
                @AggregationState NullableDoubleState combine2)
        {
            // noop this is only for annotation testing puproses
        }

        @OutputFunction("T")
        public static void output(
                @TypeParameter("T") Type type,
                @AggregationState NullableDoubleState state,
                BlockBuilder out)
        {
            // noop this is only for annotation testing puproses
        }
    }

    @Test
    public void testInjectTypeAggregateParse()
    {
        Signature expectedSignature = new Signature(
                "inject_type_aggregate",
                ImmutableList.of(typeVariable("T")),
                ImmutableList.of(),
                new TypeSignature("T"),
                ImmutableList.of(new TypeSignature("T")),
                false);

        ParametricAggregation aggregation = getOnlyElement(parseFunctionDefinitions(InjectTypeAggregateFunction.class));
        assertEquals(aggregation.getFunctionMetadata().getDescription(), "Simple aggregate with type injected");
        assertTrue(aggregation.getFunctionMetadata().isDeterministic());
        assertEquals(aggregation.getFunctionMetadata().getSignature(), expectedSignature);
        ParametricImplementationsGroup<AggregationImplementation> implementations = aggregation.getImplementations();

        assertEquals(implementations.getGenericImplementations().size(), 1);
        AggregationImplementation implementation = implementations.getGenericImplementations().get(0);
        assertEquals(implementation.getDefinitionClass(), InjectTypeAggregateFunction.class);
        assertDependencyCount(implementation, 1, 1, 1);

        assertTrue(implementation.getInputDependencies().get(0) instanceof TypeImplementationDependency);
        assertTrue(implementation.getCombineDependencies().get(0) instanceof TypeImplementationDependency);
        assertTrue(implementation.getOutputDependencies().get(0) instanceof TypeImplementationDependency);

        assertFalse(implementation.hasSpecializedTypeParameters());
        assertEquals(implementation.getInputParameterKinds(), ImmutableList.of(STATE, INPUT_CHANNEL));

        BoundSignature boundSignature = new BoundSignature(aggregation.getFunctionMetadata().getSignature().getName(), DoubleType.DOUBLE, ImmutableList.of(DoubleType.DOUBLE));
        specializeAggregationFunction(boundSignature, aggregation);
    }

    @AggregationFunction("inject_literal_aggregate")
    @Description("Simple aggregate with type literal")
    public static final class InjectLiteralAggregateFunction
    {
        @InputFunction
        @LiteralParameters("x")
        public static void input(
                @LiteralParameter("x") Long varcharSize,
                @AggregationState LongState state,
                @SqlType("varchar(x)") Slice slice)
        {
            // noop this is only for annotation testing puproses
        }

        @CombineFunction
        public static void combine(
                @LiteralParameter("x") Long varcharSize,
                @AggregationState LongState combine1,
                @AggregationState LongState combine2)
        {
            // noop this is only for annotation testing puproses
        }

        @OutputFunction("varchar(x)")
        public static void output(
                @LiteralParameter("x") Long varcharSize,
                @AggregationState LongState state,
                BlockBuilder out)
        {
            // noop this is only for annotation testing puproses
        }
    }

    @Test
    public void testInjectLiteralAggregateParse()
    {
        Signature expectedSignature = new Signature(
                "inject_literal_aggregate",
                new TypeSignature("varchar", TypeSignatureParameter.typeVariable("x")),
                ImmutableList.of(new TypeSignature("varchar", TypeSignatureParameter.typeVariable("x"))));

        ParametricAggregation aggregation = getOnlyElement(parseFunctionDefinitions(InjectLiteralAggregateFunction.class));
        assertEquals(aggregation.getFunctionMetadata().getDescription(), "Simple aggregate with type literal");
        assertTrue(aggregation.getFunctionMetadata().isDeterministic());
        assertEquals(aggregation.getFunctionMetadata().getSignature(), expectedSignature);
        ParametricImplementationsGroup<AggregationImplementation> implementations = aggregation.getImplementations();

        assertEquals(implementations.getGenericImplementations().size(), 1);
        AggregationImplementation implementation = implementations.getGenericImplementations().get(0);
        assertEquals(implementation.getDefinitionClass(), InjectLiteralAggregateFunction.class);
        assertDependencyCount(implementation, 1, 1, 1);

        assertTrue(implementation.getInputDependencies().get(0) instanceof LiteralImplementationDependency);
        assertTrue(implementation.getCombineDependencies().get(0) instanceof LiteralImplementationDependency);
        assertTrue(implementation.getOutputDependencies().get(0) instanceof LiteralImplementationDependency);

        assertFalse(implementation.hasSpecializedTypeParameters());
        assertEquals(implementation.getInputParameterKinds(), ImmutableList.of(STATE, INPUT_CHANNEL));

        BoundSignature boundSignature = new BoundSignature(aggregation.getFunctionMetadata().getSignature().getName(), createVarcharType(17), ImmutableList.of(createVarcharType(17)));
        AggregationFunctionMetadata aggregationMetadata = aggregation.getAggregationMetadata();
        assertFalse(aggregationMetadata.isOrderSensitive());
        assertFalse(aggregationMetadata.getIntermediateTypes().isEmpty());
        aggregation.specialize(boundSignature, NO_FUNCTION_DEPENDENCIES);
    }

    @AggregationFunction("parametric_aggregate_long_constraint")
    @Description("Parametric aggregate with parametric type returned")
    public static final class LongConstraintAggregateFunction
    {
        @InputFunction
        @LiteralParameters({"x", "y", "z"})
        @Constraint(variable = "z", expression = "x + y")
        public static void input(
                @AggregationState LongState state,
                @SqlType("varchar(x)") Slice slice1,
                @SqlType("varchar(y)") Slice slice2)
        {
            // noop this is only for annotation testing puproses
        }

        @CombineFunction
        public static void combine(
                @AggregationState LongState combine1,
                @AggregationState LongState combine2)
        {
            // noop this is only for annotation testing puproses
        }

        @OutputFunction("varchar(z)")
        public static void output(
                @AggregationState LongState state,
                BlockBuilder out)
        {
            // noop this is only for annotation testing puproses
        }
    }

    @Test
    public void testLongConstraintAggregateFunctionParse()
    {
        Signature expectedSignature = new Signature(
                "parametric_aggregate_long_constraint",
                ImmutableList.of(),
                ImmutableList.of(new LongVariableConstraint("z", "x + y")),
                new TypeSignature("varchar", TypeSignatureParameter.typeVariable("z")),
                ImmutableList.of(new TypeSignature("varchar", TypeSignatureParameter.typeVariable("x")),
                        new TypeSignature("varchar", TypeSignatureParameter.typeVariable("y"))),
                false);

        ParametricAggregation aggregation = getOnlyElement(parseFunctionDefinitions(LongConstraintAggregateFunction.class));
        assertEquals(aggregation.getFunctionMetadata().getDescription(), "Parametric aggregate with parametric type returned");
        assertTrue(aggregation.getFunctionMetadata().isDeterministic());
        assertEquals(aggregation.getFunctionMetadata().getSignature(), expectedSignature);
        ParametricImplementationsGroup<AggregationImplementation> implementations = aggregation.getImplementations();

        assertEquals(implementations.getGenericImplementations().size(), 1);
        AggregationImplementation implementation = implementations.getGenericImplementations().get(0);
        assertEquals(implementation.getDefinitionClass(), LongConstraintAggregateFunction.class);
        assertDependencyCount(implementation, 0, 0, 0);

        assertFalse(implementation.hasSpecializedTypeParameters());
        assertEquals(implementation.getInputParameterKinds(), ImmutableList.of(STATE, INPUT_CHANNEL, INPUT_CHANNEL));

        BoundSignature boundSignature = new BoundSignature(aggregation.getFunctionMetadata().getSignature().getName(), createVarcharType(30), ImmutableList.of(createVarcharType(17), createVarcharType(13)));
        AggregationFunctionMetadata aggregationMetadata = aggregation.getAggregationMetadata();
        assertFalse(aggregationMetadata.isOrderSensitive());
        assertFalse(aggregationMetadata.getIntermediateTypes().isEmpty());
        aggregation.specialize(boundSignature, NO_FUNCTION_DEPENDENCIES);
    }

    @AggregationFunction("fixed_type_parameter_injection")
    @Description("Simple aggregate with fixed parameter type injected")
    public static final class FixedTypeParameterInjectionAggregateFunction
    {
        @InputFunction
        public static void input(
                @TypeParameter("ROW(ARRAY(BIGINT),ROW(ROW(CHAR)),BIGINT,MAP(BIGINT,CHAR))") Type type,
                @AggregationState NullableDoubleState state,
                @SqlType("double") double value)
        {
            // noop this is only for annotation testing puproses
        }

        @CombineFunction
        public static void combine(
                @TypeParameter("ROW(ARRAY(BIGINT),ROW(ROW(CHAR)),BIGINT,MAP(BIGINT,CHAR))") Type type,
                @AggregationState NullableDoubleState state,
                @AggregationState NullableDoubleState otherState)
        {
            // noop this is only for annotation testing puproses
        }

        @OutputFunction("double")
        public static void output(
                @TypeParameter("ROW(ARRAY(BIGINT),ROW(ROW(CHAR)),BIGINT,MAP(BIGINT,CHAR))") Type type,
                @AggregationState NullableDoubleState state,
                BlockBuilder out)
        {
            // noop this is only for annotation testing puproses
        }
    }

    @Test
    public void testFixedTypeParameterInjectionAggregateFunctionParse()
    {
        Signature expectedSignature = new Signature(
                "fixed_type_parameter_injection",
                ImmutableList.of(),
                ImmutableList.of(),
                DoubleType.DOUBLE.getTypeSignature(),
                ImmutableList.of(DoubleType.DOUBLE.getTypeSignature()),
                false);

        ParametricAggregation aggregation = getOnlyElement(parseFunctionDefinitions(FixedTypeParameterInjectionAggregateFunction.class));
        assertEquals(aggregation.getFunctionMetadata().getDescription(), "Simple aggregate with fixed parameter type injected");
        assertTrue(aggregation.getFunctionMetadata().isDeterministic());
        assertEquals(aggregation.getFunctionMetadata().getSignature(), expectedSignature);
        assertEquals(aggregation.getStateClass(), NullableDoubleState.class);
        ParametricImplementationsGroup<AggregationImplementation> implementations = aggregation.getImplementations();
        assertImplementationCount(implementations, 1, 0, 0);
        AggregationImplementation implementationDouble = implementations.getExactImplementations().get(expectedSignature);
        assertEquals(implementationDouble.getDefinitionClass(), FixedTypeParameterInjectionAggregateFunction.class);
        assertDependencyCount(implementationDouble, 1, 1, 1);
        assertFalse(implementationDouble.hasSpecializedTypeParameters());
        assertEquals(implementationDouble.getInputParameterKinds(), ImmutableList.of(STATE, INPUT_CHANNEL));
    }

    @AggregationFunction("partially_fixed_type_parameter_injection")
    @Description("Simple aggregate with fixed parameter type injected")
    public static final class PartiallyFixedTypeParameterInjectionAggregateFunction
    {
        @InputFunction
        @TypeParameter("T1")
        @TypeParameter("T2")
        public static void input(
                @TypeParameter("ROW(ARRAY(T1),ROW(ROW(T2)),CHAR)") Type type,
                @AggregationState NullableDoubleState state,
                @SqlType("T1") double x, @SqlType("T2") double y)
        {
            // noop this is only for annotation testing purposes
        }

        @CombineFunction
        @TypeParameter("T1")
        @TypeParameter("T2")
        public static void combine(
                @TypeParameter("ROW(ARRAY(T1),ROW(ROW(T2)),CHAR)") Type type,
                @AggregationState NullableDoubleState state,
                @AggregationState NullableDoubleState otherState)
        {
            // noop this is only for annotation testing purposes
        }

        @OutputFunction("double")
        @TypeParameter("T1")
        @TypeParameter("T2")
        public static void output(
                @TypeParameter("ROW(ARRAY(T1),ROW(ROW(T2)),CHAR)") Type type,
                @AggregationState NullableDoubleState state,
                BlockBuilder out)
        {
            // noop this is only for annotation testing purposes
        }
    }

    @Test
    public void testPartiallyFixedTypeParameterInjectionAggregateFunctionParse()
    {
        Signature expectedSignature = new Signature(
                "partially_fixed_type_parameter_injection",
                ImmutableList.of(typeVariable("T1"), typeVariable("T2")),
                ImmutableList.of(),
                DoubleType.DOUBLE.getTypeSignature(),
                ImmutableList.of(new TypeSignature("T1"), new TypeSignature("T2")),
                false);

        ParametricAggregation aggregation = getOnlyElement(parseFunctionDefinitions(PartiallyFixedTypeParameterInjectionAggregateFunction.class));
        assertEquals(aggregation.getFunctionMetadata().getDescription(), "Simple aggregate with fixed parameter type injected");
        assertTrue(aggregation.getFunctionMetadata().isDeterministic());
        assertEquals(aggregation.getFunctionMetadata().getSignature(), expectedSignature);
        assertEquals(aggregation.getStateClass(), NullableDoubleState.class);
        ParametricImplementationsGroup<AggregationImplementation> implementations = aggregation.getImplementations();
        assertImplementationCount(implementations, 0, 0, 1);
        AggregationImplementation implementationDouble = getOnlyElement(implementations.getGenericImplementations());
        assertEquals(implementationDouble.getDefinitionClass(), PartiallyFixedTypeParameterInjectionAggregateFunction.class);
        assertDependencyCount(implementationDouble, 1, 1, 1);
        assertFalse(implementationDouble.hasSpecializedTypeParameters());
        assertEquals(implementationDouble.getInputParameterKinds(), ImmutableList.of(STATE, INPUT_CHANNEL, INPUT_CHANNEL));

        BoundSignature boundSignature = new BoundSignature(aggregation.getFunctionMetadata().getSignature().getName(), DoubleType.DOUBLE, ImmutableList.of(DoubleType.DOUBLE, DoubleType.DOUBLE));
        specializeAggregationFunction(boundSignature, aggregation);
    }

    @AggregationFunction
    @Description("Aggregation output function with alias")
    public static final class AggregationOutputFunctionWithAlias
    {
        @InputFunction
        public static void input(@AggregationState VarianceState state, @SqlType(StandardTypes.DOUBLE) double value)
        {
            // noop this is only for annotation testing purposes
        }

        @CombineFunction
        public static void combine(@AggregationState VarianceState state, @AggregationState VarianceState otherState)
        {
            // noop this is only for annotation testing purposes
        }

        @AggregationFunction(value = "aggregation_output", alias = {"aggregation_output_alias_1", "aggregation_output_alias_2"})
        @OutputFunction(StandardTypes.DOUBLE)
        public static void output(@AggregationState VarianceState state, BlockBuilder out)
        {
            // noop this is only for annotation testing purposes
        }
    }

    @AggregationFunction(value = "aggregation", alias = {"aggregation_alias_1", "aggregation_alias_2"})
    @Description("Aggregation function with alias")
    public static final class AggregationFunctionWithAlias
    {
        @InputFunction
        public static void input(@AggregationState TriStateBooleanState state, @SqlType(StandardTypes.BOOLEAN) boolean value)
        {
            // noop this is only for annotation testing purposes
        }

        @CombineFunction
        public static void combine(@AggregationState TriStateBooleanState state, @AggregationState TriStateBooleanState otherState)
        {
            // noop this is only for annotation testing purposes
        }

        @OutputFunction(StandardTypes.BOOLEAN)
        public static void output(@AggregationState TriStateBooleanState state, BlockBuilder out)
        {
            // noop this is only for annotation testing purposes
        }
    }

    @Test
    public void testAggregateFunctionGetCanonicalName()
    {
        List<ParametricAggregation> aggregationOutputFunctions = parseFunctionDefinitions(AggregationOutputFunctionWithAlias.class);
        assertEquals(aggregationOutputFunctions.size(), 3);
        assertEquals(
                aggregationOutputFunctions.stream()
                        .map(aggregateFunction -> aggregateFunction.getFunctionMetadata().getSignature().getName())
                        .collect(toImmutableSet()),
                ImmutableSet.of("aggregation_output", "aggregation_output_alias_1", "aggregation_output_alias_2"));
        assertEquals(
                aggregationOutputFunctions.stream()
                        .map(aggregateFunction -> aggregateFunction.getFunctionMetadata().getCanonicalName())
                        .collect(toImmutableSet()),
                ImmutableSet.of("aggregation_output"));

        List<ParametricAggregation> aggregationFunctions = parseFunctionDefinitions(AggregationFunctionWithAlias.class);
        assertEquals(aggregationFunctions.size(), 3);
        assertEquals(
                aggregationFunctions.stream()
                        .map(aggregateFunction -> aggregateFunction.getFunctionMetadata().getSignature().getName())
                        .collect(toImmutableSet()),
                ImmutableSet.of("aggregation", "aggregation_alias_1", "aggregation_alias_2"));
        assertEquals(
                aggregationFunctions.stream()
                        .map(aggregateFunction -> aggregateFunction.getFunctionMetadata().getCanonicalName())
                        .collect(toImmutableSet()),
                ImmutableSet.of("aggregation"));
    }

    private static void specializeAggregationFunction(BoundSignature boundSignature, SqlAggregationFunction aggregation)
    {
        FunctionMetadata functionMetadata = aggregation.getFunctionMetadata();
        FunctionBinding functionBinding = MetadataManager.toFunctionBinding(functionMetadata.getFunctionId(), boundSignature, functionMetadata.getSignature());

        AggregationFunctionMetadata aggregationMetadata = aggregation.getAggregationMetadata();
        assertFalse(aggregationMetadata.isOrderSensitive());
        assertFalse(aggregationMetadata.getIntermediateTypes().isEmpty());

        ResolvedFunction resolvedFunction = METADATA.resolve(TEST_SESSION, functionBinding, functionMetadata, aggregation.getFunctionDependencies(boundSignature));
        FunctionDependencies functionDependencies = new FunctionDependencies(METADATA, resolvedFunction.getTypeDependencies(), resolvedFunction.getFunctionDependencies());
        aggregation.specialize(boundSignature, functionDependencies);
    }
}


No Smoking has been in news till now because of its different theme and of course John Abraham, but now, there's a new addition to the film. Model Jesse Randhawa has done a dance sequence in the film. Anurag Kashyap, the director of the film says that he was hunting for the right girl to do this song for a while. And when he saw her hosting the Salaam-E-Ishq fashion show, he zeroed down on her.
Talking about her dance sequence, Jesse says that it is surely not an item number. She is covered from head to toe in the song and it looks very classy with no vulgarity. Though Jesse hasn't really done such performances in films, she says that she did this number because of Anurag Kashyap. She trusts him completely. The song is choreographed by Ashley Lobo and it took her two days to of rehearsals to get her steps right before shooting it.


text:
Infrastructure and Nautical Highways »
DOTr eyes completion of Davao High Priority Bus System in 3Q 2023
Author Topic: DOTr eyes completion of Davao High Priority Bus System in 3Q 2023 (Read 302 times)
By Raymond Carl Dela Cruz August 17, 2021, 5:37 pm
https://www.pna.gov.ph/articles/1150735
MANILA – Department of Transportation (DOTr) Secretary Arthur Tugade on Tuesday said planning for the Davao High Priority Bus System (HPBS), also known as the Davao Public Transport Modernization Project, is ongoing and is expected to be fully operational by the third quarter of 2023.
In a Facebook post, Tugade said conceptual engineering designs to preliminary engineering design and loan processing for the HPBS are currently ongoing.
He said the project is made up of three major components—public transport system improvement, institutional capacity strengthening, and social development program.
"This project aims to provide the Davaoeñeos a modern and reliable high priority bus system, as well as deliver a much-improved public transport infrastructure and services," Tugade said.
The HPBS, he said, will prioritize interconnected bus services along its 626-kilometer road network.
"It encompasses the development of 5 depots, 3 terminals, a driving school, along with the installation of 1,075 bus stops and other pedestrian improvements," Tugade said.
The project is expected to break ground by the second quarter of 2022 and is capable of serving 800,000 passengers per day once completed.
"This is what we call holistic infrastructure development. This is a testament that our projects are not concentrated in Central Luzon alone—we are also bringing inclusive transport development to the Visayas and Mindanao," Tugade said. (PNA)

redpajama_set_name: RedPajamaCommonCrawl


The car key replacement we use in Shantonagh are experts in lock repairs and replacements for both domestic and commercial clients. Our focus on customer service and value for money makes us the number one choice for major companies and home owners alike!
So if you're locked out of your house or you've lost your keys in Shantonagh, if you're having problems locking your doors or need a broken window boarded we are here to help 24 hours a day, seven days a week.
Do they offer car key replacement in Shantonagh?
Determine the costs for any car key replacement Shantonagh services before any works being completed. Along these lines, you are not got out by substantial bills you have nothing to do with.
Check whether a locksmith offers free gauges as a feature of their car key replacement Shantonagh services. Once more, this keeps any false impressions over installment before work is started.
Whether you are locked out of your car, home, or need a brand-new set of locks installed, you'll want to make certain to work with a trustworthy locksmith. BBB recommends finding a dependable locksmith before one is needed.
Locksmithing generally needs some kind of apprenticeship, though formal education can differ anywhere from a certificate to a diploma from an engineering college. Locksmiths can have a physical storefront or be mobile. Lots of locksmiths deal with not just locks themselves, however other existing door hardware, consisting of door hinges, frame repair work, or making keys. Associated Locksmiths of America (aloa.org) is a worldwide organization of locksmiths and other physical security professionals. There is an application process, background check, and application and charges fees which should exist in order to join.
Ask For Recommendations. Contact buddies, relative, and neighbors for recommendations of respectable locksmiths in your area. Be sure to confirm the physical address of any locksmith you find and ensure the address is actually local. See bbb.org/indy for a listing of accredited locksmiths, to read BBB Business Reviews and Customer Reviews from previous clients. Make certain business does not have any unanswered/unresolved complaints.
Call business. Beware if business addresses the phone with a generic expression like "locksmith services". Ask what their legal company name is and if they are unable to give it to you, look somewhere else for a locksmith. Search for a company that responds to the phone with their particular organisation name.
Ask for an Estimate. Prior to having actually the locksmith concerned your house or car, make certain to get a price quote that includes the expense of all labor and the replacement parts for the lock. Trusted locksmiths will have the ability to provide you a price quote over the phone.
Ask about additional charges including: if you will be charged additional for services in the middle of the night or weekends or if there is a charge by the millage they should travel. If once the locksmith arrives they are charging a higher rate than on the phone, don't allow them to begin working. Beware to never ever sign a blank file to license work.
Check Credentials. Make sure that the locksmith you hire is guaranteed so you will be covered in case the repair work causes damages. Upon arrival, ask the locksmith to provide recognition and/or an organisation card. It's also essential to check if business name and logo design on their company cards match the name and logo on the billing and vehicle. A respectable locksmith will likewise ask for to see your recognition to make sure it's actually your house they are doing work on.
Save Their Information. After the locksmith has actually completed the task, get a made a list of invoice that consists of: parts, labor, mileage, and other charges and save this document for future reference. If you think you have discovered a reputable locksmith, you need to keep business' name and information saved in your wallet or mobile phone in case their services are required in the future.
Offering a low rate for the repair then raising the rate on the labor or including mileage expenditure to the task.
Claiming a lock is not able to be selected, then drilling it off and replacing it with a pricey replacement lock.
Utilizing a local, legitimate locksmith organisation details such as an address and/or a similar sounding name when business is actually located in another city or state.
Spoofing any regional phone number, when your call is truly directed to a call center who then provides a "mobile specialist."
Whether it's for a prepared home improvement, or an emergency situation lock-out situation, utilizing a reliable locksmith is important. Do your homework before hiring a locksmith for non-emergency situations and have a locksmith's contact details that you have actually currently researched useful for those emergency situation scenarios.
Dyno Lock car key replacement Shantonagh is your emergency locksmith security company. We are an emergency 24 hour locksmith give us a Call Its Free: 1800 800 800.


text:
Colorado Rapids offensive woes continue in 2-0…
Colorado Rapids offensive woes continue in 2-0 loss at Orlando City
Colorado (1-5-1) only had three shots, just one on target
PUBLISHED: April 29, 2017 at 10:29 p.m. | UPDATED: April 29, 2017 at 11:14 p.m.
ORLANDO, Fla. — Carlos Rivas scored from distance midway through the second half, Joe Bendik only had to make one save to earn his third shutout and Orlando City remained unbeaten at home with a 2-0 win over the Colorado Rapids on Saturday.
"We weren't really threatening their goal a whole lot," Rapids coach Pablo Mastroeni said. "And I think that was a difference."
Kaká, former World Player of the year who has been out since injuring his hamstring in the season opener, subbed in at the 60-minute mark and provided the clincher for Eastern Conference leading Orlando (6-1-0), which is 5-0 at home, in stoppage time.
BOX SCORE: Orlando City 2, Colorado Rapids 0
"When (Carlos) Rivas and Kaká came into the game the fans got behind them a bit and really changed the game through their dynamic play," Mastroeni said.
Rivas notched his first goal of the season in the 70th minute, a left-footed rocket from outside the box into the upper right corner that left Zac MacMath flatfooted. The game was the final of a three-game suspension for Rapids starting keeper Tim Howard.
April 28, 2017 Son of African refugees, Swedish-born Mohammed Saeid finds a home with Colorado Rapids
April 26, 2017 Continuing scoring woes keep Colorado Rapids in Western Conference cellar
April 25, 2017 Colorado Rapids player salaries 2017
Colorado (1-5-1) only had three shots, just one on target. It was only the 16th on-target ball for the Rapids this season. Going into the day, Colorado was last in the league in on-target shots by nine.
"We get into a lot of good areas and then it seems to fizzle out," Mastroeni said. "We're not brave enough in that last third engaging people, taking people on, looking for combinations."
A minute into stoppage time, Cyle Larin put a shot off the post but Kaká was in position to tap in the rebound.
"It has been a tough string of results and the guys just have to remain positive," Rapids fullback Mekeil Williams said. "We cannot feel sorry for ourselves we just have to find ways to build and move forward."
More Rapids news
Zac MacMath
More in Colorado Rapids
Rapids trade up in MLS SuperDraft, select Clemson midfielder Philip Mayaka
Rapids acquire wing Michael Barrios in trade with FC Dallas
Rapids agree to deal with forward Jonathan Lewis that runs through 2024 season
Rapids sign defender Auston Trusty to new contract through 2023


"The brave man carves out his fortune, and every man is the son of his own works."
"None but a coward dares to boast that he has never known fear."
"All the ill that is in us comes from fear, and all the good from love."
"Desperate times call for desperate measures."
"Who is all-powerful should fear everything."
"Fear is that little darkroom where negatives are developed."
"The surest way to prevent war is not to fear it."
"Part of being a hero is knowing when you don't need to be one anymore."
"Shame arises from the fear of men, conscience from the fear of God."
"Fear cannot be without hope nor hope without fear."
"I base my calculations on the expectation that luck will be against me."
"A man of character in peace is a man of courage in war."
"Have the courage to live. Anyone can die."
"It is in great dangers that we see great courage."
"Courage is like love; it must have hope to nourish it."
"God give me the serenity to accept things which cannot be changed; Give me courage to change things which must be changed ;And the wisdom to distinguish one from the other."
"If we survive danger it steels our courage more than anything else."
"Marriage is the only adventure open to the cowardly."
"A brave man dies but once, a coward many times."
"Courage, above all things, is the first quality of a warrior."
"Courage is like a muscle. We strengthen it with use."
"If you want to conquer fear, don't sit at home and think about it. Go out and get busy."
"Sometimes it keeps us alive hope, sometimes habit, and sometimes fear. In the first case this is life, in the other vegetation, in the third hell."
"Life is a jar, where the honey is just a thin layer on top."
"The man who has ceased to fear has ceased to care."
"Fear of death keeps us from living, not from dying."
"Those who fled will fight another time."
Tertullian "De fuga in persecutione"
"Conscience and cowardice are really the same things. Conscience is the trade name of the firm, that is all."
"The courage of a soldier is found to be the cheapest and most common quality of human nature."
Edward Gibbon "The Decline and Fall of the Roman Empire"
"It is not power that corrupts but fear. The fear of losing power corrupts those who wield it, and fear of the scourge of power corrupts those who are subject to it."
F. Scott Fitzgerald "The Crack-Up, Notebook E"
"Hatred is the coward's revenge for being intimidated."
Bertolt Brecht "Life of Galileo"
"And the simple step of a simple courageous man is not to take part in the lie, not to support deceit. Let the lie come into the world, even dominate the world, but not through me."
"Of all the liars in the world, sometimes the worst are your own fears."
"Fear is the main source of superstition, and one of the main sources of cruelty."
"If people are good only because they fear punishment, and hope for reward, then we are a sorry lot indeed."
"Courage is the path that leads from fear to action."
"Falsehood is invariably the child of fear in one form or another."
Aleister Crowley "The Confessions of Aleister Crowley"


LEAD WITH INTEGRITY: What Are You Eating?
As a child growing up, I often saw signs, public service announcements, and billboards with the slogan, "You are what you eat." A few years ago, I saw similar media productions promoting milk. The general theme of these ads emphasized the impact food we eat has on our body. Today, I encourage you to consider the same concept for feeding our minds. What are you eating as mental food, and how is it impacting your mind and helping you grow as a leader?
Feeding our minds as leaders is critical to leadership, business and personal growth. The stronger our minds are, the more equipped we are to battle the adversity we face in leadership, see the challenges ahead of us, and take advantage of opportunities that come our way.
Imagine your mind as a boxer preparing for a championship fight. In the days and weeks leading up to the fight, the boxer can feast on unhealthy foods and desserts. While this diet may be enjoyable, it will not give the boxer the fuel needed to successfully compete in the fight. Imagine that same boxer loaded up on a healthy diet, full of nutrient-rich foods that strengthen his body on a consistent schedule. This "nutrient-rich" boxer will be much better prepared to compete and win.
We are what we eat, is part of the story. The full story is we are what we consume, mentally, physically and spiritually. Positive mental food is also critical to the success of a leader. Where do we find this food? It is everywhere, we just have to look for it.
I am amazed at how many free articles, videos, books and podcasts exist on leadership, business and other topics that can help leaders grow. A simple internet search can yield hours of worthwhile, good mental food for you to consume. The opportunity for us is to schedule time to consistently feed our minds. Watch a video by one of your favorite speakers, read an article by a renowned expert, or read a book by your favorite, best-selling author. After you do one of these, set a schedule to do more. Be able to answer the question: "What are you eating?" with great pride.


Note: Elizabeth is agender and prefers the pronoun "they".
Elizabeth Welch has a degree in graphic design, is pursuing a degree in biochemical engineering and physics from the University of Michigan, loves to read and cook and has a fulfilling, well-rounded life.
A few years ago, that was not the case.
Elizabeth is diagnosed with Anti-Social Personality Disorder (ASPD), and Schizo-Effective Disorder. A few years ago, Elizabeth "would not leave the house for anything". "I used to count everything; slates in the floor, ceiling tiles. I could tell you how many were in a room." The isolation and refusal to interact with people held Elizabeth back in their career and in school. They did not have friends, and recalls having imaginary friends to fill the void.
Fortunately, Elizabeth came to CNS Healthcare and began receiving case management services and new medication.
Elizabeth has benefited from the case management program at CNS Healthcare , which links consumers to CNS Healthcare and community resources and events. They participate in the peer-led Free to Be Me Group, and attended the CNS Healthcare Thanksgiving celebration.
Consent was given by consumers and patients to share their stories and in some instances, names have been changed to protect their privacy.


text:
"On my part, I remain committed to the process of dialogue. It is my firm belief that dialogue and a willingness to look with honesty and clarity at the reality of Tibet can lead us to a viable solution."
US No. 2 diplomat meets with Dalai Lama for talks
WASHINGTON, 19 Oct (AP) : The Dalai Lama met with a senior U.S.
diplomat, continuing a swing through Washington that China says has
undermined its relations with the United States.
Deputy Secretary of State John Negroponte met with the exiled Tibetan
spiritual leader Friday to discuss the situation in Tibet and the
Dalai Lama's work on behalf of his followers, said Rob McInturff, a
State Department spokesman.
China is furious over the U.S. Congress' award to the Dalai Lama of
its highest civilian honor, personally bestowed by President George W.
Bush in a ceremony Wednesday.
China is demanding Washington stop supporting the Buddhist monk and
that it act to repair ties.
The Dalai Lama is considered a figure of moral authority in much of
the world, but China reviles him as a Tibetan separatist. The
72-year-old monk and Nobel Peace Prize laureate has reiterated in
Washington that he wants "real autonomy" for Tibet, not independence.


The funny thing about a dream is that unless you take action it will remain a dream. Without action Dream is ephemeral. Dream is far-off. Dream is someday… When you follow your dream and it starts to happen it becomes reality and reality is hard work.
I was working at a horrible (absolutely soul-sucking, mind-twisting, wretched) job and, in a moment of despair, wondered about what life would look like if I were truly happy. Would that mean another job? Well, yes, but that would only make me happy in the short term. Was it moving to another city? Not really, I love New York and there's really no reason to just up and leave… What would be The Thing that would allow me to relax my shoulders, lose the scrunched up look to my face, sleep at night? Sailing around the world on a sailboat. The answer came to me almost as quickly as I asked myself the question. In a flash I could see the blue water, feel the sun and the wind, I could almost taste the salt air. In that instant I had found my dream.
So, a dream goes on. I told my Better Half about it when I got home that night. The sea virtually flows in his veins but he had never ventured to suggest such a thing to me. He was excited. I was excited. We looked at a really, really expensive boat that was pretty but didn't sail worth a darn. We got a little less excited when we figured on how much of a payment that would be. We didn't want a boat payment; we wanted to be free. Reality set in. Maybe in a few years. Maybe if our business takes off. Maybe, maybe, maybe… I got a new and much better job. I kept the dream as a little spark, a little jewel in the back of my mind that I could take out and examine once in a while. But it started to tarnish. It started to fade. I thought about all the reasons why it was a stupid dream. It was hard. It couldn't be done. We renewed the lease on our apartment. Comfort and ease and familiarity were winning.
Then: Christmas. All the trappings and gee gaws and bustle and stress and money and expectations came rushing into our lives full force. I, again, had a vision: an alternative to the madness; a different Christmas's celebration aboard our boat. Nothing but some pine boughs wrapped around the mast, some ornaments and a nice breakfast. The dream was back. It was strong and it wouldn't let go of my mind.
It's been said Where there's a will there's a way. This is true. Sometimes all it takes is to be open to the possibilities of what hasn't been considered before. I had the Will, my brain gave me the Way. No financial advisor is going to suggest this Way (then again, I would say that no financial advisor is going to suggest much of what we're doing. Read what I write at your own risk). We scraped together what we could and we bought a boat. A boat that sails (we hope). A boat that immediately felt like Home.
Now, buying a boat is awesome if you're going to sail your boat on the weekends and love it and come back to your house full of all the things you have collected throughout your life. Buying a boat is scary if you're going to live on your boat and you have to get rid of almost everything you have collected throughout your life. No furniture is needed (note: sell furniture). No large wall spaces (note: sell or store artwork). Not a lot of storage (note: purge like you're saving your most treasured possessions from a fire). Where does that leave us? We have sold most of our furniture and are in the process of selling the rest of it. We are paring down our clothes, kitchen items, books, knick-knacks, art… What's left? A lot. We have found someone to take on a new lease on our apartment and we have 25 days left until they move in.
There have been dark moments, to be sure. The day I decided that there was no possible way for any of this to be accomplished was particularly rough. How is this ever going to work?!?!? The funny thing is that I know in my soul that we are on the right path. Everything is falling into place even better than we could have planned it to. There are no insurmountable obstacles. My head sometimes gets in the way but we own a boat. A boat that is going to be our new home. A boat that we love. A boat that is the manifestation of a dream. There's no going back.
Ooh, I can relate to so much of this. We bought a dilapidated boat and my husband renovated her completely. I had to get rid of everything, all my clothes, possessions, furniture. I know how you must have felt! Now we live aboard permanently and dont have a home on land. We don't have much money, but we are free!
Ultimately, stuff is just stuff, isn't it? For me it all came down to perspective and priorities… That being said, it ain't easy!


text:
Q: List of variables in an EJS template I'm using espress.js and the ejs template engine.
I'm trying to get a list of variables sent to the view...
Here a kind of controller :
    homeAction(req, res) {
            res.render('index', {form: this.renderForm('aForm'), title: "My Super Title" });
    }

In this function, I send two variables, form and title.
Is there a way to access in my view.ejs to a kind of context where all variables sent to the view are listed ?

A: As @Intervalia says, you should be using a super-object which contains all your variables. But if you absolutely cannot do that, you can try using the internal variable locals which has all your variables (in your template, you can use locals.form etc). Note that this is internal to EJS, and might change/be removed with future releases of EJS so depending on this for production code is a bad idea.

redpajama_set_name: RedPajamaStackExchange


text:
In Iowa stop, President Trump says EU trade talks will help Midwest farmers
President Donald Trump participates in a tour of an advanced manufacturing lab with Ivanka Trump, right, and Gov. Kim Reynolds, R-Iowa, second from left, at Northeast Iowa Community College, Thursday, July 26, 2018, in Peosta, Iowa. (AP Photo/Evan Vucci)
President Donald Trump on Thursday trumpeted his trade deal with European allies, hailing it as a benefit to Iowa farmers who have been hurt by the fallout from his protectionist trade measures.
PEOSTA, Iowa (AP) — President Donald Trump on Thursday trumpeted his trade deal with European allies, hailing it as a benefit to Iowa farmers who have been hurt by the fallout from his protectionist trade measures.
Trump said during a roundtable discussion at Northeast Iowa Community College that his White House meetings Wednesday with the European Union had helped the two sides avoid a trade dispute and would open up new markets for American agriculture.
"We just opened up Europe for you farmers. You're not going to be too angry with Trump, I can tell you," the president said at the workforce development event, where he was joined by two Iowa Republicans, Gov. Kim Reynolds and Rep. Rod Blum.
Trump and European Union Commission President Jean-Claude Juncker agreed to open talks to tear down trade barriers and address U.S. tariffs on steel imports. Trump also said the EU had agreed to buy more soybeans from American farmers, who have seen prices decline sharply since China imposed retaliatory tariffs.
Farmers and manufacturers have criticized tariffs imposed by Trump, warning that they will spur a global trade war and retaliatory tariffs from countries like China, Mexico and Canada that will damage their livelihoods and raise prices on consumers.
Iowa is among the nation's leading producers of soybeans, and the Northeast Iowa event came on the heels of the Agriculture Department's announcement of $12 billion in temporary aid to help farmers deal with retaliatory tariffs from U.S. trading partners.
Trump was accompanied on his Midwest trip by Ivanka Trump, his daughter and senior adviser, who said the president planned to sign legislation next week to reauthorize a program that provides money for job training and related programs for students.
Congress last authorized the Carl D. Perkins Career and Technical Education Act in 2006. Lawmakers passed the bill Wednesday.
Ivanka Trump said it would help 11 million students and workers across the country acquire the technical skills they need to thrive in an increasingly digital economy. After she said Trump would sign the bill, the president joked: "Unless I don't sign it. Maybe I'll veto it."
Trump was meeting later Thursday with steelworkers in Granite City, Illinois, where U.S. Steel recently announced it was firing up a furnace at Granite City Works that had been idled for more than two years. The company credited Trump's tariffs on imported steel and aluminum for helping it re-open the steel mill east of St. Louis.
The president was scheduled to tour Granite City Works and address workers at the company's steel coil warehouse.
Trump's tariffs have been criticized by business leaders and members of Congress who say they could hurt companies that use steel and aluminum in their manufacturing and raise prices for consumers.
Tariffs threaten more than $3.8 billion in Illinois exports, according to the U.S. Chamber of Commerce, and major companies including Caterpillar and Boeing already have been negatively affected.
Commerce Secretary Wilbur Ross, briefing reporters aboard Air Force One, said more jobs have been created by the steel and aluminum tariffs than are being lost and he said the tariffs were instrumental in the EU talks.
"This is a real vindication that the president's trade policy is starting to work," Ross said.
The more than 2,000 workers laid off from Granite City Works were given notice just before Thanksgiving 2015. U.S. Steel cited low oil prices — because the mill produces steel for oil refineries and the auto industry — as well as the availability of cheap, imported steel.
Granite City Works is now near its 2015 employment level of 2,100, with a second blast furnace to be operating by this fall. Jobs there mean dozens more at steel-processing plants throughout the city that bend, cut, coat or reshape the raw product, said James Amos, Granite City's economic development director.
Associated Press writers Ken Thomas and Darlene Superville in Washington and Sara Burnett in Chicago contributed.
Iowa governor to talk trade with President Trump
President Trump announces "zero tariffs" trade pledge with EU
International trade war concerns farmers
Iowa supporters sticking with President Trump despite trade war fallout
Vice President to talk taxes in Iowa
Midwest tourism awards for North Iowa
Klobuchar taking campaign to Midwest states that President Trump won
Farmers prefer Trump do trade deals than hand them cash
Taking aim at Midwest voters, Sen. Klobuchar makes campaign stop in North Iowa


1	.	The skates haven't been brought back.
2	.	At the station he was met by the man from the travel bureau.
3	.	I am often invited to the theatre.
4	.	This book was translated into French.
5	.	The work was being done from 4 till 5 yesterday.
6	.	The truth had been told.
7	.	A new medicine was prescribed by the doctor.
8	.	The large shopping centre is being built in our town.
9	.	We will be invited to his place, I'm sure.
10	.	The teacher was interrupted.
11	.	The telegram was received yesterday.
12	.	America was discovered by Columbus.
13	.	The letters have been typed by the secretary.
14	.	Tennis was being played from 4 to 5 yesterday.
15	.	The dishes are often washed by me.
16	.	Your luggage will be brought by the porter.
17	.	The text was translated at the last lesson.
18	.	All the texts were looked through yesterday and not a single mistake had been found.
19	.	The doctor will be sent for.
2. Open the brackets using the Passive Voice.
1	.	The telegram (receive) tomorrow.
2	.	I (give) a very interesting book last week.
4	.	Nick (invite) to the conference last week.
5	.	Flowers (sell) in the shops.
6	.	This text (translate) from 5 p.m. till 7 p.m. yesterday.
7	.	Our mother already (give) a present.
8	.	The letter (send) before they arrived.
9	.	His new book (finish) by next year.
10	.	Many houses (burn) during the fire.
11	.	Doctors (give) a new pay rise by the government.
12	.	Usually I (pay) my salary twice a month.
13	.	Switch on the radio. The President's speech (broadcast) now.
14	.	My husband just (offer) an interesting job in this firm.
15	.	For two years Tyler (tell) that his brother was dead.
16	.	The injured man couldn't walk and had (carry).
17	.	She (ask) to come here tomorrow, too.
18	.	The museum (not open) by last April.
19	.	Brian told me he (rob) in the street.
1. Коньки еще не вернули.
2. На вокзале его встретил человек из бюро путешествий.
3. Меня часто приглашают в театр.
4. Эта книга была переведена на французский язык.
5. Работу выполняли вчера с 4 до 5.
7. Новое лекарство было назначено врачом.
8. Новый торговый центр строится в нашем городе.
9. Нас пригласят к нему, я уверен.
10. Учителя перебили во время разговора.
12. Америка была открыта Колумбом.
13. Письма были напечатаны секретарем.
14. В теннис играли вчера с 4 до 5.
15. Посуду обычно мою я.
16. Ваш багаж отнесет носильщик.
17. Этот текст был переведен на прошлом уроке.
18. Все тексты просмотрели вчера, и ни одна ошибка не была обнаружена.
2. Раскройте скобки, используя страдательный залог.


text:
by Michael Sitver · July 16
Entrepreneur Pieter Levels has a history of odd, entertaining products. Among my personal favorites are Go Fucking Do It (a motivation tool) and GifBook (Turn GIFs into flipbooks). His products are fun to use, but often they are more "startup as art" than " daily must-use". They pay his bills and make people happy, but they aren't essential.
His latest project, Hoodmaps.com, has me stumped. It falls between those two categories, and which way it goes is anyone's guess.
The idea is cool: crowdsourced, (almost) un-censored neighborhood maps. When you visit a new city, you want to know where to stay, where to visit, and where to work. The contributors to Hoodmaps have you covered.
In many cities, especially my current home-town (Chicago), you also need to know where not to go. Where you will get mugged, robbed, or worse. Hoodmaps has you covered there too.
This is a map of my neighborhood.
@levelsio Nailed my neighborhood in Chicago pic.twitter.com/q1nwOHqssH
— Michael Sitver 🇺🇸 (@msitver) July 16, 2017
It tells you (in a wonderfully candid way) not to go to Washington Park, which is something that Google and Apple maps could never (but absolutely should) say.
Also highlighted are the main attractions of the area, the university and the museums, and the generally ugly student apartments above. Hoodmaps, and its contributors, do a good job of boiling down a neighborhood. That is why I think this product has potential to be the travel guide of the future. If I could get a complete picture of a city with a few swipes of a map, I would use Hoodmaps wherever I went.
The challenge is, Hoodmaps has a long way to go. Community-driven products thrive on scale, and data, and as a young product it hasn't yet benefited from a massive number of contributors. My neighborhood in DC, where I'm spending the summer, is entirely empty of captioning. Many other areas of the city are too.
Right now, Hoodmaps gives you the "god view" of a neighborhood. It hasn't mastered the details. It may tell you "neighborhood of hipsters", but it won't show you where to get coffee, or where to take a date. The way data is displayed (the shading, the captions) could also use refining. (Side note: There's actually a lot of fascinating history behind why maps display data as they do)
Still, Hoodmaps can be a winner. Watching Pieter Levels transform his most successful project to-date, Nomadlist, from a spreadsheet to a fully functioning search engine and community has given me confidence in his skill for iteration and community building.
If the interface becomes a bit clearer and every city develops a community of passionate contributors to fill in the blanks on the map, Hoodmaps could find its way into my daily toolkit. I look forward to seeing it develop further, but you should give it a try today (and maybe share some knowledge on your city).
Check out your city on Hoodmaps and tweet me what you think.
Powered by Flywheel: Hassle-free wordpress hosting
Michael Sitver
Michael Sitver is a technology insider who has been blogging about technology since 2011. Along the way, he's interviewed founders of innovative startups, and executives from fortune 500 companies, and he's tried dozens or hundreds of gadgets. Michael has also contributed to works featured in Newsday, The San Francisco Chronicle, and the associated press. Michael also occasionally consults, and writes for Seeking Alpha and Yahoo News.
WWDC KeynoteLive Notes Liveblog
by Michael Sitver · Published June 10 · Last modified July 30
Zuckerberg's Next Greatest Creation: Chicken wrapped in bacon inside a duck wrapped in bacon inside a turkey inside a pig
by Michael Sitver · Published July 27 · Last modified July 30
Color Zen Puzzle Game Review
by Michael Sitver · Published July 31 · Last modified August 1


text:
Serial Trump-Hater Barbara Streisand Just Ended Her Own Career
RRJ
Like most of Hollywood's serial Trump-haters, Barbara Streisand isn't the sharpest, or most straight, tool in the shed when it comes to commenting on current events.
Just a few months ago, Streisand accused President Trump of being "indecent."
And yet, in remarks to a British newspaper last week, Streisand appeared to be defending the indecency of the late Michael Jackson, who is accused of sexually molesting little boys.
Trump might have made some lewd locker-room jokes, but that's a far cry from sexually abusing children.
And yet, Streisand thinks Trump's lighter offense makes him "indecent," while Jackson's far more serious crime (if it's true) is somehow justifiable.
In a series of unbelievable answers, Streisand told the Times of London that the two men who are accusing Jackson of molesting them as children were "thrilled" to be invited to a sleepover at the pop legend's compound.
Streisand further insisted that being molested "didn't kill" the boys, and that people must understand that Michael Jackson had particular "sexual needs."
She later tried to feign sympathy for the two boys, but these are kinds of remarks that could effectively end Barbar Streisand's career.
Via Time