 
 #include <nvbio/basic/numbers.h>
 #include <nvbio/basic/algorithms.h>
+#include <nvbio/basic/priority_queue.h>
 #include <nvbio/basic/transform_iterator.h>
+#include <nvbio/basic/vector_wrapper.h>
 #include <nvbio/basic/cuda/ldg.h>
 #include <thrust/iterator/counting_iterator.h>
 #include <thrust/iterator/transform_iterator.h>

        nvbio::make_transform_iterator( mems, mem_read_id_functor() ),
        n_mems ) - nvbio::make_transform_iterator( mems, mem_read_id_functor() ) );

    // process the seeds in order
    //nvbio::cuda::ldg_pointer<mem_state::mem_type> mems_ldg( mems );
    for (uint32 i = mem_begin; i < mem_end; ++i)
    {
        const mem_state::mem_type seed = mems[ mems_index[i] ];

        // insert seed
    }
}


        loc.begin() + n_mems,
        mem->mems_index.begin() );
}

struct chain
{
    // construct an empty chain
    NVBIO_FORCEINLINE NVBIO_HOST_DEVICE
    chain() {}

    // construct a new chain from a single seed
    NVBIO_FORCEINLINE NVBIO_HOST_DEVICE
    chain(const mem_state::mem_type seed) : ref( seed.index_pos() ) {}

    // test whether we can merge the given mem into this chain
    NVBIO_FORCEINLINE NVBIO_HOST_DEVICE
    bool merge(const mem_state::mem_type seed)
    {
        return false;
    }

    // a list of seeds : how do we store it? we need a large arena of some kind from where
    // to carve list entries...
    //seed_list seeds;

    uint32 ref; // cache the leftmost reference coordinate
};

struct chain_compare
{
    NVBIO_FORCEINLINE NVBIO_HOST_DEVICE
    bool operator() (const chain& chain1, const chain& chain2) const
    {
        // compare by the reference coordinate of the first seed of each chain
        return chain1.ref < chain2.ref;
    }
};

// build chains for the current pipeline::chunk of reads
__global__
