@Override
  public ProfileFeature addProfileFeature(ProfileFeature feature, int profileId)
      throws FeatureManagementException {
    try {
      PolicyManagementDAOFactory.beginTransaction();
      feature = featureDAO.addProfileFeature(feature, profileId);
      PolicyManagementDAOFactory.commitTransaction();

    } catch (PolicyManagerDAOException e) {
      String msg =
          "Error occurred while adding profile feature ("
              + feature.getFeatureCode()
              + " - "
              + profileId
              + ")";
      log.error(msg, e);
      throw new FeatureManagementException(msg, e);
    } catch (FeatureManagerDAOException e) {
      try {
        PolicyManagementDAOFactory.rollbackTransaction();
      } catch (PolicyManagerDAOException e1) {
        log.warn("Unable to roll back the transaction");
      }
      String msg =
          "Error occurred while adding profile feature ("
              + feature.getFeatureCode()
              + " - "
              + profileId
              + ") to database.";
      log.error(msg, e);
      throw new FeatureManagementException(msg, e);
    }
    return feature;
  }
 /**
  * Set compliance of the feature according to the device status for the specific feature.
  *
  * @param activeFeature
  * @param deviceFeature
  * @return Returns setting up compliance feature.
  */
 public ComplianceFeature setComplianceFeatures(
     ProfileFeature activeFeature, Profile deviceFeature) {
   ComplianceFeature complianceFeature = new ComplianceFeature();
   complianceFeature.setFeature(activeFeature);
   complianceFeature.setFeatureCode(activeFeature.getFeatureCode());
   complianceFeature.setCompliance(deviceFeature.isCompliance());
   return complianceFeature;
 }
  /**
   * Generate Compliance Features.
   *
   * @param syncmlDocument syncmlDocument object parsed from the syncml engine.
   * @throws NotificationManagementException
   * @throws FeatureManagementException
   * @throws PolicyComplianceException
   */
  public void generateComplianceFeatureStatus(SyncmlDocument syncmlDocument)
      throws NotificationManagementException, FeatureManagementException, PolicyComplianceException,
          WindowsDeviceEnrolmentException, WindowsOperationException {
    List<Profile> profiles = generateDeviceOperationStatusObject(syncmlDocument);
    DeviceIdentifier deviceIdentifier =
        convertToDeviceIdentifierObject(syncmlDocument.getHeader().getSource().getLocURI());
    boolean isCompliance = false;
    if (profiles.size() != Constants.EMPTY) {
      try {
        if (WindowsAPIUtils.getPolicyManagerService()
                .getAppliedPolicyToDevice(deviceIdentifier)
                .getProfile()
                .getProfileFeaturesList()
            != null) {
          List<ProfileFeature> profileFeatures =
              WindowsAPIUtils.getPolicyManagerService()
                  .getAppliedPolicyToDevice(deviceIdentifier)
                  .getProfile()
                  .getProfileFeaturesList();
          List<ComplianceFeature> complianceFeatures = new ArrayList<>();
          for (ProfileFeature activeFeature : profileFeatures) {
            JSONObject policyContent = new JSONObject(activeFeature.getContent().toString());

            for (Profile deviceFeature : profiles) {
              if (deviceFeature.getFeatureCode().equals(activeFeature.getFeatureCode())
                  && (PluginConstants.OperationCodes.CAMERA.equals(
                      deviceFeature.getFeatureCode()))) {
                if (policyContent.getBoolean(PluginConstants.PolicyConfigProperties.POLICY_ENABLE)
                    == (deviceFeature.isEnable())) {
                  isCompliance = true;
                  deviceFeature.setCompliance(isCompliance);
                } else {
                  deviceFeature.setCompliance(isCompliance);
                }
                ComplianceFeature complianceFeature =
                    setComplianceFeatures(activeFeature, deviceFeature);
                complianceFeatures.add(complianceFeature);
              }
              if (deviceFeature.getFeatureCode().equals(activeFeature.getFeatureCode())
                  && (PluginConstants.OperationCodes.ENCRYPT_STORAGE.equals(
                      deviceFeature.getFeatureCode()))) {
                if (policyContent.getBoolean(
                        PluginConstants.PolicyConfigProperties.ENCRYPTED_ENABLE)
                    == (deviceFeature.isEnable())) {
                  isCompliance = true;
                  deviceFeature.setCompliance(isCompliance);
                } else {
                  deviceFeature.setCompliance(isCompliance);
                }
                ComplianceFeature complianceFeature =
                    setComplianceFeatures(activeFeature, deviceFeature);
                complianceFeatures.add(complianceFeature);
              }
              if (deviceFeature.getFeatureCode().equals(activeFeature.getFeatureCode())
                  && (PluginConstants.OperationCodes.PASSCODE_POLICY.equals(
                      deviceFeature.getFeatureCode()))) {
                if (policyContent.getBoolean(PluginConstants.PolicyConfigProperties.ENABLE_PASSWORD)
                    == (deviceFeature.isEnable())) {
                  isCompliance = true;
                  deviceFeature.setCompliance(isCompliance);
                } else {
                  deviceFeature.setCompliance(isCompliance);
                }
                ComplianceFeature complianceFeature =
                    setComplianceFeatures(activeFeature, deviceFeature);
                complianceFeatures.add(complianceFeature);
              }
            }
          }
          WindowsAPIUtils.getPolicyManagerService()
              .checkPolicyCompliance(deviceIdentifier, complianceFeatures);
        }
      } catch (JSONException e) {
        String msg = "Error occurred while parsing json object.";
        log.error(msg);
        throw new WindowsDeviceEnrolmentException(msg, e);
      } catch (PolicyComplianceException e) {
        String msg = "Error occurred while setting up policy compliance.";
        log.error(msg, e);
        throw new PolicyComplianceException(msg, e);
      } catch (PolicyManagementException e) {
        String msg = "Error occurred while getting effective policy.";
        log.error(msg, e);
        throw new PolicyComplianceException(msg, e);
      }
    }
  }