/** Reads the data from the cell item. */
  private void readCellData() {
    // Load stored essentia from data
    for (int index = 0; index < this.totalTypes; index++) {
      // Is there a essentia tag?
      if (this.cellData.hasKey(HandlerItemEssentiaCell.NBT_ESSENTIA_NUMBER_KEY + index)) {
        // Set the storage
        this.storedEssentia[index] =
            AspectStack.loadAspectStackFromNBT(
                this.cellData.getCompoundTag(
                    HandlerItemEssentiaCell.NBT_ESSENTIA_NUMBER_KEY + index));

        if (this.storedEssentia[index] != null) {
          // Update the stored amount
          this.usedEssentiaStorage += this.storedEssentia[index].stackSize;
        }
      }
    }

    // Load the sort mode
    if (this.cellData.hasKey(HandlerItemEssentiaCell.NBT_SORT_KEY)) {
      this.sortMode =
          ComparatorMode.VALUES[this.cellData.getInteger(HandlerItemEssentiaCell.NBT_SORT_KEY)];
    } else {
      this.sortMode = ComparatorMode.MODE_ALPHABETIC;
    }

    // Load partition list
    if (this.cellData.hasKey(HandlerItemEssentiaCell.NBT_PARTITION_KEY)) {
      // Get the partition tag
      NBTTagCompound partitionData =
          this.cellData.getCompoundTag(HandlerItemEssentiaCell.NBT_PARTITION_KEY);

      // Get the partition count
      int partitionCount =
          partitionData.getInteger(HandlerItemEssentiaCell.NBT_PARTITION_COUNT_KEY);

      // Read the partition list
      String tag;
      Aspect partitionAspect;
      for (int i = 0; i < partitionCount; i++) {
        // Read the aspect tag
        tag = partitionData.getString(HandlerItemEssentiaCell.NBT_PARTITION_NUMBER_KEY + i);

        // Skip if empty tag
        if (tag.equals("")) {
          continue;
        }

        // Get the aspect
        partitionAspect = Aspect.aspects.get(tag);

        if (partitionAspect != null) {
          // Add the aspect
          this.partitionAspects.add(partitionAspect);
        }
      }
    }
  }
  /**
   * Attempts to add the essentia to the cell
   *
   * @param aspect
   * @param Amount
   * @return Amount not stored
   */
  private long addEssentiaToCell(final Aspect aspect, final long amount, final Actionable mode) {
    // Calculate amount to store
    long amountToStore = Math.min(amount, this.totalEssentiaStorage - this.usedEssentiaStorage);

    // Ensure we can store any
    if (amountToStore == 0) {
      // Cell is full
      return amount;
    }

    // Get the slot for this aspect
    int slotIndex = this.getSlotFor(aspect);

    // Ensure there is somewhere to put the essentia
    if (slotIndex == -1) {
      return amount;
    }

    // Are we modulating?
    if (mode == Actionable.MODULATE) {
      // Get the slot
      AspectStack stackToAddTo = this.storedEssentia[slotIndex];

      // Is the slot null?
      if (stackToAddTo == null) {
        // Create the stack
        stackToAddTo = new AspectStack(aspect, 0);

        // Store it
        this.storedEssentia[slotIndex] = stackToAddTo;
      }

      // Add to the stack
      stackToAddTo.stackSize += amountToStore;

      // Adjust the used amount
      this.usedEssentiaStorage += amountToStore;

      // Write the changes to the data tag
      this.writeStorageChanges(slotIndex, stackToAddTo);
    }

    // Return the amount we could not store
    return (amount - amountToStore);
  }
  /**
   * Attempts to extract essentia from the cell.
   *
   * @param aspect
   * @param amount
   * @param mode
   * @return Amount extracted.
   */
  private long extractEssentiaFromCell(
      final Aspect aspect, final long amount, final Actionable mode) {
    // Do we have this essentia stored?
    int slotIndex = this.getSlotFor(aspect);
    if ((slotIndex == -1) || (this.storedEssentia[slotIndex] == null)) {
      // Not stored.
      return 0;
    }

    // Get the slot
    AspectStack slotToExtractFrom = this.storedEssentia[slotIndex];

    // Calculate the amount to extract
    long amountToExtract = Math.min(slotToExtractFrom.stackSize, amount);

    // Are we modulating?
    if (mode == Actionable.MODULATE) {
      // Extract from the slot
      slotToExtractFrom.stackSize -= amountToExtract;

      // Is the slot now empty?
      if (slotToExtractFrom.stackSize == 0) {
        // Null it
        slotToExtractFrom = null;

        // Update the storage
        this.storedEssentia[slotIndex] = null;
      }

      // Adjust the used amount
      this.usedEssentiaStorage -= amountToExtract;

      // Sync the data tag
      this.writeStorageChanges(slotIndex, slotToExtractFrom);
    }

    return amountToExtract;
  }
  private void addContentsToCellDescription(
      HandlerItemEssentiaCell cellHandler, List displayList, EntityPlayer player) {
    // Get the list of stored aspects
    List<AspectStack> cellAspects = cellHandler.getAvailableAspects();

    // Sort the list
    Collections.sort(cellAspects, new AspectStackComparator());

    for (AspectStack currentStack : cellAspects) {
      if (currentStack != null) {
        // Get the chat color
        String aspectChatColor = currentStack.getChatColor();

        // Does this aspect have color?
        if (aspectChatColor != null) {
          // Add the color header
          aspectChatColor = GuiHelper.CHAT_COLOR_HEADER + aspectChatColor;
        } else {
          // It does not, set to gray
          aspectChatColor = EnumChatFormatting.GRAY.toString();
        }

        // Build the display string
        String aspectInfo =
            String.format(
                "%s%s%s x %d",
                aspectChatColor,
                currentStack.getAspectName(player),
                EnumChatFormatting.GRAY.toString(),
                currentStack.amount);

        // Add to the list
        displayList.add(aspectInfo);
      }
    }
  }
  /**
   * Synchronizes the data tag to the changed slot.
   *
   * @param slotIndex
   * @param fluidStack
   */
  private void writeStorageChanges(final int slotIndex, final AspectStack aspectStack) {
    // Create a new NBT
    NBTTagCompound essentiaTag = new NBTTagCompound();

    // Is there data to write?
    if ((aspectStack != null) && (aspectStack.aspect != null) && (aspectStack.stackSize > 0)) {
      // Write the essentia to the tag
      aspectStack.writeToNBT(essentiaTag);

      // Update the data tag
      this.cellData.setTag(
          HandlerItemEssentiaCell.NBT_ESSENTIA_NUMBER_KEY + slotIndex, essentiaTag);
    } else {
      // Remove the tag, as it is now empty
      this.cellData.removeTag(HandlerItemEssentiaCell.NBT_ESSENTIA_NUMBER_KEY + slotIndex);
    }

    // Inform the save provider
    if (this.saveProvider != null) {
      this.saveProvider.saveChanges(this);
    }
  }