/** "Find the appropriate BlockProcessor for the given block type code." [DTN2] */
  public static BlockProcessor find_processor(bundle_block_type_t type) {

    Iterator<BlockProcessor> iter = processors_.iterator();
    while (iter.hasNext()) {
      BlockProcessor bp = iter.next();
      if (bp.block_type() == type) {
        return bp;
      }
    }

    return null;
  }
  /**
   * "Generate a BlockInfoVec for the outgoing link and put it into xmit_blocks_." [DTN2]
   *
   * @return a list of new BLockInfo
   */
  public static BlockInfoVec prepare_blocks(Bundle bundle, final Link link) {
    // "create a new block list for the outgoing link by first calling
    // prepare on all the BlockProcessor classes for the blocks that
    // arrived on the link" [DTN2]
    BlockInfoVec xmit_blocks = bundle.xmit_link_block_set().create_blocks(link);
    BlockInfoVec recv_blocks = bundle.recv_blocks();

    if (recv_blocks.size() > 0) {
      // "if there is a received block, the first one better be the primary"
      // [DTN2]
      assert (recv_blocks.front().type() == bundle_block_type_t.PRIMARY_BLOCK);

      Iterator<BlockInfo> iter = recv_blocks.iterator();
      while (iter.hasNext()) {
        BlockInfo block = iter.next();

        if (bundle.fragmented_incoming()
            && xmit_blocks.find_block(BundleProtocol.bundle_block_type_t.PAYLOAD_BLOCK) != null) {
          continue;
        }

        block
            .owner()
            .prepare(bundle, xmit_blocks, block, link, BlockInfo.list_owner_t.LIST_RECEIVED);
      }

    } else {
      BPF.getInstance().getBPFLogger().debug(TAG, "adding primary and payload block");
      BlockProcessor bp = find_processor(BundleProtocol.bundle_block_type_t.PRIMARY_BLOCK);
      bp.prepare(bundle, xmit_blocks, null, link, BlockInfo.list_owner_t.LIST_NONE);
      bp = find_processor(bundle_block_type_t.PAYLOAD_BLOCK);
      bp.prepare(bundle, xmit_blocks, null, link, BlockInfo.list_owner_t.LIST_NONE);
    }

    // "now we also make sure to prepare() on any registered processors
    // that don't already have a block in the output list. this
    // handles the case where we have a locally generated block with
    // nothing in the recv_blocks vector" [DTN2]

    Iterator<BlockProcessor> itr = processors_.iterator();
    while (itr.hasNext()) {
      BlockProcessor bp = itr.next();
      if (!xmit_blocks.has_block(bp.block_type())) {
        bp.prepare(bundle, xmit_blocks, null, link, BlockInfo.list_owner_t.LIST_NONE);
      }
    }

    // Now prepare security blocks
    BPF.getInstance().getBPFLogger().debug(TAG, "Now preparing security blocks...");
    Security.prepare_out_blocks(bundle, link, xmit_blocks);

    return xmit_blocks;
  }