@Override
  public void markExpiredPendingUnhealthy(
      final AutoScalingGroupMetadata group, final Collection<String> instanceIds, final long maxAge)
      throws AutoScalingMetadataException {
    final AutoScalingInstance example = exampleForGroup(group);
    example.setHealthStatus(HealthStatus.Healthy);

    final List<AutoScalingInstance> instancesToMark =
        instanceIds.isEmpty()
            ? Collections.<AutoScalingInstance>emptyList()
            : persistenceSupport.listByExample(
                example,
                LifecycleState.Pending,
                Property.forName("displayName").in(instanceIds),
                Collections.<String, String>emptyMap(),
                Functions.<AutoScalingInstance>identity());

    for (final AutoScalingInstance instance : instancesToMark) {
      try {
        persistenceSupport.updateByExample(
            AutoScalingInstance.withUuid(instance.getNaturalId()),
            group.getOwner(),
            instance.getInstanceId(),
            new Callback<AutoScalingInstance>() {
              @Override
              public void fire(final AutoScalingInstance instance) {
                if (instance.getCreationTimestamp().getTime() < maxAge) {
                  logger.info("Marking pending instance unhealthy: " + instance.getInstanceId());
                  instance.setHealthStatus(HealthStatus.Unhealthy);
                } else {
                  logger.debug(
                      "Not marking pending instance unhealthy (within timeout): "
                          + instance.getInstanceId());
                }
              }
            });
      } catch (final AutoScalingMetadataNotFoundException e) {
        // removed, no need to mark unhealthy
      }
    }
  }
  @Override
  public void markMissingInstancesUnhealthy(
      final AutoScalingGroupMetadata group, final Collection<String> instanceIds)
      throws AutoScalingMetadataException {
    final AutoScalingInstance example = exampleForGroup(group);
    example.setHealthStatus(HealthStatus.Healthy);

    final List<AutoScalingInstance> instancesToMark =
        persistenceSupport.listByExample(
            example,
            LifecycleState.InService,
            instanceIds.isEmpty()
                ? Restrictions.conjunction()
                : Restrictions.not(Property.forName("displayName").in(instanceIds)),
            Collections.<String, String>emptyMap(),
            Functions.<AutoScalingInstance>identity());

    for (final AutoScalingInstance instance : instancesToMark) {
      try {
        persistenceSupport.updateByExample(
            AutoScalingInstance.withUuid(instance.getNaturalId()),
            group.getOwner(),
            instance.getInstanceId(),
            new Callback<AutoScalingInstance>() {
              @Override
              public void fire(final AutoScalingInstance instance) {
                if (instance.healthStatusGracePeriodExpired()) {
                  logger.info("Marking instance unhealthy: " + instance.getInstanceId());
                  instance.setHealthStatus(HealthStatus.Unhealthy);
                } else {
                  logger.debug(
                      "Instance not healthy but within grace period: " + instance.getInstanceId());
                }
              }
            });
      } catch (final AutoScalingMetadataNotFoundException e) {
        // removed, no need to mark unhealthy
      }
    }
  }
 private AutoScalingInstance exampleForGroup(final AutoScalingGroupMetadata group) {
   final AutoScalingInstance example = AutoScalingInstance.withOwner(group.getOwner());
   example.clearUserIdentity();
   example.setAutoScalingGroupName(group.getDisplayName());
   return example;
 }