private static SortedSet<FormationValue> createSortedFormationResults(
      EvaluationResult formationEvalResult) {
    SortedSet<FormationValue> result = new TreeSet<FormationValue>();

    for (Alternative a : formationEvalResult.getResultMultiplicativeIndexMap().keySet()) {
      Double value = formationEvalResult.getResultMultiplicativeIndexMap().get(a);
      result.add(
          new FormationValue(
              ((FormationAlternative) a).getFormation().getComponentSolutions(), value));
    }

    return result;
  }
  private static SortedSet<ComponentSolution> computeComponent(
      Component c, int numAMIs, int numServices) throws Exception {

    long startTimeAMIModel = new Date().getTime();
    List<AMI> amis = new ArrayList<AMI>();
    for (int i = 0; i < numAMIs; i++) {
      AMI ami = new AMI("ami-" + i);
      ami.getAttributes()
          .add(
              new Attribute<Double>(
                  EApplianceAttribute.COSTPERHOUR, new Double((Math.random() * 0.4 + 0.1))));
      ami.getAttributes()
          .add(new Attribute<Double>(EApplianceAttribute.POPULARITY, new Double(Math.random())));
      amis.add(ami);
    }

    // System.out.println("Generated AMIs: " + amis);

    ApplianceDecision ad = new ApplianceDecision();
    ad.setName("AMI Decision");

    Goal bestAppliance = new Goal("Best Appliance");
    bestAppliance.setGoalType(GoalType.POSITIVE);
    Criterion appliancePopularity = new Criterion("Appliance Popularity");
    appliancePopularity.setType(CriterionType.QUANTITATIVE);
    bestAppliance.addChild(appliancePopularity);

    Goal cheapestAppliance = new Goal("Cheapest Appliance");
    cheapestAppliance.setGoalType(GoalType.NEGATIVE);
    Criterion applianceCosts = new Criterion("Appliance Costs");
    applianceCosts.setType(CriterionType.QUANTITATIVE);
    cheapestAppliance.addChild(applianceCosts);

    ad.addGoal(bestAppliance);
    ad.addGoal(cheapestAppliance);

    List<ApplianceAlternative> applianceAlternatives = new ArrayList<ApplianceAlternative>();
    for (AMI a : amis) {
      ApplianceAlternative aa = new ApplianceAlternative(a, "alternative-" + a.getName());
      applianceAlternatives.add(aa);
      ad.addAlternative(aa);
    }

    // System.out.println("AMI Decision: " + ad);

    List<Evaluation> amiEvaluations = new ArrayList<Evaluation>();
    Evaluation evBest = new Evaluation();
    evBest
        .getEvaluations()
        .add(createAMIMatrix(applianceAlternatives, EApplianceAttribute.POPULARITY));
    Evaluation evCheapest = new Evaluation();
    evCheapest
        .getEvaluations()
        .add(createAMIMatrix(applianceAlternatives, EApplianceAttribute.COSTPERHOUR));
    amiEvaluations.add(evBest);
    amiEvaluations.add(evCheapest);

    long endTimeAMIModel = new Date().getTime();
    System.out.println("AMI Model Creation took " + (endTimeAMIModel - startTimeAMIModel) + " ms");

    long startTimeAMIEval = new Date().getTime();
    AnalyticHierarchyProcess ahpAMI = new AnalyticHierarchyProcess(ad);
    EvaluationResult amiEvalResult = ahpAMI.evaluateFull(amiEvaluations);
    long endTimeAMIEval = new Date().getTime();
    System.out.println("AMI Evaluation took " + (endTimeAMIEval - startTimeAMIEval) + " ms");

    long startTimeServiceModel = new Date().getTime();
    List<EC2Resource> services = new ArrayList<EC2Resource>();
    for (int i = 0; i < numServices; i++) {
      EC2Resource ec2 = new EC2Resource("ec2-" + i);
      ec2.getAttributes()
          .add(
              new Attribute<Double>(
                  EComputeServiceAttribute.COSTPERHOUR, new Double((Math.random() * 0.39 + 0.01))));
      ec2.getAttributes()
          .add(
              new Attribute<Double>(
                  EComputeServiceAttribute.CPUBENCHMARK, new Double(Math.random() * 1000)));
      ec2.getAttributes()
          .add(
              new Attribute<Double>(
                  EComputeServiceAttribute.RAMBENCHMARK, new Double(Math.random() * 1000)));
      ec2.getAttributes()
          .add(
              new Attribute<Double>(
                  EComputeServiceAttribute.DISKBENCHMARK, new Double(Math.random() * 1000)));
      ec2.getAttributes()
          .add(
              new Attribute<Double>(
                  EComputeServiceAttribute.MAXLATENCY, new Double(Math.random() * 450 + 50)));
      ec2.getAttributes()
          .add(
              new Attribute<Double>(
                  EComputeServiceAttribute.AVGLATENCY, new Double(Math.random() * 490 + 10)));
      ec2.getAttributes()
          .add(
              new Attribute<Double>(
                  EComputeServiceAttribute.SERVICEPOPULARITY, new Double(Math.random())));
      ec2.getAttributes()
          .add(
              new Attribute<Double>(
                  EComputeServiceAttribute.UPTIME, new Double(Math.random() * 0.1 + 0.9)));

      ec2.setProvider(providers.get(new Random().nextInt(NUM_PROVIDERS)));

      services.add(ec2);
    }

    ComputeDecision sd = new ComputeDecision();
    sd.setName("Service Decision");

    Goal bestService = new Goal("Best Service");
    bestService.setGoalType(GoalType.POSITIVE);
    Criterion servicePopularity = new Criterion("Service Popularity");
    servicePopularity.setType(CriterionType.QUANTITATIVE);
    Criterion serviceCPU = new Criterion("Service CPU");
    serviceCPU.setType(CriterionType.BENCHMARK);
    Criterion serviceRAM = new Criterion("Service RAM");
    serviceRAM.setType(CriterionType.BENCHMARK);
    Criterion serviceDisk = new Criterion("Service Disk");
    serviceDisk.setType(CriterionType.BENCHMARK);
    Criterion serviceUptime = new Criterion("Service Uptime");
    serviceUptime.setType(CriterionType.QUANTITATIVE);

    bestService.addChild(servicePopularity);
    bestService.addChild(serviceCPU);
    bestService.addChild(serviceRAM);
    bestService.addChild(serviceDisk);
    bestService.addChild(serviceUptime);

    Goal cheapestService = new Goal("Cheapest Service");
    cheapestService.setGoalType(GoalType.NEGATIVE);
    Criterion serviceCosts = new Criterion("Service Costs");
    serviceCosts.setType(CriterionType.QUANTITATIVE);
    cheapestService.addChild(serviceCosts);

    Goal latencyService = new Goal("Low Latency Service");
    latencyService.setGoalType(GoalType.NEGATIVE);
    Criterion serviceMaxLatency = new Criterion("Service Max Latency");
    serviceMaxLatency.setType(CriterionType.BENCHMARK);
    Criterion serviceAvgLatency = new Criterion("Service Avg Latency");
    serviceAvgLatency.setType(CriterionType.BENCHMARK);
    latencyService.addChild(serviceMaxLatency);
    latencyService.addChild(serviceAvgLatency);

    sd.addGoal(bestService);
    sd.addGoal(cheapestService);
    sd.addGoal(latencyService);

    List<ComputeServiceAlternative> ec2Alternatives = new ArrayList<ComputeServiceAlternative>();
    for (EC2Resource e : services) {
      ComputeServiceAlternative ea = new ComputeServiceAlternative(e, "alternative-" + e.getName());
      ec2Alternatives.add(ea);
      sd.addAlternative(ea);
    }

    List<Evaluation> serviceEvaluations = new ArrayList<Evaluation>();

    Evaluation evServicePopularity = new Evaluation();
    evServicePopularity
        .getEvaluations()
        .add(createServiceMatrix(ec2Alternatives, EComputeServiceAttribute.SERVICEPOPULARITY));
    evServicePopularity
        .getEvaluations()
        .add(createServiceMatrix(ec2Alternatives, EComputeServiceAttribute.CPUBENCHMARK));
    evServicePopularity
        .getEvaluations()
        .add(createServiceMatrix(ec2Alternatives, EComputeServiceAttribute.RAMBENCHMARK));
    evServicePopularity
        .getEvaluations()
        .add(createServiceMatrix(ec2Alternatives, EComputeServiceAttribute.DISKBENCHMARK));
    Evaluation evServiceCheapest = new Evaluation();
    evServiceCheapest
        .getEvaluations()
        .add(createServiceMatrix(ec2Alternatives, EComputeServiceAttribute.COSTPERHOUR));
    Evaluation evServiceLatency = new Evaluation();
    evServiceLatency
        .getEvaluations()
        .add(createServiceMatrix(ec2Alternatives, EComputeServiceAttribute.MAXLATENCY));
    evServiceLatency
        .getEvaluations()
        .add(createServiceMatrix(ec2Alternatives, EComputeServiceAttribute.AVGLATENCY));
    serviceEvaluations.add(evServicePopularity);
    serviceEvaluations.add(evServiceCheapest);
    serviceEvaluations.add(evServiceLatency);

    long endTimeServiceModel = new Date().getTime();
    System.out.println(
        "Service Model Creation took " + (endTimeServiceModel - startTimeServiceModel) + " ms");

    long startTimeServiceEval = new Date().getTime();
    AnalyticHierarchyProcess ahpService = new AnalyticHierarchyProcess(sd);
    EvaluationResult serviceEvalResult = ahpService.evaluateFull(serviceEvaluations);
    long endTimeServiceEval = new Date().getTime();
    System.out.println(
        "Service Evaluation took " + (endTimeServiceEval - startTimeServiceEval) + " ms");

    long startTimeCombined = new Date().getTime();
    List<CombinationValue> combinations = new ArrayList<CombinationValue>();
    for (ApplianceAlternative aa : applianceAlternatives)
      for (ComputeServiceAlternative csa : ec2Alternatives)
        combinations.add(
            new CombinationValue(
                aa.getAppl(),
                csa.getComputeService(),
                amiEvalResult.getResultMultiplicativeIndexMap().get(aa),
                serviceEvalResult.getResultMultiplicativeIndexMap().get(csa)));

    long endTimeCombined = new Date().getTime();
    System.out.println(
        "Combination Model took "
            + (endTimeCombined - startTimeCombined)
            + " ms (for "
            + combinations.size()
            + " combinations)");
    long startTimeCombinedEval = new Date().getTime();

    SortedSet<ComponentSolution> combinationResults = new TreeSet<ComponentSolution>();
    for (CombinationValue cv : combinations) {
      Double value = cv.getApplianceValue() + cv.getServiceValue();
      combinationResults.add(new ComponentSolution(c, new CombinationTotalValue(cv, value)));
    }
    long endTimeCombinedEval = new Date().getTime();
    System.out.println(
        "Combination Eval took " + (endTimeCombinedEval - startTimeCombinedEval) + " ms");

    System.out.println("Worst Combination: " + combinationResults.first());
    System.out.println("Best Combination: " + combinationResults.last());

    TIME_INTERMEDIATE_TOTAL =
        ((endTimeAMIModel - startTimeAMIModel)
            + (endTimeAMIEval - startTimeAMIEval)
            + (endTimeServiceModel - startTimeServiceModel)
            + (endTimeServiceEval - startTimeServiceEval)
            + (endTimeCombined - startTimeCombined)
            + (endTimeCombinedEval - startTimeCombinedEval));
    TIME_COMPONENTS_TOTAL += TIME_INTERMEDIATE_TOTAL;

    FileWriter fw = new FileWriter("out_components.txt", true);
    BufferedWriter out = new BufferedWriter(fw);
    out.write(
        ""
            + c.getName()
            + ","
            + NUM_COMPONENTS
            + ","
            + numAMIs
            + ","
            + numServices
            + ","
            + (endTimeAMIModel - startTimeAMIModel)
            + ","
            + (endTimeAMIEval - startTimeAMIEval)
            + ","
            + (endTimeServiceModel - startTimeServiceModel)
            + ","
            + (endTimeServiceEval - startTimeServiceEval)
            + ","
            + (endTimeCombined - startTimeCombined)
            + ","
            + (endTimeCombinedEval - startTimeCombinedEval)
            + ","
            + TIME_INTERMEDIATE_TOTAL
            + "\n");
    out.close();

    return combinationResults;
  }