    /*
     *  call-seq:
     *     IndexWriter.new(options = {}) -> index_writer
     *
     *  Create a new IndexWriter. You should either pass a path or a directory to
     *  this constructor. For example, here are three ways you can create an
     *  IndexWriter;
     *
     *    dir = RAMDirectory.new()
     *    iw = IndexWriter.new(:dir => dir)
     *
     *    dir = FSDirectory.new("/path/to/index")
     *    iw = IndexWriter.new(:dir => dir)
     *
     *    iw = IndexWriter.new(:path => "/path/to/index")
     *
     * See IndexWriter for more options.
     */
    static VALUE
    frb_iw_init(int argc, VALUE *argv, VALUE self)
    {
        VALUE roptions, rval;
        bool create = false;
        bool create_if_missing = true;
        Store *store = NULL;
        Analyzer *analyzer = NULL;
        IndexWriter *volatile iw = NULL;
        Config config = default_config;

        rb_scan_args(argc, argv, "01", &roptions);
        if (argc > 0) {
            Check_Type(roptions, T_HASH);

            if ((rval = rb_hash_aref(roptions, sym_dir)) != Qnil) {
                Check_Type(rval, T_DATA);
                store = DATA_PTR(rval);
            } else if ((rval = rb_hash_aref(roptions, sym_path)) != Qnil) {
                StringValue(rval);
                frb_create_dir(rval);
                store = open_fs_store(rs2s(rval));
                DEREF(store);
            }

            /* Let ruby's garbage collector handle the closing of the store
               if (!close_dir) {
               close_dir = RTEST(rb_hash_aref(roptions, sym_close_dir));
               }
               */
            /* use_compound_file defaults to true */
            config.use_compound_file =
                (rb_hash_aref(roptions, sym_use_compound_file) == Qfalse)
                ? false
                : true;

            if ((rval = rb_hash_aref(roptions, sym_analyzer)) != Qnil) {
                analyzer = frb_get_cwrapped_analyzer(rval);
            }

            create = RTEST(rb_hash_aref(roptions, sym_create));
            if ((rval = rb_hash_aref(roptions, sym_create_if_missing)) != Qnil) {
                create_if_missing = RTEST(rval);
            }
            SET_INT_ATTR(chunk_size);
            SET_INT_ATTR(max_buffer_memory);
            SET_INT_ATTR(index_interval);
            SET_INT_ATTR(skip_interval);
            SET_INT_ATTR(merge_factor);
            SET_INT_ATTR(max_buffered_docs);
            SET_INT_ATTR(max_merge_docs);
            SET_INT_ATTR(max_field_length);
        }
        if (NULL == store) {
            store = open_ram_store();
            DEREF(store);
        }
        if (!create && create_if_missing && !store->exists(store, "segments")) {
            create = true;
        }
        if (create) {
            FieldInfos *fis;
            if ((rval = rb_hash_aref(roptions, sym_field_infos)) != Qnil) {
                Data_Get_Struct(rval, FieldInfos, fis);
                index_create(store, fis);
            } else {
                fis = fis_new(STORE_YES, INDEX_YES,
                              TERM_VECTOR_WITH_POSITIONS_OFFSETS);
                index_create(store, fis);
                fis_deref(fis);
            }
        }

        iw = iw_open(store, analyzer, &config);

        Frt_Wrap_Struct(self, &frb_iw_mark, &frb_iw_free, iw);

        if (rb_block_given_p()) {
            rb_yield(self);
            frb_iw_close(self);
            return Qnil;
        } else {
            return self;
        }
    }