/**
   * Move a value from one named store to another store
   *
   * @param key Binary key to transfer from the source store to the destination store
   * @param source a hint for discovering the source repository; may be null
   * @param destination a hint for discovering the destination repository
   * @return the {@link BinaryKey} value of the moved binary, never {@code null}
   * @throws BinaryStoreException if a source store cannot be found or the source store does not
   *     contain the binary key
   */
  public BinaryKey moveValue(BinaryKey key, String source, String destination)
      throws BinaryStoreException {
    final BinaryStore sourceStore;

    if (source == null) {
      sourceStore = findBinaryStoreContainingKey(key);
    } else {
      sourceStore = selectBinaryStore(source);
    }

    // could not find source store, or
    if (sourceStore == null || !sourceStore.hasBinary(key)) {
      throw new BinaryStoreException(JcrI18n.unableToFindBinaryValue.text(key, sourceStore));
    }

    BinaryStore destinationStore = selectBinaryStore(destination);

    // key is already in the destination store
    if (sourceStore.equals(destinationStore)) {
      return key;
    }

    final BinaryValue binaryValue = storeValue(sourceStore.getInputStream(key), destination);
    sourceStore.markAsUnused(java.util.Collections.singleton(key));

    return binaryValue.getKey();
  }
  @Override
  public InputStream getInputStream(BinaryKey key) throws BinaryStoreException {
    Iterator<Map.Entry<String, BinaryStore>> it = getNamedStoreIterator();

    while (it.hasNext()) {
      final Map.Entry<String, BinaryStore> entry = it.next();

      final String binaryStoreKey = entry.getKey();

      BinaryStore binaryStore = entry.getValue();
      logger.trace("Checking binary store " + binaryStoreKey + " for key " + key);
      try {
        return binaryStore.getInputStream(key);
      } catch (BinaryStoreException e) {
        // this exception is "normal", and is thrown
        logger.trace(e, "The named store " + binaryStoreKey + " raised exception");
      }
    }

    throw new BinaryStoreException(JcrI18n.unableToFindBinaryValue.text(key, this.toString()));
  }