custom_content: |
  #### Creating an authorized service object
  To make authenticated requests to Google Cloud Resource Manager, you must create a service object
  with Google Cloud SDK credentials. You can then make API calls by calling methods on the Resource
  Manager service object. The simplest way to authenticate is to use
  [Application Default Credentials](https://developers.google.com/identity/protocols/application-default-credentials).
  These credentials are automatically inferred from your environment, so you only need the following
  code to create your service object:

  ```java
  import com.google.cloud.resourcemanager.ResourceManager;
  import com.google.cloud.resourcemanager.ResourceManagerOptions;

  ResourceManager resourceManager = ResourceManagerOptions.getDefaultInstance().getService();
  ```

  #### Getting a specific project
  You can load a project if you know its project ID and have read permissions to the project.
  To get a project, add the following import at the top of your file:

  ```java
  import com.google.cloud.resourcemanager.Project;
  ```

  Then use the following code to get the project:

  ```java
  String projectId = "my-globally-unique-project-id"; // Change to a unique project ID
  Project project = resourceManager.get(projectId);
  ```

  #### Creating a project
  All you need to create a project is a globally unique project ID. You can also optionally attach a
  non-unique name and labels to your project. Read more about naming guidelines for project IDs,
  names, and labels [here](https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects).
  To create a project, add the following imports at the top of your file:

  ```java
  import com.google.cloud.resourcemanager.Project;
  import com.google.cloud.resourcemanager.ProjectInfo;
  ```

  Then add the following code to create a project (be sure to change `projectId` to your own unique
  project ID).

  ```java
  String projectId = "my-globally-unique-project-id"; // Change to a unique project ID
  Project project = resourceManager.create(ProjectInfo.newBuilder(projectId).build());
  ```

  Note that the return value from `create` is a `Project` that includes additional read-only
  information, like creation time, project number, and lifecycle state. Read more about these fields
  on the [Projects page](https://cloud.google.com/resource-manager/reference/rest/v1beta1/projects).
  `Project`, a subclass of `ProjectInfo`, adds a layer of service-related functionality over
  `ProjectInfo`.

  #### Editing a project
  To edit a project, create a new `ProjectInfo` object and pass it in to the `Project.replace` method.
  For example, to add a label to a project to denote that it's launch status is "in development", add
  the following code:

  ```java
  Project newProject = project.toBuilder()
      .addLabel("launch-status", "in-development")
      .build()
      .replace();
  ```

  Note that the values of the project you pass in to `replace` overwrite the server's values for
  non-read-only fields, namely `projectName` and `labels`. For example, if you create a project with
  `projectName` "some-project-name" and subsequently call replace using a `ProjectInfo` object that
  didn't set the `projectName`, then the server will unset the project's name. The server ignores any
  attempted changes to the read-only fields `projectNumber`, `lifecycleState`, and `createTime`.
  The `projectId` cannot change.

  #### Listing all projects
  Suppose that we want a list of all projects for which we have read permissions. Add the following
  import:

  ```java
  import java.util.Iterator;
  ```

  Then add the following code to print a list of projects you can view:

  ```java
  Iterator<Project> projectIterator = resourceManager.list().iterateAll().iterator();
  System.out.println("Projects I can view:");
  while (projectIterator.hasNext()) {
    System.out.println(projectIterator.next().getProjectId());
  }
  ```

  #### Managing IAM Policies
  You can edit [Google Cloud IAM](https://cloud.google.com/iam/) (Identity and Access Management)
  policies on the project-level using this library as well. We recommend using the read-modify-write
  pattern to make policy changes.  This entails reading the project's current policy, updating it
  locally, and then sending the modified policy for writing, as shown in the snippet below. First,
  add these imports:

  ```java
  import com.google.cloud.Identity;
  import com.google.cloud.Policy;
  import com.google.cloud.Role;
  ```

  Assuming you have completed the steps above to create the `ResourceManager` service object and load
  a project from the server, you just need to add the following code:

  ```java
  // Get the project's policy
  Policy policy = project.getPolicy();

  // Add a viewer
  Policy.Builder modifiedPolicy = policy.toBuilder();
  Identity newViewer = Identity.user("<insert user's email address here>");
  modifiedPolicy.addIdentity(Role.viewer(), newViewer);

  // Write policy
  Policy updatedPolicy = project.replacePolicy(modifiedPolicy.build());
  ```

  Note that the policy you pass in to `replacePolicy` overwrites the original policy. For example, if
  the original policy has two bindings and you call `replacePolicy` with a new policy containing only
  one binding, the two original bindings are lost.

  #### Complete source code

  We put together all the code shown above into three programs. The programs assume that you are
  running from your own desktop and used the Google Cloud SDK to authenticate yourself.

  The first program creates a project if it does not exist. Complete source code can be found at
  [GetOrCreateProject.java](https://github.com/googleapis/google-cloud-java/blob/master/google-cloud-examples/src/main/java/com/google/cloud/examples/resourcemanager/snippets/GetOrCreateProject.java).

  The second program updates a project if it exists and lists all projects the user has permission to
  view. Complete source code can be found at
  [UpdateAndListProjects.java](https://github.com/googleapis/google-cloud-java/blob/master/google-cloud-examples/src/main/java/com/google/cloud/examples/resourcemanager/snippets/UpdateAndListProjects.java).

  The third program modifies the IAM policy associated with a project using the read-modify-write
  pattern.  Complete source code can be found at
  [ModifyPolicy.java](https://github.com/googleapis/google-cloud-java/blob/master/google-cloud-examples/src/main/java/com/google/cloud/examples/resourcemanager/snippets/ModifyPolicy.java)
