/**
   * Create device specifications.
   *
   * @return
   * @throws SiteWhereException
   */
  public IDeviceSpecification[] createDeviceSpecifications() throws SiteWhereException {
    IDeviceSpecification[] results = new DeviceSpecification[SPECIFICATION_INFO.length];
    int index = 0;
    for (SpecificationDetails details : SPECIFICATION_INFO) {
      DeviceSpecificationCreateRequest request = new DeviceSpecificationCreateRequest();
      request.setAssetModuleId(FileSystemDeviceAssetModule.MODULE_ID);
      request.setAssetId(details.getAssetId());
      request.setName(details.getName());
      request.setToken(details.getUuid());

      // Add fields for gateway.
      if (details.getUuid().equals("75126a52-0607-4cca-b995-df40e73a707b")) {
        request.setContainerPolicy(DeviceContainerPolicy.Composite);
        DeviceElementSchema schema = createDeviceElementSchema();
        request.setDeviceElementSchema(schema);
      } else if (details.getUuid().equals(OPENHAB_SPEC_TOKEN)) {
        request.setContainerPolicy(DeviceContainerPolicy.Composite);
        DeviceElementSchema schema = new DeviceElementSchema();
        request.setDeviceElementSchema(schema);
      } else {
        request.setContainerPolicy(DeviceContainerPolicy.Standalone);
      }

      IDeviceSpecification spec = getDeviceManagement().createDeviceSpecification(request);
      createDeviceCommands(spec);
      results[index] = spec;
      index++;
    }
    return results;
  }
 /**
  * Get a random assignment from the list of allowed choices.
  *
  * @param details
  * @return
  */
 protected AssignmentChoice getRandomAssignmentChoice(SpecificationDetails details) {
   int slot = (int) Math.floor(details.getAssignmentChoices().length * Math.random());
   return details.getAssignmentChoices()[slot];
 }
  @Override
  public void initialize(IDeviceManagement deviceManagement, IAssetModuleManager assetModuleManager)
      throws SiteWhereException {
    this.deviceManagement = deviceManagement;
    this.assetModuleManager = assetModuleManager;

    // Use the system account for logging "created by" on created elements.
    SecurityContextHolder.getContext().setAuthentication(SiteWhereServer.getSystemAuthentication());

    // Coordinates for edges of zone.
    zoneLocations = new ArrayList<Location>();
    zoneLocations.add(new Location(34.10260138703638, -84.24412965774536));
    zoneLocations.add(new Location(34.101837372446774, -84.24243450164795));
    zoneLocations.add(new Location(34.101517550337825, -84.24091100692749));
    zoneLocations.add(new Location(34.10154953265732, -84.23856675624847));
    zoneLocations.add(new Location(34.10153176473365, -84.23575580120087));
    zoneLocations.add(new Location(34.10409030732968, -84.23689305782318));
    zoneLocations.add(new Location(34.104996439280704, -84.23700034618376));
    zoneLocations.add(new Location(34.10606246444614, -84.23700034618376));
    zoneLocations.add(new Location(34.107691680235604, -84.23690915107727));

    // Create device specifications.
    this.deviceSpecifications = createDeviceSpecifications();

    IDeviceGroup heavy = createHeavyEquipmentGroup();
    IDeviceGroup personnel = createPersonnelTrackingGroup();
    IDeviceGroup tools = createToolTrackingGroup();

    Map<String, SpecificationDetails> specMap = new HashMap<String, SpecificationDetails>();
    for (int i = 0; i < SPECIFICATION_INFO.length; i++) {
      specMap.put(SPECIFICATION_INFO[i].getUuid(), SPECIFICATION_INFO[i]);
    }

    List<ISite> sites = createSites();
    for (ISite site : sites) {
      List<DeviceAssignment> assignments = createAssignments(site, specMap);
      List<IDeviceGroupElementCreateRequest> heavyRequests =
          new ArrayList<IDeviceGroupElementCreateRequest>();
      List<IDeviceGroupElementCreateRequest> personnelRequests =
          new ArrayList<IDeviceGroupElementCreateRequest>();
      List<IDeviceGroupElementCreateRequest> toolsRequests =
          new ArrayList<IDeviceGroupElementCreateRequest>();

      for (DeviceAssignment assignment : assignments) {
        DeviceGroupElementCreateRequest request = new DeviceGroupElementCreateRequest();
        request.setType(GroupElementType.Device);
        request.setElementId(assignment.getDeviceHardwareId());
        request.setRoles(new ArrayList<String>());
        SpecificationDetails info = specMap.get(assignment.getDevice().getSpecificationToken());
        if (info.getAssignmentChoices() == HEAVY_EQUIPMENT) {
          heavyRequests.add(request);
        } else if (info.getAssignmentChoices() == PERSONNEL) {
          personnelRequests.add(request);
        } else if (info.getAssignmentChoices() == TOOLS) {
          toolsRequests.add(request);
        }
      }
      getDeviceManagement().addDeviceGroupElements(heavy.getToken(), heavyRequests);
      getDeviceManagement().addDeviceGroupElements(personnel.getToken(), personnelRequests);
      getDeviceManagement().addDeviceGroupElements(tools.getToken(), toolsRequests);
    }

    SecurityContextHolder.getContext().setAuthentication(null);
  }