text:
import itertools
from typing import Any, Dict, List, Optional, Tuple, Union

from moto.packages.boto.ec2.blockdevicemapping import (
    BlockDeviceType,
    BlockDeviceMapping,
)
from moto.ec2.exceptions import InvalidInstanceIdError

from collections import OrderedDict
from moto.core import BaseBackend, BackendDict, BaseModel, CloudFormationModel
from moto.core.utils import camelcase_to_underscores
from moto.ec2 import ec2_backends
from moto.ec2.models import EC2Backend
from moto.ec2.models.instances import Instance
from moto.elb.models import elb_backends, ELBBackend
from moto.elbv2.models import elbv2_backends, ELBv2Backend
from moto.elb.exceptions import LoadBalancerNotFoundError
from moto.moto_api._internal import mock_random as random
from .exceptions import (
    AutoscalingClientError,
    ResourceContentionError,
    InvalidInstanceError,
    ValidationError,
)

# http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/AS_Concepts.html#Cooldown
DEFAULT_COOLDOWN = 300

ASG_NAME_TAG = "aws:autoscaling:groupName"

class InstanceState(object):
    def __init__(
        self,
        instance: "Instance",
        lifecycle_state: str = "InService",
        health_status: str = "Healthy",
        protected_from_scale_in: Optional[bool] = False,
        autoscaling_group: Optional["FakeAutoScalingGroup"] = None,
    ):
        self.instance = instance
        self.lifecycle_state = lifecycle_state
        self.health_status = health_status
        self.protected_from_scale_in = protected_from_scale_in
        if not hasattr(self.instance, "autoscaling_group"):
            self.instance.autoscaling_group = autoscaling_group  # type: ignore[attr-defined]

class FakeLifeCycleHook(BaseModel):
    def __init__(
        self,
        name: str,
        as_name: str,
        transition: Optional[str],
        timeout: Optional[int],
        result: Optional[str],
    ):
        self.name = name
        self.as_name = as_name
        if transition:
            self.transition = transition
        if timeout:
            self.timeout = timeout
        else:
            self.timeout = 3600
        if result:
            self.result = result
        else:
            self.result = "ABANDON"

class FakeScalingPolicy(BaseModel):
    def __init__(
        self,
        name: str,
        policy_type: str,
        metric_aggregation_type: str,
        adjustment_type: str,
        as_name: str,
        min_adjustment_magnitude: str,
        scaling_adjustment: Optional[int],
        cooldown: Optional[int],
        target_tracking_config: str,
        step_adjustments: str,
        estimated_instance_warmup: str,
        predictive_scaling_configuration: str,
        autoscaling_backend: "AutoScalingBackend",
    ):
        self.name = name
        self.policy_type = policy_type
        self.metric_aggregation_type = metric_aggregation_type
        self.adjustment_type = adjustment_type
        self.as_name = as_name
        self.min_adjustment_magnitude = min_adjustment_magnitude
        self.scaling_adjustment = scaling_adjustment
        if cooldown is not None:
            self.cooldown = cooldown
        else:
            self.cooldown = DEFAULT_COOLDOWN
        self.target_tracking_config = target_tracking_config
        self.step_adjustments = step_adjustments
        self.estimated_instance_warmup = estimated_instance_warmup
        self.predictive_scaling_configuration = predictive_scaling_configuration
        self.autoscaling_backend = autoscaling_backend

    @property
    def arn(self) -> str:
        return f"arn:aws:autoscaling:{self.autoscaling_backend.region_name}:{self.autoscaling_backend.account_id}:scalingPolicy:c322761b-3172-4d56-9a21-0ed9d6161d67:autoScalingGroupName/{self.as_name}:policyName/{self.name}"

    def execute(self) -> None:
        if self.adjustment_type == "ExactCapacity":
            self.autoscaling_backend.set_desired_capacity(
                self.as_name, self.scaling_adjustment
            )
        elif self.adjustment_type == "ChangeInCapacity":
            self.autoscaling_backend.change_capacity(
                self.as_name, self.scaling_adjustment
            )
        elif self.adjustment_type == "PercentChangeInCapacity":
            self.autoscaling_backend.change_capacity_percent(
                self.as_name, self.scaling_adjustment
            )

class FakeLaunchConfiguration(CloudFormationModel):
    def __init__(
        self,
        name: str,
        image_id: str,
        key_name: Optional[str],
        ramdisk_id: str,
        kernel_id: str,
        security_groups: List[str],
        user_data: str,
        instance_type: str,
        instance_monitoring: bool,
        instance_profile_name: Optional[str],
        spot_price: Optional[str],
        ebs_optimized: str,
        associate_public_ip_address: Union[str, bool],
        block_device_mapping_dict: List[Dict[str, Any]],
        account_id: str,
        region_name: str,
        metadata_options: Optional[str],
        classic_link_vpc_id: Optional[str],
        classic_link_vpc_security_groups: Optional[str],
    ):
        self.name = name
        self.image_id = image_id
        self.key_name = key_name
        self.ramdisk_id = ramdisk_id
        self.kernel_id = kernel_id
        self.security_groups = security_groups if security_groups else []
        self.user_data = user_data
        self.instance_type = instance_type
        self.instance_monitoring = instance_monitoring
        self.instance_profile_name = instance_profile_name
        self.spot_price = spot_price
        self.ebs_optimized = ebs_optimized
        if isinstance(associate_public_ip_address, str):
            self.associate_public_ip_address = (
                associate_public_ip_address.lower() == "true"
            )
        else:
            self.associate_public_ip_address = associate_public_ip_address
        self.block_device_mapping_dict = block_device_mapping_dict
        self.metadata_options = metadata_options
        self.classic_link_vpc_id = classic_link_vpc_id
        self.classic_link_vpc_security_groups = classic_link_vpc_security_groups
        self.arn = f"arn:aws:autoscaling:{region_name}:{account_id}:launchConfiguration:9dbbbf87-6141-428a-a409-0752edbe6cad:launchConfigurationName/{self.name}"

    @classmethod
    def create_from_instance(
        cls, name: str, instance: Instance, backend: "AutoScalingBackend"
    ) -> "FakeLaunchConfiguration":
        config = backend.create_launch_configuration(
            name=name,
            image_id=instance.image_id,
            kernel_id="",
            ramdisk_id="",
            key_name=instance.key_name,
            security_groups=instance.security_groups,
            user_data=instance.user_data,
            instance_type=instance.instance_type,
            instance_monitoring=False,
            instance_profile_name=None,
            spot_price=None,
            ebs_optimized=instance.ebs_optimized,
            associate_public_ip_address=instance.associate_public_ip,
            # We expect a dictionary in the same format as when the user calls it
            block_device_mappings=instance.block_device_mapping.to_source_dict(),
        )
        return config

    @staticmethod
    def cloudformation_name_type() -> str:
        return "LaunchConfigurationName"

    @staticmethod
    def cloudformation_type() -> str:
        # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-launchconfiguration.html
        return "AWS::AutoScaling::LaunchConfiguration"

    @classmethod
    def create_from_cloudformation_json(  # type: ignore[misc]
        cls,
        resource_name: str,
        cloudformation_json: Any,
        account_id: str,
        region_name: str,
        **kwargs: Any,
    ) -> "FakeLaunchConfiguration":
        properties = cloudformation_json["Properties"]

        instance_profile_name = properties.get("IamInstanceProfile")

        backend = autoscaling_backends[account_id][region_name]
        config = backend.create_launch_configuration(
            name=resource_name,
            image_id=properties.get("ImageId"),
            kernel_id=properties.get("KernelId"),
            ramdisk_id=properties.get("RamdiskId"),
            key_name=properties.get("KeyName"),
            security_groups=properties.get("SecurityGroups"),
            user_data=properties.get("UserData"),
            instance_type=properties.get("InstanceType"),
            instance_monitoring=properties.get("InstanceMonitoring"),
            instance_profile_name=instance_profile_name,
            spot_price=properties.get("SpotPrice"),
            ebs_optimized=properties.get("EbsOptimized"),
            associate_public_ip_address=properties.get("AssociatePublicIpAddress"),
            block_device_mappings=properties.get("BlockDeviceMapping.member"),
        )
        return config

    @classmethod
    def update_from_cloudformation_json(  # type: ignore[misc]
        cls,
        original_resource: Any,
        new_resource_name: str,
        cloudformation_json: Any,
        account_id: str,
        region_name: str,
    ) -> "FakeLaunchConfiguration":
        cls.delete_from_cloudformation_json(
            original_resource.name, cloudformation_json, account_id, region_name
        )
        return cls.create_from_cloudformation_json(
            new_resource_name, cloudformation_json, account_id, region_name
        )

    @classmethod
    def delete_from_cloudformation_json(  # type: ignore[misc]
        cls,
        resource_name: str,
        cloudformation_json: Any,
        account_id: str,
        region_name: str,
    ) -> None:
        backend = autoscaling_backends[account_id][region_name]
        try:
            backend.delete_launch_configuration(resource_name)
        except KeyError:
            pass

    def delete(self, account_id: str, region_name: str) -> None:
        backend = autoscaling_backends[account_id][region_name]
        backend.delete_launch_configuration(self.name)

    @property
    def physical_resource_id(self) -> str:
        return self.name

    @property
    def block_device_mappings(self) -> Optional[BlockDeviceMapping]:
        if not self.block_device_mapping_dict:
            return None
        else:
            return self._parse_block_device_mappings()

    @property
    def instance_monitoring_enabled(self) -> str:
        if self.instance_monitoring:
            return "true"
        return "false"

    def _parse_block_device_mappings(self) -> BlockDeviceMapping:
        block_device_map = BlockDeviceMapping()
        for mapping in self.block_device_mapping_dict:
            block_type = BlockDeviceType()
            mount_point = mapping.get("DeviceName")
            if mapping.get("VirtualName") and "ephemeral" in mapping.get("VirtualName"):  # type: ignore[operator]
                block_type.ephemeral_name = mapping.get("VirtualName")
            elif mapping.get("NoDevice", "false") == "true":
                block_type.no_device = "true"
            else:
                ebs = mapping.get("Ebs", {})
                block_type.volume_type = ebs.get("VolumeType")
                block_type.snapshot_id = ebs.get("SnapshotId")
                block_type.delete_on_termination = ebs.get("DeleteOnTermination")
                block_type.size = ebs.get("VolumeSize")
                block_type.iops = ebs.get("Iops")
                block_type.throughput = ebs.get("Throughput")
                block_type.encrypted = ebs.get("Encrypted")
            block_device_map[mount_point] = block_type
        return block_device_map

class FakeScheduledAction(CloudFormationModel):
    def __init__(
        self,
        name: str,
        desired_capacity: Optional[int],
        max_size: Optional[int],
        min_size: Optional[int],
        scheduled_action_name: str,
        start_time: str,
        end_time: str,
        recurrence: str,
    ):

        self.name = name
        self.desired_capacity = desired_capacity
        self.max_size = max_size
        self.min_size = min_size
        self.start_time = start_time
        self.end_time = end_time
        self.recurrence = recurrence
        self.scheduled_action_name = scheduled_action_name

    @staticmethod
    def cloudformation_name_type() -> str:
        return "ScheduledActionName"

    @staticmethod
    def cloudformation_type() -> str:
        # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-scheduledaction.html
        return "AWS::AutoScaling::ScheduledAction"

    @classmethod
    def create_from_cloudformation_json(  # type: ignore[misc]
        cls,
        resource_name: str,
        cloudformation_json: Dict[str, Any],
        account_id: str,
        region_name: str,
        **kwargs: Any,
    ) -> "FakeScheduledAction":

        properties = cloudformation_json["Properties"]

        backend = autoscaling_backends[account_id][region_name]

        scheduled_action_name = (
            kwargs["LogicalId"]
            if kwargs.get("LogicalId")
            else "ScheduledScalingAction-{random.randint(0,100)}"
        )

        scheduled_action = backend.put_scheduled_update_group_action(
            name=properties.get("AutoScalingGroupName"),
            desired_capacity=properties.get("DesiredCapacity"),
            max_size=properties.get("MaxSize"),
            min_size=properties.get("MinSize"),
            scheduled_action_name=scheduled_action_name,
            start_time=properties.get("StartTime"),
            end_time=properties.get("EndTime"),
            recurrence=properties.get("Recurrence"),
        )
        return scheduled_action

def set_string_propagate_at_launch_booleans_on_tags(
    tags: List[Dict[str, Any]]
) -> List[Dict[str, Any]]:
    bool_to_string = {True: "true", False: "false"}
    for tag in tags:
        if "PropagateAtLaunch" in tag:
            tag["PropagateAtLaunch"] = bool_to_string[tag["PropagateAtLaunch"]]
    return tags

class FakeAutoScalingGroup(CloudFormationModel):
    def __init__(
        self,
        name: str,
        availability_zones: List[str],
        desired_capacity: Optional[int],
        max_size: Optional[int],
        min_size: Optional[int],
        launch_config_name: str,
        launch_template: Dict[str, Any],
        vpc_zone_identifier: str,
        default_cooldown: Optional[int],
        health_check_period: Optional[int],
        health_check_type: Optional[str],
        load_balancers: List[str],
        target_group_arns: List[str],
        placement_group: str,
        termination_policies: List[str],
        autoscaling_backend: "AutoScalingBackend",
        ec2_backend: EC2Backend,
        tags: List[Dict[str, str]],
        mixed_instance_policy: Optional[Dict[str, Any]],
        capacity_rebalance: bool,
        new_instances_protected_from_scale_in: bool = False,
    ):
        self.autoscaling_backend = autoscaling_backend
        self.ec2_backend = ec2_backend
        self.name = name
        self._id = str(random.uuid4())
        self.region = self.autoscaling_backend.region_name
        self.account_id = self.autoscaling_backend.account_id
        self.service_linked_role = f"arn:aws:iam::{self.account_id}:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling"

        self.vpc_zone_identifier: Optional[str] = None
        self._set_azs_and_vpcs(availability_zones, vpc_zone_identifier)

        self.max_size = max_size
        self.min_size = min_size

        self.launch_template = None
        self.launch_config = None

        self._set_launch_configuration(
            launch_config_name, launch_template, mixed_instance_policy
        )
        self.mixed_instance_policy = mixed_instance_policy

        self.default_cooldown = (
            default_cooldown if default_cooldown else DEFAULT_COOLDOWN
        )
        self.health_check_period = health_check_period
        self.health_check_type = health_check_type if health_check_type else "EC2"
        self.load_balancers = load_balancers
        self.target_group_arns = target_group_arns
        self.placement_group = placement_group
        self.capacity_rebalance = capacity_rebalance
        self.termination_policies = termination_policies or ["Default"]
        self.new_instances_protected_from_scale_in = (
            new_instances_protected_from_scale_in
        )

        self.suspended_processes: List[str] = []
        self.instance_states: List[InstanceState] = []
        self.tags: List[Dict[str, str]] = tags or []
        self.set_desired_capacity(desired_capacity)

        self.metrics: List[str] = []

    @property
    def tags(self) -> List[Dict[str, str]]:
        return self._tags

    @tags.setter
    def tags(self, tags: List[Dict[str, str]]) -> None:
        for tag in tags:
            if "resource_id" not in tag or not tag["resource_id"]:
                tag["resource_id"] = self.name
            if "resource_type" not in tag or not tag["resource_type"]:
                tag["resource_type"] = "auto-scaling-group"
        self._tags = tags

    @property
    def arn(self) -> str:
        return f"arn:aws:autoscaling:{self.region}:{self.account_id}:autoScalingGroup:{self._id}:autoScalingGroupName/{self.name}"

    def active_instances(self) -> List[InstanceState]:
        return [x for x in self.instance_states if x.lifecycle_state == "InService"]

    def _set_azs_and_vpcs(
        self,
        availability_zones: List[str],
        vpc_zone_identifier: Optional[str],
        update: bool = False,
    ) -> None:
        # for updates, if only AZs are provided, they must not clash with
        # the AZs of existing VPCs
        if update and availability_zones and not vpc_zone_identifier:
            vpc_zone_identifier = self.vpc_zone_identifier

        if vpc_zone_identifier:
            # extract azs for vpcs
            subnet_ids = vpc_zone_identifier.split(",")
            subnets = self.autoscaling_backend.ec2_backend.get_all_subnets(
                subnet_ids=subnet_ids
            )
            vpc_zones = [subnet.availability_zone for subnet in subnets]

            if availability_zones and set(availability_zones) != set(vpc_zones):
                raise AutoscalingClientError(
                    "ValidationError",
                    "The availability zones of the specified subnets and the Auto Scaling group do not match",
                )
            availability_zones = vpc_zones
        elif not availability_zones:
            if not update:
                raise AutoscalingClientError(
                    "ValidationError",
                    "At least one Availability Zone or VPC Subnet is required.",
                )
            return

        self.availability_zones = availability_zones
        self.vpc_zone_identifier = vpc_zone_identifier

    def _set_launch_configuration(
        self,
        launch_config_name: str,
        launch_template: Dict[str, Any],
        mixed_instance_policy: Optional[Dict[str, Any]],
    ) -> None:
        if launch_config_name:
            self.launch_config = self.autoscaling_backend.launch_configurations[
                launch_config_name
            ]
            self.launch_config_name = launch_config_name

        if launch_template or mixed_instance_policy:
            if launch_template:
                launch_template_id = launch_template.get("launch_template_id")
                launch_template_name = launch_template.get("launch_template_name")
                self.launch_template_version = (
                    launch_template.get("version") or "$Default"
                )
            elif mixed_instance_policy:
                spec = mixed_instance_policy["LaunchTemplate"][
                    "LaunchTemplateSpecification"
                ]
                launch_template_id = spec.get("LaunchTemplateId")
                launch_template_name = spec.get("LaunchTemplateName")
                self.launch_template_version = spec.get("Version") or "$Default"

            if not (launch_template_id or launch_template_name) or (
                launch_template_id and launch_template_name
            ):
                raise ValidationError(
                    "Valid requests must contain either launchTemplateId or LaunchTemplateName"
                )

            if launch_template_id:
                self.launch_template = self.ec2_backend.get_launch_template(
                    launch_template_id
                )
            elif launch_template_name:
                self.launch_template = self.ec2_backend.get_launch_template_by_name(
                    launch_template_name
                )

    @staticmethod
    def cloudformation_name_type() -> str:
        return "AutoScalingGroupName"

    @staticmethod
    def cloudformation_type() -> str:
        # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-autoscalinggroup.html
        return "AWS::AutoScaling::AutoScalingGroup"

    @classmethod
    def create_from_cloudformation_json(  # type: ignore[misc]
        cls,
        resource_name: str,
        cloudformation_json: Dict[str, Any],
        account_id: str,
        region_name: str,
        **kwargs: Any,
    ) -> "FakeAutoScalingGroup":
        properties = cloudformation_json["Properties"]

        launch_config_name = properties.get("LaunchConfigurationName")
        launch_template = {
            camelcase_to_underscores(k): v
            for k, v in properties.get("LaunchTemplate", {}).items()
        }
        load_balancer_names = properties.get("LoadBalancerNames", [])
        target_group_arns = properties.get("TargetGroupARNs", [])

        backend = autoscaling_backends[account_id][region_name]
        group = backend.create_auto_scaling_group(
            name=resource_name,
            availability_zones=properties.get("AvailabilityZones", []),
            desired_capacity=properties.get("DesiredCapacity"),
            max_size=properties.get("MaxSize"),
            min_size=properties.get("MinSize"),
            launch_config_name=launch_config_name,
            launch_template=launch_template,
            vpc_zone_identifier=(
                ",".join(properties.get("VPCZoneIdentifier", [])) or None
            ),
            default_cooldown=properties.get("Cooldown"),
            health_check_period=properties.get("HealthCheckGracePeriod"),
            health_check_type=properties.get("HealthCheckType"),
            load_balancers=load_balancer_names,
            target_group_arns=target_group_arns,
            placement_group=None,
            termination_policies=properties.get("TerminationPolicies", []),
            tags=set_string_propagate_at_launch_booleans_on_tags(
                properties.get("Tags", [])
            ),
            new_instances_protected_from_scale_in=properties.get(
                "NewInstancesProtectedFromScaleIn", False
            ),
        )
        return group

    @classmethod
    def update_from_cloudformation_json(  # type: ignore[misc]
        cls,
        original_resource: Any,
        new_resource_name: str,
        cloudformation_json: Dict[str, Any],
        account_id: str,
        region_name: str,
    ) -> "FakeAutoScalingGroup":
        cls.delete_from_cloudformation_json(
            original_resource.name, cloudformation_json, account_id, region_name
        )
        return cls.create_from_cloudformation_json(
            new_resource_name, cloudformation_json, account_id, region_name
        )

    @classmethod
    def delete_from_cloudformation_json(  # type: ignore[misc]
        cls,
        resource_name: str,
        cloudformation_json: Dict[str, Any],
        account_id: str,
        region_name: str,
    ) -> None:
        backend = autoscaling_backends[account_id][region_name]
        try:
            backend.delete_auto_scaling_group(resource_name)
        except KeyError:
            pass

    def delete(self, account_id: str, region_name: str) -> None:
        backend = autoscaling_backends[account_id][region_name]
        backend.delete_auto_scaling_group(self.name)

    @property
    def physical_resource_id(self) -> str:
        return self.name

    @property
    def image_id(self) -> str:
        if self.launch_template:
            version = self.launch_template.get_version(self.launch_template_version)
            return version.image_id

        return self.launch_config.image_id  # type: ignore[union-attr]

    @property
    def instance_type(self) -> str:
        if self.launch_template:
            version = self.launch_template.get_version(self.launch_template_version)
            return version.instance_type

        return self.launch_config.instance_type  # type: ignore[union-attr]

    @property
    def user_data(self) -> str:
        if self.launch_template:
            version = self.launch_template.get_version(self.launch_template_version)
            return version.user_data

        return self.launch_config.user_data  # type: ignore[union-attr]

    @property
    def security_groups(self) -> List[str]:
        if self.launch_template:
            version = self.launch_template.get_version(self.launch_template_version)
            return version.security_groups

        return self.launch_config.security_groups  # type: ignore[union-attr]

    def update(
        self,
        availability_zones: List[str],
        desired_capacity: Optional[int],
        max_size: Optional[int],
        min_size: Optional[int],
        launch_config_name: str,
        launch_template: Dict[str, Any],
        vpc_zone_identifier: str,
        health_check_period: int,
        health_check_type: str,
        new_instances_protected_from_scale_in: Optional[bool] = None,
    ) -> None:
        self._set_azs_and_vpcs(availability_zones, vpc_zone_identifier, update=True)

        if max_size is not None:
            self.max_size = max_size
        if min_size is not None:
            self.min_size = min_size

        if desired_capacity is None:
            if min_size is not None and min_size > len(self.instance_states):
                desired_capacity = min_size
            if max_size is not None and max_size < len(self.instance_states):
                desired_capacity = max_size

        self._set_launch_configuration(
            launch_config_name, launch_template, mixed_instance_policy=None
        )

        if health_check_period is not None:
            self.health_check_period = health_check_period
        if health_check_type is not None:
            self.health_check_type = health_check_type
        if new_instances_protected_from_scale_in is not None:
            self.new_instances_protected_from_scale_in = (
                new_instances_protected_from_scale_in
            )

        if desired_capacity is not None:
            self.set_desired_capacity(desired_capacity)

    def set_desired_capacity(self, new_capacity: Optional[int]) -> None:
        if new_capacity is None:
            self.desired_capacity = self.min_size
        else:
            self.desired_capacity = new_capacity

        curr_instance_count = len(self.active_instances())

        if self.desired_capacity == curr_instance_count:
            pass  # Nothing to do here
        elif self.desired_capacity > curr_instance_count:  # type: ignore[operator]
            # Need more instances
            count_needed = int(self.desired_capacity) - int(curr_instance_count)  # type: ignore[arg-type]

            propagated_tags = self.get_propagated_tags()
            self.replace_autoscaling_group_instances(count_needed, propagated_tags)
        else:
            # Need to remove some instances
            count_to_remove = curr_instance_count - self.desired_capacity  # type: ignore[operator]
            instances_to_remove = [  # only remove unprotected
                state
                for state in self.instance_states
                if not state.protected_from_scale_in
            ][:count_to_remove]
            if instances_to_remove:  # just in case not instances to remove
                instance_ids_to_remove = [
                    instance.instance.id for instance in instances_to_remove
                ]
                self.autoscaling_backend.ec2_backend.terminate_instances(
                    instance_ids_to_remove
                )
                self.instance_states = list(
                    set(self.instance_states) - set(instances_to_remove)
                )
        if self.name in self.autoscaling_backend.autoscaling_groups:
            self.autoscaling_backend.update_attached_elbs(self.name)
            self.autoscaling_backend.update_attached_target_groups(self.name)

    def get_propagated_tags(self) -> Dict[str, str]:
        propagated_tags = {}
        for tag in self.tags:
            # boto uses 'propagate_at_launch
            # boto3 and cloudformation use PropagateAtLaunch
            if "propagate_at_launch" in tag and tag["propagate_at_launch"] == "true":
                propagated_tags[tag["key"]] = tag["value"]
            if "PropagateAtLaunch" in tag and tag["PropagateAtLaunch"] == "true":
                propagated_tags[tag["Key"]] = tag["Value"]
        return propagated_tags

    def replace_autoscaling_group_instances(
        self, count_needed: int, propagated_tags: Dict[str, str]
    ) -> None:
        propagated_tags[ASG_NAME_TAG] = self.name

        # VPCZoneIdentifier:
        # A comma-separated list of subnet IDs for a virtual private cloud (VPC) where instances in the Auto Scaling group can be created.
        # We'll create all instances in a single subnet to make things easier
        subnet_id = (
            self.vpc_zone_identifier.split(",")[0] if self.vpc_zone_identifier else None
        )
        associate_public_ip = (
            self.launch_config.associate_public_ip_address
            if self.launch_config
            else None
        )
        reservation = self.autoscaling_backend.ec2_backend.add_instances(
            self.image_id,
            count_needed,
            self.user_data,
            self.security_groups,
            instance_type=self.instance_type,
            tags={"instance": propagated_tags},
            placement=random.choice(self.availability_zones),
            launch_config=self.launch_config,
            is_instance_type_default=False,
            associate_public_ip=associate_public_ip,
            subnet_id=subnet_id,
        )
        for instance in reservation.instances:
            instance.autoscaling_group = self
            self.instance_states.append(
                InstanceState(
                    instance,
                    protected_from_scale_in=self.new_instances_protected_from_scale_in,
                )
            )

    def append_target_groups(self, target_group_arns: List[str]) -> None:
        append = [x for x in target_group_arns if x not in self.target_group_arns]
        self.target_group_arns.extend(append)

    def enable_metrics_collection(self, metrics: List[str]) -> None:
        self.metrics = metrics or []

class AutoScalingBackend(BaseBackend):
    def __init__(self, region_name: str, account_id: str):
        super().__init__(region_name, account_id)
        self.autoscaling_groups: Dict[str, FakeAutoScalingGroup] = OrderedDict()
        self.launch_configurations: Dict[str, FakeLaunchConfiguration] = OrderedDict()
        self.scheduled_actions: Dict[str, FakeScheduledAction] = OrderedDict()
        self.policies: Dict[str, FakeScalingPolicy] = {}
        self.lifecycle_hooks: Dict[str, FakeLifeCycleHook] = {}
        self.ec2_backend: EC2Backend = ec2_backends[self.account_id][region_name]
        self.elb_backend: ELBBackend = elb_backends[self.account_id][region_name]
        self.elbv2_backend: ELBv2Backend = elbv2_backends[self.account_id][region_name]

    @staticmethod
    def default_vpc_endpoint_service(service_region: str, zones: List[str]) -> List[Dict[str, Any]]:  # type: ignore[misc]
        """Default VPC endpoint service."""
        return BaseBackend.default_vpc_endpoint_service_factory(
            service_region, zones, "autoscaling"
        ) + BaseBackend.default_vpc_endpoint_service_factory(
            service_region, zones, "autoscaling-plans"
        )

    def create_launch_configuration(
        self,
        name: str,
        image_id: str,
        key_name: Optional[str],
        kernel_id: str,
        ramdisk_id: str,
        security_groups: List[str],
        user_data: str,
        instance_type: str,
        instance_monitoring: bool,
        instance_profile_name: Optional[str],
        spot_price: Optional[str],
        ebs_optimized: str,
        associate_public_ip_address: str,
        block_device_mappings: List[Dict[str, Any]],
        instance_id: Optional[str] = None,
        metadata_options: Optional[str] = None,
        classic_link_vpc_id: Optional[str] = None,
        classic_link_vpc_security_groups: Optional[str] = None,
    ) -> FakeLaunchConfiguration:
        valid_requests = [
            instance_id is not None,
            image_id is not None and instance_type is not None,
        ]
        if not any(valid_requests):
            raise ValidationError(
                "Valid requests must contain either the InstanceID parameter or both the ImageId and InstanceType parameters."
            )
        if instance_id is not None:
            # TODO: https://docs.aws.amazon.com/autoscaling/ec2/userguide/create-lc-with-instanceID.html
            pass
        launch_configuration = FakeLaunchConfiguration(
            name=name,
            image_id=image_id,
            key_name=key_name,
            kernel_id=kernel_id,
            ramdisk_id=ramdisk_id,
            security_groups=security_groups,
            user_data=user_data,
            instance_type=instance_type,
            instance_monitoring=instance_monitoring,
            instance_profile_name=instance_profile_name,
            spot_price=spot_price,
            ebs_optimized=ebs_optimized,
            associate_public_ip_address=associate_public_ip_address,
            block_device_mapping_dict=block_device_mappings,
            account_id=self.account_id,
            region_name=self.region_name,
            metadata_options=metadata_options,
            classic_link_vpc_id=classic_link_vpc_id,
            classic_link_vpc_security_groups=classic_link_vpc_security_groups,
        )
        self.launch_configurations[name] = launch_configuration
        return launch_configuration

    def describe_launch_configurations(
        self, names: Optional[List[str]]
    ) -> List[FakeLaunchConfiguration]:
        configurations = self.launch_configurations.values()
        if names:
            return [
                configuration
                for configuration in configurations
                if configuration.name in names
            ]
        else:
            return list(configurations)

    def delete_launch_configuration(self, launch_configuration_name: str) -> None:
        self.launch_configurations.pop(launch_configuration_name, None)

    def make_int(self, value: Union[None, str, int]) -> Optional[int]:
        return int(value) if value is not None else value

    def put_scheduled_update_group_action(
        self,
        name: str,
        desired_capacity: Union[None, str, int],
        max_size: Union[None, str, int],
        min_size: Union[None, str, int],
        scheduled_action_name: str,
        start_time: str,
        end_time: str,
        recurrence: str,
    ) -> FakeScheduledAction:
        max_size = self.make_int(max_size)
        min_size = self.make_int(min_size)
        desired_capacity = self.make_int(desired_capacity)

        scheduled_action = FakeScheduledAction(
            name=name,
            desired_capacity=desired_capacity,
            max_size=max_size,
            min_size=min_size,
            scheduled_action_name=scheduled_action_name,
            start_time=start_time,
            end_time=end_time,
            recurrence=recurrence,
        )

        self.scheduled_actions[scheduled_action_name] = scheduled_action
        return scheduled_action

    def describe_scheduled_actions(
        self,
        autoscaling_group_name: Optional[str] = None,
        scheduled_action_names: Optional[List[str]] = None,
    ) -> List[FakeScheduledAction]:
        scheduled_actions = []
        for scheduled_action in self.scheduled_actions.values():
            if (
                not autoscaling_group_name
                or scheduled_action.name == autoscaling_group_name
            ):
                if (
                    not scheduled_action_names
                    or scheduled_action.scheduled_action_name in scheduled_action_names
                ):
                    scheduled_actions.append(scheduled_action)

        return scheduled_actions

    def delete_scheduled_action(
        self, auto_scaling_group_name: str, scheduled_action_name: str
    ) -> None:
        scheduled_action = self.describe_scheduled_actions(
            auto_scaling_group_name, [scheduled_action_name]
        )
        if scheduled_action:
            self.scheduled_actions.pop(scheduled_action_name, None)

    def create_auto_scaling_group(
        self,
        name: str,
        availability_zones: List[str],
        desired_capacity: Union[None, str, int],
        max_size: Union[None, str, int],
        min_size: Union[None, str, int],
        launch_config_name: str,
        launch_template: Dict[str, Any],
        vpc_zone_identifier: str,
        default_cooldown: Optional[int],
        health_check_period: Union[None, str, int],
        health_check_type: Optional[str],
        load_balancers: List[str],
        target_group_arns: List[str],
        placement_group: str,
        termination_policies: List[str],
        tags: List[Dict[str, str]],
        capacity_rebalance: bool = False,
        new_instances_protected_from_scale_in: bool = False,
        instance_id: Optional[str] = None,
        mixed_instance_policy: Optional[Dict[str, Any]] = None,
    ) -> FakeAutoScalingGroup:
        max_size = self.make_int(max_size)
        min_size = self.make_int(min_size)
        desired_capacity = self.make_int(desired_capacity)
        default_cooldown = self.make_int(default_cooldown)

        # Verify only a single launch config-like parameter is provided.
        params = [
            launch_config_name,
            launch_template,
            instance_id,
            mixed_instance_policy,
        ]
        num_params = sum([1 for param in params if param])

        if num_params != 1:
            raise ValidationError(
                "Valid requests must contain either LaunchTemplate, LaunchConfigurationName, "
                "InstanceId or MixedInstancesPolicy parameter."
            )

        if instance_id:
            try:
                instance = self.ec2_backend.get_instance(instance_id)
                launch_config_name = name
                FakeLaunchConfiguration.create_from_instance(
                    launch_config_name, instance, self
                )
            except InvalidInstanceIdError:
                raise InvalidInstanceError(instance_id)

        group = FakeAutoScalingGroup(
            name=name,
            availability_zones=availability_zones,
            desired_capacity=desired_capacity,
            max_size=max_size,
            min_size=min_size,
            launch_config_name=launch_config_name,
            launch_template=launch_template,
            vpc_zone_identifier=vpc_zone_identifier,
            default_cooldown=default_cooldown,
            health_check_period=self.make_int(health_check_period)
            if health_check_period
            else 300,
            health_check_type=health_check_type,
            load_balancers=load_balancers,
            target_group_arns=target_group_arns,
            placement_group=placement_group,
            termination_policies=termination_policies,
            autoscaling_backend=self,
            ec2_backend=self.ec2_backend,
            tags=tags,
            new_instances_protected_from_scale_in=new_instances_protected_from_scale_in,
            mixed_instance_policy=mixed_instance_policy,
            capacity_rebalance=capacity_rebalance,
        )

        self.autoscaling_groups[name] = group
        self.update_attached_elbs(group.name)
        self.update_attached_target_groups(group.name)
        return group

    def update_auto_scaling_group(
        self,
        name: str,
        availability_zones: List[str],
        desired_capacity: Optional[int],
        max_size: Optional[int],
        min_size: Optional[int],
        launch_config_name: str,
        launch_template: Dict[str, Any],
        vpc_zone_identifier: str,
        health_check_period: int,
        health_check_type: str,
        new_instances_protected_from_scale_in: Optional[bool] = None,
    ) -> FakeAutoScalingGroup:
        """
        The parameter DefaultCooldown, PlacementGroup, TerminationPolicies are not yet implemented
        """
        # TODO: Add MixedInstancesPolicy once implemented.
        # Verify only a single launch config-like parameter is provided.
        if launch_config_name and launch_template:
            raise ValidationError(
                "Valid requests must contain either LaunchTemplate, LaunchConfigurationName "
                "or MixedInstancesPolicy parameter."
            )

        group = self.autoscaling_groups[name]
        group.update(
            availability_zones=availability_zones,
            desired_capacity=desired_capacity,
            max_size=max_size,
            min_size=min_size,
            launch_config_name=launch_config_name,
            launch_template=launch_template,
            vpc_zone_identifier=vpc_zone_identifier,
            health_check_period=health_check_period,
            health_check_type=health_check_type,
            new_instances_protected_from_scale_in=new_instances_protected_from_scale_in,
        )
        return group

    def describe_auto_scaling_groups(
        self, names: List[str]
    ) -> List[FakeAutoScalingGroup]:
        groups = self.autoscaling_groups.values()
        if names:
            return [group for group in groups if group.name in names]
        else:
            return list(groups)

    def delete_auto_scaling_group(self, group_name: str) -> None:
        self.set_desired_capacity(group_name, 0)
        self.autoscaling_groups.pop(group_name, None)

    def describe_auto_scaling_instances(
        self, instance_ids: List[str]
    ) -> List[InstanceState]:
        instance_states = []
        for group in self.autoscaling_groups.values():
            instance_states.extend(
                [
                    x
                    for x in group.instance_states
                    if not instance_ids or x.instance.id in instance_ids
                ]
            )
        return instance_states

    def attach_instances(self, group_name: str, instance_ids: List[str]) -> None:
        group = self.autoscaling_groups[group_name]
        original_size = len(group.instance_states)

        if (original_size + len(instance_ids)) > group.max_size:  # type: ignore[operator]
            raise ResourceContentionError
        else:
            group.desired_capacity = original_size + len(instance_ids)
            new_instances = [
                InstanceState(
                    self.ec2_backend.get_instance(x),
                    protected_from_scale_in=group.new_instances_protected_from_scale_in,
                    autoscaling_group=group,
                )
                for x in instance_ids
            ]
            for instance in new_instances:
                self.ec2_backend.create_tags(
                    [instance.instance.id], {ASG_NAME_TAG: group.name}
                )
            group.instance_states.extend(new_instances)
            self.update_attached_elbs(group.name)
            self.update_attached_target_groups(group.name)

    def set_instance_health(self, instance_id: str, health_status: str) -> None:
        """
        The ShouldRespectGracePeriod-parameter is not yet implemented
        """
        instance = self.ec2_backend.get_instance(instance_id)
        instance_state = next(
            instance_state
            for group in self.autoscaling_groups.values()
            for instance_state in group.instance_states
            if instance_state.instance.id == instance.id
        )
        instance_state.health_status = health_status

    def detach_instances(
        self, group_name: str, instance_ids: List[str], should_decrement: bool
    ) -> List[InstanceState]:
        group = self.autoscaling_groups[group_name]
        original_size = group.desired_capacity

        detached_instances = [
            x for x in group.instance_states if x.instance.id in instance_ids
        ]
        for instance in detached_instances:
            self.ec2_backend.delete_tags(
                [instance.instance.id], {ASG_NAME_TAG: group.name}
            )

        new_instance_state = [
            x for x in group.instance_states if x.instance.id not in instance_ids
        ]
        group.instance_states = new_instance_state

        if should_decrement:
            group.desired_capacity = original_size - len(instance_ids)  # type: ignore[operator]

        group.set_desired_capacity(group.desired_capacity)
        return detached_instances

    def set_desired_capacity(
        self, group_name: str, desired_capacity: Optional[int]
    ) -> None:
        group = self.autoscaling_groups[group_name]
        group.set_desired_capacity(desired_capacity)
        self.update_attached_elbs(group_name)

    def change_capacity(
        self, group_name: str, scaling_adjustment: Optional[int]
    ) -> None:
        group = self.autoscaling_groups[group_name]
        desired_capacity = group.desired_capacity + scaling_adjustment  # type: ignore[operator]
        self.set_desired_capacity(group_name, desired_capacity)

    def change_capacity_percent(
        self, group_name: str, scaling_adjustment: Optional[int]
    ) -> None:
        """http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/as-scale-based-on-demand.html
        If PercentChangeInCapacity returns a value between 0 and 1,
        Auto Scaling will round it off to 1. If the PercentChangeInCapacity
        returns a value greater than 1, Auto Scaling will round it off to the
        lower value. For example, if PercentChangeInCapacity returns 12.5,
        then Auto Scaling will round it off to 12."""
        group = self.autoscaling_groups[group_name]
        percent_change = 1 + (scaling_adjustment / 100.0)  # type: ignore[operator]
        desired_capacity = group.desired_capacity * percent_change  # type: ignore[operator]
        if group.desired_capacity < desired_capacity < group.desired_capacity + 1:  # type: ignore[operator]
            desired_capacity = group.desired_capacity + 1  # type: ignore[operator]
        else:
            desired_capacity = int(desired_capacity)
        self.set_desired_capacity(group_name, desired_capacity)

    def create_lifecycle_hook(
        self,
        name: str,
        as_name: str,
        transition: str,
        timeout: Optional[int],
        result: str,
    ) -> FakeLifeCycleHook:
        lifecycle_hook = FakeLifeCycleHook(name, as_name, transition, timeout, result)

        self.lifecycle_hooks[f"{as_name}_{name}"] = lifecycle_hook
        return lifecycle_hook

    def describe_lifecycle_hooks(
        self, as_name: str, lifecycle_hook_names: Optional[List[str]] = None
    ) -> List[FakeLifeCycleHook]:
        return [
            lifecycle_hook
            for lifecycle_hook in self.lifecycle_hooks.values()
            if (lifecycle_hook.as_name == as_name)
            and (
                not lifecycle_hook_names or lifecycle_hook.name in lifecycle_hook_names
            )
        ]

    def delete_lifecycle_hook(self, as_name: str, name: str) -> None:
        self.lifecycle_hooks.pop(f"{as_name}_{name}", None)

    def put_scaling_policy(
        self,
        name: str,
        policy_type: str,
        metric_aggregation_type: str,
        adjustment_type: str,
        as_name: str,
        min_adjustment_magnitude: str,
        scaling_adjustment: Optional[int],
        cooldown: Optional[int],
        target_tracking_config: str,
        step_adjustments: str,
        estimated_instance_warmup: str,
        predictive_scaling_configuration: str,
    ) -> FakeScalingPolicy:
        policy = FakeScalingPolicy(
            name,
            policy_type,
            metric_aggregation_type,
            adjustment_type=adjustment_type,
            as_name=as_name,
            min_adjustment_magnitude=min_adjustment_magnitude,
            scaling_adjustment=scaling_adjustment,
            cooldown=cooldown,
            target_tracking_config=target_tracking_config,
            step_adjustments=step_adjustments,
            estimated_instance_warmup=estimated_instance_warmup,
            predictive_scaling_configuration=predictive_scaling_configuration,
            autoscaling_backend=self,
        )

        self.policies[name] = policy
        return policy

    def describe_policies(
        self,
        autoscaling_group_name: Optional[str] = None,
        policy_names: Optional[List[str]] = None,
        policy_types: Optional[List[str]] = None,
    ) -> List[FakeScalingPolicy]:
        return [
            policy
            for policy in self.policies.values()
            if (not autoscaling_group_name or policy.as_name == autoscaling_group_name)
            and (not policy_names or policy.name in policy_names)
            and (not policy_types or policy.policy_type in policy_types)
        ]

    def delete_policy(self, group_name: str) -> None:
        self.policies.pop(group_name, None)

    def execute_policy(self, group_name: str) -> None:
        policy = self.policies[group_name]
        policy.execute()

    def update_attached_elbs(self, group_name: str) -> None:
        group = self.autoscaling_groups[group_name]
        group_instance_ids = set(
            state.instance.id for state in group.active_instances()
        )

        # skip this if group.load_balancers is empty
        # otherwise elb_backend.describe_load_balancers returns all available load balancers
        if not group.load_balancers:
            return
        try:
            elbs = self.elb_backend.describe_load_balancers(names=group.load_balancers)
        except LoadBalancerNotFoundError:
            # ELBs can be deleted before their autoscaling group
            return

        for elb in elbs:
            elb_instace_ids = set(elb.instance_ids)
            self.elb_backend.register_instances(
                elb.name, group_instance_ids - elb_instace_ids, from_autoscaling=True
            )
            self.elb_backend.deregister_instances(
                elb.name, elb_instace_ids - group_instance_ids, from_autoscaling=True
            )

    def update_attached_target_groups(self, group_name: str) -> None:
        group = self.autoscaling_groups[group_name]
        group_instance_ids = set(state.instance.id for state in group.instance_states)

        # no action necessary if target_group_arns is empty
        if not group.target_group_arns:
            return

        target_groups = self.elbv2_backend.describe_target_groups(
            target_group_arns=group.target_group_arns,
            load_balancer_arn=None,
            names=None,
        )

        for target_group in target_groups:
            asg_targets = [
                {"id": x, "port": target_group.port} for x in group_instance_ids
            ]
            self.elbv2_backend.register_targets(target_group.arn, (asg_targets))

    def create_or_update_tags(self, tags: List[Dict[str, str]]) -> None:
        for tag in tags:
            group_name = tag["resource_id"]
            group = self.autoscaling_groups[group_name]
            old_tags = group.tags

            new_tags = []
            # if key was in old_tags, update old tag
            for old_tag in old_tags:
                if old_tag["key"] == tag["key"]:
                    new_tags.append(tag)
                else:
                    new_tags.append(old_tag)

            # if key was never in old_tag's add it (create tag)
            if not any(new_tag["key"] == tag["key"] for new_tag in new_tags):
                new_tags.append(tag)

            group.tags = new_tags

    def delete_tags(self, tags: List[Dict[str, str]]) -> None:
        for tag_to_delete in tags:
            group_name = tag_to_delete["resource_id"]
            key_to_delete = tag_to_delete["key"]
            group = self.autoscaling_groups[group_name]
            old_tags = group.tags
            group.tags = [x for x in old_tags if x["key"] != key_to_delete]

    def attach_load_balancers(
        self, group_name: str, load_balancer_names: List[str]
    ) -> None:
        group = self.autoscaling_groups[group_name]
        group.load_balancers.extend(
            [x for x in load_balancer_names if x not in group.load_balancers]
        )
        self.update_attached_elbs(group_name)

    def describe_load_balancers(self, group_name: str) -> List[str]:
        return self.autoscaling_groups[group_name].load_balancers

    def detach_load_balancers(
        self, group_name: str, load_balancer_names: List[str]
    ) -> None:
        group = self.autoscaling_groups[group_name]
        group_instance_ids = set(state.instance.id for state in group.instance_states)
        elbs = self.elb_backend.describe_load_balancers(names=group.load_balancers)
        for elb in elbs:
            self.elb_backend.deregister_instances(
                elb.name, group_instance_ids, from_autoscaling=True
            )
        group.load_balancers = [
            x for x in group.load_balancers if x not in load_balancer_names
        ]

    def attach_load_balancer_target_groups(
        self, group_name: str, target_group_arns: List[str]
    ) -> None:
        group = self.autoscaling_groups[group_name]
        group.append_target_groups(target_group_arns)
        self.update_attached_target_groups(group_name)

    def describe_load_balancer_target_groups(self, group_name: str) -> List[str]:
        return self.autoscaling_groups[group_name].target_group_arns

    def detach_load_balancer_target_groups(
        self, group_name: str, target_group_arns: List[str]
    ) -> None:
        group = self.autoscaling_groups[group_name]
        group.target_group_arns = [
            x for x in group.target_group_arns if x not in target_group_arns
        ]
        for target_group in target_group_arns:
            asg_targets = [{"id": x.instance.id} for x in group.instance_states]
            self.elbv2_backend.deregister_targets(target_group, (asg_targets))

    def suspend_processes(self, group_name: str, scaling_processes: List[str]) -> None:
        all_proc_names = [
            "Launch",
            "Terminate",
            "AddToLoadBalancer",
            "AlarmNotification",
            "AZRebalance",
            "HealthCheck",
            "InstanceRefresh",
            "ReplaceUnhealthy",
            "ScheduledActions",
        ]
        group = self.autoscaling_groups[group_name]
        set_to_add = set(scaling_processes or all_proc_names)
        group.suspended_processes = list(
            set(group.suspended_processes).union(set_to_add)
        )

    def resume_processes(self, group_name: str, scaling_processes: List[str]) -> None:
        group = self.autoscaling_groups[group_name]
        if scaling_processes:
            group.suspended_processes = list(
                set(group.suspended_processes).difference(set(scaling_processes))
            )
        else:
            group.suspended_processes = []

    def set_instance_protection(
        self,
        group_name: str,
        instance_ids: List[str],
        protected_from_scale_in: Optional[bool],
    ) -> None:
        group = self.autoscaling_groups[group_name]
        protected_instances = [
            x for x in group.instance_states if x.instance.id in instance_ids
        ]
        for instance in protected_instances:
            instance.protected_from_scale_in = protected_from_scale_in

    def notify_terminate_instances(self, instance_ids: List[str]) -> None:
        for (
            autoscaling_group_name,
            autoscaling_group,
        ) in self.autoscaling_groups.items():
            original_active_instance_count = len(autoscaling_group.active_instances())
            autoscaling_group.instance_states = list(
                filter(
                    lambda i_state: i_state.instance.id not in instance_ids,
                    autoscaling_group.instance_states,
                )
            )
            difference = original_active_instance_count - len(
                autoscaling_group.active_instances()
            )
            if difference > 0:
                autoscaling_group.replace_autoscaling_group_instances(
                    difference, autoscaling_group.get_propagated_tags()
                )
                self.update_attached_elbs(autoscaling_group_name)

    def enter_standby_instances(
        self, group_name: str, instance_ids: List[str], should_decrement: bool
    ) -> Tuple[List[InstanceState], Optional[int], Optional[int]]:
        group = self.autoscaling_groups[group_name]
        original_size = group.desired_capacity
        standby_instances = []
        for instance_state in group.instance_states:
            if instance_state.instance.id in instance_ids:
                instance_state.lifecycle_state = "Standby"
                standby_instances.append(instance_state)
        if should_decrement:
            group.desired_capacity = group.desired_capacity - len(instance_ids)  # type: ignore[operator]
        group.set_desired_capacity(group.desired_capacity)
        return standby_instances, original_size, group.desired_capacity

    def exit_standby_instances(
        self, group_name: str, instance_ids: List[str]
    ) -> Tuple[List[InstanceState], Optional[int], int]:
        group = self.autoscaling_groups[group_name]
        original_size = group.desired_capacity
        standby_instances = []
        for instance_state in group.instance_states:
            if instance_state.instance.id in instance_ids:
                instance_state.lifecycle_state = "InService"
                standby_instances.append(instance_state)
        group.desired_capacity = group.desired_capacity + len(instance_ids)  # type: ignore[operator]
        group.set_desired_capacity(group.desired_capacity)
        return standby_instances, original_size, group.desired_capacity

    def terminate_instance(
        self, instance_id: str, should_decrement: bool
    ) -> Tuple[InstanceState, Any, Any]:
        instance = self.ec2_backend.get_instance(instance_id)
        instance_state = next(
            instance_state
            for group in self.autoscaling_groups.values()
            for instance_state in group.instance_states
            if instance_state.instance.id == instance.id
        )
        group = instance.autoscaling_group  # type: ignore[attr-defined]
        original_size = group.desired_capacity
        self.detach_instances(group.name, [instance.id], should_decrement)
        self.ec2_backend.terminate_instances([instance.id])
        return instance_state, original_size, group.desired_capacity

    def describe_tags(self, filters: List[Dict[str, str]]) -> List[Dict[str, str]]:
        """
        Pagination is not yet implemented.
        Only the `auto-scaling-group` and `propagate-at-launch` filters are implemented.
        """
        resources = self.autoscaling_groups.values()
        tags = list(itertools.chain(*[r.tags for r in resources]))
        for f in filters:
            if f["Name"] == "auto-scaling-group":
                tags = [t for t in tags if t["resource_id"] in f["Values"]]
            if f["Name"] == "propagate-at-launch":
                values = [v.lower() for v in f["Values"]]
                tags = [
                    t
                    for t in tags
                    if t.get("propagate_at_launch", "").lower() in values
                ]
        return tags

    def enable_metrics_collection(self, group_name: str, metrics: List[str]) -> None:
        group = self.describe_auto_scaling_groups([group_name])[0]
        group.enable_metrics_collection(metrics)

autoscaling_backends = BackendDict(AutoScalingBackend, "autoscaling")


text:
cask "fantastical" do
  version "3.7.1,1512"
  sha256 "1b8f3c3761df3c5c1865c67c17ebc7d33c844fc98ac2c0640b7203c540b2b2ff"

  url "https://cdn.flexibits.com/Fantastical_#{version.csv.first}.zip"
  name "Fantastical"
  desc "Calendar software"
  homepage "https://flexibits.com/fantastical"

  livecheck do
    url "https://flexibits.com/fantastical/appcast2.php"
    strategy :sparkle
  end

  auto_updates true
  depends_on macos: ">= :high_sierra"

  app "Fantastical.app"

  uninstall launchctl: "com.flexibits.fantastical#{version.major}.mac.launcher",
            quit:      [
              "85C27NK92C.com.flexibits.fantastical#{version.major}.mac.helper",
              "com.flexibits.fantastical#{version.major}.mac",
            ]

  zap trash: [
    "~/Library/Application Scripts/com.flexibits.fantastical#{version.major}.*",
    "~/Library/Application Scripts/com.flexibits.fbcaldav.*",
    "~/Library/Containers/com.flexibits.fantastical#{version.major}.*",
    "~/Library/Containers/com.flexibits.fbcaldav.*",
    "~/Library/Preferences/com.flexibits.fantastical.plist",
  ]
end

redpajama_set_name: RedPajamaGithub


text:
package com.jeecg.alipay.api.base;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.request.AlipayMobilePublicLabelAddRequest;
import com.alipay.api.request.AlipayMobilePublicLabelDeleteRequest;
import com.alipay.api.request.AlipayMobilePublicLabelQueryRequest;
import com.alipay.api.request.AlipayMobilePublicLabelUpdateRequest;
import com.alipay.api.request.AlipayMobilePublicLabelUserAddRequest;
import com.alipay.api.request.AlipayMobilePublicLabelUserDeleteRequest;
import com.alipay.api.request.AlipayMobilePublicLabelUserQueryRequest;
import com.alipay.api.request.AlipayMobilePublicMessageLabelSendRequest;
import com.alipay.api.response.AlipayMobilePublicLabelAddResponse;
import com.alipay.api.response.AlipayMobilePublicLabelDeleteResponse;
import com.alipay.api.response.AlipayMobilePublicLabelQueryResponse;
import com.alipay.api.response.AlipayMobilePublicLabelUpdateResponse;
import com.alipay.api.response.AlipayMobilePublicLabelUserAddResponse;
import com.alipay.api.response.AlipayMobilePublicLabelUserDeleteResponse;
import com.alipay.api.response.AlipayMobilePublicLabelUserQueryResponse;
import com.alipay.api.response.AlipayMobilePublicMessageLabelSendResponse;
import com.jeecg.alipay.api.base.vo.LableGroupVo.LableGroup;
import com.jeecg.alipay.api.base.vo.LableUserAddVo.UserAddLable;
import com.jeecg.alipay.api.base.vo.LableVo.LableId;
import com.jeecg.alipay.api.base.vo.LableVo.UpDateLable;
import com.jeecg.alipay.api.core.AlipayClientFactory;
import com.jeecg.alipay.api.core.AlipayConfig;

/**
 * 支付服务窗标签API
 *
 * @author zhangdaihao
 *
 */
public class JwLableAPI {

	/**
	 * 创建标签
	 *
	 * @param appAuthToken
	 * @param name
	 *            标签名不能重复
	 * @return
	 * @throws AlipayApiException
	 */
	public static AlipayMobilePublicLabelAddResponse lableadd(String appAuthToken, String name,AlipayConfig config) throws AlipayApiException {
		AlipayMobilePublicLabelAddRequest request = new AlipayMobilePublicLabelAddRequest();
		request.putOtherTextParam("app_auth_token", appAuthToken);
		JSONObject json = new JSONObject();
		json.put("name", name);
		request.setBizContent(json.toJSONString());
		return AlipayClientFactory.getAlipayClientInstance(config).execute(request);
	}

	/**
	 * 查询标签
	 *
	 * @param appAuthToken
	 * @return
	 * @throws AlipayApiException
	 */
	public static AlipayMobilePublicLabelQueryResponse lablequery(String appAuthToken,AlipayConfig config) throws AlipayApiException {
		AlipayMobilePublicLabelQueryRequest request = new AlipayMobilePublicLabelQueryRequest();
		request.putOtherTextParam("app_auth_token", appAuthToken);
		return AlipayClientFactory.getAlipayClientInstance(config).execute(request);
	}

	/**
	 * 修改标签
	 *
	 * @param appAuthToken
	 * @param model
	 * @return
	 * @throws AlipayApiException
	 */
	public static AlipayMobilePublicLabelUpdateResponse lableupdate(String appAuthToken, UpDateLable model,AlipayConfig config) throws AlipayApiException {
		AlipayMobilePublicLabelUpdateRequest request = new AlipayMobilePublicLabelUpdateRequest();
		request.putOtherTextParam("app_auth_token", appAuthToken);
		String json = JSONObject.toJSONString(model);
		request.setBizContent(json);
		return AlipayClientFactory.getAlipayClientInstance(config).execute(request);
	}

	/**
	 * 删除标签
	 *
	 * @param appAuthToken
	 * @param model
	 * @return
	 * @throws AlipayApiException
	 */
	public static AlipayMobilePublicLabelDeleteResponse labledel(String appAuthToken, LableId model,AlipayConfig config) throws AlipayApiException {
		AlipayMobilePublicLabelDeleteRequest request = new AlipayMobilePublicLabelDeleteRequest();
		request.putOtherTextParam("app_auth_token", appAuthToken);
		String json = JSONObject.toJSONString(model);
		request.setBizContent(json);
		return AlipayClientFactory.getAlipayClientInstance(config).execute(request);
	}

	/**
	 * 用户增加标签
	 *
	 * @param appAuthToken
	 * @param model
	 * @return
	 * @throws AlipayApiException
	 */
	public static AlipayMobilePublicLabelUserAddResponse lableUserAdd(String appAuthToken, UserAddLable model,AlipayConfig config) throws AlipayApiException {
		AlipayMobilePublicLabelUserAddRequest request = new AlipayMobilePublicLabelUserAddRequest();
		request.putOtherTextParam("app_auth_token", appAuthToken);
		String json = JSONObject.toJSONString(model);
		request.setBizContent(json);
		return AlipayClientFactory.getAlipayClientInstance(config).execute(request);
	}

//	/**
//	 * 添加用户标签  (新版API)
//	 * @param appAuthToken
//	 * @param model
//	 * @param config
//	 * @return
//	 * @throws AlipayApiException
//	 */
//	public static AlipayOpenPublicLabelUserCreateResponse labelUserAddNew(String appAuthToken, UserAddLable model,AlipayConfig config) throws AlipayApiException {
//		AlipayOpenPublicLabelUserCreateRequest request = new AlipayOpenPublicLabelUserCreateRequest();
//		String json = JSONObject.toJSONString(model);
//		System.out.println("添加用户标签:"+json);
//
//		request.setBizContent(json);
//		return AlipayClientFactory.getAlipayClientInstance(config).execute(request);
//	}

	/**
	 * 查询用户标签
	 *
	 * @param appAuthToken
	 * @param model
	 * @return
	 * @throws AlipayApiException
	 */
	public static AlipayMobilePublicLabelUserQueryResponse lableUserQuery(String appAuthToken, UserAddLable model,AlipayConfig config) throws AlipayApiException {
		AlipayMobilePublicLabelUserQueryRequest request = new AlipayMobilePublicLabelUserQueryRequest();
		request.putOtherTextParam("app_auth_token", appAuthToken);
		String json = JSONObject.toJSONString(model);
		request.setBizContent(json);
		return AlipayClientFactory.getAlipayClientInstance(config).execute(request);
	}

	/**
	 * 删除用户标签
	 *
	 * @param appAuthToken
	 * @param model
	 * @return
	 * @throws AlipayApiException
	 */
	public static AlipayMobilePublicLabelUserDeleteResponse lableUserDel(String appAuthToken, UserAddLable model,AlipayConfig config) throws AlipayApiException {
		AlipayMobilePublicLabelUserDeleteRequest request = new AlipayMobilePublicLabelUserDeleteRequest();
		request.putOtherTextParam("app_auth_token", appAuthToken);
		String json = JSONObject.toJSONString(model);
		request.setBizContent(json);
		return AlipayClientFactory.getAlipayClientInstance(config).execute(request);
	}

	/**
	 * 根据标签组发
	 *
	 * @param appAuthToken
	 * @param model
	 * @return
	 * @throws AlipayApiException
	 */
	public static AlipayMobilePublicMessageLabelSendResponse sendMsg(String appAuthToken, LableGroup model,AlipayConfig config) throws AlipayApiException {
		AlipayMobilePublicMessageLabelSendRequest request = new AlipayMobilePublicMessageLabelSendRequest();
		request.putOtherTextParam("app_auth_token", appAuthToken);
		String json = JSONObject.toJSONString(model);
		request.setBizContent(json);
		return AlipayClientFactory.getAlipayClientInstance(config).execute(request);
	}

}


text:
package ch.uzh.ifi.seal.permo.performance.main.ui.trigger;

import org.eclipse.core.expressions.PropertyTester;

/**
 * In the plugin.xml file, a menu entry is contributed to the context menu of the Java editor to trigger the 'monitor
 * method' command. This class contains the logic to determine whether the menu entry shall be visible or not. It
 * proves, whether the cursor is positioned onto a method.
 */
public class IsMethodSelectedPropertyTester extends PropertyTester {

  /**
   * {@inheritDoc}
   */
  @Override
  public boolean test(final Object receiver, final String property, final Object[] args, final Object expectedValue) {
    return SelectedMethods.getSelectedMethodInActiveEditor().isPresent();
  }

}


text:
title: IT Lesson 50 - The Third
layout: post
author: brendan.frank
permalink: /it-lesson-50---the-third/
source-id: 1lqch7MikyNLx3CZgW3AnpWllF74U1roedJ32zvIYAMo
published: true
---

    Title
    IT Lesson 50

    Date
    25/09/2017

    Starting point:
    Some knowledge of spreadsheets.

    Target for this lesson?
    To be able to use code to call upon data to perform calculations

    Did I reach my target?
    Yes, I have acquired this knowledge and also learned how to use the vlookup command to call upon data in a range on a different sheet.

    Lesson Review

    How did I learn? What strategies were effective?

    I learned by exploring what I could do but also trying to find the simplest ways to perform the action that I was instructed to do.

    What limited my learning? Which habits do I need to work on?

    Not much limited my learning as I 'put my head down' and focused on what I needed to do. Sometimes I asked my partner for help but he guided me towards finding out the answer to my problem instead of just telling me the answer to it.

    What will I change for next time? How will I improve my learning?

    Next time I will try to finish even more and try to retain the knowledge that I have learned!

Spreadsheet Work


text:
package com.hazelcast.core;

import com.hazelcast.cluster.Member;
import com.hazelcast.cluster.MemberSelector;
import com.hazelcast.config.SplitBrainProtectionConfig;
import com.hazelcast.executor.LocalExecutorStats;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

/**
 * Distributed implementation of {@link ExecutorService}.
 * IExecutorService provides additional methods like executing tasks
 * on a specific member, on a member who is owner of a specific key,
 * executing a tasks on multiple members and listening execution result using a callback.
 *
 * Supports split brain protection {@link SplitBrainProtectionConfig} since 3.10 in cluster
 * versions 3.10 and higher.
 *
 * @see ExecutorService
 * @see ExecutionCallback
 * @see MultiExecutionCallback
 */
public interface IExecutorService extends ExecutorService, DistributedObject {

    /**
     * Executes a task on a randomly selected member.
     *
     * @param command        the task that is executed on a randomly selected member
     * @param memberSelector memberSelector
     * @throws java.util.concurrent.RejectedExecutionException if no member is selected
     */
    void execute(@Nonnull Runnable command,
                 @Nonnull MemberSelector memberSelector);

    /**
     * Executes a task on the owner of the specified key.
     *
     * @param command a task executed on the owner of the specified key
     * @param key     the specified key
     */
    void executeOnKeyOwner(@Nonnull Runnable command,
                           @Nonnull Object key);

    /**
     * Executes a task on the specified member.
     *
     * @param command the task executed on the specified member
     * @param member  the specified member
     */
    void executeOnMember(@Nonnull Runnable command,
                         @Nonnull Member member);

    /**
     * Executes a task on each of the specified members.
     *
     * @param command the task executed on the specified members
     * @param members the specified members
     */
    void executeOnMembers(@Nonnull Runnable command,
                          @Nonnull Collection<Member> members);

    /**
     * Executes a task on each of the selected members.
     *
     * @param command        a task executed on each of the selected members
     * @param memberSelector memberSelector
     * @throws java.util.concurrent.RejectedExecutionException if no member is selected
     */
    void executeOnMembers(@Nonnull Runnable command,
                          @Nonnull MemberSelector memberSelector);

    /**
     * Executes a task on all of the known cluster members.
     *
     * @param command a task executed  on all of the known cluster members
     */
    void executeOnAllMembers(@Nonnull Runnable command);

    /**
     * Submits a task to a randomly selected member and returns a Future
     * representing that task.
     *
     * @param task           task submitted to a randomly selected member
     * @param memberSelector memberSelector
     * @param <T>            the result type of callable
     * @return a Future representing pending completion of the task
     * @throws java.util.concurrent.RejectedExecutionException if no member is selected
     */
    <T> Future<T> submit(@Nonnull Callable<T> task,
                         @Nonnull MemberSelector memberSelector);

    /**
     * Submits a task to the owner of the specified key and returns a Future
     * representing that task.
     *
     * @param task task submitted to the owner of the specified key
     * @param key  the specified key
     * @param <T>  the result type of callable
     * @return a Future representing pending completion of the task
     */
    <T> Future<T> submitToKeyOwner(@Nonnull Callable<T> task,
                                   @Nonnull Object key);

    /**
     * Submits a task to the specified member and returns a Future
     * representing that task.
     *
     * @param task   the task submitted to the specified member
     * @param member the specified member
     * @param <T>    the result type of callable
     * @return a Future representing pending completion of the task
     */
    <T> Future<T> submitToMember(@Nonnull Callable<T> task,
                                 @Nonnull Member member);

    /**
     * Submits a task to given members and returns
     * map of Member-Future pairs representing pending completion of the task on each member
     *
     * @param task    the task submitted to given members
     * @param members the given members
     * @param <T>     the result type of callable
     * @return map of Member-Future pairs representing pending completion of the task on each member
     */
    <T> Map<Member, Future<T>> submitToMembers(@Nonnull Callable<T> task,
                                               @Nonnull Collection<Member> members);

    /**
     * Submits a task to selected members and returns a
     * map of Member-Future pairs representing pending completion of the task on each member.
     *
     * @param task           the task submitted to selected members
     * @param memberSelector memberSelector
     * @param <T>            the result type of callable
     * @return map of Member-Future pairs representing pending completion of the task on each member
     * @throws java.util.concurrent.RejectedExecutionException if no member is selected
     */
    <T> Map<Member, Future<T>> submitToMembers(@Nonnull Callable<T> task,
                                               @Nonnull MemberSelector memberSelector);

    /**
     * Submits task to all cluster members and returns a
     * map of Member-Future pairs representing pending completion of the task on each member.
     *
     * @param task the task submitted to all cluster members
     * @param <T>  the result type of callable
     * @return map of Member-Future pairs representing pending completion of the task on each member
     */
    <T> Map<Member, Future<T>> submitToAllMembers(@Nonnull Callable<T> task);

    /**
     * Submits a task to a random member. Caller will be notified of the result of the task by
     * {@link ExecutionCallback#onResponse(Object)} or {@link ExecutionCallback#onFailure(Throwable)}.
     *
     * @param task     a task submitted to a random member
     * @param callback callback
     * @param <T>      the response type of callback
     */
    <T> void submit(@Nonnull Runnable task,
                    @Nullable ExecutionCallback<T> callback);

    /**
     * Submits a task to randomly selected members. Caller will be notified for the result of the task by
     * {@link ExecutionCallback#onResponse(Object)} or {@link ExecutionCallback#onFailure(Throwable)}.
     *
     * @param task           the task submitted to randomly selected members
     * @param memberSelector memberSelector
     * @param callback       callback
     * @param <T>            the response type of callback
     * @throws java.util.concurrent.RejectedExecutionException if no member is selected
     */
    <T> void submit(@Nonnull Runnable task,
                    @Nonnull MemberSelector memberSelector,
                    @Nullable ExecutionCallback<T> callback);

    /**
     * Submits a task to the owner of the specified key. Caller will be notified for the result of the task by
     * {@link ExecutionCallback#onResponse(Object)} or {@link ExecutionCallback#onFailure(Throwable)}.
     *
     * @param task     task submitted to the owner of the specified key
     * @param key      the specified key
     * @param callback callback
     * @param <T>      the response type of callback
     */
    <T> void submitToKeyOwner(@Nonnull Runnable task,
                              @Nonnull Object key,
                              @Nonnull ExecutionCallback<T> callback);

    /**
     * Submits a task to the specified member. Caller will be notified for the result of the task by
     * {@link ExecutionCallback#onResponse(Object)} or {@link ExecutionCallback#onFailure(Throwable)}.
     *
     * @param task     the task submitted to the specified member
     * @param member   the specified member
     * @param callback callback
     * @param <T>      the response type of callback
     */
    <T> void submitToMember(@Nonnull Runnable task,
                            @Nonnull Member member,
                            @Nullable ExecutionCallback<T> callback);

    /**
     * Submits a task to the specified members. Caller will be notified for the result of the each task by
     * {@link MultiExecutionCallback#onResponse(Member, Object)}, and when all tasks are completed,
     * {@link MultiExecutionCallback#onComplete(java.util.Map)} will be called.
     *
     * @param task     the task submitted to the specified members
     * @param members  the specified members
     * @param callback callback
     */
    void submitToMembers(@Nonnull Runnable task,
                         @Nonnull Collection<Member> members,
                         @Nonnull MultiExecutionCallback callback);

    /**
     * Submits task to the selected members. Caller will be notified for the result of the each task by
     * {@link MultiExecutionCallback#onResponse(Member, Object)}, and when all tasks are completed,
     * {@link MultiExecutionCallback#onComplete(java.util.Map)} will be called.
     *
     * @param task           the task submitted to the selected members
     * @param memberSelector memberSelector
     * @param callback       callback
     * @throws java.util.concurrent.RejectedExecutionException if no member is selected
     */
    void submitToMembers(@Nonnull Runnable task,
                         @Nonnull MemberSelector memberSelector,
                         @Nonnull MultiExecutionCallback callback);

    /**
     * Submits task to all the cluster members. Caller will be notified for the result of each task by
     * {@link MultiExecutionCallback#onResponse(Member, Object)}, and when all tasks are completed,
     * {@link MultiExecutionCallback#onComplete(java.util.Map)} will be called.
     *
     * @param task     the task submitted to all the cluster members
     * @param callback callback
     */
    void submitToAllMembers(@Nonnull Runnable task,
                            @Nonnull MultiExecutionCallback callback);

    /**
     * Submits a task to a random member. Caller will be notified for the result of the task by
     * {@link ExecutionCallback#onResponse(Object)} or {@link ExecutionCallback#onFailure(Throwable)}.
     *
     * @param task     the task submitted to a random member
     * @param callback callback
     * @param <T>      the result type of callable
     */
    <T> void submit(@Nonnull Callable<T> task,
                    @Nullable ExecutionCallback<T> callback);

    /**
     * Submits task to a randomly selected member. Caller will be notified for the result of the task by
     * {@link ExecutionCallback#onResponse(Object)} or {@link ExecutionCallback#onFailure(Throwable)}.
     *
     * @param task           the task submitted to a randomly selected member
     * @param memberSelector memberSelector
     * @param callback       callback
     * @param <T>            the result type of callable
     * @throws java.util.concurrent.RejectedExecutionException if no member is selected
     */
    <T> void submit(@Nonnull Callable<T> task,
                    @Nonnull MemberSelector memberSelector,
                    @Nullable ExecutionCallback<T> callback);

    /**
     * Submits task to the owner of the specified key. Caller will be notified for the result of the task by
     * {@link ExecutionCallback#onResponse(Object)} or {@link ExecutionCallback#onFailure(Throwable)}.
     *
     * @param task     the task submitted to the owner of the specified key
     * @param key      the specified key
     * @param callback callback
     * @param <T>      the result type of callable
     */
    <T> void submitToKeyOwner(@Nonnull Callable<T> task,
                              @Nonnull Object key,
                              @Nullable ExecutionCallback<T> callback);

    /**
     * Submits a task to the specified member. Caller will be notified for the result of the task by
     * {@link ExecutionCallback#onResponse(Object)} or {@link ExecutionCallback#onFailure(Throwable)}.
     *
     * @param task     the task submitted to the specified member
     * @param member   the specified member
     * @param callback callback
     * @param <T>      the result type of callable
     */
    <T> void submitToMember(@Nonnull Callable<T> task,
                            @Nonnull Member member,
                            @Nullable ExecutionCallback<T> callback);

    /**
     * Submits a task to the specified members. Caller will be notified for the result of each task by
     * {@link MultiExecutionCallback#onResponse(Member, Object)}, and when all tasks are completed,
     * {@link MultiExecutionCallback#onComplete(java.util.Map)} will be called.
     *
     * @param task     the task submitted to the specified members
     * @param members  the specified members
     * @param callback callback
     * @param <T>      the result type of callable
     */
    <T> void submitToMembers(@Nonnull Callable<T> task,
                             @Nonnull Collection<Member> members,
                             @Nonnull MultiExecutionCallback callback);

    /**
     * Submits task to the selected members. Caller will be notified for the result of each task by
     * {@link MultiExecutionCallback#onResponse(Member, Object)}, and when all tasks are completed,
     * {@link MultiExecutionCallback#onComplete(java.util.Map)} will be called.
     *
     * @param task           the task submitted to the selected members
     * @param memberSelector memberSelector
     * @param callback       callback
     * @param <T>            the result type of callable
     * @throws java.util.concurrent.RejectedExecutionException if no member is selected
     */
    <T> void submitToMembers(@Nonnull Callable<T> task,
                             @Nonnull MemberSelector memberSelector,
                             @Nonnull MultiExecutionCallback callback);

    /**
     * Submits task to all the cluster members. Caller will be notified for the result of the each task by
     * {@link MultiExecutionCallback#onResponse(Member, Object)}, and when all tasks are completed,
     * {@link MultiExecutionCallback#onComplete(java.util.Map)} will be called.
     *
     * @param task     the task submitted to all the cluster members
     * @param callback callback
     * @param <T>      the result type of callable
     */
    <T> void submitToAllMembers(@Nonnull Callable<T> task,
                                @Nonnull MultiExecutionCallback callback);

    /**
     * Returns local statistics related to this executor service.
     *
     * @return local statistics related to this executor service
     */
    LocalExecutorStats getLocalExecutorStats();
}


text:
layout: docwithnav-edge
title: MQTT Gateway API Reference
description: Supported MQTT Gateway API Reference for IoT Devices

---

{% include docs/reference/gateway-mqtt-api.md %}


text:
namespace madoka {

// These macros transform a line number to a string constant.
#define MADOKA_INT_TO_STR(value) #value
#define MADOKA_LINE_TO_STR(line) MADOKA_INT_TO_STR(line)
#define MADOKA_LINE_STR MADOKA_LINE_TO_STR(__LINE__)

// MADOKA_THROW() throws an exception with `message'.
#define MADOKA_THROW(message) \
  (throw ::madoka::Exception(__FILE__ ":" MADOKA_LINE_STR ": " message))

// MADOKA_THROW_IF() throws an exception if `condition' is true. Also,
// `condition' is used as the error message of that exception.
#define MADOKA_THROW_IF(condition) \
  static_cast<void>((!(condition)) || (MADOKA_THROW(#condition), 0))

class Exception {
 public:
  Exception() noexcept : what_("") {}
  ~Exception() noexcept {}

  explicit Exception(const char *what) noexcept : what_(what) {}

  Exception(const Exception &exception) noexcept : what_(exception.what_) {}

  Exception &operator=(const Exception &exception) noexcept {
    what_ = exception.what_;
    return *this;
  }

  const char *what() const noexcept {
    return what_;
  }

 private:
  const char *what_;
};

}  // namespace madoka
#endif  // __cplusplus

#endif  // MADOKA_EXCEPTION_H


text:
SetLocale for Golang
====================

A wrapper for setlocale(3).

Usage
-----

Just import "github.com/famz/SetLocale", then call SetLocale:

```go
SetLocale.SetLocale(SetLocale.LC_*, "<your-locale>")
```

Install
-------

Simply run `go get github.com/famz/SetLocale`

Example
-------

```go
package main
import (
    "github.com/famz/SetLocale"
    "fmt"
)

func main() {
    SetLocale.SetLocale(SetLocale.LC_ALL, "")
}
```


text:
package view // import "go.opencensus.io/stats/view"

// TODO(acetechnologist): Add a link to the language independent OpenCensus
// spec when it is available.


text:
import java.text.DecimalFormat;

// Definition of class Square.
public final class Circle extends Two_D_Shape
{

private final String MY_SHAPE = "Circle";  //You can initialize here
                                           //OR you can do it in the constructor.
private int myRadius;
private final double PI = 3.14;
   // constructors
   public Circle()
   {
      //  Implicit call to 'Two_D_Shape' default constructor right HERE!
      //  Basically, invisible right here is:  super();
      setMyRadius(0);
   }
   public Circle( int x, int y, int radi )
   {
       super(x,y);
       setMyRadius(radi);
   }
   public void finalize()
   {
       super.finalize();
   }

   // NOTE: Overridden getMyShapeStats()
   public String getMyShapeStats()
   {
      return MY_SHAPE + " @ " +  getMyPoint() +
            "   radius = " + getMyRadius() + "   area = " + getArea() + "\n";
   }

   public String getArea() // REM: DecimalFormat returns a "String!"
   {
   DecimalFormat precision2 = new DecimalFormat( "0.00" );

      return precision2.format(PI * Math.pow(getMyRadius(),2));
   }

   // toString
   public String toString()
   {
       return getMyShapeStats();
   }

   // set method
   public void setMyRadius( int radi )
   {
      myRadius = radi;
   }

   // get method
   public double getMyRadius()
   {
      return myRadius;
   }

   // ERROR!!!
   //public Point getMyPoint()  // NOTE: This 'final' method was declared in Shape
   //{                          //       so we can NOT do it here!
   //     return myPoint;
   //}
  /* public double getArea()
   {
       return (Math.pow(getMySide,2));
    }*/

}  // end class Circle


text:
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateNoteTagTable extends Migration
{

    const TABLE = 'note_tag';

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create(static::TABLE, function (Blueprint $table) {
            $table
                ->mediumInteger('note_id')
                ->unsigned()
            ;
            $table
                ->smallInteger('tag_id')
                ->unsigned()
            ;
            $table->primary(['note_id', 'tag_id']);
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists(static::TABLE);
    }
}


text:
<?php

namespace RoyallTheFourth\QuickList\Console\Message;

use RoyallTheFourth\QuickList\Db\Message;
use RoyallTheFourth\SmoothPdo\DataObject;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

class Show extends Command
{
    private $db;

    public function __construct(DataObject $db)
    {
        $this->db = $db;
        parent::__construct();
    }

    protected function configure()
    {
        $this
            ->setName('message:list')
            ->setDescription('Lists all messages.');
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        (new SymfonyStyle($input, $output))
            ->table(['id', 'name', 'date added'], Message\all($this->db));
    }
}


text:
namespace News.Migrations
{
    using System;
    using System.Data.Entity.Migrations;

    public partial class InitialCreate : DbMigration
    {
        public override void Up()
        {
            CreateTable(
                "dbo.Articles",
                c => new
                    {
                        Id = c.Int(nullable: false, identity: true),
                        Title = c.String(nullable: false, maxLength: 50),
                        Summary = c.String(nullable: false),
                        Content = c.String(nullable: false),
                        PublishedAt = c.DateTime(nullable: false),
                        Author = c.String(nullable: false),
                        isLead = c.Boolean(nullable: false),
                    })
                .PrimaryKey(t => t.Id);

            CreateTable(
                "dbo.Images",
                c => new
                    {
                        Id = c.Int(nullable: false, identity: true),
                        ImageSmall = c.Binary(),
                        ImageLarge = c.Binary(),
                        ArticleId = c.Int(nullable: false),
                    })
                .PrimaryKey(t => t.Id)
                .ForeignKey("dbo.Articles", t => t.ArticleId, cascadeDelete: true)
                .Index(t => t.ArticleId);

        }

        public override void Down()
        {
            DropForeignKey("dbo.Images", "ArticleId", "dbo.Articles");
            DropIndex("dbo.Images", new[] { "ArticleId" });
            DropTable("dbo.Images");
            DropTable("dbo.Articles");
        }
    }
}


text:
package io.netty.example.http2.helloworld.client;

import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.DefaultFullHttpRequest;
import io.netty.handler.codec.http.HttpClientCodec;
import io.netty.handler.codec.http.HttpClientUpgradeHandler;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http2.DefaultHttp2Connection;
import io.netty.handler.codec.http2.DelegatingDecompressorFrameListener;
import io.netty.handler.codec.http2.Http2ClientUpgradeCodec;
import io.netty.handler.codec.http2.Http2Connection;
import io.netty.handler.codec.http2.Http2FrameLogger;
import io.netty.handler.codec.http2.HttpToHttp2ConnectionHandler;
import io.netty.handler.codec.http2.InboundHttp2ToHttpAdapter;
import io.netty.handler.ssl.ApplicationProtocolNames;
import io.netty.handler.ssl.ApplicationProtocolNegotiationHandler;
import io.netty.handler.ssl.SslContext;

import static io.netty.handler.logging.LogLevel.INFO;

/**
 * Configures the client pipeline to support HTTP/2 frames.
 */
public class Http2ClientInitializer extends ChannelInitializer<SocketChannel> {
    private static final Http2FrameLogger logger = new Http2FrameLogger(INFO, Http2ClientInitializer.class);

    private final SslContext sslCtx;
    private final int maxContentLength;
    private HttpToHttp2ConnectionHandler connectionHandler;
    private HttpResponseHandler responseHandler;
    private Http2SettingsHandler settingsHandler;

    public Http2ClientInitializer(SslContext sslCtx, int maxContentLength) {
        this.sslCtx = sslCtx;
        this.maxContentLength = maxContentLength;
    }

    @Override
    public void initChannel(SocketChannel ch) throws Exception {
        final Http2Connection connection = new DefaultHttp2Connection(false);
        connectionHandler = new HttpToHttp2ConnectionHandler.Builder()
                .frameListener(new DelegatingDecompressorFrameListener(connection,
                        new InboundHttp2ToHttpAdapter.Builder(connection)
                            .maxContentLength(maxContentLength)
                            .propagateSettings(true)
                            .build()))
                .frameLogger(logger)
                .build(connection);
        responseHandler = new HttpResponseHandler();
        settingsHandler = new Http2SettingsHandler(ch.newPromise());
        if (sslCtx != null) {
            configureSsl(ch);
        } else {
            configureClearText(ch);
        }
    }

    public HttpResponseHandler responseHandler() {
        return responseHandler;
    }

    public Http2SettingsHandler settingsHandler() {
        return settingsHandler;
    }

    protected void configureEndOfPipeline(ChannelPipeline pipeline) {
        pipeline.addLast(settingsHandler, responseHandler);
    }

    /**
     * Configure the pipeline for TLS NPN negotiation to HTTP/2.
     */
    private void configureSsl(SocketChannel ch) {
        ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast(sslCtx.newHandler(ch.alloc()));
        // We must wait for the handshake to finish and the protocol to be negotiated before configuring
        // the HTTP/2 components of the pipeline.
        pipeline.addLast(new ApplicationProtocolNegotiationHandler("") {
            @Override
            protected void configurePipeline(ChannelHandlerContext ctx, String protocol) {
                if (ApplicationProtocolNames.HTTP_2.equals(protocol)) {
                    ChannelPipeline p = ctx.pipeline();
                    p.addLast(connectionHandler);
                    configureEndOfPipeline(p);
                    return;
                }
                ctx.close();
                throw new IllegalStateException("unknown protocol: " + protocol);
            }
        });
    }

    /**
     * Configure the pipeline for a cleartext upgrade from HTTP to HTTP/2.
     */
    private void configureClearText(SocketChannel ch) {
        HttpClientCodec sourceCodec = new HttpClientCodec();
        Http2ClientUpgradeCodec upgradeCodec = new Http2ClientUpgradeCodec(connectionHandler);
        HttpClientUpgradeHandler upgradeHandler = new HttpClientUpgradeHandler(sourceCodec, upgradeCodec, 65536);

        ch.pipeline().addLast(sourceCodec,
                              upgradeHandler,
                              new UpgradeRequestHandler(),
                              new UserEventLogger());
    }

    /**
     * A handler that triggers the cleartext upgrade to HTTP/2 by sending an initial HTTP request.
     */
    private final class UpgradeRequestHandler extends ChannelHandlerAdapter {
        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            DefaultFullHttpRequest upgradeRequest =
                    new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/");
            ctx.writeAndFlush(upgradeRequest);

            super.channelActive(ctx);

            // Done with this handler, remove it from the pipeline.
            ctx.pipeline().remove(this);

            configureEndOfPipeline(ctx.pipeline());
        }
    }

    /**
     * Class that logs any User Events triggered on this channel.
     */
    private static class UserEventLogger extends ChannelHandlerAdapter {
        @Override
        public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
            System.out.println("User Event Triggered: " + evt);
            super.userEventTriggered(ctx, evt);
        }
    }
}


text:
using System.Windows;

namespace SimpleExample.UI.Shell
{
    /// <summary>
    /// Interaction logic for ShellView.xaml
    /// </summary>
    public partial class ShellView : Window
    {
        public ShellView()
        {
            InitializeComponent();
        }
    }
}