/**
   * Returns the <code>Dictionary</code> for the given <code>pid</code>.
   *
   * @param pid The identifier for the dictionary to load.
   * @return The dictionary for the identifier. This must not be <code>null</code> but may be empty.
   * @throws IOException If an error occurrs loading the dictionary. An <code>IOException</code>
   *     must also be thrown if no dictionary exists for the given identifier.
   */
  public Dictionary load(String pid) throws IOException {
    logger.debug("Config load call for {}", pid);
    Dictionary result = null;

    try {
      if (isReady(0) && requireRepository) {
        String id = pidToId(pid);
        ReadRequest readRequest = Requests.newReadRequest(id);
        Resource existing = repo.read(readRequest);
        Map<String, Object> existingConfig = existing.getContent().asMap();
        Object configMap = existingConfig.get(JSONEnhancedConfig.JSON_CONFIG_PROPERTY);
        String configString = serializeConfig(configMap);
        existingConfig.put(JSONEnhancedConfig.JSON_CONFIG_PROPERTY, configString);
        logger.debug("Config loaded {} {}", pid, existing);
        result = mapToDict(existingConfig);
      } else if (!requireRepository) {
        result = tempStore.get(pid);
        if (result == null) {
          throw new IOException("No entry for " + pid + " exists.");
        }

        logger.debug("Config loaded from temporary store {} {}", pid, result);
      }
    } catch (NotFoundException ex) {
      result = tempStore.get(pid);
      if (result == null) {
        throw new IOException("No entry for " + pid + " exists.");
      }

      logger.debug("Config loaded from temporary store {} {}", pid, result);
    } catch (ResourceException ex) {
      throw new IOException("Failed to load configuration in repository: " + ex.getMessage(), ex);
    }
    return result;
  }
 /**
  * Returns a JSON object containing only the specified fields from the provided resource. If the
  * list of fields is empty then the resource is returned unchanged.
  *
  * <p><b>NOTE:</b> this method only performs a shallow copy of extracted fields, so changes to the
  * filtered resource may impact the original resource, and vice-versa.
  *
  * @param resource The resource whose fields are to be filtered.
  * @param fields The list of fields to be extracted.
  * @return The filtered resource.
  */
 public static Resource filterResource(
     final Resource resource, final Collection<JsonPointer> fields) {
   final JsonValue unfiltered = resource.getContent();
   final JsonValue filtered = filterResource(unfiltered, fields);
   if (filtered == unfiltered) {
     return resource; // Unchanged.
   } else {
     return new Resource(resource.getId(), resource.getRevision(), filtered);
   }
 }
  @Test
  public void smokeTest() throws Exception {

    // @formatter:off
    final ApiDescriptor api =
        ApiDescriptor.builder("urn:forgerock:openam:api:repo:1.0")
            .setDescription("Example OpenAM REST API")
            .addRelation("", API_URN)
            .setMultiplicity(Multiplicity.ONE_TO_ONE)
            .build()
            .addRelation("users", USERS_URN)
            .build()
            .addRelation("groups", "urn:forgerock:openam:resource:group:1.0")
            .build()
            .addRelation("realms", "urn:forgerock:openam:resource:realm:1.0")
            .setDescription("An OpenAM realm")
            .build()
            .addResource(API_URN)
            .setDescription("Commons Rest API Descriptor")
            .setSchema(ApiDescriptor.class)
            .build()
            .addResource("urn:forgerock:openam:resource:user:1.0")
            .setDescription("An OpenAM user")
            .addAction("login")
            .setDescription("Authenticates a user")
            .addParameter("password", "The user's password")
            .build()
            .setSchema(User.class)
            .addProfile(
                "urn:forgerock:ldap:profile:schema:1.0",
                json(object(field("objectClass", "inetOrgPerson"))))
            .build()
            .addResource("urn:forgerock:openam:resource:admin:1.0")
            .setDescription("An OpenAM administrator")
            .setParent("urn:forgerock:openam:resource:user:1.0")
            .setSchema(AdminUser.class)
            .build()
            .addResource("urn:forgerock:openam:resource:group:1.0")
            .setDescription("An OpenAM group")
            .setSchema(Group.class)
            .build()
            .addResource("urn:forgerock:openam:resource:realm:1.0")
            .setDescription("An OpenAM realm")
            .addRelation("users", USERS_URN)
            .addAction("bulk-add")
            .setDescription("Bulk add a load of users")
            .build()
            .build()
            .addRelation("groups", "urn:forgerock:openam:resource:group:1.0")
            .build()
            .addRelation("subrealms", "urn:forgerock:openam:resource:realm:1.0")
            .setDescription("An OpenAM sub-realm")
            .build()
            .setSchema(Realm.class)
            .build()
            .build();
    // @formatter:on
    final RequestHandler handler = Api.newApiDispatcher(api, new ResolverFactoryImpl(api));
    final Connection connection = Resources.newInternalConnection(handler);

    System.out.println("#### Reading API Descriptor");
    System.out.println();
    final Resource apiValue = connection.read(new RootContext(), newReadRequest(""));
    WRITER.writeObject(apiValue.getContent().getObject());

    System.out.println();
    System.out.println("#### Reading user realms/com/subrealms/example/users/bjensen");
    System.out.println();
    final Resource bjensen =
        connection.read(
            new RootContext(), newReadRequest("realms/com/subrealms/example/users/bjensen"));
    WRITER.writeObject(bjensen.getContent().getObject());

    //        System.out.println("#### Serializing API Descriptor");
    //        System.out.println();
    //        WRITER.writeObject(api);
  }