client.entities.publishEntity(request) -> Entityclient.entities.getEntity(entityId) -> Entityclient.entities.overrideEntity(entityId, fieldPath, request) -> Entityclient.entities.removeEntityOverride(entityId, fieldPath) -> Entityclient.entities.longPollEntityEvents(request) -> EntityEventResponseclient.entities.streamEntities(request) -> Iterable<StreamEntitiesResponse>client.tasks.createTask(request) -> Taskclient.tasks.getTask(taskId) -> Taskclient.tasks.updateTaskStatus(taskId, request) -> Taskclient.tasks.queryTasks(request) -> TaskQueryResultsclient.tasks.listenAsAgent(request) -> AgentRequestclient.objects.listObjects() -> SyncPagingIterable<PathMetadata>client.objects.getObject(objectPath) -> InputStreamclient.objects.uploadObject(objectPath, request) -> PathMetadataclient.objects.deleteObject(objectPath)client.objects.getObjectMetadata(objectPath)client.oAuth2.getToken(request) -> GetTokenResponseAn entity ID must be provided when calling this endpoint. If the entity referenced by the entity ID does not exist + * then it will be created. Otherwise the entity will be updated. An entity will only be updated if its + * provenance.sourceUpdateTime is greater than the provenance.sourceUpdateTime of the existing entity.
+ */ + public CompletableFutureNote that overrides are applied in an eventually consistent manner. If multiple overrides are created + * concurrently for the same field path, the last writer wins.
+ */ + public CompletableFutureThis endpoint enables clients to maintain a real-time view of the common operational picture (COP) + * by first streaming all pre-existing entities that match filter criteria, then continuously delivering + * updates as entities are created, modified, or deleted.
+ *The server first sends events with type PREEXISTING for all live entities matching the filter that existed before the stream was open, + * then streams CREATE events for newly created entities, UPDATE events when existing entities change, and DELETED events when entities are removed. The stream remains open + * indefinitely unless preExistingOnly is set to true.
+ *Heartbeat messages can be configured to maintain connection health and detect disconnects by setting the heartbeatIntervalMS + * parameter. These heartbeats help keep the connection alive and allow clients to verify the server is still responsive.
+ *Clients can optimize bandwidth usage by specifying which entity components they need populated using the componentsToInclude parameter. + * This allows receiving only relevant data instead of complete entities.
+ *The connection automatically recovers from temporary disconnections, resuming the stream where it left off. Unlike polling approaches, + * this provides real-time updates with minimal latency and reduced server load.
+ */ + public CompletableFutureAn entity ID must be provided when calling this endpoint. If the entity referenced by the entity ID does not exist + * then it will be created. Otherwise the entity will be updated. An entity will only be updated if its + * provenance.sourceUpdateTime is greater than the provenance.sourceUpdateTime of the existing entity.
+ */ + public CompletableFutureNote that overrides are applied in an eventually consistent manner. If multiple overrides are created + * concurrently for the same field path, the last writer wins.
+ */ + public CompletableFutureThis endpoint enables clients to maintain a real-time view of the common operational picture (COP) + * by first streaming all pre-existing entities that match filter criteria, then continuously delivering + * updates as entities are created, modified, or deleted.
+ *The server first sends events with type PREEXISTING for all live entities matching the filter that existed before the stream was open, + * then streams CREATE events for newly created entities, UPDATE events when existing entities change, and DELETED events when entities are removed. The stream remains open + * indefinitely unless preExistingOnly is set to true.
+ *Heartbeat messages can be configured to maintain connection health and detect disconnects by setting the heartbeatIntervalMS + * parameter. These heartbeats help keep the connection alive and allow clients to verify the server is still responsive.
+ *Clients can optimize bandwidth usage by specifying which entity components they need populated using the componentsToInclude parameter. + * This allows receiving only relevant data instead of complete entities.
+ *The connection automatically recovers from temporary disconnections, resuming the stream where it left off. Unlike polling approaches, + * this provides real-time updates with minimal latency and reduced server load.
+ */ + public CompletableFutureAn entity ID must be provided when calling this endpoint. If the entity referenced by the entity ID does not exist + * then it will be created. Otherwise the entity will be updated. An entity will only be updated if its + * provenance.sourceUpdateTime is greater than the provenance.sourceUpdateTime of the existing entity.
+ */ + public Entity publishEntity(RequestOptions requestOptions) { + return this.rawClient.publishEntity(requestOptions).body(); + } + /** * Publish an entity for ingest into the Entities API. Entities created with this method are "owned" by the originator: other sources, * such as the UI, may not edit or delete these entities. The server validates entities at API call time and @@ -71,6 +83,10 @@ public Entity getEntity(String entityId) { return this.rawClient.getEntity(entityId).body(); } + public Entity getEntity(String entityId, RequestOptions requestOptions) { + return this.rawClient.getEntity(entityId, requestOptions).body(); + } + public Entity getEntity(String entityId, GetEntityRequest request) { return this.rawClient.getEntity(entityId, request).body(); } @@ -91,6 +107,20 @@ public Entity overrideEntity(String entityId, String fieldPath) { return this.rawClient.overrideEntity(entityId, fieldPath).body(); } + /** + * Only fields marked with overridable can be overridden. Please refer to our documentation to see the comprehensive + * list of fields that can be overridden. The entity in the request body should only have a value set on the field + * specified in the field path parameter. Field paths are rooted in the base entity object and must be represented + * using lower_snake_case. Do not include "entity" in the field path. + *Note that overrides are applied in an eventually consistent manner. If multiple overrides are created + * concurrently for the same field path, the last writer wins.
+ */ + public Entity overrideEntity(String entityId, String fieldPath, RequestOptions requestOptions) { + return this.rawClient + .overrideEntity(entityId, fieldPath, requestOptions) + .body(); + } + /** * Only fields marked with overridable can be overridden. Please refer to our documentation to see the comprehensive * list of fields that can be overridden. The entity in the request body should only have a value set on the field @@ -125,6 +155,15 @@ public Entity removeEntityOverride(String entityId, String fieldPath) { return this.rawClient.removeEntityOverride(entityId, fieldPath).body(); } + /** + * This operation clears the override value from the specified field path on the entity. + */ + public Entity removeEntityOverride(String entityId, String fieldPath, RequestOptions requestOptions) { + return this.rawClient + .removeEntityOverride(entityId, fieldPath, requestOptions) + .body(); + } + /** * This operation clears the override value from the specified field path on the entity. */ @@ -192,6 +231,26 @@ public IterableThis endpoint enables clients to maintain a real-time view of the common operational picture (COP) + * by first streaming all pre-existing entities that match filter criteria, then continuously delivering + * updates as entities are created, modified, or deleted.
+ *The server first sends events with type PREEXISTING for all live entities matching the filter that existed before the stream was open, + * then streams CREATE events for newly created entities, UPDATE events when existing entities change, and DELETED events when entities are removed. The stream remains open + * indefinitely unless preExistingOnly is set to true.
+ *Heartbeat messages can be configured to maintain connection health and detect disconnects by setting the heartbeatIntervalMS + * parameter. These heartbeats help keep the connection alive and allow clients to verify the server is still responsive.
+ *Clients can optimize bandwidth usage by specifying which entity components they need populated using the componentsToInclude parameter. + * This allows receiving only relevant data instead of complete entities.
+ *The connection automatically recovers from temporary disconnections, resuming the stream where it left off. Unlike polling approaches, + * this provides real-time updates with minimal latency and reduced server load.
+ */ + public IterableAn entity ID must be provided when calling this endpoint. If the entity referenced by the entity ID does not exist + * then it will be created. Otherwise the entity will be updated. An entity will only be updated if its + * provenance.sourceUpdateTime is greater than the provenance.sourceUpdateTime of the existing entity.
+ */ + public LatticeHttpResponseNote that overrides are applied in an eventually consistent manner. If multiple overrides are created + * concurrently for the same field path, the last writer wins.
+ */ + public LatticeHttpResponseThis endpoint enables clients to maintain a real-time view of the common operational picture (COP) + * by first streaming all pre-existing entities that match filter criteria, then continuously delivering + * updates as entities are created, modified, or deleted.
+ *The server first sends events with type PREEXISTING for all live entities matching the filter that existed before the stream was open, + * then streams CREATE events for newly created entities, UPDATE events when existing entities change, and DELETED events when entities are removed. The stream remains open + * indefinitely unless preExistingOnly is set to true.
+ *Heartbeat messages can be configured to maintain connection health and detect disconnects by setting the heartbeatIntervalMS + * parameter. These heartbeats help keep the connection alive and allow clients to verify the server is still responsive.
+ *Clients can optimize bandwidth usage by specifying which entity components they need populated using the componentsToInclude parameter. + * This allows receiving only relevant data instead of complete entities.
+ *The connection automatically recovers from temporary disconnections, resuming the stream where it left off. Unlike polling approaches, + * this provides real-time updates with minimal latency and reduced server load.
+ */ + public LatticeHttpResponseThe client identifier
+ */ + @JsonSetter(value = "client_id", nulls = Nulls.SKIP) + public Builder clientId(OptionalThe client secret
+ */ + @JsonSetter(value = "client_secret", nulls = Nulls.SKIP) + public Builder clientSecret(OptionalThe access token
+ */ + TokenTypeStage accessToken(@NotNull String accessToken); + + Builder from(GetTokenResponse other); + } + + public interface TokenTypeStage { + /** + *The type of token (typically "Bearer")
+ */ + _FinalStage tokenType(@NotNull String tokenType); + } + + public interface _FinalStage { + GetTokenResponse build(); + + /** + *Lifetime of the access token in seconds
+ */ + _FinalStage expiresIn(OptionalLifetime of the refresh token
+ */ + _FinalStage refreshExpiresIn(OptionalEnforce that a token cannot be used before a specific unixtime
+ */ + _FinalStage notBeforePolicy(OptionalThe scope of the access token
+ */ + _FinalStage scope(OptionalThe access token
+ *The access token
+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + @JsonSetter("access_token") + public TokenTypeStage accessToken(@NotNull String accessToken) { + this.accessToken = Objects.requireNonNull(accessToken, "accessToken must not be null"); + return this; + } + + /** + *The type of token (typically "Bearer")
+ *The type of token (typically "Bearer")
+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + @JsonSetter("token_type") + public _FinalStage tokenType(@NotNull String tokenType) { + this.tokenType = Objects.requireNonNull(tokenType, "tokenType must not be null"); + return this; + } + + /** + *The scope of the access token
+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + public _FinalStage scope(String scope) { + this.scope = Optional.ofNullable(scope); + return this; + } + + /** + *The scope of the access token
+ */ + @java.lang.Override + @JsonSetter(value = "scope", nulls = Nulls.SKIP) + public _FinalStage scope(OptionalEnforce that a token cannot be used before a specific unixtime
+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + public _FinalStage notBeforePolicy(Integer notBeforePolicy) { + this.notBeforePolicy = Optional.ofNullable(notBeforePolicy); + return this; + } + + /** + *Enforce that a token cannot be used before a specific unixtime
+ */ + @java.lang.Override + @JsonSetter(value = "not-before-policy", nulls = Nulls.SKIP) + public _FinalStage notBeforePolicy(OptionalLifetime of the refresh token
+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + public _FinalStage refreshExpiresIn(Integer refreshExpiresIn) { + this.refreshExpiresIn = Optional.ofNullable(refreshExpiresIn); + return this; + } + + /** + *Lifetime of the refresh token
+ */ + @java.lang.Override + @JsonSetter(value = "refresh_expires_in", nulls = Nulls.SKIP) + public _FinalStage refreshExpiresIn(OptionalLifetime of the access token in seconds
+ * @return Reference to {@code this} so that method calls can be chained together. + */ + @java.lang.Override + public _FinalStage expiresIn(Integer expiresIn) { + this.expiresIn = Optional.ofNullable(expiresIn); + return this; + } + + /** + *Lifetime of the access token in seconds
+ */ + @java.lang.Override + @JsonSetter(value = "expires_in", nulls = Nulls.SKIP) + public _FinalStage expiresIn(OptionalThis method initiates a new task with a unique ID (either provided or auto-generated), + * sets the initial task state to STATUS_CREATED, and establishes task ownership. The task + * can be assigned to a specific agent through the Relations field.
+ *Once created, a task enters the lifecycle workflow and can be tracked, updated, and managed + * through other Tasks API endpoints.
+ */ + public CompletableFutureThis method initiates a new task with a unique ID (either provided or auto-generated),
@@ -154,6 +166,18 @@ public CompletableFuture This method returns detailed information about a task including its current status,
+ * specification, relations, and other metadata. The response includes the complete Task object
+ * with all associated fields. By default, the method returns the latest definition version of the task from the manager's
+ * perspective. This method returns detailed information about a task including its current status,
@@ -254,6 +278,20 @@ public CompletableFuture This method allows agents or operators to report the current state of a task,
+ * which could include changes to task status, and error information. Each status update increments the task's status_version. When updating status,
+ * clients must provide the current version to ensure consistency. The system rejects
+ * updates with mismatched versions to prevent race conditions. Terminal states ( This method allows agents or operators to report the current state of a task,
@@ -373,6 +411,26 @@ public CompletableFuture This method allows filtering tasks based on multiple criteria including: Results are returned in pages. When more results are available than can be returned in a single
+ * response, a page_token is provided that can be used in subsequent requests to retrieve the next
+ * set of results. By default, this returns the latest task version for each matching task from the manager's perspective. This method allows filtering tasks based on multiple criteria including: This method creates a persistent connection from Tasks API to an agent, allowing the server
+ * to push tasks to the agent as they become available. The agent receives a stream of tasks that
+ * match its selector criteria (entity IDs). The stream delivers three types of requests: This is the primary method for taskable agents to receive and process tasks in real-time.
+ * Agents should maintain this connection and process incoming tasks according to their capabilities. When an agent receives a task, it should update the task status using the UpdateStatus endpoint
+ * to provide progress information back to Tasks API. This is a long polling API that will block until a new task is ready for delivery. If no new task is
+ * available then the server will hold on to your request for up to 5 minutes, after that 5 minute timeout
+ * period you will be expected to reinitiate a new request. This method creates a persistent connection from Tasks API to an agent, allowing the server
diff --git a/src/main/java/com/anduril/resources/tasks/AsyncTasksClient.java b/src/main/java/com/anduril/resources/tasks/AsyncTasksClient.java
index 075a5c2e..5305bdfc 100644
--- a/src/main/java/com/anduril/resources/tasks/AsyncTasksClient.java
+++ b/src/main/java/com/anduril/resources/tasks/AsyncTasksClient.java
@@ -44,6 +44,18 @@ public CompletableFuture This method initiates a new task with a unique ID (either provided or auto-generated),
+ * sets the initial task state to STATUS_CREATED, and establishes task ownership. The task
+ * can be assigned to a specific agent through the Relations field. Once created, a task enters the lifecycle workflow and can be tracked, updated, and managed
+ * through other Tasks API endpoints. This method initiates a new task with a unique ID (either provided or auto-generated),
@@ -80,6 +92,18 @@ public CompletableFuture This method returns detailed information about a task including its current status,
+ * specification, relations, and other metadata. The response includes the complete Task object
+ * with all associated fields. By default, the method returns the latest definition version of the task from the manager's
+ * perspective. This method returns detailed information about a task including its current status,
@@ -118,6 +142,20 @@ public CompletableFuture This method allows agents or operators to report the current state of a task,
+ * which could include changes to task status, and error information. Each status update increments the task's status_version. When updating status,
+ * clients must provide the current version to ensure consistency. The system rejects
+ * updates with mismatched versions to prevent race conditions. Terminal states ( This method allows agents or operators to report the current state of a task,
@@ -167,6 +205,26 @@ public CompletableFuture This method allows filtering tasks based on multiple criteria including: Results are returned in pages. When more results are available than can be returned in a single
+ * response, a page_token is provided that can be used in subsequent requests to retrieve the next
+ * set of results. By default, this returns the latest task version for each matching task from the manager's perspective. This method allows filtering tasks based on multiple criteria including: This method creates a persistent connection from Tasks API to an agent, allowing the server
+ * to push tasks to the agent as they become available. The agent receives a stream of tasks that
+ * match its selector criteria (entity IDs). The stream delivers three types of requests: This is the primary method for taskable agents to receive and process tasks in real-time.
+ * Agents should maintain this connection and process incoming tasks according to their capabilities. When an agent receives a task, it should update the task status using the UpdateStatus endpoint
+ * to provide progress information back to Tasks API. This is a long polling API that will block until a new task is ready for delivery. If no new task is
+ * available then the server will hold on to your request for up to 5 minutes, after that 5 minute timeout
+ * period you will be expected to reinitiate a new request. This method creates a persistent connection from Tasks API to an agent, allowing the server
diff --git a/src/main/java/com/anduril/resources/tasks/RawTasksClient.java b/src/main/java/com/anduril/resources/tasks/RawTasksClient.java
index 26e6f983..50fca287 100644
--- a/src/main/java/com/anduril/resources/tasks/RawTasksClient.java
+++ b/src/main/java/com/anduril/resources/tasks/RawTasksClient.java
@@ -50,6 +50,18 @@ public LatticeHttpResponse This method initiates a new task with a unique ID (either provided or auto-generated),
+ * sets the initial task state to STATUS_CREATED, and establishes task ownership. The task
+ * can be assigned to a specific agent through the Relations field. Once created, a task enters the lifecycle workflow and can be tracked, updated, and managed
+ * through other Tasks API endpoints. This method initiates a new task with a unique ID (either provided or auto-generated),
@@ -132,6 +144,18 @@ public LatticeHttpResponse This method returns detailed information about a task including its current status,
+ * specification, relations, and other metadata. The response includes the complete Task object
+ * with all associated fields. By default, the method returns the latest definition version of the task from the manager's
+ * perspective. This method returns detailed information about a task including its current status,
@@ -212,6 +236,20 @@ public LatticeHttpResponse This method allows agents or operators to report the current state of a task,
+ * which could include changes to task status, and error information. Each status update increments the task's status_version. When updating status,
+ * clients must provide the current version to ensure consistency. The system rejects
+ * updates with mismatched versions to prevent race conditions. Terminal states ( This method allows agents or operators to report the current state of a task,
@@ -312,6 +350,26 @@ public LatticeHttpResponse This method allows filtering tasks based on multiple criteria including: Results are returned in pages. When more results are available than can be returned in a single
+ * response, a page_token is provided that can be used in subsequent requests to retrieve the next
+ * set of results. By default, this returns the latest task version for each matching task from the manager's perspective. This method allows filtering tasks based on multiple criteria including: This method creates a persistent connection from Tasks API to an agent, allowing the server
+ * to push tasks to the agent as they become available. The agent receives a stream of tasks that
+ * match its selector criteria (entity IDs). The stream delivers three types of requests: This is the primary method for taskable agents to receive and process tasks in real-time.
+ * Agents should maintain this connection and process incoming tasks according to their capabilities. When an agent receives a task, it should update the task status using the UpdateStatus endpoint
+ * to provide progress information back to Tasks API. This is a long polling API that will block until a new task is ready for delivery. If no new task is
+ * available then the server will hold on to your request for up to 5 minutes, after that 5 minute timeout
+ * period you will be expected to reinitiate a new request. This method creates a persistent connection from Tasks API to an agent, allowing the server
diff --git a/src/main/java/com/anduril/resources/tasks/TasksClient.java b/src/main/java/com/anduril/resources/tasks/TasksClient.java
index bbfa2e2e..32ac79ec 100644
--- a/src/main/java/com/anduril/resources/tasks/TasksClient.java
+++ b/src/main/java/com/anduril/resources/tasks/TasksClient.java
@@ -43,6 +43,18 @@ public Task createTask() {
return this.rawClient.createTask().body();
}
+ /**
+ * Creates a new Task in the system with the specified parameters.
+ * This method initiates a new task with a unique ID (either provided or auto-generated),
+ * sets the initial task state to STATUS_CREATED, and establishes task ownership. The task
+ * can be assigned to a specific agent through the Relations field. Once created, a task enters the lifecycle workflow and can be tracked, updated, and managed
+ * through other Tasks API endpoints. This method initiates a new task with a unique ID (either provided or auto-generated),
@@ -79,6 +91,18 @@ public Task getTask(String taskId) {
return this.rawClient.getTask(taskId).body();
}
+ /**
+ * Retrieves a specific Task by its ID, with options to select a particular task version or view.
+ * This method returns detailed information about a task including its current status,
+ * specification, relations, and other metadata. The response includes the complete Task object
+ * with all associated fields. By default, the method returns the latest definition version of the task from the manager's
+ * perspective. This method returns detailed information about a task including its current status,
@@ -117,6 +141,20 @@ public Task updateTaskStatus(String taskId) {
return this.rawClient.updateTaskStatus(taskId).body();
}
+ /**
+ * Updates the status of a Task as it progresses through its lifecycle.
+ * This method allows agents or operators to report the current state of a task,
+ * which could include changes to task status, and error information. Each status update increments the task's status_version. When updating status,
+ * clients must provide the current version to ensure consistency. The system rejects
+ * updates with mismatched versions to prevent race conditions. Terminal states ( This method allows agents or operators to report the current state of a task,
@@ -165,6 +203,26 @@ public TaskQueryResults queryTasks() {
return this.rawClient.queryTasks().body();
}
+ /**
+ * Searches for Tasks that match specified filtering criteria and returns matching tasks in paginated form.
+ * This method allows filtering tasks based on multiple criteria including: Results are returned in pages. When more results are available than can be returned in a single
+ * response, a page_token is provided that can be used in subsequent requests to retrieve the next
+ * set of results. By default, this returns the latest task version for each matching task from the manager's perspective. This method allows filtering tasks based on multiple criteria including: This method creates a persistent connection from Tasks API to an agent, allowing the server
+ * to push tasks to the agent as they become available. The agent receives a stream of tasks that
+ * match its selector criteria (entity IDs). The stream delivers three types of requests: This is the primary method for taskable agents to receive and process tasks in real-time.
+ * Agents should maintain this connection and process incoming tasks according to their capabilities. When an agent receives a task, it should update the task status using the UpdateStatus endpoint
+ * to provide progress information back to Tasks API. This is a long polling API that will block until a new task is ready for delivery. If no new task is
+ * available then the server will hold on to your request for up to 5 minutes, after that 5 minute timeout
+ * period you will be expected to reinitiate a new request. This method creates a persistent connection from Tasks API to an agent, allowing the server
diff --git a/src/main/java/com/anduril/types/AgentStreamHeartbeat.java b/src/main/java/com/anduril/types/AgentStreamHeartbeat.java
new file mode 100644
index 00000000..a0dfb963
--- /dev/null
+++ b/src/main/java/com/anduril/types/AgentStreamHeartbeat.java
@@ -0,0 +1,125 @@
+/**
+ * This file was auto-generated by Fern from our API Definition.
+ */
+package com.anduril.types;
+
+import com.anduril.core.ObjectMappers;
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonSetter;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import org.jetbrains.annotations.NotNull;
+
+@JsonInclude(JsonInclude.Include.NON_ABSENT)
+@JsonDeserialize(builder = AgentStreamHeartbeat.Builder.class)
+public final class AgentStreamHeartbeat {
+ private final AgentStreamHeartbeatEvent event;
+
+ private final AgentStreamHeartbeatData data;
+
+ private final Map The timestamp at which the heartbeat message was sent.STATUS_DONE_OK and STATUS_DONE_NOT_OK) are permanent; once a task
+ * reaches these states, no further updates are allowed.
+ *
+ *
+ *
+ * STATUS_DONE_OK and STATUS_DONE_NOT_OK) are permanent; once a task
+ * reaches these states, no further updates are allowed.
+ *
+ *
+ *
+ * STATUS_DONE_OK and STATUS_DONE_NOT_OK) are permanent; once a task
+ * reaches these states, no further updates are allowed.
+ *
+ *
+ *
+ * STATUS_DONE_OK and STATUS_DONE_NOT_OK) are permanent; once a task
+ * reaches these states, no further updates are allowed.
+ *
+ *
+ *
+ *