/** {@inheritDoc} */
 @Override
 public synchronized void setEditMode(boolean editMode) {
   if (editMode != this.editMode) {
     this.editMode = editMode;
     parent.updatePathUI();
   }
 }
 /** {@inheritDoc} */
 @Override
 public void setPathStyle(PathStyle pathStyle) {
   if (this.pathStyle != pathStyle) {
     this.pathStyle = pathStyle;
     parent.updatePathUI();
   }
 }
 /** {@inheritDoc} */
 @Override
 public synchronized void setClosedPath(boolean closedPath) {
   if (closedPath != this.closedPath) {
     this.closedPath = closedPath;
     parent.updatePathUI();
   }
 }
 /** {@inheritDoc} */
 @Override
 public boolean addNode(float x, float y, float z, String name) {
   synchronized (pathNodes) {
     if (pathNodes.add(new IndexedPathNode(this, new Vector3f(x, y, z), name, pathNodes.size()))) {
       parent.updatePathUI();
       return true;
     }
     return false;
   }
 }
 /** {@inheritDoc} */
 @Override
 public synchronized void setFrom(PathCellState state) {
   if (state != null) {
     closedPath = state.isClosedPath();
     editMode = state.isEditMode();
     replacePathStyle(state);
     replaceNodes(state);
     parent.updatePathUI();
   }
 }
 /** {@inheritDoc} */
 @Override
 public boolean addNode(Vector3f position, String name) {
   synchronized (pathNodes) {
     if (position != null
         && pathNodes.add(new IndexedPathNode(this, position, name, pathNodes.size()))) {
       parent.updatePathUI();
       return true;
     }
     return false;
   }
 }
 /**
  * Add a new node to this PathCell.
  *
  * @param node The node to be added to this PathCell.
  * @return True if the node was able to be added successfully.
  */
 @Override
 public boolean addNode(ClientPathNode node) {
   synchronized (pathNodes) {
     if (node != null && pathNodes.add(node)) {
       node.setSequenceIndex(pathNodes.size() - 1);
       parent.updatePathUI();
       return true;
     } else {
       return false;
     }
   }
 }
 /** Remove all the ClientPathNodes in this PathCell. */
 @Override
 public void removeAllNodes() {
   synchronized (pathNodes) {
     if (!pathNodes.isEmpty()) {
       // ToDo synch UI with changes.
       ClientPathNode current = null;
       while (pathNodes.size() > 0) {
         current = pathNodes.remove(pathNodes.size() - 1);
         current.dispose();
       }
       parent.updatePathUI();
     }
   }
 }
 /**
  * Remove the specified IndexedPathNode from the PathCell.
  *
  * @param node The IndexedPathNode to be removed from the PathCell.
  * @return True if the IndexedPathNode was not null and existed in the PathCell and was able to be
  *     removed successfully.
  */
 @Override
 public boolean removeNode(ClientPathNode node) {
   synchronized (pathNodes) {
     if (node != null && !pathNodes.isEmpty()) {
       final int nodeIndex = pathNodes.indexOf(node);
       if (nodeIndex >= 0) {
         removeNodeAt(nodeIndex);
         parent.updatePathUI();
         return true;
       }
     }
     return false;
   }
 }
 /**
  * Set the IndexedPathNode position.
  *
  * @param index The index of the PathNode for which to set the position.
  * @param x The new X position of the PathNode.
  * @param y The new Y position of the PathNode.
  * @param z The new Z position of the PathNode.
  * @throws IndexOutOfBoundsException If the specified index of the PathNode to be updated was
  *     outside the valid range.
  */
 @Override
 public void setNodePosition(int index, float x, float y, float z)
     throws IndexOutOfBoundsException {
   synchronized (pathNodes) {
     if (index >= 0 && index < pathNodes.size()) {
       ClientPathNode node = pathNodes.get(index);
       node.getPosition().set(x, y, z);
       // Not working properly yet
       // parent.updateNodeUI(index, true);
       // Update the whole path as a temporary measure.
       parent.updatePathUI();
     } else {
       throw new IndexOutOfBoundsException(
           "The index of the PathNode to have its position updated was outside the valid range!");
     }
   }
 }
 /**
  * Remove the IndexedPathNode at the specified node index.
  *
  * @param nodeIndex The index of the IndexedPathNode to be removed.
  * @return The IndexedPathNode removed from the specified index.
  */
 @Override
 public ClientPathNode removeNodeAt(int nodeIndex) throws IndexOutOfBoundsException {
   synchronized (pathNodes) {
     ClientPathNode node = null;
     // ToDo synch UI with changes
     // Based on the number after removing one.
     final int noOfNodes = pathNodes.size() - 1;
     if (nodeIndex >= 0 && nodeIndex <= noOfNodes) {
       node = pathNodes.remove(nodeIndex);
       while (nodeIndex < noOfNodes) {
         pathNodes.get(nodeIndex).setSequenceIndex(nodeIndex);
         nodeIndex++;
       }
       parent.updatePathUI();
     }
     return node;
   }
 }
 /**
  * Insert the specified ClientPathNode at the specified node index.
  *
  * @param nodeIndex The index at which the ClientPathNode is to be inserted. If the insertion
  *     index is the same as the number of nodes before insertion then the method is essentially
  *     like addNode except there is no ClientPathNode to be returned by the method in that case.
  * @param node The ClientPathNode to be inserted at the specified index.
  * @return The ClientPathNode which used to be at the specified index (if any).
  * @throws IndexOutOfBoundsException If the specified nodeIndex at which to insert the node is
  *     invalid.
  */
 @Override
 public ClientPathNode insertNode(int nodeIndex, ClientPathNode node)
     throws IllegalArgumentException, IndexOutOfBoundsException {
   synchronized (pathNodes) {
     if (node == null) {
       throw new IllegalArgumentException("The specified path node to be inserted was null!");
     } else {
       final int noOfNodes = pathNodes.size();
       if (nodeIndex >= 0 && nodeIndex <= noOfNodes) {
         if (nodeIndex == noOfNodes) {
           addNode(node);
           return null;
         } else {
           ClientPathNode previous = pathNodes.get(nodeIndex);
           pathNodes.add(nodeIndex, node);
           node.setSequenceIndex(nodeIndex);
           nodeIndex++;
           previous.setSequenceIndex(nodeIndex);
           nodeIndex++;
           // Use less than or equal as the number of nodes has gone up by one.
           while (nodeIndex <= noOfNodes) {
             pathNodes.get(nodeIndex).setSequenceIndex(nodeIndex);
             nodeIndex++;
           }
           parent.updatePathUI();
           return previous;
         }
       } else {
         throw new IndexOutOfBoundsException(
             String.format(
                 "The node index: %d at which the path node was to be inserted was outside the range of valid indices at which to insert! No of path nodes: %d.",
                 nodeIndex, pathNodes.size()));
       }
     }
   }
 }