/**
  * Destroys a virtual system in hyper-v
  *
  * @param vmDispatch TODO
  * @return the error code of
  */
 public int destroyVirtualSystem(final IJIDispatch vmDispatch) throws Exception {
   JIVariant tmp = vmDispatch.get("Path_");
   IJIDispatch dispatchTemp =
       (IJIDispatch)
           JIObjectFactory.narrowObject(
               tmp.getObjectAsComObject().queryInterface(IJIDispatch.IID));
   String virtualSystemPath = dispatchTemp.get("Path").getObjectAsString2();
   JIVariant[] results =
       dispatch.callMethodA(
           "DestroyVirtualSystem",
           new Object[] {
             new JIString(virtualSystemPath), JIVariant.EMPTY_BYREF(), JIVariant.EMPTY_BYREF()
           });
   int error = results[0].getObjectAsInt();
   if (results.length > 1) {
     if (error != 0) {
       if (error == 4096) {
         logger.debug("Destroying virtual system...");
         String jobPath = results[2].getObjectAsVariant().getObjectAsString2();
         HyperVUtils.monitorJob(jobPath, service.getObjectDispatcher());
       } else {
         String message = "The virtual system could no te destroyed " + virtualSystemPath;
         logger.error(message);
         throw new JIException(error, message);
       }
     }
   }
   return error;
 }
  /**
   * Removes resources to an existing virtual computer system
   *
   * @param vmDispatch A reference to the computer system instance to which the resource is to be
   *     added.
   * @param resourceAllocationDispatch the resource allocation setting data reference to be removed.
   * @throws JIException
   */
  public void removeVirtualSystemResources(
      final IJIDispatch vmDispatch, final IJIDispatch resourceAllocationDispatch)
      throws JIException {
    // Getting the dispatcher of the VM Path
    IJIDispatch vmPathDispatcher =
        (IJIDispatch)
            JIObjectFactory.narrowObject(
                vmDispatch.get("Path_").getObjectAsComObject().queryInterface(IJIDispatch.IID));

    // Getting the virtual machine path
    String vmPath = vmPathDispatcher.get("Path").getObjectAsString2();

    // Getting the dispatcher of the resource path
    IJIDispatch resourcePathDispatcher =
        (IJIDispatch)
            JIObjectFactory.narrowObject(
                resourceAllocationDispatch
                    .get("Path_")
                    .getObjectAsComObject()
                    .queryInterface(IJIDispatch.IID));

    // Getting the virtual machine path
    String resourcePath = resourcePathDispatcher.get("Path").getObjectAsString2();

    JIVariant[] tmp =
        dispatch.callMethodA(
            "RemoveVirtualSystemResources",
            new Object[] {
              new JIString(vmPath),
              new JIArray(new JIString[] {new JIString(resourcePath)}),
              JIVariant.EMPTY_BYREF(),
              JIVariant.EMPTY_BYREF()
            });

    int result = tmp[0].getObjectAsInt();

    String name = resourceAllocationDispatch.get("ElementName").getObjectAsString2();

    if (result == 0) {
      logger.debug(name + " removed from " + vmPath);
    } else {
      if (result == 4096) {
        logger.debug("Removing resources...");
        String jobPath = tmp[2].getObjectAsVariant().getObjectAsString2();
        HyperVUtils.monitorJob(jobPath, service.getObjectDispatcher());
      } else {
        logger.error(name + " deleting to " + vmPath + " failed with error code " + result);
        throw new IllegalStateException(
            "Cannot remove resource "
                + name
                + " to "
                + vmDispatch.get("ElementName").getObjectAsString2());
      }
    }
  }
  /**
   * Modifies the settings for an existing virtual computer system.
   *
   * @param vmDispatch A reference to the virtual computer system to be modified.
   * @param systemSettingData describes the modified setting values for the virtual computer system.
   * @throws JIException
   */
  public void modifyVirtualSystem(final IJIDispatch vmDispatch, final IJIDispatch systemSettingData)
      throws JIException {
    // Getting the dispatcher of the VM Path
    IJIDispatch vmPathDispatcher =
        (IJIDispatch)
            JIObjectFactory.narrowObject(
                vmDispatch.get("Path_").getObjectAsComObject().queryInterface(IJIDispatch.IID));

    // Getting the virtual machine path
    String vmPath = vmPathDispatcher.get("Path").getObjectAsString2();

    // Getting the dispatcher of the resource path

    String resourceText =
        systemSettingData.callMethodA("GetText_", new Object[] {new Integer(1)})[0]
            .getObjectAsString2();

    JIVariant[] tmp =
        dispatch.callMethodA(
            "ModifyVirtualSystem",
            new Object[] {
              new JIString(vmPath),
              new JIArray(new JIString[] {new JIString(resourceText)}),
              JIVariant.EMPTY_BYREF(),
              JIVariant.EMPTY_BYREF()
            });

    int result = tmp[0].getObjectAsInt();

    String name = systemSettingData.get("ElementName").getObjectAsString2();
    if (result == 0) {
      logger.debug("Setting data properly modified" + vmPath);
    } else {
      if (result == 4096) {
        logger.debug("Modifying setting data...");
        String jobPath = tmp[1].getObjectAsVariant().getObjectAsString2();
        HyperVUtils.monitorJob(jobPath, service.getObjectDispatcher());
      } else {
        logger.error(name + " addition to " + vmPath + " failed with error code " + result);
        throw new IllegalStateException(
            "Setting data cannot be modified to"
                + vmDispatch.get("ElementName").getObjectAsString2());
      }
    }
  }
  /**
   * Add resources to an existing virtual computer system
   *
   * @param vmDispatch A reference to the computer system instance to which the resource is to be
   *     added.
   * @param newResourceAllocationDispatch the new resource allocation setting data reference to be
   *     added.
   * @return the resource allocation setting data path of the added resource
   * @throws JIException
   */
  public String addVirtualSystemResources(
      final IJIDispatch vmDispatch, final IJIDispatch newResourceAllocationDispatch)
      throws JIException {
    // Getting the dispatcher of the VM Path
    IJIDispatch vmPathDispatcher =
        (IJIDispatch)
            JIObjectFactory.narrowObject(
                vmDispatch.get("Path_").getObjectAsComObject().queryInterface(IJIDispatch.IID));

    // Getting the virtual machine path
    String vmPath = vmPathDispatcher.get("Path").getObjectAsString2();

    // Getting the dispatcher of the resource path

    String resourceText =
        newResourceAllocationDispatch.callMethodA("GetText_", new Object[] {new Integer(1)})[0]
            .getObjectAsString2();

    JIVariant[] tmp =
        dispatch.callMethodA(
            "AddVirtualSystemResources",
            new Object[] {
              new JIString(vmPath),
              new JIArray(new JIString[] {new JIString(resourceText)}),
              JIVariant.EMPTY_BYREF(),
              JIVariant.EMPTY_BYREF()
            });

    int result = tmp[0].getObjectAsInt();

    JIVariant resultVariant = tmp[2];

    JIVariant variant2 = resultVariant.getObjectAsVariant();

    JIArray newResourcesArr = variant2.getObjectAsArray();

    if (newResourcesArr == null) {
      throw new JIException(32768, "The resource could not be added");
    }

    JIVariant[] newResourcesVarArr = (JIVariant[]) newResourcesArr.getArrayInstance();

    String newResourcePath = newResourcesVarArr[0].getObjectAsString2();

    String name = newResourceAllocationDispatch.get("ElementName").getObjectAsString2();
    if (result == 0) {
      logger.debug(name + " added to " + vmPath);
    } else {
      if (result == 4096) {
        logger.debug("Addind resources...");
        String jobPath = tmp[1].getObjectAsVariant().getObjectAsString2();
        HyperVUtils.monitorJob(jobPath, service.getObjectDispatcher());
      } else {
        logger.error(name + " addition to " + vmPath + " failed with error code " + result);
        throw new IllegalStateException(
            "Cannot add resource "
                + name
                + " to "
                + vmDispatch.get("ElementName").getObjectAsString2());
      }
    }

    return newResourcePath;
  }