@Override
  public void handleResult(final Instance instance) {
    LOG.debug("Received Instance:" + instance.getUrl() + " from Network Manager");

    executor.execute(
        new Runnable() {
          public void run() {
            try {
              DhtWriter dhtWriter = dhtClientFactory.createWriter();
              dhtWriter.update(
                  piIdBuilder.getPIdForEc2AvailabilityZone(instance),
                  instance,
                  new UpdateResolvingPiContinuation<Instance>() {
                    @Override
                    public Instance update(Instance existingEntity, Instance requestedEntity) {

                      String hostname = "";

                      try {
                        hostname = InetAddress.getLocalHost().getHostName();
                        existingEntity.setHostname(hostname);
                      } catch (UnknownHostException e) {
                        LOG.error("Unable to retrieve hostname", e);
                      }

                      LOG.debug(
                          String.format(
                              "Updating instance: %s hostname: %s and nodeId: %s",
                              existingEntity.getInstanceId(), hostname, nodeId));

                      existingEntity.setNodeId(nodeId);
                      existingEntity.setSourceImagePath(instance.getSourceImagePath());
                      existingEntity.setSourceKernelPath(instance.getSourceKernelPath());
                      existingEntity.setSourceRamdiskPath(instance.getSourceRamdiskPath());
                      existingEntity.setKernelId(instance.getKernelId());
                      existingEntity.setRamdiskId(instance.getRamdiskId());
                      existingEntity.setPlatform(instance.getPlatform());
                      return existingEntity;
                    }

                    @Override
                    public void handleResult(Instance result) {
                      LOG.debug(String.format("Run instances state update result: %s", result));
                    }
                  });

              runInstanceHandler.startInstance(instance);

            } catch (Throwable t) {
              LOG.error(t.getMessage(), t);
            }
          }
        });
  }
  public ReservationInstances runInstances(final Reservation reservation) {
    LOG.debug(String.format("runInstances(%s)", reservation));

    String securityGroupUrl =
        SecurityGroup.getUrl(reservation.getUserId(), reservation.getSecurityGroupName());
    PId securityGroupId = getPiIdBuilder().getPId(securityGroupUrl).forLocalRegion();
    SecurityGroup securityGroup =
        (SecurityGroup) getDhtClientFactory().createBlockingReader().get(securityGroupId);

    validateReservation(reservation, securityGroup);

    reservation.setReservationId(getIdFactory().createNewReservationId());

    AvailabilityZone availabilityZone;
    if (StringUtils.isNotEmpty(reservation.getAvailabilityZone())) {
      try {
        availabilityZone = getAvailabilityZoneByName(reservation.getAvailabilityZone());
      } catch (AvailabilityZoneNotFoundException e) {
        throw new IllegalArgumentException(
            String.format("Unknown availability zone: %s", reservation.getAvailabilityZone()));
      }
    } else {
      availabilityZone = getLocalAvailabilityZone();
      reservation.setAvailabilityZone(availabilityZone.getAvailabilityZoneName());
    }

    // setup return object
    ReservationInstances reservationInstances = new ReservationInstances();
    reservationInstances.setReservation(reservation);

    for (int i = 0; i < reservation.getMaxCount(); i++) {
      String instanceId =
          getIdFactory().createNewInstanceId(availabilityZone.getGlobalAvailabilityZoneCode());
      // create instance
      Instance instance = new Instance(reservation);
      instance.setInstanceType(reservation.getInstanceType());
      instance.setUserId(reservation.getUserId());
      instance.setInstanceId(instanceId);
      instance.setState(InstanceState.PENDING);
      instance.setLaunchTime(System.currentTimeMillis());
      instance.setAvailabilityZoneCode(availabilityZone.getAvailabilityZoneCodeWithinRegion());
      instance.setRegionCode(availabilityZone.getRegionCode());
      LOG.info(String.format("Requesting new %s", instance));
      reservationInstances.getInstances().add(instance);

      // create instance in dht
      PId instanceDhtId =
          getPiIdBuilder().getPIdForEc2AvailabilityZone(Instance.getUrl(instanceId));
      BlockingDhtWriter blockingDhtWriter = getDhtClientFactory().createBlockingWriter();
      AddNewInstanceResolver addNewInstanceResolver = new AddNewInstanceResolver();
      blockingDhtWriter.update(instanceDhtId, instance, addNewInstanceResolver);

      reservation.addInstanceId(instance.getInstanceId());
    }

    getUserService()
        .addInstancesToUser(
            reservation.getUserId(), reservation.getInstanceIds(), reservation.getInstanceType());

    // write security group to DHT
    getDhtClientFactory()
        .createBlockingWriter()
        .update(
            securityGroupId,
            null,
            new AddInstanceToSecurityGroupResolver(reservation.getInstanceIds()));

    // add to task processing queue
    PId runInstanceQueueId =
        getPiIdBuilder()
            .getPId(PiQueue.RUN_INSTANCE.getUrl())
            .forGlobalAvailablityZoneCode(availabilityZone.getGlobalAvailabilityZoneCode());
    for (String instanceId : reservation.getInstanceIds()) {
      getTaskProcessingQueueHelper()
          .addUrlToQueue(runInstanceQueueId, Instance.getUrl(instanceId), instanceTaskQueueRetries);
    }

    // anycast message
    PubSubMessageContext pubSubMessageContext =
        getApiApplicationManager()
            .newPubSubMessageContextFromGlobalAvzCode(
                PiTopics.RUN_INSTANCE, availabilityZone.getGlobalAvailabilityZoneCode());
    pubSubMessageContext.randomAnycast(EntityMethod.CREATE, reservation);

    return reservationInstances;
  }