public Directory buildCrowdDirectory(CrowdDirectoryConfiguration configuration) {
    ImmutableDirectory.Builder builder = createBuilder();
    builder.setAllowedOperations(configuration.getCrowdPermissionOption().getAllowedOperations());
    builder.setActive(configuration.isActive());
    builder.setId(configuration.getDirectoryId());
    builder.setImplementationClass(RemoteCrowdDirectory.class.getName());
    builder.setName(configuration.getName());
    builder.setType(DirectoryType.CROWD);

    CrowdDirectoryAttributes attributes = new CrowdDirectoryAttributes();
    BeanUtils.copyProperties(
        configuration, attributes); // ignores attributes that don't exist in the target - perfect!
    // Convert polling interval from minutes to seconds to store in crowd
    attributes.setCrowdServerSynchroniseIntervalInSeconds(
        Long.toString(configuration.getCrowdServerSynchroniseIntervalInMin() * 60));
    builder.setAttributes(attributes.toAttributesMap());

    return builder.toDirectory();
  }
  public CrowdDirectoryConfiguration toCrowdConfiguration(Directory directory) {
    CrowdDirectoryConfiguration configuration = new CrowdDirectoryConfiguration();
    configuration.setCrowdPermissionOption(
        CrowdPermissionOption.fromAllowedOperations(directory.getAllowedOperations()));
    configuration.setDirectoryId(directory.getId() != null ? directory.getId() : 0);
    configuration.setActive(directory.isActive());
    configuration.setName(directory.getName());

    CrowdDirectoryAttributes attributes =
        CrowdDirectoryAttributes.fromAttributesMap(directory.getAttributes());
    BeanUtils.copyProperties(attributes, configuration);
    // Convert polling interval to minutes to display to user
    configuration.setCrowdServerSynchroniseIntervalInMin(
        NumberUtils.toLong(attributes.getCrowdServerSynchroniseIntervalInSeconds()) / 60);

    return configuration;
  }