+ return FALSE;
+}
+
+/* AVHV: Support for treating arrays as if they were hashes. The
+ * first element of the array should be a hash reference that maps
+ * hash keys to array indices.
+ */
+
+STATIC I32
+S_avhv_index_sv(pTHX_ SV* sv)
+{
+ I32 index = SvIV(sv);
+ if (index < 1)
+ Perl_croak(aTHX_ "Bad index while coercing array into hash");
+ return index;
+}
+
+HV*
+Perl_avhv_keys(pTHX_ AV *av)
+{
+ SV **keysp = av_fetch(av, 0, FALSE);
+ if (keysp) {
+ SV *sv = *keysp;
+ if (SvGMAGICAL(sv))
+ mg_get(sv);
+ if (SvROK(sv)) {
+ sv = SvRV(sv);
+ if (SvTYPE(sv) == SVt_PVHV)
+ return (HV*)sv;
+ }
+ }
+ Perl_croak(aTHX_ "Can't coerce array into hash");
+ return Nullhv;
+}
+
+SV**
+Perl_avhv_fetch_ent(pTHX_ AV *av, SV *keysv, I32 lval, U32 hash)
+{
+ SV **indsvp;
+ HV *keys = avhv_keys(av);
+ HE *he;
+ STRLEN n_a;
+
+ he = hv_fetch_ent(keys, keysv, FALSE, hash);
+ if (!he)
+ Perl_croak(aTHX_ "No such pseudo-hash field \"%s\"", SvPV(keysv,n_a));
+ return av_fetch(av, avhv_index_sv(HeVAL(he)), lval);
+}
+
+SV *
+Perl_avhv_delete_ent(pTHX_ AV *av, SV *keysv, I32 flags, U32 hash)
+{
+ HV *keys = avhv_keys(av);
+ HE *he;
+
+ he = hv_fetch_ent(keys, keysv, FALSE, hash);
+ if (!he || !SvOK(HeVAL(he)))
+ return Nullsv;
+
+ return av_delete(av, avhv_index_sv(HeVAL(he)), flags);
+}
+
+/* Check for the existence of an element named by a given key.
+ *
+ */
+bool
+Perl_avhv_exists_ent(pTHX_ AV *av, SV *keysv, U32 hash)
+{
+ HV *keys = avhv_keys(av);
+ HE *he;
+
+ he = hv_fetch_ent(keys, keysv, FALSE, hash);
+ if (!he || !SvOK(HeVAL(he)))
+ return FALSE;
+
+ return av_exists(av, avhv_index_sv(HeVAL(he)));
+}
+
+HE *
+Perl_avhv_iternext(pTHX_ AV *av)
+{
+ HV *keys = avhv_keys(av);
+ return hv_iternext(keys);
+}
+
+SV *
+Perl_avhv_iterval(pTHX_ AV *av, register HE *entry)
+{
+ SV *sv = hv_iterval(avhv_keys(av), entry);
+ return *av_fetch(av, avhv_index_sv(sv), TRUE);