    /*
     *  call-seq:
     *     index_reader.get_document(doc_id) -> LazyDoc
     *     index_reader[doc_id] -> LazyDoc
     *
     *  Retrieve a document from the index. See LazyDoc for more details on the
     *  document returned. Documents are referenced internally by document ids
     *  which are returned by the Searchers search methods.
     */
    static VALUE
    frt_ir_get_doc(int argc, VALUE *argv, VALUE self)
    {
        IndexReader *ir = (IndexReader *)DATA_PTR(self);
        VALUE arg1, arg2;
        long pos, len;
        long max = ir->max_doc(ir);
        rb_scan_args(argc, argv, "11", &arg1, &arg2);
        if (argc == 1) {
            if (FIXNUM_P(arg1)) {
                pos = FIX2INT(arg1);
                pos = (pos < 0) ? (max + pos) : pos;
                if (pos < 0 || pos >= max) {
                    rb_raise(rb_eArgError, ":%d is out of range [%d..%d] for "
                             "IndexReader#[]", pos, 0, max,
                             rb_id2name(SYM2ID(argv)));
                }
                return frt_get_lazy_doc(ir->get_lazy_doc(ir, pos));
            }

            /* check if idx is Range */
            switch (rb_range_beg_len(arg1, &pos, &len, max, 0)) {
                case Qfalse:
                    rb_raise(rb_eArgError, ":%s isn't a valid argument for "
                             "IndexReader.get_document(index)",
                             rb_id2name(SYM2ID(argv)));
                case Qnil:
                    return Qnil;
                default:
                    return frt_get_doc_range(ir, pos, len, max);
            }
        }
        else {
            pos = FIX2LONG(arg1);
            len = FIX2LONG(arg2);
            return frt_get_doc_range(ir, pos, len, max);
        }
    }