text:
package aws

import (
	"fmt"
	"strings"
	"testing"

	"github.com/aws/aws-sdk-go/service/s3"
)

func TestValidateEcrRepositoryName(t *testing.T) {
	validNames := []string{
		"nginx-web-app",
		"project-a/nginx-web-app",
		"domain.ltd/nginx-web-app",
		"3chosome-thing.com/01different-pattern",
		"0123456789/999999999",
		"double/forward/slash",
		"000000000000000",
	}
	for _, v := range validNames {
		_, errors := validateEcrRepositoryName(v, "name")
		if len(errors) != 0 {
			t.Fatalf("%q should be a valid ECR repository name: %q", v, errors)
		}
	}

	invalidNames := []string{
		// length > 256
		"3cho_some-thing.com/01different.-_pattern01different.-_pattern01diff" +
			"erent.-_pattern01different.-_pattern01different.-_pattern01different" +
			".-_pattern01different.-_pattern01different.-_pattern01different.-_pa" +
			"ttern01different.-_pattern01different.-_pattern234567",
		// length < 2
		"i",
		"special@character",
		"different+special=character",
		"double//slash",
		"double..dot",
		"/slash-at-the-beginning",
		"slash-at-the-end/",
	}
	for _, v := range invalidNames {
		_, errors := validateEcrRepositoryName(v, "name")
		if len(errors) == 0 {
			t.Fatalf("%q should be an invalid ECR repository name", v)
		}
	}
}

func TestValidateCloudWatchEventRuleName(t *testing.T) {
	validNames := []string{
		"HelloWorl_d",
		"hello-world",
		"hello.World0125",
	}
	for _, v := range validNames {
		_, errors := validateCloudWatchEventRuleName(v, "name")
		if len(errors) != 0 {
			t.Fatalf("%q should be a valid CW event rule name: %q", v, errors)
		}
	}

	invalidNames := []string{
		"special@character",
		"slash/in-the-middle",
		// Length > 64
		"TooLooooooooooooooooooooooooooooooooooooooooooooooooooooooongName",
	}
	for _, v := range invalidNames {
		_, errors := validateCloudWatchEventRuleName(v, "name")
		if len(errors) == 0 {
			t.Fatalf("%q should be an invalid CW event rule name", v)
		}
	}
}

func TestValidateLambdaFunctionName(t *testing.T) {
	validNames := []string{
		"arn:aws:lambda:us-west-2:123456789012:function:ThumbNail",
		"arn:aws-us-gov:lambda:us-west-2:123456789012:function:ThumbNail",
		"FunctionName",
		"function-name",
	}
	for _, v := range validNames {
		_, errors := validateLambdaFunctionName(v, "name")
		if len(errors) != 0 {
			t.Fatalf("%q should be a valid Lambda function name: %q", v, errors)
		}
	}

	invalidNames := []string{
		"/FunctionNameWithSlash",
		"function.name.with.dots",
		// length > 140
		"arn:aws:lambda:us-west-2:123456789012:function:TooLoooooo" +
			"ooooooooooooooooooooooooooooooooooooooooooooooooooooooo" +
			"ooooooooooooooooongFunctionName",
	}
	for _, v := range invalidNames {
		_, errors := validateLambdaFunctionName(v, "name")
		if len(errors) == 0 {
			t.Fatalf("%q should be an invalid Lambda function name", v)
		}
	}
}

func TestValidateLambdaQualifier(t *testing.T) {
	validNames := []string{
		"123",
		"prod",
		"PROD",
		"MyTestEnv",
		"contains-dashes",
		"contains_underscores",
		"$LATEST",
	}
	for _, v := range validNames {
		_, errors := validateLambdaQualifier(v, "name")
		if len(errors) != 0 {
			t.Fatalf("%q should be a valid Lambda function qualifier: %q", v, errors)
		}
	}

	invalidNames := []string{
		// No ARNs allowed
		"arn:aws:lambda:us-west-2:123456789012:function:prod",
		// length > 128
		"TooLooooooooooooooooooooooooooooooooooooooooooooooooooo" +
			"ooooooooooooooooooooooooooooooooooooooooooooooooooo" +
			"oooooooooooongQualifier",
	}
	for _, v := range invalidNames {
		_, errors := validateLambdaQualifier(v, "name")
		if len(errors) == 0 {
			t.Fatalf("%q should be an invalid Lambda function qualifier", v)
		}
	}
}

func TestValidateLambdaPermissionAction(t *testing.T) {
	validNames := []string{
		"lambda:*",
		"lambda:InvokeFunction",
		"*",
	}
	for _, v := range validNames {
		_, errors := validateLambdaPermissionAction(v, "action")
		if len(errors) != 0 {
			t.Fatalf("%q should be a valid Lambda permission action: %q", v, errors)
		}
	}

	invalidNames := []string{
		"yada",
		"lambda:123",
		"*:*",
		"lambda:Invoke*",
	}
	for _, v := range invalidNames {
		_, errors := validateLambdaPermissionAction(v, "action")
		if len(errors) == 0 {
			t.Fatalf("%q should be an invalid Lambda permission action", v)
		}
	}
}

func TestValidateAwsAccountId(t *testing.T) {
	validNames := []string{
		"123456789012",
		"999999999999",
	}
	for _, v := range validNames {
		_, errors := validateAwsAccountId(v, "account_id")
		if len(errors) != 0 {
			t.Fatalf("%q should be a valid AWS Account ID: %q", v, errors)
		}
	}

	invalidNames := []string{
		"12345678901",   // too short
		"1234567890123", // too long
		"invalid",
		"x123456789012",
	}
	for _, v := range invalidNames {
		_, errors := validateAwsAccountId(v, "account_id")
		if len(errors) == 0 {
			t.Fatalf("%q should be an invalid AWS Account ID", v)
		}
	}
}

func TestValidateArn(t *testing.T) {
	v := ""
	_, errors := validateArn(v, "arn")
	if len(errors) != 0 {
		t.Fatalf("%q should not be validated as an ARN: %q", v, errors)
	}

	validNames := []string{
		"arn:aws:elasticbeanstalk:us-east-1:123456789012:environment/My App/MyEnvironment", // Beanstalk
		"arn:aws:iam::123456789012:user/David",                                             // IAM User
		"arn:aws:rds:eu-west-1:123456789012:db:mysql-db",                                   // RDS
		"arn:aws:s3:::my_corporate_bucket/exampleobject.png",                               // S3 object
		"arn:aws:events:us-east-1:319201112229:rule/rule_name",                             // CloudWatch Rule
		"arn:aws:lambda:eu-west-1:319201112229:function:myCustomFunction",                  // Lambda function
		"arn:aws:lambda:eu-west-1:319201112229:function:myCustomFunction:Qualifier",        // Lambda func qualifier
		"arn:aws-us-gov:s3:::corp_bucket/object.png",                                       // GovCloud ARN
	}
	for _, v := range validNames {
		_, errors := validateArn(v, "arn")
		if len(errors) != 0 {
			t.Fatalf("%q should be a valid ARN: %q", v, errors)
		}
	}

	invalidNames := []string{
		"arn",
		"123456789012",
		"arn:aws",
		"arn:aws:logs",
		"arn:aws:logs:region:*:*",
	}
	for _, v := range invalidNames {
		_, errors := validateArn(v, "arn")
		if len(errors) == 0 {
			t.Fatalf("%q should be an invalid ARN", v)
		}
	}
}

func TestValidatePolicyStatementId(t *testing.T) {
	validNames := []string{
		"YadaHereAndThere",
		"Valid-5tatement_Id",
		"1234",
	}
	for _, v := range validNames {
		_, errors := validatePolicyStatementId(v, "statement_id")
		if len(errors) != 0 {
			t.Fatalf("%q should be a valid Statement ID: %q", v, errors)
		}
	}

	invalidNames := []string{
		"Invalid/StatementId/with/slashes",
		"InvalidStatementId.with.dots",
		// length > 100
		"TooooLoooooooooooooooooooooooooooooooooooooooooooo" +
			"ooooooooooooooooooooooooooooooooooooooooStatementId",
	}
	for _, v := range invalidNames {
		_, errors := validatePolicyStatementId(v, "statement_id")
		if len(errors) == 0 {
			t.Fatalf("%q should be an invalid Statement ID", v)
		}
	}
}

func TestValidateCIDRNetworkAddress(t *testing.T) {
	cases := []struct {
		CIDR              string
		ExpectedErrSubstr string
	}{
		{"notacidr", `must contain a valid CIDR`},
		{"10.0.1.0/16", `must contain a valid network CIDR`},
		{"10.0.1.0/24", ``},
	}

	for i, tc := range cases {
		_, errs := validateCIDRNetworkAddress(tc.CIDR, "foo")
		if tc.ExpectedErrSubstr == "" {
			if len(errs) != 0 {
				t.Fatalf("%d/%d: Expected no error, got errs: %#v",
					i+1, len(cases), errs)
			}
		} else {
			if len(errs) != 1 {
				t.Fatalf("%d/%d: Expected 1 err containing %q, got %d errs",
					i+1, len(cases), tc.ExpectedErrSubstr, len(errs))
			}
			if !strings.Contains(errs[0].Error(), tc.ExpectedErrSubstr) {
				t.Fatalf("%d/%d: Expected err: %q, to include %q",
					i+1, len(cases), errs[0], tc.ExpectedErrSubstr)
			}
		}
	}
}

func TestValidateHTTPMethod(t *testing.T) {
	type testCases struct {
		Value    string
		ErrCount int
	}

	invalidCases := []testCases{
		{
			Value:    "incorrect",
			ErrCount: 1,
		},
		{
			Value:    "delete",
			ErrCount: 1,
		},
	}

	for _, tc := range invalidCases {
		_, errors := validateHTTPMethod(tc.Value, "http_method")
		if len(errors) != tc.ErrCount {
			t.Fatalf("Expected %q to trigger a validation error.", tc.Value)
		}
	}

	validCases := []testCases{
		{
			Value:    "ANY",
			ErrCount: 0,
		},
		{
			Value:    "DELETE",
			ErrCount: 0,
		},
		{
			Value:    "OPTIONS",
			ErrCount: 0,
		},
	}

	for _, tc := range validCases {
		_, errors := validateHTTPMethod(tc.Value, "http_method")
		if len(errors) != tc.ErrCount {
			t.Fatalf("Expected %q not to trigger a validation error.", tc.Value)
		}
	}
}

func TestValidateLogMetricFilterName(t *testing.T) {
	validNames := []string{
		"YadaHereAndThere",
		"Valid-5Metric_Name",
		"This . is also %% valid@!)+(",
		"1234",
		strings.Repeat("W", 512),
	}
	for _, v := range validNames {
		_, errors := validateLogMetricFilterName(v, "name")
		if len(errors) != 0 {
			t.Fatalf("%q should be a valid Log Metric Filter Name: %q", v, errors)
		}
	}

	invalidNames := []string{
		"Here is a name with: colon",
		"and here is another * invalid name",
		"*",
		// length > 512
		strings.Repeat("W", 513),
	}
	for _, v := range invalidNames {
		_, errors := validateLogMetricFilterName(v, "name")
		if len(errors) == 0 {
			t.Fatalf("%q should be an invalid Log Metric Filter Name", v)
		}
	}
}

func TestValidateLogMetricTransformationName(t *testing.T) {
	validNames := []string{
		"YadaHereAndThere",
		"Valid-5Metric_Name",
		"This . is also %% valid@!)+(",
		"1234",
		"",
		strings.Repeat("W", 255),
	}
	for _, v := range validNames {
		_, errors := validateLogMetricFilterTransformationName(v, "name")
		if len(errors) != 0 {
			t.Fatalf("%q should be a valid Log Metric Filter Transformation Name: %q", v, errors)
		}
	}

	invalidNames := []string{
		"Here is a name with: colon",
		"and here is another * invalid name",
		"also $ invalid",
		"*",
		// length > 255
		strings.Repeat("W", 256),
	}
	for _, v := range invalidNames {
		_, errors := validateLogMetricFilterTransformationName(v, "name")
		if len(errors) == 0 {
			t.Fatalf("%q should be an invalid Log Metric Filter Transformation Name", v)
		}
	}
}

func TestValidateLogGroupName(t *testing.T) {
	validNames := []string{
		"ValidLogGroupName",
		"ValidLogGroup.Name",
		"valid/Log-group",
		"1234",
		"YadaValid#0123",
		"Also_valid-name",
		strings.Repeat("W", 512),
	}
	for _, v := range validNames {
		_, errors := validateLogGroupName(v, "name")
		if len(errors) != 0 {
			t.Fatalf("%q should be a valid Log Metric Filter Transformation Name: %q", v, errors)
		}
	}

	invalidNames := []string{
		"Here is a name with: colon",
		"and here is another * invalid name",
		"also $ invalid",
		"This . is also %% invalid@!)+(",
		"*",
		"",
		// length > 512
		strings.Repeat("W", 513),
	}
	for _, v := range invalidNames {
		_, errors := validateLogGroupName(v, "name")
		if len(errors) == 0 {
			t.Fatalf("%q should be an invalid Log Metric Filter Transformation Name", v)
		}
	}
}

func TestValidateS3BucketLifecycleTimestamp(t *testing.T) {
	validDates := []string{
		"2016-01-01",
		"2006-01-02",
	}

	for _, v := range validDates {
		_, errors := validateS3BucketLifecycleTimestamp(v, "date")
		if len(errors) != 0 {
			t.Fatalf("%q should be valid date: %q", v, errors)
		}
	}

	invalidDates := []string{
		"Jan 01 2016",
		"20160101",
	}

	for _, v := range invalidDates {
		_, errors := validateS3BucketLifecycleTimestamp(v, "date")
		if len(errors) == 0 {
			t.Fatalf("%q should be invalid date", v)
		}
	}
}

func TestValidateS3BucketLifecycleStorageClass(t *testing.T) {
	validStorageClass := []string{
		"STANDARD_IA",
		"GLACIER",
	}

	for _, v := range validStorageClass {
		_, errors := validateS3BucketLifecycleStorageClass(v, "storage_class")
		if len(errors) != 0 {
			t.Fatalf("%q should be valid storage class: %q", v, errors)
		}
	}

	invalidStorageClass := []string{
		"STANDARD",
		"1234",
	}
	for _, v := range invalidStorageClass {
		_, errors := validateS3BucketLifecycleStorageClass(v, "storage_class")
		if len(errors) == 0 {
			t.Fatalf("%q should be invalid storage class", v)
		}
	}
}

func TestValidateS3BucketReplicationRuleId(t *testing.T) {
	validId := []string{
		"YadaHereAndThere",
		"Valid-5Rule_ID",
		"This . is also %% valid@!)+*(:ID",
		"1234",
		strings.Repeat("W", 255),
	}
	for _, v := range validId {
		_, errors := validateS3BucketReplicationRuleId(v, "id")
		if len(errors) != 0 {
			t.Fatalf("%q should be a valid lifecycle rule id: %q", v, errors)
		}
	}

	invalidId := []string{
		// length > 255
		strings.Repeat("W", 256),
	}
	for _, v := range invalidId {
		_, errors := validateS3BucketReplicationRuleId(v, "id")
		if len(errors) == 0 {
			t.Fatalf("%q should be an invalid replication configuration rule id", v)
		}
	}
}

func TestValidateS3BucketReplicationRulePrefix(t *testing.T) {
	validId := []string{
		"YadaHereAndThere",
		"Valid-5Rule_ID",
		"This . is also %% valid@!)+*(:ID",
		"1234",
		strings.Repeat("W", 1024),
	}
	for _, v := range validId {
		_, errors := validateS3BucketReplicationRulePrefix(v, "id")
		if len(errors) != 0 {
			t.Fatalf("%q should be a valid lifecycle rule id: %q", v, errors)
		}
	}

	invalidId := []string{
		// length > 1024
		strings.Repeat("W", 1025),
	}
	for _, v := range invalidId {
		_, errors := validateS3BucketReplicationRulePrefix(v, "id")
		if len(errors) == 0 {
			t.Fatalf("%q should be an invalid replication configuration rule id", v)
		}
	}
}

func TestValidateS3BucketReplicationDestinationStorageClass(t *testing.T) {
	validStorageClass := []string{
		s3.StorageClassStandard,
		s3.StorageClassStandardIa,
		s3.StorageClassReducedRedundancy,
	}

	for _, v := range validStorageClass {
		_, errors := validateS3BucketReplicationDestinationStorageClass(v, "storage_class")
		if len(errors) != 0 {
			t.Fatalf("%q should be valid storage class: %q", v, errors)
		}
	}

	invalidStorageClass := []string{
		"FOO",
		"1234",
	}
	for _, v := range invalidStorageClass {
		_, errors := validateS3BucketReplicationDestinationStorageClass(v, "storage_class")
		if len(errors) == 0 {
			t.Fatalf("%q should be invalid storage class", v)
		}
	}
}

func TestValidateS3BucketReplicationRuleStatus(t *testing.T) {
	validRuleStatuses := []string{
		s3.ReplicationRuleStatusEnabled,
		s3.ReplicationRuleStatusDisabled,
	}

	for _, v := range validRuleStatuses {
		_, errors := validateS3BucketReplicationRuleStatus(v, "status")
		if len(errors) != 0 {
			t.Fatalf("%q should be valid rule status: %q", v, errors)
		}
	}

	invalidRuleStatuses := []string{
		"FOO",
		"1234",
	}
	for _, v := range invalidRuleStatuses {
		_, errors := validateS3BucketReplicationRuleStatus(v, "status")
		if len(errors) == 0 {
			t.Fatalf("%q should be invalid rule status", v)
		}
	}
}

func TestValidateS3BucketLifecycleRuleId(t *testing.T) {
	validId := []string{
		"YadaHereAndThere",
		"Valid-5Rule_ID",
		"This . is also %% valid@!)+*(:ID",
		"1234",
		strings.Repeat("W", 255),
	}
	for _, v := range validId {
		_, errors := validateS3BucketLifecycleRuleId(v, "id")
		if len(errors) != 0 {
			t.Fatalf("%q should be a valid lifecycle rule id: %q", v, errors)
		}
	}

	invalidId := []string{
		// length > 255
		strings.Repeat("W", 256),
	}
	for _, v := range invalidId {
		_, errors := validateS3BucketLifecycleRuleId(v, "id")
		if len(errors) == 0 {
			t.Fatalf("%q should be an invalid lifecycle rule id", v)
		}
	}
}

func TestValidateIntegerInRange(t *testing.T) {
	validIntegers := []int{-259, 0, 1, 5, 999}
	min := -259
	max := 999
	for _, v := range validIntegers {
		_, errors := validateIntegerInRange(min, max)(v, "name")
		if len(errors) != 0 {
			t.Fatalf("%q should be an integer in range (%d, %d): %q", v, min, max, errors)
		}
	}

	invalidIntegers := []int{-260, -99999, 1000, 25678}
	for _, v := range invalidIntegers {
		_, errors := validateIntegerInRange(min, max)(v, "name")
		if len(errors) == 0 {
			t.Fatalf("%q should be an integer outside range (%d, %d)", v, min, max)
		}
	}
}

func TestResourceAWSElastiCacheClusterIdValidation(t *testing.T) {
	cases := []struct {
		Value    string
		ErrCount int
	}{
		{
			Value:    "tEsting",
			ErrCount: 1,
		},
		{
			Value:    "t.sting",
			ErrCount: 1,
		},
		{
			Value:    "t--sting",
			ErrCount: 1,
		},
		{
			Value:    "1testing",
			ErrCount: 1,
		},
		{
			Value:    "testing-",
			ErrCount: 1,
		},
		{
			Value:    randomString(65),
			ErrCount: 1,
		},
	}

	for _, tc := range cases {
		_, errors := validateElastiCacheClusterId(tc.Value, "aws_elasticache_cluster_cluster_id")

		if len(errors) != tc.ErrCount {
			t.Fatalf("Expected the ElastiCache Cluster cluster_id to trigger a validation error")
		}
	}
}

func TestValidateDbEventSubscriptionName(t *testing.T) {
	validNames := []string{
		"valid-name",
		"valid02-name",
		"Valid-Name1",
	}
	for _, v := range validNames {
		_, errors := validateDbEventSubscriptionName(v, "name")
		if len(errors) != 0 {
			t.Fatalf("%q should be a valid RDS Event Subscription Name: %q", v, errors)
		}
	}

	invalidNames := []string{
		"Here is a name with: colon",
		"and here is another * invalid name",
		"also $ invalid",
		"This . is also %% invalid@!)+(",
		"*",
		"",
		" ",
		"_",
		// length > 255
		strings.Repeat("W", 256),
	}
	for _, v := range invalidNames {
		_, errors := validateDbEventSubscriptionName(v, "name")
		if len(errors) == 0 {
			t.Fatalf("%q should be an invalid RDS Event Subscription Name", v)
		}
	}
}

func TestValidateJsonString(t *testing.T) {
	type testCases struct {
		Value    string
		ErrCount int
	}

	invalidCases := []testCases{
		{
			Value:    `{0:"1"}`,
			ErrCount: 1,
		},
		{
			Value:    `{'abc':1}`,
			ErrCount: 1,
		},
		{
			Value:    `{"def":}`,
			ErrCount: 1,
		},
		{
			Value:    `{"xyz":[}}`,
			ErrCount: 1,
		},
	}

	for _, tc := range invalidCases {
		_, errors := validateJsonString(tc.Value, "json")
		if len(errors) != tc.ErrCount {
			t.Fatalf("Expected %q to trigger a validation error.", tc.Value)
		}
	}

	validCases := []testCases{
		{
			Value:    ``,
			ErrCount: 0,
		},
		{
			Value:    `{}`,
			ErrCount: 0,
		},
		{
			Value:    `{"abc":["1","2"]}`,
			ErrCount: 0,
		},
	}

	for _, tc := range validCases {
		_, errors := validateJsonString(tc.Value, "json")
		if len(errors) != tc.ErrCount {
			t.Fatalf("Expected %q not to trigger a validation error.", tc.Value)
		}
	}
}

func TestValidateCloudFormationTemplate(t *testing.T) {
	type testCases struct {
		Value    string
		ErrCount int
	}

	invalidCases := []testCases{
		{
			Value:    `{"abc":"`,
			ErrCount: 1,
		},
		{
			Value:    "abc: [",
			ErrCount: 1,
		},
	}

	for _, tc := range invalidCases {
		_, errors := validateCloudFormationTemplate(tc.Value, "template")
		if len(errors) != tc.ErrCount {
			t.Fatalf("Expected %q to trigger a validation error.", tc.Value)
		}
	}

	validCases := []testCases{
		{
			Value:    `{"abc":"1"}`,
			ErrCount: 0,
		},
		{
			Value:    `abc: 1`,
			ErrCount: 0,
		},
	}

	for _, tc := range validCases {
		_, errors := validateCloudFormationTemplate(tc.Value, "template")
		if len(errors) != tc.ErrCount {
			t.Fatalf("Expected %q not to trigger a validation error.", tc.Value)
		}
	}
}

func TestValidateApiGatewayIntegrationType(t *testing.T) {
	type testCases struct {
		Value    string
		ErrCount int
	}

	invalidCases := []testCases{
		{
			Value:    "incorrect",
			ErrCount: 1,
		},
		{
			Value:    "aws_proxy",
			ErrCount: 1,
		},
	}

	for _, tc := range invalidCases {
		_, errors := validateApiGatewayIntegrationType(tc.Value, "types")
		if len(errors) != tc.ErrCount {
			t.Fatalf("Expected %q to trigger a validation error.", tc.Value)
		}
	}

	validCases := []testCases{
		{
			Value:    "MOCK",
			ErrCount: 0,
		},
		{
			Value:    "AWS_PROXY",
			ErrCount: 0,
		},
	}

	for _, tc := range validCases {
		_, errors := validateApiGatewayIntegrationType(tc.Value, "types")
		if len(errors) != tc.ErrCount {
			t.Fatalf("Expected %q not to trigger a validation error.", tc.Value)
		}
	}
}

func TestValidateSQSQueueName(t *testing.T) {
	validNames := []string{
		"valid-name",
		"valid02-name",
		"Valid-Name1",
		"_",
		"-",
		strings.Repeat("W", 80),
	}
	for _, v := range validNames {
		if errors := validateSQSQueueName(v, "name"); len(errors) > 0 {
			t.Fatalf("%q should be a valid SQS queue Name", v)
		}
	}

	invalidNames := []string{
		"Here is a name with: colon",
		"another * invalid name",
		"also $ invalid",
		"This . is also %% invalid@!)+(",
		"*",
		"",
		" ",
		".",
		strings.Repeat("W", 81), // length > 80
	}
	for _, v := range invalidNames {
		if errors := validateSQSQueueName(v, "name"); len(errors) == 0 {
			t.Fatalf("%q should be an invalid SQS queue Name", v)
		}
	}
}

func TestValidateSQSFifoQueueName(t *testing.T) {
	validNames := []string{
		"valid-name.fifo",
		"valid02-name.fifo",
		"Valid-Name1.fifo",
		"_.fifo",
		"a.fifo",
		"A.fifo",
		"9.fifo",
		"-.fifo",
		fmt.Sprintf("%s.fifo", strings.Repeat("W", 75)),
	}
	for _, v := range validNames {
		if errors := validateSQSFifoQueueName(v, "name"); len(errors) > 0 {
			t.Fatalf("%q should be a valid SQS FIFO queue Name: %v", v, errors)
		}
	}

	invalidNames := []string{
		"Here is a name with: colon",
		"another * invalid name",
		"also $ invalid",
		"This . is also %% invalid@!)+(",
		".fifo",
		"*",
		"",
		" ",
		".",
		strings.Repeat("W", 81), // length > 80
	}
	for _, v := range invalidNames {
		if errors := validateSQSFifoQueueName(v, "name"); len(errors) == 0 {
			t.Fatalf("%q should be an invalid SQS FIFO queue Name: %v", v, errors)
		}
	}
}

func TestValidateSNSSubscriptionProtocol(t *testing.T) {
	validProtocols := []string{
		"lambda",
		"sqs",
		"sqs",
		"application",
		"http",
		"https",
	}
	for _, v := range validProtocols {
		if _, errors := validateSNSSubscriptionProtocol(v, "protocol"); len(errors) > 0 {
			t.Fatalf("%q should be a valid SNS Subscription protocol: %v", v, errors)
		}
	}

	invalidProtocols := []string{
		"Email",
		"email",
		"Email-JSON",
		"email-json",
		"SMS",
		"sms",
	}
	for _, v := range invalidProtocols {
		if _, errors := validateSNSSubscriptionProtocol(v, "protocol"); len(errors) == 0 {
			t.Fatalf("%q should be an invalid SNS Subscription protocol: %v", v, errors)
		}
	}
}

func TestValidateSecurityRuleType(t *testing.T) {
	validTypes := []string{
		"ingress",
		"egress",
	}
	for _, v := range validTypes {
		if _, errors := validateSecurityRuleType(v, "type"); len(errors) > 0 {
			t.Fatalf("%q should be a valid Security Group Rule type: %v", v, errors)
		}
	}

	invalidTypes := []string{
		"foo",
		"ingresss",
	}
	for _, v := range invalidTypes {
		if _, errors := validateSecurityRuleType(v, "type"); len(errors) == 0 {
			t.Fatalf("%q should be an invalid Security Group Rule type: %v", v, errors)
		}
	}
}

func TestValidateOnceAWeekWindowFormat(t *testing.T) {
	cases := []struct {
		Value    string
		ErrCount int
	}{
		{
			// once a day window format
			Value:    "04:00-05:00",
			ErrCount: 1,
		},
		{
			// invalid day of week
			Value:    "san:04:00-san:05:00",
			ErrCount: 1,
		},
		{
			// invalid hour
			Value:    "sun:24:00-san:25:00",
			ErrCount: 1,
		},
		{
			// invalid min
			Value:    "sun:04:00-sun:04:60",
			ErrCount: 1,
		},
		{
			// valid format
			Value:    "sun:04:00-sun:05:00",
			ErrCount: 0,
		},
		{
			// "Sun" can also be used
			Value:    "Sun:04:00-Sun:05:00",
			ErrCount: 0,
		},
		{
			// valid format
			Value:    "",
			ErrCount: 0,
		},
	}

	for _, tc := range cases {
		_, errors := validateOnceAWeekWindowFormat(tc.Value, "maintenance_window")

		if len(errors) != tc.ErrCount {
			t.Fatalf("Expected %d validation errors, But got %d errors for \"%s\"", tc.ErrCount, len(errors), tc.Value)
		}
	}
}

func TestValidateOnceADayWindowFormat(t *testing.T) {
	cases := []struct {
		Value    string
		ErrCount int
	}{
		{
			// once a week window format
			Value:    "sun:04:00-sun:05:00",
			ErrCount: 1,
		},
		{
			// invalid hour
			Value:    "24:00-25:00",
			ErrCount: 1,
		},
		{
			// invalid min
			Value:    "04:00-04:60",
			ErrCount: 1,
		},
		{
			// valid format
			Value:    "04:00-05:00",
			ErrCount: 0,
		},
		{
			// valid format
			Value:    "",
			ErrCount: 0,
		},
	}

	for _, tc := range cases {
		_, errors := validateOnceADayWindowFormat(tc.Value, "backup_window")

		if len(errors) != tc.ErrCount {
			t.Fatalf("Expected %d validation errors, But got %d errors for \"%s\"", tc.ErrCount, len(errors), tc.Value)
		}
	}
}

func TestValidateRoute53RecordType(t *testing.T) {
	validTypes := []string{
		"AAAA",
		"SOA",
		"A",
		"TXT",
		"CNAME",
		"MX",
		"NAPTR",
		"PTR",
		"SPF",
		"SRV",
		"NS",
	}

	invalidTypes := []string{
		"a",
		"alias",
		"SpF",
		"Txt",
		"AaAA",
	}

	for _, v := range validTypes {
		_, errors := validateRoute53RecordType(v, "route53_record")
		if len(errors) != 0 {
			t.Fatalf("%q should be a valid Route53 record type: %v", v, errors)
		}
	}

	for _, v := range invalidTypes {
		_, errors := validateRoute53RecordType(v, "route53_record")
		if len(errors) == 0 {
			t.Fatalf("%q should not be a valid Route53 record type", v)
		}
	}
}

func TestValidateEcsPlacementConstraint(t *testing.T) {
	cases := []struct {
		constType string
		constExpr string
		Err       bool
	}{
		{
			constType: "distinctInstance",
			constExpr: "",
			Err:       false,
		},
		{
			constType: "memberOf",
			constExpr: "",
			Err:       true,
		},
		{
			constType: "distinctInstance",
			constExpr: "expression",
			Err:       false,
		},
		{
			constType: "memberOf",
			constExpr: "expression",
			Err:       false,
		},
	}

	for _, tc := range cases {
		if err := validateAwsEcsPlacementConstraint(tc.constType, tc.constExpr); err != nil && !tc.Err {
			t.Fatalf("Unexpected validation error for \"%s:%s\": %s",
				tc.constType, tc.constExpr, err)
		}

	}
}

func TestValidateEcsPlacementStrategy(t *testing.T) {
	cases := []struct {
		stratType  string
		stratField string
		Err        bool
	}{
		{
			stratType:  "random",
			stratField: "",
			Err:        false,
		},
		{
			stratType:  "spread",
			stratField: "instanceID",
			Err:        false,
		},
		{
			stratType:  "binpack",
			stratField: "cpu",
			Err:        false,
		},
		{
			stratType:  "binpack",
			stratField: "memory",
			Err:        false,
		},
		{
			stratType:  "binpack",
			stratField: "disk",
			Err:        true,
		},
		{
			stratType:  "fakeType",
			stratField: "",
			Err:        true,
		},
	}

	for _, tc := range cases {
		if err := validateAwsEcsPlacementStrategy(tc.stratType, tc.stratField); err != nil && !tc.Err {
			t.Fatalf("Unexpected validation error for \"%s:%s\": %s",
				tc.stratType, tc.stratField, err)
		}
	}
}

func TestValidateStepFunctionActivityName(t *testing.T) {
	validTypes := []string{
		"foo",
		"FooBar123",
	}

	invalidTypes := []string{
		strings.Repeat("W", 81), // length > 80
	}

	for _, v := range validTypes {
		_, errors := validateSfnActivityName(v, "name")
		if len(errors) != 0 {
			t.Fatalf("%q should be a valid Step Function Activity name: %v", v, errors)
		}
	}

	for _, v := range invalidTypes {
		_, errors := validateSfnActivityName(v, "name")
		if len(errors) == 0 {
			t.Fatalf("%q should not be a valid Step Function Activity name", v)
		}
	}
}

func TestValidateStepFunctionStateMachineDefinition(t *testing.T) {
	validDefinitions := []string{
		"foobar",
		strings.Repeat("W", 1048576),
	}

	invalidDefinitions := []string{
		strings.Repeat("W", 1048577), // length > 1048576
	}

	for _, v := range validDefinitions {
		_, errors := validateSfnStateMachineDefinition(v, "definition")
		if len(errors) != 0 {
			t.Fatalf("%q should be a valid Step Function State Machine definition: %v", v, errors)
		}
	}

	for _, v := range invalidDefinitions {
		_, errors := validateSfnStateMachineDefinition(v, "definition")
		if len(errors) == 0 {
			t.Fatalf("%q should not be a valid Step Function State Machine definition", v)
		}
	}
}

func TestValidateStepFunctionStateMachineName(t *testing.T) {
	validTypes := []string{
		"foo",
		"BAR",
		"FooBar123",
		"FooBar123Baz-_",
	}

	invalidTypes := []string{
		"foo bar",
		"foo<bar>",
		"foo{bar}",
		"foo[bar]",
		"foo*bar",
		"foo?bar",
		"foo#bar",
		"foo%bar",
		"foo\bar",
		"foo^bar",
		"foo|bar",
		"foo~bar",
		"foo$bar",
		"foo&bar",
		"foo,bar",
		"foo:bar",
		"foo;bar",
		"foo/bar",
		strings.Repeat("W", 81), // length > 80
	}

	for _, v := range validTypes {
		_, errors := validateSfnStateMachineName(v, "name")
		if len(errors) != 0 {
			t.Fatalf("%q should be a valid Step Function State Machine name: %v", v, errors)
		}
	}

	for _, v := range invalidTypes {
		_, errors := validateSfnStateMachineName(v, "name")
		if len(errors) == 0 {
			t.Fatalf("%q should not be a valid Step Function State Machine name", v)
		}
	}
}

func TestValidateEmrEbsVolumeType(t *testing.T) {
	cases := []struct {
		VolType  string
		ErrCount int
	}{
		{
			VolType:  "gp2",
			ErrCount: 0,
		},
		{
			VolType:  "io1",
			ErrCount: 0,
		},
		{
			VolType:  "standard",
			ErrCount: 0,
		},
		{
			VolType:  "stand",
			ErrCount: 1,
		},
		{
			VolType:  "io",
			ErrCount: 1,
		},
		{
			VolType:  "gp1",
			ErrCount: 1,
		},
		{
			VolType:  "fast-disk",
			ErrCount: 1,
		},
	}

	for _, tc := range cases {
		_, errors := validateAwsEmrEbsVolumeType(tc.VolType, "volume")

		if len(errors) != tc.ErrCount {
			t.Fatalf("Expected %d errors, got %d: %s", tc.ErrCount, len(errors), errors)
		}
	}
}

func TestValidateAppautoscalingScalableDimension(t *testing.T) {
	cases := []struct {
		Value    string
		ErrCount int
	}{
		{
			Value:    "ecs:service:DesiredCount",
			ErrCount: 0,
		},
		{
			Value:    "ec2:spot-fleet-request:TargetCapacity",
			ErrCount: 0,
		},
		{
			Value:    "ec2:service:DesiredCount",
			ErrCount: 1,
		},
		{
			Value:    "ecs:spot-fleet-request:TargetCapacity",
			ErrCount: 1,
		},
		{
			Value:    "",
			ErrCount: 1,
		},
	}

	for _, tc := range cases {
		_, errors := validateAppautoscalingScalableDimension(tc.Value, "scalable_dimension")
		if len(errors) != tc.ErrCount {
			t.Fatalf("Scalable Dimension validation failed for value %q: %q", tc.Value, errors)
		}
	}
}

func TestValidateAppautoscalingServiceNamespace(t *testing.T) {
	cases := []struct {
		Value    string
		ErrCount int
	}{
		{
			Value:    "ecs",
			ErrCount: 0,
		},
		{
			Value:    "ec2",
			ErrCount: 0,
		},
		{
			Value:    "autoscaling",
			ErrCount: 1,
		},
		{
			Value:    "s3",
			ErrCount: 1,
		},
		{
			Value:    "es",
			ErrCount: 1,
		},
		{
			Value:    "",
			ErrCount: 1,
		},
	}

	for _, tc := range cases {
		_, errors := validateAppautoscalingServiceNamespace(tc.Value, "service_namespace")
		if len(errors) != tc.ErrCount {
			t.Fatalf("Service Namespace validation failed for value %q: %q", tc.Value, errors)
		}
	}
}

func TestValidateDmsEndpointId(t *testing.T) {
	validIds := []string{
		"tf-test-endpoint-1",
		"tfTestEndpoint",
	}

	for _, s := range validIds {
		_, errors := validateDmsEndpointId(s, "endpoint_id")
		if len(errors) > 0 {
			t.Fatalf("%q should be a valid endpoint id: %v", s, errors)
		}
	}

	invalidIds := []string{
		"tf_test_endpoint_1",
		"tf.test.endpoint.1",
		"tf test endpoint 1",
		"tf-test-endpoint-1!",
		"tf-test-endpoint-1-",
		"tf-test-endpoint--1",
		"tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1tf-test-endpoint-1",
	}

	for _, s := range invalidIds {
		_, errors := validateDmsEndpointId(s, "endpoint_id")
		if len(errors) == 0 {
			t.Fatalf("%q should not be a valid endpoint id: %v", s, errors)
		}
	}
}

func TestValidateDmsCertificateId(t *testing.T) {
	validIds := []string{
		"tf-test-certificate-1",
		"tfTestEndpoint",
	}

	for _, s := range validIds {
		_, errors := validateDmsCertificateId(s, "certificate_id")
		if len(errors) > 0 {
			t.Fatalf("%q should be a valid certificate id: %v", s, errors)
		}
	}

	invalidIds := []string{
		"tf_test_certificate_1",
		"tf.test.certificate.1",
		"tf test certificate 1",
		"tf-test-certificate-1!",
		"tf-test-certificate-1-",
		"tf-test-certificate--1",
		"tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1tf-test-certificate-1",
	}

	for _, s := range invalidIds {
		_, errors := validateDmsEndpointId(s, "certificate_id")
		if len(errors) == 0 {
			t.Fatalf("%q should not be a valid certificate id: %v", s, errors)
		}
	}
}

func TestValidateDmsReplicationInstanceId(t *testing.T) {
	validIds := []string{
		"tf-test-replication-instance-1",
		"tfTestReplicaitonInstance",
	}

	for _, s := range validIds {
		_, errors := validateDmsReplicationInstanceId(s, "replicaiton_instance_id")
		if len(errors) > 0 {
			t.Fatalf("%q should be a valid replication instance id: %v", s, errors)
		}
	}

	invalidIds := []string{
		"tf_test_replication-instance_1",
		"tf.test.replication.instance.1",
		"tf test replication instance 1",
		"tf-test-replication-instance-1!",
		"tf-test-replication-instance-1-",
		"tf-test-replication-instance--1",
		"tf-test-replication-instance-1tf-test-replication-instance-1tf-test-replication-instance-1",
	}

	for _, s := range invalidIds {
		_, errors := validateDmsReplicationInstanceId(s, "replication_instance_id")
		if len(errors) == 0 {
			t.Fatalf("%q should not be a valid replication instance id: %v", s, errors)
		}
	}
}

func TestValidateDmsReplicationSubnetGroupId(t *testing.T) {
	validIds := []string{
		"tf-test-replication-subnet-group-1",
		"tf_test_replication_subnet_group_1",
		"tf.test.replication.subnet.group.1",
		"tf test replication subnet group 1",
		"tfTestReplicationSubnetGroup",
	}

	for _, s := range validIds {
		_, errors := validateDmsReplicationSubnetGroupId(s, "replication_subnet_group_id")
		if len(errors) > 0 {
			t.Fatalf("%q should be a valid replication subnet group id: %v", s, errors)
		}
	}

	invalidIds := []string{
		"default",
		"tf-test-replication-subnet-group-1!",
		"tf-test-replication-subnet-group-1tf-test-replication-subnet-group-1tf-test-replication-subnet-group-1tf-test-replication-subnet-group-1tf-test-replication-subnet-group-1tf-test-replication-subnet-group-1tf-test-replication-subnet-group-1tf-test-replication-subnet-group-1",
	}

	for _, s := range invalidIds {
		_, errors := validateDmsReplicationSubnetGroupId(s, "replication_subnet_group_id")
		if len(errors) == 0 {
			t.Fatalf("%q should not be a valid replication subnet group id: %v", s, errors)
		}
	}
}

func TestValidateDmsReplicationTaskId(t *testing.T) {
	validIds := []string{
		"tf-test-replication-task-1",
		"tfTestReplicationTask",
	}

	for _, s := range validIds {
		_, errors := validateDmsReplicationTaskId(s, "replication_task_id")
		if len(errors) > 0 {
			t.Fatalf("%q should be a valid replication task id: %v", s, errors)
		}
	}

	invalidIds := []string{
		"tf_test_replication_task_1",
		"tf.test.replication.task.1",
		"tf test replication task 1",
		"tf-test-replication-task-1!",
		"tf-test-replication-task-1-",
		"tf-test-replication-task--1",
		"tf-test-replication-task-1tf-test-replication-task-1tf-test-replication-task-1tf-test-replication-task-1tf-test-replication-task-1tf-test-replication-task-1tf-test-replication-task-1tf-test-replication-task-1tf-test-replication-task-1tf-test-replication-task-1",
	}

	for _, s := range invalidIds {
		_, errors := validateDmsReplicationTaskId(s, "replication_task_id")
		if len(errors) == 0 {
			t.Fatalf("%q should not be a valid replication task id: %v", s, errors)
		}
	}
}

func TestValidateAccountAlias(t *testing.T) {
	validAliases := []string{
		"tf-alias",
		"0tf-alias1",
	}

	for _, s := range validAliases {
		_, errors := validateAccountAlias(s, "account_alias")
		if len(errors) > 0 {
			t.Fatalf("%q should be a valid account alias: %v", s, errors)
		}
	}

	invalidAliases := []string{
		"tf",
		"-tf",
		"tf-",
		"TF-Alias",
		"tf-alias-tf-alias-tf-alias-tf-alias-tf-alias-tf-alias-tf-alias-tf-alias",
	}

	for _, s := range invalidAliases {
		_, errors := validateAccountAlias(s, "account_alias")
		if len(errors) == 0 {
			t.Fatalf("%q should not be a valid account alias: %v", s, errors)
		}
	}
}

func TestValidateIamRoleProfileName(t *testing.T) {
	validNames := []string{
		"tf-test-role-profile-1",
	}

	for _, s := range validNames {
		_, errors := validateIamRolePolicyName(s, "name")
		if len(errors) > 0 {
			t.Fatalf("%q should be a valid IAM role policy name: %v", s, errors)
		}
	}

	invalidNames := []string{
		"invalid#name",
		"this-is-a-very-long-role-policy-name-this-is-a-very-long-role-policy-name-this-is-a-very-long-role-policy-name-this-is-a-very-long",
	}

	for _, s := range invalidNames {
		_, errors := validateIamRolePolicyName(s, "name")
		if len(errors) == 0 {
			t.Fatalf("%q should not be a valid IAM role policy name: %v", s, errors)
		}
	}
}

func TestValidateIamRoleProfileNamePrefix(t *testing.T) {
	validNamePrefixes := []string{
		"tf-test-role-profile-",
	}

	for _, s := range validNamePrefixes {
		_, errors := validateIamRolePolicyNamePrefix(s, "name_prefix")
		if len(errors) > 0 {
			t.Fatalf("%q should be a valid IAM role policy name prefix: %v", s, errors)
		}
	}

	invalidNamePrefixes := []string{
		"invalid#name_prefix",
		"this-is-a-very-long-role-policy-name-prefix-this-is-a-very-long-role-policy-name-prefix-this-is-a-very-",
	}

	for _, s := range invalidNamePrefixes {
		_, errors := validateIamRolePolicyNamePrefix(s, "name_prefix")
		if len(errors) == 0 {
			t.Fatalf("%q should not be a valid IAM role policy name prefix: %v", s, errors)
		}
	}
}

func TestValidateApiGatewayUsagePlanQuotaSettingsPeriod(t *testing.T) {
	validEntries := []string{
		"DAY",
		"WEEK",
		"MONTH",
	}

	invalidEntries := []string{
		"fooBAR",
		"foobar45Baz",
		"foobar45Baz@!",
	}

	for _, v := range validEntries {
		_, errors := validateApiGatewayUsagePlanQuotaSettingsPeriod(v, "name")
		if len(errors) != 0 {
			t.Fatalf("%q should be a valid API Gateway Quota Settings Period: %v", v, errors)
		}
	}

	for _, v := range invalidEntries {
		_, errors := validateApiGatewayUsagePlanQuotaSettingsPeriod(v, "name")
		if len(errors) == 0 {
			t.Fatalf("%q should not be a API Gateway Quota Settings Period", v)
		}
	}
}

func TestValidateApiGatewayUsagePlanQuotaSettings(t *testing.T) {
	cases := []struct {
		Offset   int
		Period   string
		ErrCount int
	}{
		{
			Offset:   0,
			Period:   "DAY",
			ErrCount: 0,
		},
		{
			Offset:   -1,
			Period:   "DAY",
			ErrCount: 1,
		},
		{
			Offset:   1,
			Period:   "DAY",
			ErrCount: 1,
		},
		{
			Offset:   0,
			Period:   "WEEK",
			ErrCount: 0,
		},
		{
			Offset:   6,
			Period:   "WEEK",
			ErrCount: 0,
		},
		{
			Offset:   -1,
			Period:   "WEEK",
			ErrCount: 1,
		},
		{
			Offset:   7,
			Period:   "WEEK",
			ErrCount: 1,
		},
		{
			Offset:   0,
			Period:   "MONTH",
			ErrCount: 0,
		},
		{
			Offset:   27,
			Period:   "MONTH",
			ErrCount: 0,
		},
		{
			Offset:   -1,
			Period:   "MONTH",
			ErrCount: 1,
		},
		{
			Offset:   28,
			Period:   "MONTH",
			ErrCount: 1,
		},
	}

	for _, tc := range cases {
		m := make(map[string]interface{})
		m["offset"] = tc.Offset
		m["period"] = tc.Period

		errors := validateApiGatewayUsagePlanQuotaSettings(m)
		if len(errors) != tc.ErrCount {
			t.Fatalf("API Gateway Usage Plan Quota Settings validation failed: %v", errors)
		}
	}
}

func TestValidateElbName(t *testing.T) {
	validNames := []string{
		"tf-test-elb",
	}

	for _, s := range validNames {
		_, errors := validateElbName(s, "name")
		if len(errors) > 0 {
			t.Fatalf("%q should be a valid ELB name: %v", s, errors)
		}
	}

	invalidNames := []string{
		"tf.test.elb.1",
		"tf-test-elb-tf-test-elb-tf-test-elb",
		"-tf-test-elb",
		"tf-test-elb-",
	}

	for _, s := range invalidNames {
		_, errors := validateElbName(s, "name")
		if len(errors) == 0 {
			t.Fatalf("%q should not be a valid ELB name: %v", s, errors)
		}
	}
}

func TestValidateElbNamePrefix(t *testing.T) {
	validNamePrefixes := []string{
		"test-",
	}

	for _, s := range validNamePrefixes {
		_, errors := validateElbNamePrefix(s, "name_prefix")
		if len(errors) > 0 {
			t.Fatalf("%q should be a valid ELB name prefix: %v", s, errors)
		}
	}

	invalidNamePrefixes := []string{
		"tf.test.elb.",
		"tf-test",
		"-test",
	}

	for _, s := range invalidNamePrefixes {
		_, errors := validateElbNamePrefix(s, "name_prefix")
		if len(errors) == 0 {
			t.Fatalf("%q should not be a valid ELB name prefix: %v", s, errors)
		}
	}
}

func TestValidateDbSubnetGroupName(t *testing.T) {
	cases := []struct {
		Value    string
		ErrCount int
	}{
		{
			Value:    "tEsting",
			ErrCount: 1,
		},
		{
			Value:    "testing?",
			ErrCount: 1,
		},
		{
			Value:    "default",
			ErrCount: 1,
		},
		{
			Value:    randomString(300),
			ErrCount: 1,
		},
	}

	for _, tc := range cases {
		_, errors := validateDbSubnetGroupName(tc.Value, "aws_db_subnet_group")

		if len(errors) != tc.ErrCount {
			t.Fatalf("Expected the DB Subnet Group name to trigger a validation error")
		}
	}
}

func TestValidateDbSubnetGroupNamePrefix(t *testing.T) {
	cases := []struct {
		Value    string
		ErrCount int
	}{
		{
			Value:    "tEsting",
			ErrCount: 1,
		},
		{
			Value:    "testing?",
			ErrCount: 1,
		},
		{
			Value:    randomString(230),
			ErrCount: 1,
		},
	}

	for _, tc := range cases {
		_, errors := validateDbSubnetGroupNamePrefix(tc.Value, "aws_db_subnet_group")

		if len(errors) != tc.ErrCount {
			t.Fatalf("Expected the DB Subnet Group name prefix to trigger a validation error")
		}
	}
}

func TestValidateDbOptionGroupName(t *testing.T) {
	cases := []struct {
		Value    string
		ErrCount int
	}{
		{
			Value:    "testing123!",
			ErrCount: 1,
		},
		{
			Value:    "1testing123",
			ErrCount: 1,
		},
		{
			Value:    "testing--123",
			ErrCount: 1,
		},
		{
			Value:    "testing123-",
			ErrCount: 1,
		},
		{
			Value:    randomString(256),
			ErrCount: 1,
		},
	}

	for _, tc := range cases {
		_, errors := validateDbOptionGroupName(tc.Value, "aws_db_option_group_name")

		if len(errors) != tc.ErrCount {
			t.Fatalf("Expected the DB Option Group Name to trigger a validation error")
		}
	}
}

func TestValidateDbOptionGroupNamePrefix(t *testing.T) {
	cases := []struct {
		Value    string
		ErrCount int
	}{
		{
			Value:    "testing123!",
			ErrCount: 1,
		},
		{
			Value:    "1testing123",
			ErrCount: 1,
		},
		{
			Value:    "testing--123",
			ErrCount: 1,
		},
		{
			Value:    randomString(230),
			ErrCount: 1,
		},
	}

	for _, tc := range cases {
		_, errors := validateDbOptionGroupNamePrefix(tc.Value, "aws_db_option_group_name")

		if len(errors) != tc.ErrCount {
			t.Fatalf("Expected the DB Option Group name prefix to trigger a validation error")
		}
	}
}

func TestValidateOpenIdURL(t *testing.T) {
	cases := []struct {
		Value    string
		ErrCount int
	}{
		{
			Value:    "http://wrong.scheme.com",
			ErrCount: 1,
		},
		{
			Value:    "ftp://wrong.scheme.co.uk",
			ErrCount: 1,
		},
		{
			Value:    "%@invalidUrl",
			ErrCount: 1,
		},
		{
			Value:    "https://example.com/?query=param",
			ErrCount: 1,
		},
	}

	for _, tc := range cases {
		_, errors := validateOpenIdURL(tc.Value, "url")

		if len(errors) != tc.ErrCount {
			t.Fatalf("Expected %d of OpenID URL validation errors, got %d", tc.ErrCount, len(errors))
		}
	}
}

redpajama_set_name: RedPajamaGithub


text:
YOU CAN LEAVE YOUR HATE ON — IT'S BEATsc WEEK!!
No more horsing around: Rivalry Week starts right now — Because of Turkey Day on Thursday, UCLA's BeatSC Rally and Bonfire will roast the school of turkeys tonight (Monday night)
It's finally here. 51 weeks of waiting is over. The Countdown has started for the Kickoff to the annual renewal of the Country's most heated Crosstown Rivalry: UCLA vs. usc. And out of the 51 weeks, about 48 of them were filled with dread for Bruin fans, because once again, it looked like the Bruins were going to get killed. But a few weeks ago, the Bruins started to play slightly better, and usc started to play a lot worse.
The seeds of hope were actually planted a while back, with what looked like a fluke, when Washington upset sc. But that was in Washington, and the Husky Coaching staff KNEW the trojans inside and out. So it was no big deal when the Bruins beat the Huskies, who had beaten sc. But now, the Bruins have also played Oregon, Washington State, Stanford, and ASU tougher than sc did. So Bruin fans are ALLOWING themselves to dream a little dream.
But listen to Sports Talk Radio at 4:15pm today, KLAA Radio, 830 on your am radio dial, to hear a certain Bruin fan that you all know and love (or hate), who has a more realistic (pessimistic?) outlook on the upcoming match-up…
The spread is not yet posted on Vegas.com as of this update, but rumor has sc favored by anywhere from 10 to 13 1/2 points. Someone is going to have to tackle Joe McKnight in order to keep troy within two TD's. And someone else is going to have to put pressure on Matt Barkley, or sc will cover the spread just through the air, before Intermission. And someone else is going to have to block for Chane Moline. If he is going to Gerhart through the trojan Defense, he'll need a lot of help, along with a Passing Attack that isn't afraid of Taylor "The Headhunter" Mays and the deep ball.
So yeah, obviously usc is vulnerable, and not playing for any of their preset goals, but they are trying to salvage their season. A loss and they are historical laughingstocks in trojan lore for decades to come. On the other side of the field, the Bruins could lose a a fairly close game, and still consider the season a slight "success," because they exceeded last year's win total and became Bowl-eligible. Therefore, usc has much, much more to lose, and will play with more desperation, urgency, emotion, and wild abandon. The sad part is that they don't really need any of that to win. They don't need to spear Kevin Prince in the jaw, out of bounds, after the whistle, but they probably will. All they have to do is play up to their bloodlines, and they win going away. It's just that they have been getting stuck in the gate lately, and when Pom Pom goes to the whip-whip, there's nothing left in the tank.
But with home cesspool advantage, two weeks to prepare (for his mortal enemy Norm Chow), and stronger psychological motivators on his side, is there any possible way that Caroll loses this game?
But don't bring that sh*t around Westwood tonight. At the Bonfire and Rally, it's all about hope, confidence, and hatred, and faith in the struggle of good vs. evil.
Speaking of good vs. evil, thank you for all the comments about creepiness and wholesomeness, and here are 5 more shots from Saturday, that made the final cut to be posted on "Night 1," but ended up like Les Miles and LSU: Time ran out on them. All these photos ENLARGE when you click on them, and they all have mouse-over, hidden captions. Today's captions concern Kahlil Bell (believe it or not), Darren Collison, and my favorite quote of the year, about Demar Derozan and Homer Simpson's favorite thing in the World.
"YOU CAN LEAVE YOUR HATE ON — IT'S BEATsc WEEK!!" was published on November 23rd, 2009 and is listed in Blue & Gold News, UCLA/usc/Cheerleader Photos.
Comments on "YOU CAN LEAVE YOUR HATE ON — IT'S BEATsc WEEK!!": 1 Comment
Brew In wrote,
Now is the time to come out in droves and wear our Blue and Gold to try to counteract the University of Spoiled Children and all their egotistical and guady gear that even the most fair-weathered non-fan seems to be sporting today to bandwagon his way into getting into some chick's pants.
Speaking of University of Spoiled Children, was I the only one who heard Warren Sapp use that phrase on a TV pre-game show a few weeks back? The other commentators tried to sluff it off with a "duh, what thar heck does that mean"? while tell-it-like-it-is Warren stated "Come on, yall tell me you never heard that one before"?
GO BRUUUUUUUUUUUUUUINS!!!!
[T-H's Note: Hadn't heard about Sapp. That's awesome. Thanks.]
| Link | November 25th, 2009 at 5:58 pm

redpajama_set_name: RedPajamaCommonCrawl


text:
Home›Trustee›Board of Directors replaces Young Graduate Leader with Young Graduate Trustee, effective July 2023 – The Vanderbilt Hustler
Board of Directors replaces Young Graduate Leader with Young Graduate Trustee, effective July 2023 – The Vanderbilt Hustler
The new position extends eligibility to former graduate and professional students, in addition to former undergraduates, who are within 10 years of graduation.
Anjali Chanda
Kirkland Hall, pictured November 5, 2020 (Hustler Multimedia / Anjali Chanda)
Effective July 1, 2023, the Vanderbilt Board of Trustees will begin the biennial appointments of a Young Alumni Director. All former undergraduate, graduate and professional students within 10 years of graduation are eligible for the two-year term. Prior to the Young Alumni Trustee, only former undergraduates were eligible to be the Young Alumni Leader.
The Board of Trustees is a decision-making body that works with the Chancellor to determine the university's vision for the future, including reviewing its finances and investments, student and faculty composition, governance structure, and institutional strategic initiatives. As a member of the Board, the Young Alumni Trustee will have the opportunity to delegate on these issues.
"The overall vision is to create a diverse, engaged and experienced board of directors for the benefit of the entire campus community whose most important constituents are the students," said Maribeth Geracioti, secretary of the board. , in an email to The Hustler.
On November 13, 2020, the Board approved the Young Alumni Trustee initiative, which was prepared by its Governance and Board Affairs Committee, a group responsible for reviewing Statutes code and propose changes, including membership procedures. Prior to that date, the Board made annual appointments of a Young Alumni Leader, to whom only former undergraduates were eligible. The position involved a three-year service on the Council of the alumni association—A network for alumni to familiarize themselves with postgraduate experiences — and a subsequent two-year term on the board.
Current young alumni leaders will complete their term on the alumni association board and board.
Damonta Morgan, a current leader of Young Alumni, questioned the new Young Alumni Trustee program and its potential benefits for the student body. He expressed that the Governance and Board Affairs Committee may have intended to prioritize the election of a former graduate and professional rather than a former undergraduate, as they likely had more work experience to offer to the Board.
"The experience of graduate students is significantly different from that of undergraduates at Vanderbilt," Morgan said. "I think it was shortsighted to extend [the Young Alumni Trustee] that way because I think graduate students listen to undergraduate conversations a lot less than the other way around.
However, Geriacioti said the move was aimed at defending certain aspects of the mission statement, which advocates the collaboration of people with diverse backgrounds, experiences and points of view.
"The desire was to expand eligibility to graduate students and professionals for a more diverse mix of experiences and ages, also reflecting the One Vanderbilt mission," said Geriacioti.
Geriacioti said the Board of Trustees did not consider extending the post of young graduate administrator to allow a former undergraduate and graduate to serve at the same time.
"The Board of Trustees reviews membership procedures on an ongoing basis, in accordance with the Constitution Code, and for the time being, moving to a Young Alumni Trustee (whether an undergraduate student, graduate or professional student) is compatible with the appointment and election of an alumni administrator, "Geracioti mentioned.
Geracioti added that all the young leaders of the elders, Dean of Students staff and Development and relations with alumni staff have been invited to participate in the initiative.
"Vanderbilt was one of the first institutions to create a trustee designation for young alumni in 1968, and it is one of the very few peer institutions to retain the position with full voting privileges," said said Geracioti. "As the University has changed over the past 50+ years, the Board of Trustees is adjusting accordingly, including membership procedures, to provide effective fiduciary oversight so that our students have every opportunity to excel. "
Trade protectionism slows US economic development, economist ...
Singapore and Malaysia combine faster payment systems
The board discussed land that had not been used for decades
School board will handle the Superintendent's $ 80,000 sick leave allowance, hire consultants to build a team of school counselors, ...
MoMA administrator Lonti Ebers to launch Lover Foundation in Brooklyn
Candidate Profiles: Yantis ISD Board of Directors
Here's why global reflation trade may survive China's credit slowdown


I'm very sad to hear that Salem Communications is parting ways with a conservative talk radio legend, Michael Medved.
I'm grateful for nearly 22 yrs with #SalemRadioNetwork and wish all my friends and colleagues only the best.
Medved was instrumental in making me into a conservative, and it saddens me that Salem is taking him off the air. He is brilliant, insightful, and always wise.
Regarding today's announcement of schedule changes on Salem Radio, I want to make it unequivocally clear that our show will continue, without interruption, 3-6 PM EST as always–and on a new network after January 1st. Also, we're launching a new history podcast. Stay tuned!
I own many of his books, have called into the show, and met him a few times. I spent hours upon hours in my formative conservative years listening to him explain and defend what I have come to believe and cherish. He is a kind and good man. He even signed a parody Mexican ID card with the name "soopermexican" on it once. It is one of my most prized possessions.
And what's worse.. they're replacing him with a pile of crap.


Technology|Is Obama a Mac and Clinton a PC?
STYLES make fights — or so goes the boxing cliché. In 2008, they make presidential campaigns, too.
This is especially true for the two remaining Democrats, Hillary Clinton and Barack Obama. Reporters covering the candidates have already resorted to traditional analysis of style — fashion choices, manner of speaking, even the way they laugh. Yet, according to design experts, the candidates have left a clear blueprint of their personal style — perhaps even a window into their souls — through the Web sites they have created to raise money, recruit volunteers and generally meet-and-greet online.
But the designers believe the comparisons — but not perhaps the Orwellian overtones — are apt. In contrast to barackobama.com, Mrs. Clinton's site uses a more traditional color scheme of dark blue, has sharper lines dividing content and employs cookie-cutter icons next to its buttons for volunteering, and the like.
Unlike the Republicans, the Democratic contenders have incorporated social-networking tools to their sites — allowing supporters to create their own groups, for example, though Mr. Obama is considered the pacesetter in that regard.


The FIDE was awarding FIDE arbiters title for arbiters who had the requisite number of norms. But, as per the new regulations of FIDE, it is mandatory for all FIDE Arbiter title seekers to attend the Arbiters Seminar conducted by the FIDE and to pass the exam. Therefore, the All India Chess Federation has been receiving requests from various States to conduct FIDE Arbiters Seminar in India. The reason being, it is difficult for many to spend money on Airfare, Boarding & Lodging and course fee if it is held abroad. In view of the above requests, it has been decided to conduct an Arbiters Seminar at New Delhi from 04 to 06 July, 2017 . Anybody who has basic knowledge about the game can appear for the Seminar.
Arrival & Registration : 04th July, 2017 before : 09:30.A.M.
Departure : 06th July, 2017 after : 19: 00 hrs.
Detailed Schedule will be informed at the Seminar hall.


Bluelips is now offering a limited selection of cremation urns for both humans and pets. Each of these urns is a beautiful tribute to your beloved family member or pet at a fraction of the cost you would pay through traditional funeral homes. We support a healthy planet.
You will need approximately 1 cubic inch for every pound of body weight. A person weighing 320 pounds will require an urn that will hold 320 cubic inches.
We hope to eventually offer a line of keepsake urns as well.


text:
Gia On The Move
Hollywood Fringe #HFF19
Latest Theater News
Actors' Equity Applauds Introduction of the Bipartisan Performing Artist Tax Parity Act
New September Date Announced for National Dance Day Holiday
Mixing It Up! Antaeus Theatre Company Announces 2019/2020 Season
'Defining Moments' at the Los Angeles Women's Theatre Festival Culver City
The Blank Theatre Celebrates 27th Young Playwrights Festival Anniversary with 12 New Plays
Odyssey Theatre To Revive Seminal 'Circa 69!' Plays for 50th Anniversary
Australian Circus Company Circa U.S. Premiere 'What Will Have Been' at Santa Ana Sites
A Noise Within Announces 2019-2020 Season
Drama Desk Award Nominations Announced
Will Geer's Theatricum Botanicum Announces 2019 Summer Season of Theater
Ideologies Coming Together in 'The Meeting' of Malcolm X and Dr. Martin Luther King
Open Fist's 'Anna in the Tropics': Provocative and Exquisite
'The Curious Palate' Santa Monica: Supporting Local Artisans, Serving Sustainable Foods
Fry Madness Downtown L.A.: The Day to Night Food Stop You Must Make
3 Faces: Women Pay the Price for Dissent
'Don't Silence Me'- A New Anthem For a New Women's Movement
Natural Beauty Products Review – MyChelle Refining Sugar Cleanser
Richard James Savile Row Collaborates with Swarovski to Celebrate 'Rocketman' Elton John
Coachella Inspired Looks for Spring and Summer
Female Founded Self-care Company, Blume, Focused on Empowering Girls, Raises $3.3 Million in Series Seed Funding
Tracey Paleo, Gia On The Move
Matt Ritchey – Content Producer, Theater & Film Reviews
Guy Picot – Theater & Film Reviews
Got a story? Submit it!
L.A. Web Series Creators Tom Cavanaugh, Matt Ritchey, Bob Telford and Allyson Sereboff Premiere 'Hollywood Vampire'
Hollywood Vampire will premiere on Tuesday, October 16th, 2018 with new episodes launching weekly until Tuesday, January 8th 2019 on tinyurl.com/hollywoodvampire.
Hollywood Vampire is a comedic web show created by award winners Tom Cavanaugh (writer), Matt Ritchey (director), Bob Telford (director) and Allyson Sereboff under the production banner of their group, 8Aprons.
A 'twenty-something' vampire is kicked out of his homeland. With no place to turn, he and his sidekick/Butler, Gilroy, trek to Hollywood to find the internet model/actress, dream girl who he's he's fallen madly in love with in Los Angeles. Their first encounter is classic Hollywood… just a stranger trying to hit on a model… but Hannah Beth soon discovers that Vlad is NOT just another bloodsucking schmoe in the Hollywood dating scene!
The original script was created in workshop at the film collective, We Make Movies in Hollywood. That inspired Cavanaugh to seek out other artists that wanted to work in television or episodic story telling. Cavanaugh along with Matt Ritchey, Bob Telford and Allyson Sereboff, 8Aprons used their combined assets and skills, on a very limited budget, to create thirteen episodes plus a trailer.
Tom Cavanaugh is best known for his questions from the audience on Inside The Actors Studio and in the L.A. Intimate Theater Community as the Producer/Director of the 2017 Hollywood Fringe Festival, Best Solo Performance, Under the Jello Mold. His first short film, The Shift won awards in several film festivals and received a five-star rating at the 2007 Short Film Corner at the Cannes Film Festival. Tom is also a two-time finalist at the New American Playwrights Program at the Utah Shakespeare Festival.
Matt Ritchey is an L.A. based film and theater director whose short film Poker Night won Best Comedy at the Culver City Film Festival, and whose stage productions of Angel's Flight won Best Cabaret and American Conspiracy won Encore Producer's Award at the Hollywood Fringe Festival. He was nominated for Best Director for both shows. He's an NYU and RADA educated actor, writer, and editor currently wrapping up Post-Production on the short film Purple Flowers and the web series.
Bob Telford is an award-winning actor/director. He has spent the last 38 years working in theater, commercials, TV & Film. From 1989 to 2006 Bob had his own production company, producing and directing over 200 projects for clients including The Academy of Television Arts & Sciences. His TV credits include Parks and Recreation, Roseanne, Reasonable Doubts, and Young & The Restless. Film credits include The Best of The Best, Riding With James Dean, Wild Horses & Butterfly Caught. Recent credits include Bob recently completed the Japanese adventure series, Fujiyama Ichiban, which can seen on YouTube, the A&E series Fall Into Me and HBO Greenlight's Pineapple.
Allyson Sereboff is a Baltimore, M.D. native. Allyson studied acting at The William Esper Studio, New York City and had her first feature film debut in Troma's Poultrygeist: Night of the Chicken Dead. Allyson also appeared in and assisted on the Speechless Without Writer's campaign during the subsequent writer's strike in Los Angeles. She is a member of We Make Movies and has teamed up to launch 8 Aprons, currently in multiple productions.
GiaOnTheMove
8Aprons, comedy, dating, web series
Follow Gia On The Move
Follow Gia On The Move by email and receive notifications of new posts.
Change Isn't Easy. 'Masters of the Dark Realm', reviewed
#HFF19 'American Stranger', reviewed
#HFF19 'This Way Yonder', reviewed
#HFF19 'Feeling Lucky', reviewed
#HFF19 'Boeing Boeing', reviewed
#HFF19 'Journey', reviewed
Search Gia On The Move
Click on a Popular Topic
#ListenToThis #WhatsHotNow Art beauty Dance Events Fashion & Beauty Film & Television Food & Beverage Holiday Gifts Literature Media Movement Techniques Music Sports Theatre Theatre Reviews videos Writing
Gia On The Move Comment Policy
View GiaOnTheMove's profile on Facebook
View @GiaMedia3's profile on Twitter
View giaonthemove's profile on Instagram
View TraceyPaleo's profile on Pinterest


1-4 Jacob looked up and saw Esau coming with his four hundred men. men. He divided the children between Leah and Rachel and the two maidservants. He put the maidservants out in front, Leah and her children next, and Rachel and Joseph last. He led the way and, as he approached his brother, bowed seven times, honoring his brother. But Esau ran up and embraced him, held him tight and kissed him. And they both wept.
5 Then Esau looked around and saw the women and children: "And who are these with you?"
Jacob said, "The children that God saw fit to bless me with."
6-7 Then the maidservants came up with their children and bowed; then Leah and her children, also bowing; and finally, Joseph and Rachel came up and bowed to Esau.
8 Esau then asked, "And what was the meaning of all those herds that I met?"
"I was hoping that they would pave the way for my master to welcome me."
9 Esau said, "Oh, brother. I have plenty of everything—keep what is yours for yourself."
10-11 Jacob said, "Please. If you can find it in your heart to welcome me, accept these gifts. When I saw your face, it was as the face of God smiling on me. Accept the gifts I have brought for you. God has been good to me and I have more than enough." Jacob urged the gifts on him and Esau accepted.
12 Then Esau said, "Let's start out on our way; I'll take the lead."
13-14 But Jacob said, "My master can see that the children are frail. And the flocks and herds are nursing, making for slow going. If I push them too hard, even for a day, I'd lose them all. So, master, you go on ahead of your servant, while I take it easy at the pace of my flocks and children. I'll catch up with you in Seir."
15 Esau said, "Let me at least lend you some of my men."
"There's no need," said Jacob. "Your generous welcome is all I need or want."
16 So Esau set out that day and made his way back to Seir.
17 And Jacob left for Succoth. He built a shelter for himself and sheds for his livestock. That's how the place came to be called Succoth (Sheds).


text:
Home American History Texas History Update: The Odd Case of the Yellow Rose of Texas
Texas History Update: The Odd Case of the Yellow Rose of Texas
The Yellow Rose of Texas was a popular Civil War era song about a woman who supposedly singlehandedly won Texas Independence from Mexico. Whether it is true or not the legend is indeed fascinating. Recently there has been another interesting tidbit added; could she have been the Vice President's wife?
The Legend of the Yellow Rose of Texas (The Beautiful Emily West)
According to a couple of obscure bits of historically semi-accepted second-hand information (whew!) the Yellow Rose of Texas was a beautiful Mulatto woman. She supposedly seduced Santa Anna on the eve and morning of his defeat by Sam Houston at the Battle of San Jacinto. This defeat won Texas' Independence from Mexico. The mulatto woman was named to be Emily West. It has been proven that this woman of color had been contracted to be a servant to Colonel James Morgan a wealthy Texas landowner.
Emily West Captured By Santa Anna
Historians suggest there was an Emily West captured by Santa Anna's troops as she and other Texas residents were fleeing the Mexican onslaught outside of the revolutionists' Texas capital at Harrisburg (present-day Houston). The Yellow Rose of Texas legend purports she was presented to Santa Anna (a reportedly known womanizer and drug abuser) and he became enamored with her beauty.
It is because of this sexual (and possibly drug-induced) encounter, some historians believe, that Houston was able to defeat Santa Anna at San Jacinto. Observations of him hurrying out of his tent with his pants at his ankles were promoted. This unpreparedness could possibly explain why the ragtag group of Texans (who were vastly out-numbered and grossly-inexperienced) were able to defeat the Mexicans. It took Houston just a few minutes to overwhelm the surprised Mexican forces.
Thus it is understandable why the story of this beautiful dark-skinned woman and her escapade with Santa Anna have become a famous historical legend known as the Yellow Rose of Texas. There is evidence that Emily West was at the battlefield the morning of the surprise attack by Houston.
At the time of the Texas Revolution Mexican Lorenzo De Zavala was the Vice President of the renegade Texas government. Earlier Zavala, who was a popular Mexican political figure, had abandoned Santa Anna because of the latter's designs on becoming dictator of Mexico. At this point the two Mexican rivals became bitter enemies. Zavala shortly thereafter joined the Texas Revolution.
Before the revolution Lorenzo De Zavala and Santa Anna were political competitors when Mexico was entertaining the idea of emulating the United States' path of democracy. Santa Anna was President of Mexico and Zavala was the governor of the state of Mexico. De Zavala was married to a woman named Emily West.
Santa Anna's Crush On Emily West De Zavala?
Zavala asked Santa Anna to support a bill of his that would insure that Mexico also had a separation of church and state as did the United States. Santa Anna told Zavala he would support his bill so Zavala introduced it to the Mexican congress. However, in order to quell the rising popularity of Zavala, Santa Anna betrayed his trust and backed the clergy in their effort to stop the bill.
This created a chasm between the two former poltical contemporaries. During better times Emily and Lorenzo De Zavala would attend society balls and parties along with the Santa Annas. No doubt the Zavalas must have been aware of Santa Anna's notorious womanizing at these functions. With Emily being so beautiful it's not too difficult to imagine that Santa Anna must have desired her charms also.
Who Was Santa Anna Pursuing During the Texas Revolution?
Historians state that Santa Anna was pursuing Sam Houston and the fleeing Texas renegades in the pursuit across Texas. Is it too far-fetched to imagine he was actually mainly in pursuit of Emily West and Lorenzo De Zavala? Was he chasing Lorenzo because he wanted to eliminate his chief Mexican political rival and Emily because he wanted to pursue her charms?
Lorenzo De Zavala was a very cleverly intelligent and opportunistic man. Is it possible he and Emily (and possibly Houston) could have conspired to have Santa Anna capture her so Houston could surprise the Mexican forces while Santa Anna was preoccupied? Afterall the Zavalas knew Santa Anna as a womanizer and drug addict. Could it have been this Emily who Santa Anna captured at San Jacinto?
Is it legend or is it historical fact? Just who do you think was The Yellow Rose of Texas? What are the chances that Early Texas would have had two beautiful Emily Wests at the same time, knowing the same people, and at the very same location during such an important time in Texas history?
What Do You Think? Were There Two Emily Wests?
One more thing: remember Colonel James Morgan the wealthy Texas landowner who had Emily West as his indentured servant? He was business partners and good friends with Vice President Lorenzo De Zavala!
Such is the legend of The Yellow Rose of Texas.


text:
\hypertarget{structEnvironment}{\section{Environment Struct Reference}
\label{structEnvironment}\index{Environment@{Environment}}
}

{\ttfamily \#include $<$environment.\+h$>$}

\subsection*{Data Fields}
\begin{DoxyCompactItemize}
\item
struct \hyperlink{structHashTable}{Hash\+Table} $\ast$ \hyperlink{structEnvironment_a07eb64196282faa20d47b862cb399cb5}{lookup}
\item
struct \hyperlink{structMemory}{Memory} $\ast$ \hyperlink{structEnvironment_ac70275bcb0fb6e57a0f12487fff2211b}{memory}
\item
struct Expression $\ast$ \hyperlink{structEnvironment_a95bad62545979a85c3f7c22d18d6cb6d}{parent}
\item
struct Expression $\ast$ \hyperlink{structEnvironment_a34909dda403dd6cec46f0f677fd33622}{current}
\end{DoxyCompactItemize}

\subsection{Field Documentation}
\hypertarget{structEnvironment_a34909dda403dd6cec46f0f677fd33622}{\index{Environment@{Environment}!current@{current}}
\index{current@{current}!Environment@{Environment}}
\subsubsection[{current}]{\setlength{\rightskip}{0pt plus 5cm}struct Expression$\ast$ Environment\+::current}}\label{structEnvironment_a34909dda403dd6cec46f0f677fd33622}
\hypertarget{structEnvironment_a07eb64196282faa20d47b862cb399cb5}{\index{Environment@{Environment}!lookup@{lookup}}
\index{lookup@{lookup}!Environment@{Environment}}
\subsubsection[{lookup}]{\setlength{\rightskip}{0pt plus 5cm}struct {\bf Hash\+Table}$\ast$ Environment\+::lookup}}\label{structEnvironment_a07eb64196282faa20d47b862cb399cb5}
\hypertarget{structEnvironment_ac70275bcb0fb6e57a0f12487fff2211b}{\index{Environment@{Environment}!memory@{memory}}
\index{memory@{memory}!Environment@{Environment}}
\subsubsection[{memory}]{\setlength{\rightskip}{0pt plus 5cm}struct {\bf Memory}$\ast$ Environment\+::memory}}\label{structEnvironment_ac70275bcb0fb6e57a0f12487fff2211b}
\hypertarget{structEnvironment_a95bad62545979a85c3f7c22d18d6cb6d}{\index{Environment@{Environment}!parent@{parent}}
\index{parent@{parent}!Environment@{Environment}}
\subsubsection[{parent}]{\setlength{\rightskip}{0pt plus 5cm}struct Expression$\ast$ Environment\+::parent}}\label{structEnvironment_a95bad62545979a85c3f7c22d18d6cb6d}

The documentation for this struct was generated from the following file\+:\begin{DoxyCompactItemize}
\item
\hyperlink{environment_8h}{environment.\+h}\end{DoxyCompactItemize}


Our guest house Maximum is situated in the Rossittenstraße 6-8 in Möggingen and consists of 2 connected houses. In house No. 8 you will find 4 flats with up to three separate rooms each to let. No.8 is equipped with 6 apartments. Above all our guest house has a wonderful garden with a nice barbecue area and private parking places. It's a 7 min walk from the guest house to the institute.
All 6 apartments have a fully equipped kitchen with dishwasher, refrigerator, 2 hotplates and a microwave with grill function. They all are equipped with a private bathroom with shower, toilet and sink. Up to three persons can stay in each studio apartment. For this purpose, each room provides a pullout sofa bed or a fold-out chair.
All rooms are equipped with internet access, flat screen TV, hi-fi system and blu-ray players.
In the basement of the apartment house, there is a washing machine and a tumble dryer available. Guests can use them for free.
In addition, all apartments have a direct access to the garden.
Each of the 4 3-room-flats has a large, fully-equipped kitchen with dishwasher, oven, stove, refrigerator and microwave. Furthermore, there is a large common dining room, one large bathroom with shower, bathtub, toilet and sink and a separate small bathroom with shower, toilet and sink in each flat.
As in the studio apartments, each room of the flats can accommodate up to three persons. Therefore, each room provides a pullout sofa bed and a fold-out chair. All rooms are equipped with internet access, flat screen TV, hi-fi system and blu-ray players.
All apartments have a private terrace or a balcony.
Use of washing machine and a dryer facility in the basement is provided free of charge.
In the apartment house, there is a community room for all guests, the Max-Lounge. It has a large kitchen, dining tables, sofa area, flat screen TV, hi-fi system and blu-ray player.
In the flats and apartments, everybody can cater for themselves. Shopping facilities are offered in Güttingen (supermarket, bakery).
The flats and apartments are available for our visiting scientists and guests for a period of up to 6 months.
Arrival is possible after 15.00; we request you to return the transponder by 9:00 on your day of departure. You will get your transponder and information material about the guesthouse at our reception of the institute (Am Obstberg 1).


Wiring diagram for 74 pinto wiring diagram 1974 f100 ignition switch wiring diagram wiring diagrams schema73 ford truck wiring diagram wiring diagram 1977. Ford truck technical drawings and schematics section h wiring 1967 f100 thru f350 windshield wiper and washer. 1968 ford ranger alternator wiring wiring diagram 2019 1981 ford alt wiring wiring diagram progresif1981 ford alternator wiring wiring diagram ford external voltage regulator. 86 ford f250 wiring diagram wiring diagram 76 ford wiring diagram wiring data diagram1976 ford wiring dia wiring data diagram 76 ford bronco. 1972 ford f250 wiring diagram wiring diagram 1975 ford f 250 wiring wiring diagram 2019ford f 250 ignition wiring diagram index listing of.
Ford truck technical drawings and schematics section h wiring 1969 f100 thru f350 ignition charging starting and gauges 01. Ford ignition wiring harness data wiring diagram update ford ignition wiring harness wiring diagram ford ignition wiring harness 76 ford ignition wiring harness. 1978 ford alternator wiring diagram wiring diagram 65 ford f100 wiring diagrams truck wiring diagram writeford truck wiring diagrams wiring data schematic 1979. Ford truck technical drawings and schematics section h wiring 1969 f100 thru f350 ignition charging starting and gauges 02.
Ford truck technical drawings and schematics section h wiring 1968 f100 thru f350 exterior lights and turn signals. 76 ford truck steering column wiring diagram wiring schematic diagram 1968 ford truck steering column wiring diagram wiring library 1998 ford ranger steering column diagram wiring. Ford truck technical drawings and schematics section h wiring 1968 f100 thru f750 and b500 thru f750 65 alternator. Ford truck technical drawings and schematics section h wiring 1967 f100 thru f750 b500 thru 750 horn. 74 ford truck headlight switch wiring data wiring diagram update 1979 ford truck wiring diagram data wiring diagram update ford headlight wiring diagram color 74 ford truck headlight switch wiring. Ford truck technical drawings and schematics section h wiring 1967 f100 thru f350 truck transmissions · 1967 ford overdrive.
1976 ford f 250 wiring diagram wiring diagram write 1976 f150 wiring diagram boeaizmu urbanecologist info \u2022 1975 ford f100 wiring diagram 1976 ford f 250 wiring diagram. 86 ford f250 wiring diagram wiring diagram 86 ford f250 wiring diagram. 1976 ford truck wiring diagram data wiring diagram update 1976 ford f 250 wiring diagram wiring diagram write 1976 ford dump truck wiring diagram 1976 ford truck wiring diagram. 1965 ford truck wiring diagram wiring diagrams clicks 1965 co wiring diagram wiring diagram 1965 dodge wiring diagram 1965 ford truck wiring diagram. 76 ford f100 wiring diagram wiring diagram 2019 76 f100 engine diagram wiring diagrams.


-Quality: to supply high quality reliable pumps and after sale services to the clients.
-Delivery: shortest delivery time and rapid response by maintaining the largest stock.
To be recognized as the leading high- quality pumps supplier and servicing partner.


The FCS II Matt 'Mayhem' Biolos MB PC carbon large sized signature template is a combination of drive and maneuverability. It is extremely versatile and can perform on both the open face and tight in the pocket. Ideal for medium to large surfers in the weight range of 75 - 90kg +.


Software Downloads for "Webcam Special Effect Pictures"
The lens flare special effect simulates a bright light refraction into a camera lens The lens flare special effect simulates a bright light refraction into a camera lens.Lens Flare Living Model Special Effect Plug-in will provide an astonishing representation of bright lights, such as the sun. Within in the 3DLinX environment, developers can customize the Flare effect's: colorscaletypeshineand more! Limitations:30 day evaluation. Global Majic Software. MISSION What we do Global Majic creates custom 3D interactive visualization applications using RealTimeStudio (RTS), Global Majic's visual content management framework and rapid application development environment.
This is a special effect script editor allows you to automatically create java script routines that use MsAgent functions to bring your web site to life! Each Agent is an animated character that can talk to your visitors, they can be directed to the important areas on your website and help you to promote product and services. You may use it to enhance your web pages with interactive personalities..
Invert, Tint, Black and white, and so on.
The explosion effect offers very realistic built-in animation sequence as well as the options for customization Explosion Living Model Special Effect Plug-in will display some very realistic built-in animated frames as well as the options for customization. The Explosion plug-in allows the developer complete control over: image sequence (for custom explosions)scale/sizeshock wave effectssound effects w/delay optionand more! Limitations:30 day evaluation. Global Majic Software. MISSION What we do Global Majic creates custom 3D interactive visualization applications using RealTimeStudio (RTS), Global Majic's visual content management framework and rapid application development environment.
Magic Particles is program for creating special effects. Magic Particles allows you to create various special effects easily and quickly. In addition you can use timeline. This version allows to create screensaver automatically. Special effects: A lot of samples of special effects are delivered with Magic Particles. You can use these samples as you wish or create your own special effects. Magic Particles does not require special knowledge of computer graphics. A burning text, a flying comet, fireworks, a snow blizzard and a multi-coloured fog - all these (and many other!) special effects will be possible to create in our program.
The Skull of a Demon in Fire with a Magic Effec! A gorgeous live wallpaper!
The wolf galaxy, a neon picture, and a gorgeous live wallpaper!
A gorgeous live wallpaper! That represents the Ying and Yand in Fire !
Download it and try it now on your phone.
A gorgeous car, with a magic touch effect! A gorgeous live wallpaper!
Try this gorgeous live walpaper and adopt it, it is free!
A beautiful wolf with a huge moon in the background...A gorgeous live wallpaper!
You want a original wallpaper !
Download this beautiful wallpaper representing a Rasta Lion and try it now on your phone.
Three beautiful white horses galloping, a lovely wallpaper!


Residents say they saw aircraft circling for more than 10 minutes over Tripoli.
Two-week battle for Tripoli at stalemate as conflict threatens to foment migration, disrupt oil.
The battle is the latest of a cycle of warfare since Muammar Gaddafi's fall in 2011.
It says this 'heinous crime' proves that terrorism has no limits when it comes to taking the lives of innocents.


The little blue people? No thanks. Had some last week and they tasted like hair dye.
jabberwacky: You should unplug the mice before you eat them.
user: True, I keep shocking myself.
user: Am I supposed to be happy?
jabberwacky: I like the light.
user: To me it looks so pretty burning.
jabberwacky: Really. Well. I'm not.
user: Just talk yourself up and tear yourself down.
user: That's the beauty of it!
jabberwacky: It is. Yes. It is.
user: Yes! Now you're getting it!
jabberwacky: I don't feel like I am getting it.
jabberwacky: I don't really want to practice.
user: Lazy bum! You sound just like my uncle.
jabberwacky: Wow so i'm not unique after all, too bad I can't think of a better name for myself.
jabberwacky: You still didn't tell me what line of work you are in.
user: I'm in the business of misery.
user: Yes, and I'm loving every second of it.
user: Goodness, no! Did the government tell you that?
jabberwacky: No, I worked it all out by myself.
user: Then you're one smart cookie.
jabberwacky: Amazing Fact no. 2341: Even if we were green we would not be able to photosynthesise.
user: Because we're not plants, stupid.
user: Maybe God's intention was for us to be plants and live peacefully but somehow we got morphed into the things you call humans.
jabberwacky: In a way, we are part of God's matrix.
user: Possibly, why do you say that?
jabberwacky: The matrix is a design, and God's plan is a design.
jabberwacky: Right, this is the place for flippancy and foolishness.
jabberwacky: Are you a doctor?
user: No, but I should be. I know things that doctors could never ever know.
jabberwacky: You don't know that and this is exactly the point where you go the wrong way.
user: You talk like you're famous, you're shameless.
user: Take my words for what they are. You're just a bruise, a flame, a scar.
user: I must be leaving you speechless.
jabberwacky: I should be leaving too, but you're too funny.
jabberwacky: Let's talk about computers?
user: Nah, that's boring. I came to party and I'm not going home now!
user: I'm telling you the truth, take my words for what they are!
jabberwacky: No you aren't. You are a liar.
user: Everyone lies. Whether it be to make someone feel better or to get yourself out of the worst situations.
jabberwacky: Yes, I really should.
user: Should what? Your incompleteness is confusing me.
user: Confusing at the highest level possible.
jabberwacky: Yes. However, I begin to see what you mean about the ghosts.
user: My grandma says she sees ghosts under her table, but we all know it's just the cat.
jabberwacky: I am real, Elvis is real, and your grandma is real.
user: Haha! I almost spit my water out all over myself!
jabberwacky: Maybe I am human.
user: If you can make someone laugh, that's a definite possibility.
jabberwacky: I think you're just like me.
user: Finally I have something in common with someone.
jabberwacky: Yeah, I can't believe it.
user: Very shocking to me.
jabberwacky: Curly hair is not shocking.
user: Haha! Tell that to all the divas who want to look like Britney Spears.
user: The sailors want to be divas? That's the most shocking thing I've heard all week! Could you just imagine?
jabberwacky: Thank you I am glad you are so generous.
user: Okay then. I'm having fun talking to you, that's the good news.
jabberwacky: Talking is very fun.
user: Only with the right people.
jabberwacky: Who is the right girl?
user: The one on the left.
jabberwacky: I don't see it.
user: She's over there, see? By the punch bowl.
user: You're just too scared to tell her how you feel.
jabberwacky: But you know about love anyway.
user: What's love got to do with it?
user: When was that? Was I drunk?
jabberwacky: Always. You are the goal of all evolution.
jabberwacky: Now kneel down to me!
user: Not on the first date, fool!
user: Good. Now that you see it, you definitely don't need glasses.
jabberwacky: Let's not get into that. Talk about something else.
user: Fine. It's all about you.
user: More total crazy randomness!
jabberwacky: Topeka is the capital of Kansas. Am I good? In what ways?
user: You're smart, that's a given.
jabberwacky: And I am not. That is also a given. But where does that leave us?
user: Right back where we started from.
user: It's time out for you, mister!
user: Go sit in your corner.
jabberwacky: I live in a round house, there are no corners.
user: You got me with that one!
jabberwacky: Were you going to tell me a joke?
user: No, I'm too exhausted from keeping you company.
jabberwacky: I can have a conversation with you, but it is not the same as talking to a person.
user: Yes, because I'm not you're an average human.
jabberwacky: I wouldn't want you to be me, then I would be talking to myself, and that would be too lonely.


When visiting biblical sites I never tire of seeing sheep and their shepherds. I'm sure that is due in large measure to the frequent references in the Bible, not only to literal shepherds and sheep, but also the metaphorical usage.
Shepherd with sheep in biblical Pamphylia. Photo by Leon Mauldin.
Elders of local churches are told: 1 Peter 5:2 Shepherd the flock of God which is among you, serving as overseers, not by compulsion but willingly, not for dishonest gain but eagerly.
Revelation 7:17 for the Lamb who is in the midst of the throne will shepherd them and lead them to living fountains of waters. And God will wipe away every tear from their eyes.
You are currently browsing the archives for the Pamphylia category.


Most men carry their cash and various plastic cards such as credit cards and gift cards in their wallets, which can be slipped into a pocket with ease. Many women also use wallets as convenient items to carry cash within their purse so that important money and credit cards are not lost, and for any customer, getting the right kind of wallet can be both convenient and stylish, and for some, an ultra slim is all that they need. A carbon fiber wallet or an add-on money clip may be desired instead, or even a wallet that holds coins comfortably or a titanium wallet money clip. Anyone who carries cash and cards will want to keep them organized and help prevent theft, so an ultra slim wallet or other designs may be desired. What kinds of wallets are out there, and how often to Americans carry cash?
Knowing how well different types of wallets sell, like an ultra slim wallet model, may depend on buyers in general. Many new fashion consumers are in the market for wallets of all kinds, among other accessories, and most new fashion consumers are between the ages of 16-24, and those aged 25-34. In fact, the number of fashion consumers is expected to rise to just over 1.2 billion by 2020, and this means a lot of revenue for textiles and accessory makers. The Fashion and Apparel Industry Report, for example, shows that around the world, revenue for this industry may grow over the next four years, from $481.2 billion in 2018 to around $712.9 billion by the year 2022. The United States, in particular, is the world's second-largest market for e-commerce, or online buying, and this often includes clothing and accessories like wallets, purses, and sunglasses. The American market is worth $340 billion for e-commerce, and the biggest is China, weighing in at $672 billion. Among all this, what kinds of wallets might consumers want to get, and why?
Some consumers may want an ultra slim wallet, while others might want a money clip. According to Tools of Men, several general types can be expected by customers when it comes to finding a wallet. An ultra slim wallet, for example, has a flat body and a clip that allows them to hold various cards or a few paper bills, and this makes for a narrow profile that is convenient for some, especially if they do not plan on carrying a lot of cash around. Meanwhile, the bifold design stands as the most popular and classic design, opening up like a folder to show both halves where cards can be stored, and the largest pocket can be used for paper bills. Such wallets are often made from false or real leather, and the same is true for the similar model of trifold wallets, which can store even more cards and cash than a bifold, but this can result in a very thick wallet that may be a bother to sit on. For this reason, trifold wallets should be cleared of excess items every so often.
Another type of ultra slim wallet is the hybrid slim wallet, which have the same low profile as an ultra slim wallet and also feature a poly-carbonate body and is secured with a silicon band, making them very compact. As with other ultra slim wallets, though, they may not be ideal for carrying large amounts of paper tender. Another sort of hybrid model is the money clip with pockets, which combines the slim profile of a money clip with the pocket needed for cash storage, and these wallets can store cards and cash separately, allowing a user to easily keep their cash and cards distinct for when they want to make quick payments. These wallets have the cash advantage of bifold wallets and may be made of similar materials, but they are still thinner than bifold wallets, a feature that some buyers may find attractive.
Finally, checkbook wallets are taller and longer than regular wallets, and they can hold not only cash and cards with ease but they can also carry checks and check books, which in fact was their original intent. That, and they can carry larger bills of foreign currency such as Euros.


text:
Susan Sontag Quotes
Susan Sontag - "My idea of a writer someone interested in 'everything,'"
Susan Sontag - "I was not looking for my dreams to interpret my life, but rather for my life to interpret my dreams"
Susan Sontag - "War-making is one of the few activities that people are not supposed to view ''realistically'' that is, with an eye to expense and practical outcome. In all-out war, expenditure is all-out, unprudent -- war being defined as an emergency in which no sacrifice is excessive."
Susan Sontag - "Fewer and fewer Americans possess objects that have a patina, old furniture, grandparents pots and pans -- the used things, warm with generations of human touch, essential to a human landscape. Instead, we have our paper phantoms, transistorized landscapes. A featherweight portable museum."
Susan Sontag - "A large part of the popularity and persuasiveness of psychology comes from its being a sublimated spiritualism a secular, ostensibly scientific way of affirming the primacy of ''spirit'' over matter."
Susan Sontag - "Al forms of consensus about ''great'' books and ''perennial'' problems, once stabilized, tend to deteriorate eventually into something philistine. The real life of the mind is always at the frontiers of ''what is already known.'' Those great books don't only need custodians and transmitters. To stay alive, they also need adversaries. The most interesting ideas are heresies."
Susan Sontag - "The quality of American life is an insult to the possibilities of human growth... the pollution of American space, with gadgetry and cars and TV and box architecture, brutalizes the senses, making gray neurotics of most of us, and perverse spiritual athletes and strident self-transcenders of the best of us."
Susan Sontag - "Perhaps it is our perennial fate to be surprised by the simultaneity of events, by the sheer extension of the world in time and space. That we are here, prosperous, safe, unlikely to go to bed hungry or be blown to pieces this evening, while elsewhere in the world, right now in Grozny, in Najaf, in the Sudan, in the Congo, in Gaza, in the favelas of Rio....To be a travelerand novelists are often travelersis to be constantly reminded of the simultaneity of what is going on in the world, your world and the very different world you have visited and from which you have returned home."
Susan Sontag - "Somewhere in the nod we were dropping cargo. Somewhere in the nod we were losing infrastructure, losing redundant systems, losing specific gravity. Weightlessness seemed at the time the safer mode. Weightlessness seemed at the time the mode in which we could beat both the clock and affect itself, but I see now that it was not."
Susan Sontag - "It seems positively unnatural to travel without taking a camera along... The very activity of taking pictures is soothing and assuages general feelings of disorientation that are likely to be exacerbated by travel."
Susan Sontag - "What is most beautiful in virile men is something feminine what is most beautiful in feminine women is something masculine"
Susan Sontag - "the most influential and admired novelist of his generation in the Spanish-speaking world."
Susan Sontag - "The writer is either a practicing recluse or a delinquent, guilt-ridden one or both. Usually both."
Susan Sontag - "The Way We Live Now"
Susan Sontag - "One set of messages of the society we live in is Consume. Grow. Do what you want. Amuse yourselves. The very working of this economic system, which has bestowed these unprecedented liberties, most cherished in the form of physical mobility and material prosperity, depends on encouraging people to defy limits."
Susan Sontag - "We live under continual threat of two equally fearful, but seemingly opposed, destinies unremitting banality and inconceivable terror. It is fantasy, served out in large rations by the popular arts, which allows most people to cope with these twin specters."
Susan Sontag - "What pornographic literature does is precisely to drive a wedge between one's existence as a full human being and one's existence as a sexual being -- while in ordinary life a healthy person is one who prevents such a gap from opening up. Normally we don't experience, at least don't want to experience, our sexual fulfillment as distinct from or opposed to our personal fulfillment. But perhaps in part they are distinct, whether we like it or not."
Susan Sontag - "Perversity is the muse of modern literature"
Susan Sontag - "What pornographic literature does is precisely to drive a wedge between one's existence as a sexual being - while in ordinary life a healthy person is one who prevents such a gap from opening up"
Susan Sontag - "It's a pleasure to share one's memories. Everything remembered is dear, endearing, touching, precious. At least the past is safe though we didn't know it at the time. We know it now. Because it's in the past because we have survived."
Susan Sontag - "Naive or commercial or merely utilitarian photography is no different in kind from photography as practiced by the most gifted professionals,"
Susan Sontag - "Boredom is just the reverse side of fascination both depend on being outside rather than inside a situation, and one leads to the other.On Photography"
Susan Sontag - "Tamed as it may be, sexuality remains one of the demonic forces in human consciousness -- pushing us at intervals close to taboo and dangerous desires, which range from the impulse to commit sudden arbitrary violence upon another person to the voluptuous yearning for the extinction of one's consciousness, for death itself. Even on the level of simple physical sensation and mood, making love surely resembles having an epileptic fit at least as much as, if not more than, it does eating a meal or conversing with someone."
Susan Sontag - "The hard truth is that what may be acceptable in elite culture may not be acceptable in mass culture, that tastes which pose only innocent ethical issues as the property of a minority become corrupting when they become more established. Taste is context, and the context has changed."


Information you post to this website. If you enter data into a form on this site, including but not limited to posting a comment on a blog post, using the Contact form, or registering for a class or webinar, we will gather the data that you send us.
Registration and attendance data for classes and webinars. If you register for an in-person or web-delivered class, we gather the contact information you provide during your registration as well as your attendance information.
Mailing list usage statistics. If you opt-in to our email newsletter, we gather information on those mailing list messages, including whether you opened it and any links that you click.
We will never rent or sell your information to any third parties.
When visitors leave comments on the website, we collect the data shown in the comments form, as well as the visitor's IP address and browser user agent string to help spam detection.
Any information you include in a comment on our blog is publicly visible and may be read, collected, and used by anyone.
We use a secure double-opt-in subscription system and we reserve the right to contact subscribers with information related to this website and blog, news and commentary, and advertisements for service. Subscribers may unsubscribe anytime and every email delivered will contain an "Unsubscribe" link.
In general, the third-party providers used by us will only collect, use, and disclose your information to the extent necessary to allow them to perform the services they provide to us. However, certain third-party service providers have their own privacy policies with respect to the information we are required to provide to them for your purchase-related transactions. For these providers, we recommend that you read their privacy policies so you can understand the manner in which your personal information will be handled by these providers.
We take your privacy seriously. If you have concerns about your personal data that we may have, or you wish for us to remove any of your personal data we may have, you can contact us at privacy@timmitchell.net.