diff --git a/gui/slick/images/flags/af.png b/gui/slick/images/flags/afr.png
similarity index 100%
rename from gui/slick/images/flags/af.png
rename to gui/slick/images/flags/afr.png
diff --git a/gui/slick/images/flags/am.png b/gui/slick/images/flags/amh.png
similarity index 100%
rename from gui/slick/images/flags/am.png
rename to gui/slick/images/flags/amh.png
diff --git a/gui/slick/images/flags/ar.png b/gui/slick/images/flags/ara.png
similarity index 100%
rename from gui/slick/images/flags/ar.png
rename to gui/slick/images/flags/ara.png
diff --git a/gui/slick/images/flags/an.png b/gui/slick/images/flags/arg.png
similarity index 100%
rename from gui/slick/images/flags/an.png
rename to gui/slick/images/flags/arg.png
diff --git a/gui/slick/images/flags/as.png b/gui/slick/images/flags/asm.png
similarity index 100%
rename from gui/slick/images/flags/as.png
rename to gui/slick/images/flags/asm.png
diff --git a/gui/slick/images/flags/ae.png b/gui/slick/images/flags/ave.png
similarity index 100%
rename from gui/slick/images/flags/ae.png
rename to gui/slick/images/flags/ave.png
diff --git a/gui/slick/images/flags/ay.png b/gui/slick/images/flags/aym.png
similarity index 100%
rename from gui/slick/images/flags/ay.png
rename to gui/slick/images/flags/aym.png
diff --git a/gui/slick/images/flags/az.png b/gui/slick/images/flags/aze.png
similarity index 100%
rename from gui/slick/images/flags/az.png
rename to gui/slick/images/flags/aze.png
diff --git a/gui/slick/images/flags/ba.png b/gui/slick/images/flags/bak.png
similarity index 100%
rename from gui/slick/images/flags/ba.png
rename to gui/slick/images/flags/bak.png
diff --git a/gui/slick/images/flags/bm.png b/gui/slick/images/flags/bam.png
similarity index 100%
rename from gui/slick/images/flags/bm.png
rename to gui/slick/images/flags/bam.png
diff --git a/gui/slick/images/flags/be.png b/gui/slick/images/flags/bel.png
similarity index 100%
rename from gui/slick/images/flags/be.png
rename to gui/slick/images/flags/bel.png
diff --git a/gui/slick/images/flags/bn.png b/gui/slick/images/flags/ben.png
similarity index 100%
rename from gui/slick/images/flags/bn.png
rename to gui/slick/images/flags/ben.png
diff --git a/gui/slick/images/flags/bi.png b/gui/slick/images/flags/bis.png
similarity index 100%
rename from gui/slick/images/flags/bi.png
rename to gui/slick/images/flags/bis.png
diff --git a/gui/slick/images/flags/bo.png b/gui/slick/images/flags/bod.png
similarity index 100%
rename from gui/slick/images/flags/bo.png
rename to gui/slick/images/flags/bod.png
diff --git a/gui/slick/images/flags/bs.png b/gui/slick/images/flags/bos.png
similarity index 100%
rename from gui/slick/images/flags/bs.png
rename to gui/slick/images/flags/bos.png
diff --git a/gui/slick/images/flags/br.png b/gui/slick/images/flags/bre.png
similarity index 100%
rename from gui/slick/images/flags/br.png
rename to gui/slick/images/flags/bre.png
diff --git a/gui/slick/images/flags/bg.png b/gui/slick/images/flags/bul.png
similarity index 100%
rename from gui/slick/images/flags/bg.png
rename to gui/slick/images/flags/bul.png
diff --git a/gui/slick/images/flags/ca.png b/gui/slick/images/flags/cat.png
similarity index 100%
rename from gui/slick/images/flags/ca.png
rename to gui/slick/images/flags/cat.png
diff --git a/gui/slick/images/flags/cs.png b/gui/slick/images/flags/ces.png
similarity index 100%
rename from gui/slick/images/flags/cs.png
rename to gui/slick/images/flags/ces.png
diff --git a/gui/slick/images/flags/ch.png b/gui/slick/images/flags/cha.png
similarity index 100%
rename from gui/slick/images/flags/ch.png
rename to gui/slick/images/flags/cha.png
diff --git a/gui/slick/images/flags/cu.png b/gui/slick/images/flags/chu.png
similarity index 100%
rename from gui/slick/images/flags/cu.png
rename to gui/slick/images/flags/chu.png
diff --git a/gui/slick/images/flags/cv.png b/gui/slick/images/flags/chv.png
similarity index 100%
rename from gui/slick/images/flags/cv.png
rename to gui/slick/images/flags/chv.png
diff --git a/gui/slick/images/flags/kw.png b/gui/slick/images/flags/cor.png
similarity index 100%
rename from gui/slick/images/flags/kw.png
rename to gui/slick/images/flags/cor.png
diff --git a/gui/slick/images/flags/co.png b/gui/slick/images/flags/cos.png
similarity index 100%
rename from gui/slick/images/flags/co.png
rename to gui/slick/images/flags/cos.png
diff --git a/gui/slick/images/flags/cr.png b/gui/slick/images/flags/cre.png
similarity index 100%
rename from gui/slick/images/flags/cr.png
rename to gui/slick/images/flags/cre.png
diff --git a/gui/slick/images/flags/cy.png b/gui/slick/images/flags/cym.png
similarity index 100%
rename from gui/slick/images/flags/cy.png
rename to gui/slick/images/flags/cym.png
diff --git a/gui/slick/images/flags/da.png b/gui/slick/images/flags/dan.png
similarity index 100%
rename from gui/slick/images/flags/da.png
rename to gui/slick/images/flags/dan.png
diff --git a/gui/slick/images/flags/de.png b/gui/slick/images/flags/deu.png
similarity index 100%
rename from gui/slick/images/flags/de.png
rename to gui/slick/images/flags/deu.png
diff --git a/gui/slick/images/flags/dz.png b/gui/slick/images/flags/dzo.png
similarity index 100%
rename from gui/slick/images/flags/dz.png
rename to gui/slick/images/flags/dzo.png
diff --git a/gui/slick/images/flags/el.png b/gui/slick/images/flags/ell.png
similarity index 100%
rename from gui/slick/images/flags/el.png
rename to gui/slick/images/flags/ell.png
diff --git a/gui/slick/images/flags/en.png b/gui/slick/images/flags/eng.png
similarity index 100%
rename from gui/slick/images/flags/en.png
rename to gui/slick/images/flags/eng.png
diff --git a/gui/slick/images/flags/eo.png b/gui/slick/images/flags/epo.png
similarity index 100%
rename from gui/slick/images/flags/eo.png
rename to gui/slick/images/flags/epo.png
diff --git a/gui/slick/images/flags/et.png b/gui/slick/images/flags/est.png
similarity index 100%
rename from gui/slick/images/flags/et.png
rename to gui/slick/images/flags/est.png
diff --git a/gui/slick/images/flags/ee.png b/gui/slick/images/flags/ewe.png
similarity index 100%
rename from gui/slick/images/flags/ee.png
rename to gui/slick/images/flags/ewe.png
diff --git a/gui/slick/images/flags/fo.png b/gui/slick/images/flags/fao.png
similarity index 100%
rename from gui/slick/images/flags/fo.png
rename to gui/slick/images/flags/fao.png
diff --git a/gui/slick/images/flags/fa.png b/gui/slick/images/flags/fas.png
similarity index 100%
rename from gui/slick/images/flags/fa.png
rename to gui/slick/images/flags/fas.png
diff --git a/gui/slick/images/flags/fj.png b/gui/slick/images/flags/fij.png
similarity index 100%
rename from gui/slick/images/flags/fj.png
rename to gui/slick/images/flags/fij.png
diff --git a/gui/slick/images/flags/fi.png b/gui/slick/images/flags/fin.png
similarity index 100%
rename from gui/slick/images/flags/fi.png
rename to gui/slick/images/flags/fin.png
diff --git a/gui/slick/images/flags/fr.png b/gui/slick/images/flags/fra.png
similarity index 100%
rename from gui/slick/images/flags/fr.png
rename to gui/slick/images/flags/fra.png
diff --git a/gui/slick/images/flags/gd.png b/gui/slick/images/flags/gla.png
similarity index 100%
rename from gui/slick/images/flags/gd.png
rename to gui/slick/images/flags/gla.png
diff --git a/gui/slick/images/flags/ga.png b/gui/slick/images/flags/gle.png
similarity index 100%
rename from gui/slick/images/flags/ga.png
rename to gui/slick/images/flags/gle.png
diff --git a/gui/slick/images/flags/gl.png b/gui/slick/images/flags/glg.png
similarity index 100%
rename from gui/slick/images/flags/gl.png
rename to gui/slick/images/flags/glg.png
diff --git a/gui/slick/images/flags/gn.png b/gui/slick/images/flags/grn.png
similarity index 100%
rename from gui/slick/images/flags/gn.png
rename to gui/slick/images/flags/grn.png
diff --git a/gui/slick/images/flags/gu.png b/gui/slick/images/flags/guj.png
similarity index 100%
rename from gui/slick/images/flags/gu.png
rename to gui/slick/images/flags/guj.png
diff --git a/gui/slick/images/flags/ht.png b/gui/slick/images/flags/hat.png
similarity index 100%
rename from gui/slick/images/flags/ht.png
rename to gui/slick/images/flags/hat.png
diff --git a/gui/slick/images/flags/he.png b/gui/slick/images/flags/heb.png
similarity index 100%
rename from gui/slick/images/flags/he.png
rename to gui/slick/images/flags/heb.png
diff --git a/gui/slick/images/flags/hi.png b/gui/slick/images/flags/hin.png
similarity index 100%
rename from gui/slick/images/flags/hi.png
rename to gui/slick/images/flags/hin.png
diff --git a/gui/slick/images/flags/hr.png b/gui/slick/images/flags/hrv.png
similarity index 100%
rename from gui/slick/images/flags/hr.png
rename to gui/slick/images/flags/hrv.png
diff --git a/gui/slick/images/flags/hu.png b/gui/slick/images/flags/hun.png
similarity index 100%
rename from gui/slick/images/flags/hu.png
rename to gui/slick/images/flags/hun.png
diff --git a/gui/slick/images/flags/hy.png b/gui/slick/images/flags/hye.png
similarity index 100%
rename from gui/slick/images/flags/hy.png
rename to gui/slick/images/flags/hye.png
diff --git a/gui/slick/images/flags/io.png b/gui/slick/images/flags/ido.png
similarity index 100%
rename from gui/slick/images/flags/io.png
rename to gui/slick/images/flags/ido.png
diff --git a/gui/slick/images/flags/ie.png b/gui/slick/images/flags/ile.png
similarity index 100%
rename from gui/slick/images/flags/ie.png
rename to gui/slick/images/flags/ile.png
diff --git a/gui/slick/images/flags/id.png b/gui/slick/images/flags/ind.png
similarity index 100%
rename from gui/slick/images/flags/id.png
rename to gui/slick/images/flags/ind.png
diff --git a/gui/slick/images/flags/is.png b/gui/slick/images/flags/isl.png
similarity index 100%
rename from gui/slick/images/flags/is.png
rename to gui/slick/images/flags/isl.png
diff --git a/gui/slick/images/flags/it.png b/gui/slick/images/flags/ita.png
similarity index 100%
rename from gui/slick/images/flags/it.png
rename to gui/slick/images/flags/ita.png
diff --git a/gui/slick/images/flags/ja.png b/gui/slick/images/flags/jpn.png
similarity index 100%
rename from gui/slick/images/flags/ja.png
rename to gui/slick/images/flags/jpn.png
diff --git a/gui/slick/images/flags/kn.png b/gui/slick/images/flags/kan.png
similarity index 100%
rename from gui/slick/images/flags/kn.png
rename to gui/slick/images/flags/kan.png
diff --git a/gui/slick/images/flags/ka.png b/gui/slick/images/flags/kat.png
similarity index 100%
rename from gui/slick/images/flags/ka.png
rename to gui/slick/images/flags/kat.png
diff --git a/gui/slick/images/flags/kr.png b/gui/slick/images/flags/kau.png
similarity index 100%
rename from gui/slick/images/flags/kr.png
rename to gui/slick/images/flags/kau.png
diff --git a/gui/slick/images/flags/kk.png b/gui/slick/images/flags/kaz.png
similarity index 100%
rename from gui/slick/images/flags/kk.png
rename to gui/slick/images/flags/kaz.png
diff --git a/gui/slick/images/flags/km.png b/gui/slick/images/flags/khm.png
similarity index 100%
rename from gui/slick/images/flags/km.png
rename to gui/slick/images/flags/khm.png
diff --git a/gui/slick/images/flags/ki.png b/gui/slick/images/flags/kik.png
similarity index 100%
rename from gui/slick/images/flags/ki.png
rename to gui/slick/images/flags/kik.png
diff --git a/gui/slick/images/flags/rw.png b/gui/slick/images/flags/kin.png
similarity index 100%
rename from gui/slick/images/flags/rw.png
rename to gui/slick/images/flags/kin.png
diff --git a/gui/slick/images/flags/ky.png b/gui/slick/images/flags/kir.png
similarity index 100%
rename from gui/slick/images/flags/ky.png
rename to gui/slick/images/flags/kir.png
diff --git a/gui/slick/images/flags/kg.png b/gui/slick/images/flags/kon.png
similarity index 100%
rename from gui/slick/images/flags/kg.png
rename to gui/slick/images/flags/kon.png
diff --git a/gui/slick/images/flags/ko.png b/gui/slick/images/flags/kor.png
similarity index 100%
rename from gui/slick/images/flags/ko.png
rename to gui/slick/images/flags/kor.png
diff --git a/gui/slick/images/flags/la.png b/gui/slick/images/flags/lat.png
similarity index 100%
rename from gui/slick/images/flags/la.png
rename to gui/slick/images/flags/lat.png
diff --git a/gui/slick/images/flags/lv.png b/gui/slick/images/flags/lav.png
similarity index 100%
rename from gui/slick/images/flags/lv.png
rename to gui/slick/images/flags/lav.png
diff --git a/gui/slick/images/flags/li.png b/gui/slick/images/flags/lim.png
similarity index 100%
rename from gui/slick/images/flags/li.png
rename to gui/slick/images/flags/lim.png
diff --git a/gui/slick/images/flags/lt.png b/gui/slick/images/flags/lit.png
similarity index 100%
rename from gui/slick/images/flags/lt.png
rename to gui/slick/images/flags/lit.png
diff --git a/gui/slick/images/flags/lb.png b/gui/slick/images/flags/ltz.png
similarity index 100%
rename from gui/slick/images/flags/lb.png
rename to gui/slick/images/flags/ltz.png
diff --git a/gui/slick/images/flags/lu.png b/gui/slick/images/flags/lub.png
similarity index 100%
rename from gui/slick/images/flags/lu.png
rename to gui/slick/images/flags/lub.png
diff --git a/gui/slick/images/flags/mh.png b/gui/slick/images/flags/mah.png
similarity index 100%
rename from gui/slick/images/flags/mh.png
rename to gui/slick/images/flags/mah.png
diff --git a/gui/slick/images/flags/ml.png b/gui/slick/images/flags/mal.png
similarity index 100%
rename from gui/slick/images/flags/ml.png
rename to gui/slick/images/flags/mal.png
diff --git a/gui/slick/images/flags/mr.png b/gui/slick/images/flags/mar.png
similarity index 100%
rename from gui/slick/images/flags/mr.png
rename to gui/slick/images/flags/mar.png
diff --git a/gui/slick/images/flags/mk.png b/gui/slick/images/flags/mkd.png
similarity index 100%
rename from gui/slick/images/flags/mk.png
rename to gui/slick/images/flags/mkd.png
diff --git a/gui/slick/images/flags/mg.png b/gui/slick/images/flags/mlg.png
similarity index 100%
rename from gui/slick/images/flags/mg.png
rename to gui/slick/images/flags/mlg.png
diff --git a/gui/slick/images/flags/mt.png b/gui/slick/images/flags/mlt.png
similarity index 100%
rename from gui/slick/images/flags/mt.png
rename to gui/slick/images/flags/mlt.png
diff --git a/gui/slick/images/flags/mn.png b/gui/slick/images/flags/mon.png
similarity index 100%
rename from gui/slick/images/flags/mn.png
rename to gui/slick/images/flags/mon.png
diff --git a/gui/slick/images/flags/ms.png b/gui/slick/images/flags/msa.png
similarity index 100%
rename from gui/slick/images/flags/ms.png
rename to gui/slick/images/flags/msa.png
diff --git a/gui/slick/images/flags/my.png b/gui/slick/images/flags/mya.png
similarity index 100%
rename from gui/slick/images/flags/my.png
rename to gui/slick/images/flags/mya.png
diff --git a/gui/slick/images/flags/na.png b/gui/slick/images/flags/nau.png
similarity index 100%
rename from gui/slick/images/flags/na.png
rename to gui/slick/images/flags/nau.png
diff --git a/gui/slick/images/flags/nr.png b/gui/slick/images/flags/nbl.png
similarity index 100%
rename from gui/slick/images/flags/nr.png
rename to gui/slick/images/flags/nbl.png
diff --git a/gui/slick/images/flags/ng.png b/gui/slick/images/flags/ndo.png
similarity index 100%
rename from gui/slick/images/flags/ng.png
rename to gui/slick/images/flags/ndo.png
diff --git a/gui/slick/images/flags/ne.png b/gui/slick/images/flags/nep.png
similarity index 100%
rename from gui/slick/images/flags/ne.png
rename to gui/slick/images/flags/nep.png
diff --git a/gui/slick/images/flags/nl.png b/gui/slick/images/flags/nld.png
similarity index 100%
rename from gui/slick/images/flags/nl.png
rename to gui/slick/images/flags/nld.png
diff --git a/gui/slick/images/flags/no.png b/gui/slick/images/flags/nor.png
similarity index 100%
rename from gui/slick/images/flags/no.png
rename to gui/slick/images/flags/nor.png
diff --git a/gui/slick/images/flags/oc.png b/gui/slick/images/flags/oci.png
similarity index 100%
rename from gui/slick/images/flags/oc.png
rename to gui/slick/images/flags/oci.png
diff --git a/gui/slick/images/flags/om.png b/gui/slick/images/flags/orm.png
similarity index 100%
rename from gui/slick/images/flags/om.png
rename to gui/slick/images/flags/orm.png
diff --git a/gui/slick/images/flags/pa.png b/gui/slick/images/flags/pan.png
similarity index 100%
rename from gui/slick/images/flags/pa.png
rename to gui/slick/images/flags/pan.png
diff --git a/gui/slick/images/flags/pl.png b/gui/slick/images/flags/pol.png
similarity index 100%
rename from gui/slick/images/flags/pl.png
rename to gui/slick/images/flags/pol.png
diff --git a/gui/slick/images/flags/pt.png b/gui/slick/images/flags/por.png
similarity index 100%
rename from gui/slick/images/flags/pt.png
rename to gui/slick/images/flags/por.png
diff --git a/gui/slick/images/flags/ps.png b/gui/slick/images/flags/pus.png
similarity index 100%
rename from gui/slick/images/flags/ps.png
rename to gui/slick/images/flags/pus.png
diff --git a/gui/slick/images/flags/ro.png b/gui/slick/images/flags/ron.png
similarity index 100%
rename from gui/slick/images/flags/ro.png
rename to gui/slick/images/flags/ron.png
diff --git a/gui/slick/images/flags/ru.png b/gui/slick/images/flags/rus.png
similarity index 100%
rename from gui/slick/images/flags/ru.png
rename to gui/slick/images/flags/rus.png
diff --git a/gui/slick/images/flags/sg.png b/gui/slick/images/flags/sag.png
similarity index 100%
rename from gui/slick/images/flags/sg.png
rename to gui/slick/images/flags/sag.png
diff --git a/gui/slick/images/flags/sa.png b/gui/slick/images/flags/san.png
similarity index 100%
rename from gui/slick/images/flags/sa.png
rename to gui/slick/images/flags/san.png
diff --git a/gui/slick/images/flags/si.png b/gui/slick/images/flags/sin.png
similarity index 100%
rename from gui/slick/images/flags/si.png
rename to gui/slick/images/flags/sin.png
diff --git a/gui/slick/images/flags/sk.png b/gui/slick/images/flags/slk.png
similarity index 100%
rename from gui/slick/images/flags/sk.png
rename to gui/slick/images/flags/slk.png
diff --git a/gui/slick/images/flags/sl.png b/gui/slick/images/flags/slv.png
similarity index 100%
rename from gui/slick/images/flags/sl.png
rename to gui/slick/images/flags/slv.png
diff --git a/gui/slick/images/flags/se.png b/gui/slick/images/flags/sme.png
similarity index 100%
rename from gui/slick/images/flags/se.png
rename to gui/slick/images/flags/sme.png
diff --git a/gui/slick/images/flags/sm.png b/gui/slick/images/flags/smo.png
similarity index 100%
rename from gui/slick/images/flags/sm.png
rename to gui/slick/images/flags/smo.png
diff --git a/gui/slick/images/flags/sn.png b/gui/slick/images/flags/sna.png
similarity index 100%
rename from gui/slick/images/flags/sn.png
rename to gui/slick/images/flags/sna.png
diff --git a/gui/slick/images/flags/sd.png b/gui/slick/images/flags/snd.png
similarity index 100%
rename from gui/slick/images/flags/sd.png
rename to gui/slick/images/flags/snd.png
diff --git a/gui/slick/images/flags/so.png b/gui/slick/images/flags/som.png
similarity index 100%
rename from gui/slick/images/flags/so.png
rename to gui/slick/images/flags/som.png
diff --git a/gui/slick/images/flags/st.png b/gui/slick/images/flags/sot.png
similarity index 100%
rename from gui/slick/images/flags/st.png
rename to gui/slick/images/flags/sot.png
diff --git a/gui/slick/images/flags/es.png b/gui/slick/images/flags/spa.png
similarity index 100%
rename from gui/slick/images/flags/es.png
rename to gui/slick/images/flags/spa.png
diff --git a/gui/slick/images/flags/sq.png b/gui/slick/images/flags/sqi.png
similarity index 100%
rename from gui/slick/images/flags/sq.png
rename to gui/slick/images/flags/sqi.png
diff --git a/gui/slick/images/flags/sc.png b/gui/slick/images/flags/srd.png
similarity index 100%
rename from gui/slick/images/flags/sc.png
rename to gui/slick/images/flags/srd.png
diff --git a/gui/slick/images/flags/sr.png b/gui/slick/images/flags/srp.png
similarity index 100%
rename from gui/slick/images/flags/sr.png
rename to gui/slick/images/flags/srp.png
diff --git a/gui/slick/images/flags/sv.png b/gui/slick/images/flags/swe.png
similarity index 100%
rename from gui/slick/images/flags/sv.png
rename to gui/slick/images/flags/swe.png
diff --git a/gui/slick/images/flags/tt.png b/gui/slick/images/flags/tat.png
similarity index 100%
rename from gui/slick/images/flags/tt.png
rename to gui/slick/images/flags/tat.png
diff --git a/gui/slick/images/flags/tg.png b/gui/slick/images/flags/tgk.png
similarity index 100%
rename from gui/slick/images/flags/tg.png
rename to gui/slick/images/flags/tgk.png
diff --git a/gui/slick/images/flags/tl.png b/gui/slick/images/flags/tgl.png
similarity index 100%
rename from gui/slick/images/flags/tl.png
rename to gui/slick/images/flags/tgl.png
diff --git a/gui/slick/images/flags/th.png b/gui/slick/images/flags/tha.png
similarity index 100%
rename from gui/slick/images/flags/th.png
rename to gui/slick/images/flags/tha.png
diff --git a/gui/slick/images/flags/to.png b/gui/slick/images/flags/ton.png
similarity index 100%
rename from gui/slick/images/flags/to.png
rename to gui/slick/images/flags/ton.png
diff --git a/gui/slick/images/flags/tn.png b/gui/slick/images/flags/tsn.png
similarity index 100%
rename from gui/slick/images/flags/tn.png
rename to gui/slick/images/flags/tsn.png
diff --git a/gui/slick/images/flags/tk.png b/gui/slick/images/flags/tuk.png
similarity index 100%
rename from gui/slick/images/flags/tk.png
rename to gui/slick/images/flags/tuk.png
diff --git a/gui/slick/images/flags/tr.png b/gui/slick/images/flags/tur.png
similarity index 100%
rename from gui/slick/images/flags/tr.png
rename to gui/slick/images/flags/tur.png
diff --git a/gui/slick/images/flags/tw.png b/gui/slick/images/flags/twi.png
similarity index 100%
rename from gui/slick/images/flags/tw.png
rename to gui/slick/images/flags/twi.png
diff --git a/gui/slick/images/flags/ug.png b/gui/slick/images/flags/uig.png
similarity index 100%
rename from gui/slick/images/flags/ug.png
rename to gui/slick/images/flags/uig.png
diff --git a/gui/slick/images/flags/uk.png b/gui/slick/images/flags/ukr.png
similarity index 100%
rename from gui/slick/images/flags/uk.png
rename to gui/slick/images/flags/ukr.png
diff --git a/gui/slick/images/flags/und.png b/gui/slick/images/flags/und.png
new file mode 100644
index 0000000000000000000000000000000000000000..af9249bc317b724a8923e1447c60977dc9a91827
Binary files /dev/null and b/gui/slick/images/flags/und.png differ
diff --git a/gui/slick/images/flags/uz.png b/gui/slick/images/flags/uzb.png
similarity index 100%
rename from gui/slick/images/flags/uz.png
rename to gui/slick/images/flags/uzb.png
diff --git a/gui/slick/images/flags/ve.png b/gui/slick/images/flags/ven.png
similarity index 100%
rename from gui/slick/images/flags/ve.png
rename to gui/slick/images/flags/ven.png
diff --git a/gui/slick/images/flags/vi.png b/gui/slick/images/flags/vie.png
similarity index 100%
rename from gui/slick/images/flags/vi.png
rename to gui/slick/images/flags/vie.png
diff --git a/gui/slick/images/flags/za.png b/gui/slick/images/flags/zha.png
similarity index 100%
rename from gui/slick/images/flags/za.png
rename to gui/slick/images/flags/zha.png
diff --git a/gui/slick/images/flags/zh.png b/gui/slick/images/flags/zho.png
similarity index 100%
rename from gui/slick/images/flags/zh.png
rename to gui/slick/images/flags/zho.png
diff --git a/gui/slick/interfaces/default/config_subtitles.tmpl b/gui/slick/interfaces/default/config_subtitles.tmpl
index 845904fa549209ba2a6ec54d228df848f1931106..91d2139f8d96da70e8ea5e5bfbd8b33570731d76 100644
--- a/gui/slick/interfaces/default/config_subtitles.tmpl
+++ b/gui/slick/interfaces/default/config_subtitles.tmpl
@@ -19,7 +19,7 @@
   	\$(document).ready(function() {
 		\$("#subtitles_languages").tokenInput(
 				[
-	                <%=",\r\n".join("{id: \"" + lang.alpha2 + "\", name: \"" + lang.name + "\"}" for lang in subtitles.subtitleLanguageFilter())%>
+	                <%=",\r\n".join("{id: \"" + lang.alpha3 + "\", name: \"" + lang.name + "\"}" for lang in subtitles.subtitleLanguageFilter())%>
 	            ],
 	            {
 					method: "POST",
@@ -29,7 +29,7 @@
 	            		
 		            		[
 		            			<%=
-		            					",\r\n".join("{id: \"" + lang + "\", name: \"" + Language.fromalpha2(lang).name + "\"}" for lang in sickbeard.SUBTITLES_LANGUAGES) if sickbeard.SUBTITLES_LANGUAGES != '' else ''
+		            					",\r\n".join("{id: \"" + Language.fromietf(lang).alpha3 + "\", name: \"" + Language.fromietf(lang).name + "\"}" for lang in subtitles.wantedLanguages()) if subtitles.wantedLanguages() else ''
 		            			%>
 		            		]
 	            }
@@ -143,19 +143,17 @@
                     <fieldset class="component-group-list" style="margin-left: 50px; margin-top:36px">
                         <ul id="service_order_list">
                         #for $curService in $sickbeard.subtitles.sortedServiceList():
-                            #set $curName = $curService.id
-                          <li class="ui-state-default" id="$curName">
-                            <input type="checkbox" id="enable_$curName" class="service_enabler" #if $curService.enabled then "checked=\"checked\"" else ""#/>
-                            ##set $provider_url = $curService.url
-                            ##<a href="<%= anon_url(provider_url) %>" class="imgLink" target="_new">
-                                <img src="$sbRoot/images/subtitles/$curService.image" alt="$curService.name" title="$curService.name" width="16" height="16" style="vertical-align:middle;"/>
-                            ##</a>
-                            <span style="vertical-align:middle;">$curService.name.capitalize()</span>
+                            <li class="ui-state-default" id="$curService['name']">
+                                <input type="checkbox" id="enable_$curService['name']" class="service_enabler" #if $curService['enabled'] then "checked=\"checked\"" else ""#/>
+                                <a href="<%= anon_url(curService['url']) %>" class="imgLink" target="_new">
+                                    <img src="$sbRoot/images/subtitles/$curService.image" alt="$curService['url']" title="$curService['url']" width="16" height="16" style="vertical-align:middle;"/>
+                                </a>
+                            <span style="vertical-align:middle;">$curService['name'].capitalize()</span>
                             <span class="ui-icon ui-icon-arrowthick-2-n-s pull-right" style="vertical-align:middle;"></span>
                           </li>
                         #end for
                         </ul>
-                        <input type="hidden" name="service_order" id="service_order" value="<%=" ".join([x.get('id')+':'+str(int(x.get('enabled'))) for x in sickbeard.subtitles.sortedServiceList()])%>"/>
+                        <input type="hidden" name="service_order" id="service_order" value="<%=" ".join(['%s:%d' % (x['name'], x['enabled']) for x in sickbeard.subtitles.sortedServiceList()])%>"/>
                         
                         <br/><input type="submit" class="btn config_submitter" value="Save Changes" /><br/>
                     </fieldset>
diff --git a/gui/slick/interfaces/default/displayShow.tmpl b/gui/slick/interfaces/default/displayShow.tmpl
index 30decd050d83e36c1ec7970dca02f8f38c64944f..4dbd73eda10645c751d35f229f44081b75780a65 100644
--- a/gui/slick/interfaces/default/displayShow.tmpl
+++ b/gui/slick/interfaces/default/displayShow.tmpl
@@ -286,9 +286,10 @@
                 </table>
             
                 <table style="width:180px; float: right; vertical-align: middle; height: 100%;">
-                    <tr><td class="showLegend">Info Language:</td><td><img src="$sbRoot/images/flags/${show.lang}.png" width="16" height="11" alt="$show.lang" title="$show.lang" /></td></tr>
+                    #set $info_flag = $babelfish.Language.fromietf($show.lang).alpha3 if $subtitles.isValidLanguage($show.lang) else 'unknown'
+                    <tr><td class="showLegend">Info Language:</td><td><img src="$sbRoot/images/flags/${info_flag}.png" width="16" height="11" alt="$show.lang" title="$show.lang" onError="this.onerror=null;this.src='$sbRoot/images/flags/unknown.png';"/></td></tr>
                     #if $sickbeard.USE_SUBTITLES
-                    <tr><td class="showLegend">Subtitles: </td><td><img src="$sbRoot/images/#if int($show.subtitles) == 1 then "yes16.png\" alt=\"Y" else "no16.png\" alt=\"N"#" width="16" height="16" /></td></tr>
+                    <tr><td class="showLegend">Subtitles: </td><td><img src="$sbRoot/images/#if $show.subtitles then "yes16.png\" alt=\"Y" else "no16.png\" alt=\"N"#" width="16" height="16" /></td></tr>
                     #end if
                     <tr><td class="showLegend">Flat Folders: </td><td><img src="$sbRoot/images/#if $show.flatten_folders == 1 or $sickbeard.NAMING_FORCE_FOLDERS then "yes16.png\" alt=\"Y" else "no16.png\" alt=\"N"#" width="16" height="16" /></td></tr>
 					<tr><td class="showLegend">Paused: </td><td><img src="$sbRoot/images/#if int($show.paused) == 1 then "yes16.png\" alt=\"Y" else "no16.png\" alt=\"N"#" width="16" height="16" /></td></tr>
@@ -579,15 +580,10 @@
                 #end if
             </td>
             <td class="col-subtitles" align="center">
-            #if $epResult["subtitles"]:
-                #for $sub_lang in [babelfish.Language.fromietf(x.strip()) for x in $epResult["subtitles"].split(',') if x.strip() in babelfish.language_converters['alpha2'].codes]:
-                    #if $sub_lang.alpha2 != u'':
-                        <img src="$sbRoot/images/flags/${sub_lang.alpha2}.png" width="16" height="11" alt="${sub_lang.name}" />
-                    #else
-                        <img src="$sbRoot/images/flags/unknown.png" width="16" height="11" alt="Unknown" />
-                    #end if
-                #end for
-            #end if
+            #for $sub_lang in [babelfish.Language.fromietf(x) for x in $epResult["subtitles"].split(',') if $epResult["subtitles"]]:
+                #set $flag = $sub_lang.alpha3 if $hasattr($sub_lang, 'alpha3') and $sub_lang.alpha3 else $sub_lang.alpha2 if $hasattr($sub_lang, 'alpha2') and $sub_lang.alpha2 else 'unknown'
+                <img src="$sbRoot/images/flags/${flag}.png" width="16" height="11" alt="${sub_lang.name}" onError="this.onerror=null;this.src='$sbRoot/images/flags/unknown.png';" />
+            #end for
             </td>
             #set $curStatus, $curQuality = $Quality.splitCompositeStatus(int($epResult["status"]))
                 #if $curQuality != Quality.NONE:   
@@ -603,7 +599,7 @@
                         <a class="epSearch" id="#echo $str($show.indexerid)+'x'+$str(epResult["season"])+'x'+$str(epResult["episode"])#" name="#echo $str($show.indexerid)+'x'+$str(epResult["season"])+'x'+$str(epResult["episode"])#" href="searchEpisode?show=$show.indexerid&amp;season=$epResult["season"]&amp;episode=$epResult["episode"]"><img src="$sbRoot/images/search16.png" width="16" height="16" alt="search" title="Manual Search" /></a>
                     #end if
                 #end if
-                #if $sickbeard.USE_SUBTITLES and $show.subtitles and len(set(str($epResult["subtitles"]).split(',')).intersection(set($subtitles.wantedLanguages()))) < len($subtitles.wantedLanguages()) and $epResult["location"]
+                #if $sickbeard.USE_SUBTITLES and $show.subtitles and $epResult["location"] and frozenset($subtitles.wantedLanguages()).difference($epResult["subtitles"])
                     <a class="epSubtitlesSearch" href="searchEpisodeSubtitles?show=$show.indexerid&amp;season=$epResult["season"]&amp;episode=$epResult["episode"]"><img src="$sbRoot/images/closed_captioning.png" height="16" alt="search subtitles" title="Search Subtitles" /></a>
                 #end if
             </td>
diff --git a/gui/slick/interfaces/default/history.tmpl b/gui/slick/interfaces/default/history.tmpl
index 2123adea52b91ad1c39ce4feeef528e71bd9ab78..93cb143503aec5eef8b33231e82adc2a221bb4a1 100644
--- a/gui/slick/interfaces/default/history.tmpl
+++ b/gui/slick/interfaces/default/history.tmpl
@@ -131,13 +131,9 @@
 				<td class="tvShow" width="35%"><a href="$sbRoot/home/displayShow?show=$hItem["showid"]#season-$hItem["season"]">$hItem["show_name"] - <%="S%02i" % int(hItem["season"])+"E%02i" % int(hItem["episode"]) %>#if "proper" in $hItem["resource"].lower() or "repack" in $hItem["resource"].lower() then ' <span class="quality Proper">Proper</span>' else ""#</a></td>
 				<td align="center" #if $curStatus == SUBTITLED then 'class="subtitles_column"' else ''#>
 				#if $curStatus == SUBTITLED:
-				    #if $sickbeard.SUBTITLES_MULTI:
-					    <img width="16" height="11" style="vertical-align:middle;" src="$sbRoot/images/flags/<%= hItem["resource"][len(hItem["resource"])-6:len(hItem["resource"])-4]+'.png'%>" onError="this.onerror=null;this.src='$sbRoot/images/flags/unknown.png';">
-					#else
-					    <img width="16" height="11" style="vertical-align:middle;" src="$sbRoot/images/flags/unknown.png">
-					#end if
+					<img width="16" height="11" style="vertical-align:middle;" src="$sbRoot/images/flags/${hItem['resource']}.png" onError="this.onerror=null;this.src='$sbRoot/images/flags/unknown.png';">
 				#end if    
-					<span style="cursor: help; vertical-align:middle;" title="$os.path.basename($hItem["resource"])">$statusStrings[$curStatus]</span>
+					<span style="cursor: help; vertical-align:middle;" title="$os.path.basename($hItem['resource'])">$statusStrings[$curStatus]</span>
 				</td>
 				<td align="center">
 				#if $curStatus == DOWNLOADED:
@@ -153,11 +149,11 @@
 							#else:
 								<img src="$sbRoot/images/providers/missing.png" width="16" height="16" style="vertical-align:middle;" title="missing provider"/> <span style="vertical-align:middle;">Missing Provider</span>
 							#end if
-							#else:
-								<img src="$sbRoot/images/subtitles/<%=hItem["provider"]+'.png' %>" width="16" height="16" style="vertical-align:middle;" /> <span style="vertical-align:middle;"><%=hItem["provider"].capitalize()%></span>
-							#end if
+						#else:
+								<img src="$sbRoot/images/flags/${hItem['provider']}.png" width="16" height="11" style="vertical-align:middle;" /> <span style="vertical-align:middle;"><%=hItem["provider"].capitalize()%></span>
 						#end if
 					#end if
+				#end if
 				</td>
 				<span style="display: none;">$curQuality</span>
 				<td align="center"><span class="quality $Quality.qualityStrings[$curQuality].replace("720p","HD720p").replace("1080p","HD1080p").replace("HDTV", "HD720p")">$Quality.qualityStrings[$curQuality]</span></td>
@@ -226,9 +222,9 @@
 					#for $action in sorted($hItem["actions"]):
 						#set $curStatus, $curQuality = $Quality.splitCompositeStatus(int($action["action"]))
 						#if $curStatus == SUBTITLED:
-							<img src="$sbRoot/images/subtitles/<%=action["provider"]+'.png' %>" width="16" height="16" style="vertical-align:middle;" alt="$action["provider"]" title="<%=action["provider"].capitalize()%>: $os.path.basename($action["resource"])"/>
+							<img src="$sbRoot/images/subtitles/$action['provider'].png" %>" width="16" height="16" style="vertical-align:middle;" alt="$action["provider"]" title="<%=action["provider"].capitalize()%>: $os.path.basename($action["resource"])"/>
 							<span style="vertical-align:middle;"> / </span> 
-							<img width="16" height="11" style="vertical-align:middle;" src="$sbRoot/images/flags/<%= action["resource"][len(action["resource"])-6:len(action["resource"])-4]+'.png'%>" style="vertical-align: middle !important;">
+							<img width="16" height="11" style="vertical-align:middle;" src="$sbRoot/images/flags/$action['resource'].png" onError="this.onerror=null;this.src='$sbRoot/images/flags/unknown.png';" style="vertical-align: middle !important;">
 							&nbsp;
 						#end if    
 					#end for
diff --git a/gui/slick/interfaces/default/manage_subtitleMissed.tmpl b/gui/slick/interfaces/default/manage_subtitleMissed.tmpl
index 8a2ff96b02c1f5441d55a2f099d12358d6e54b51..ecc04db93c9cb61acbf7a4197cfe2f7aa9a6cced 100644
--- a/gui/slick/interfaces/default/manage_subtitleMissed.tmpl
+++ b/gui/slick/interfaces/default/manage_subtitleMissed.tmpl
@@ -1,7 +1,8 @@
-#import sickbeard
+#from sickbeard import subtitles
 #import subliminal
 #import babelfish
 #import datetime
+#import sickbeard
 #from sickbeard import common
 #set global $title="Episode Overview"
 #set global $header="Episode Overview"
@@ -30,8 +31,8 @@
 <form action="$sbRoot/manage/subtitleMissed" method="get">
 Manage episodes without <select name="whichSubs" class="form-control form-control-inline input-sm">
 <option value="all">All</option>
-#for $sub_lang in [$babelfish.Language.fromietf(x.strip()) for x in $sickbeard.SUBTITLES_LANGUAGES]:
-#<option value="$sub_lang.alpha2">$sub_lang.name</option>
+#for $sub_lang in [$babelfish.Language.fromietf(x) for x in $subtitles.wantedLanguages]:
+<option value="$sub_lang.alpha3">$sub_lang.name</option>
 #end for
 </select>
 subtitles
diff --git a/sickbeard/history.py b/sickbeard/history.py
index 2df2590477ba97bff30202590549780b4e298834..773aa1c09996f7f851abd8e80affec66400900ce 100644
--- a/sickbeard/history.py
+++ b/sickbeard/history.py
@@ -77,11 +77,12 @@ def logDownload(episode, filename, new_ep_quality, release_group=None, version=-
 
 
 def logSubtitle(showid, season, episode, status, subtitleResult):
-    resource = subtitleResult.path
-    provider = subtitleResult.service
+    resource = subtitleResult
+    provider = subtitleResult
     status, quality = Quality.splitCompositeStatus(status)
     action = Quality.compositeStatus(SUBTITLED, quality)
 
+    # FIXME: Broken with new subliminal
     _logHistoryItem(action, showid, season, episode, quality, resource, provider)
 
 
diff --git a/sickbeard/postProcessor.py b/sickbeard/postProcessor.py
index 216837555ca355c2a6a7307ae594d2fbe22193c7..06b262e50a57a2865ad0a2c5356bb3536b03db10 100644
--- a/sickbeard/postProcessor.py
+++ b/sickbeard/postProcessor.py
@@ -37,7 +37,7 @@ from sickbeard import notifiers
 from sickbeard import show_name_helpers
 from sickbeard import failed_history
 from sickbeard import name_cache
-
+from sickbeard import subtitles
 from sickbeard import encodingKludge as ek
 from sickbeard.exceptions import ex
 
@@ -300,7 +300,7 @@ class PostProcessor(object):
             # check if file have subtitles language
             if os.path.splitext(cur_extension)[1][1:] in common.subtitleExtensions:
                 cur_lang = os.path.splitext(cur_extension)[0]
-                if cur_lang in sickbeard.SUBTITLES_LANGUAGES:
+                if cur_lang in subtitles.wantedSubtitles():
                     cur_extension = cur_lang + os.path.splitext(cur_extension)[1]
 
             # replace .nfo with .nfo-orig to avoid conflicts
diff --git a/sickbeard/subtitles.py b/sickbeard/subtitles.py
index 81fbb3ee32cfc3f83ea23490d50386c03047bc0f..be6f4672db20e24a55cc42afde1e4064efb52cac 100644
--- a/sickbeard/subtitles.py
+++ b/sickbeard/subtitles.py
@@ -31,35 +31,52 @@ import babelfish
 
 subliminal.cache_region.configure('dogpile.cache.memory')
 
+provider_urls = {'addic7ed': 'http://www.addic7ed.com',
+                 'opensubtitles': 'http://www.opensubtitles.org',
+                 'podnapisi': 'http://www.podnapisi.net',
+                 'thesubdb': 'http://www.thesubdb.com',
+                 'tvsubtitles': 'http://www.tvsubtitles.net'
+                }
+
 SINGLE = 'und'
 def sortedServiceList():
     newList = []
+    lmgtfy = 'http://lmgtfy.com/?q='
 
     curIndex = 0
     for curService in sickbeard.SUBTITLES_SERVICES_LIST:
         if curService in subliminal.provider_manager.available_providers:
-            curServiceDict = {'id': curService, 'image': curService+'.png', 'name': curService, 'enabled': sickbeard.SUBTITLES_SERVICES_ENABLED[curIndex] == 1}
-            newList.append(curServiceDict)
+            newList.append({'name': curService,
+                            'url': provider_urls[curService] if curService in provider_urls else lmgtfy % curService,
+                            'image': curService + '.png',
+                            'enabled': sickbeard.SUBTITLES_SERVICES_ENABLED[curIndex] == 1
+                           })
         curIndex += 1
 
-    # add any services that are missing from that list
     for curService in subliminal.provider_manager.available_providers:
-        if curService not in [x['id'] for x in newList]:
-            curServiceDict = {'id': curService, 'image': curService+'.png', 'name': curService, 'enabled': False}
-            newList.append(curServiceDict)
+        if curService not in [x['name'] for x in newList]:
+            newList.append({'name': curService,
+                            'url': provider_urls[curService] if curService in provider_urls else lmgtfy % curService,
+                            'image': curService + '.png',
+                            'enabled': False,
+                           })
 
     return newList
 
-
 def getEnabledServiceList():
     return [x['name'] for x in sortedServiceList() if x['enabled']]
-    
+
 def isValidLanguage(language):
-    return language if language in babelfish.language_converters['alpha2'].codes else u''
+    try:
+        langObj = babelfish.Language.fromietf(language)
+    except:
+        return False
+    return True
 
-def getLanguageName(selectLang):
-    return babelfish.Language.fromalpha2(selectLang).name
+def getLanguageName(language):
+    return babelfish.Language.fromietf(language).name
 
+# TODO: Filter here for non-languages in sickbeard.SUBTITLES_LANGUAGES
 def wantedLanguages(sqlLike = False):
     wantedLanguages = sorted(sickbeard.SUBTITLES_LANGUAGES)
     if sqlLike:
@@ -68,19 +85,31 @@ def wantedLanguages(sqlLike = False):
 
 def subtitlesLanguages(video_path):
     """Return a list detected subtitles for the given video file"""
-
+    resultList = []
     languages = subliminal.video.scan_subtitle_languages(video_path)
-    return u','.join([lang.alpha2 for lang in languages if lang.alpha2 in babelfish.language_converters['alpha2'].codes])
 
-# Return a list with languages that have alpha2 code
+    for language in languages:
+        if hasattr(language, 'alpha3') and language.alpha3:
+                resultList.append(language.alpha3)
+        elif hasattr(language, 'alpha2') and language.alpha2:
+            resultList.append(language.alpha2)
+
+    defaultLang = wantedLanguages()
+    if len(resultList) is 1 and len(defaultLang) is 1:
+        return defaultLang
+
+    return sorted(resultList)
+
+# TODO: Return only languages our providers allow
 def subtitleLanguageFilter():
-    return [language for language in babelfish.LANGUAGE_MATRIX if language.alpha2 in babelfish.language_converters['alpha2'].codes]
+    return [language for language in babelfish.LANGUAGE_MATRIX if hasattr(language, 'alpha2') and language.alpha2]
 
 class SubtitlesFinder():
     """
     The SubtitlesFinder will be executed every hour but will not necessarly search
     and download subtitles. Only if the defined rule is true
     """
+
     def run(self, force=False):
         if not sickbeard.USE_SUBTITLES:
             return
@@ -102,11 +131,17 @@ class SubtitlesFinder():
 
         # you have 5 minutes to understand that one. Good luck
         myDB = db.DBConnection()
-        sqlResults = myDB.select('SELECT s.show_name, e.showid, e.season, e.episode, e.status, e.subtitles, e.subtitles_searchcount AS searchcount, e.subtitles_lastsearch AS lastsearch, e.location, (? - e.airdate) AS airdate_daydiff FROM tv_episodes AS e INNER JOIN tv_shows AS s ON (e.showid = s.indexer_id) WHERE s.subtitles = 1 AND e.subtitles NOT LIKE (?) AND ((e.subtitles_searchcount <= 2 AND (? - e.airdate) > 7) OR (e.subtitles_searchcount <= 7 AND (? - e.airdate) <= 7)) AND (e.status IN ('+','.join([str(x) for x in Quality.DOWNLOADED])+') OR (e.status IN ('+','.join([str(x) for x in Quality.SNATCHED + Quality.SNATCHED_PROPER])+') AND e.location != ""))', [today, wantedLanguages(True), today, today])
+
+        sqlResults = myDB.select('SELECT s.show_name, e.showid, e.season, e.episode, e.status, e.subtitles, e.subtitles_searchcount AS searchcount, e.subtitles_lastsearch AS lastsearch, e.location, (? - e.airdate) AS airdate_daydiff ' +
+        'FROM tv_episodes AS e INNER JOIN tv_shows AS s ON (e.showid = s.indexer_id) ' +
+        'WHERE s.subtitles = 1 AND e.subtitles NOT LIKE (?) ' +
+        'AND ((e.subtitles_searchcount <= 2 AND (? - e.airdate) > 7) OR (e.subtitles_searchcount <= 7 AND (? - e.airdate) <= 7)) ' +
+        'AND (e.status IN (?) OR (e.status IN (?) AND e.location != ""))', [today, wantedLanguages(True), today, today, str(Quality.DOWNLOADED), ','.join([str(x) for x in Quality.SNATCHED + Quality.SNATCHED_PROPER])])
+
         if len(sqlResults) == 0:
             logger.log('No subtitles to download', logger.INFO)
             return
-        
+
         rules = self._getRules()
         now = datetime.datetime.now()
         for epToSub in sqlResults:
@@ -114,7 +149,7 @@ class SubtitlesFinder():
             if not ek.ek(os.path.isfile, epToSub['location']):
                 logger.log('Episode file does not exist, cannot download subtitles for episode %dx%d of show %s' % (epToSub['season'], epToSub['episode'], epToSub['show_name']), logger.DEBUG)
                 continue
-            
+
             # Old shows rule
             throwaway = datetime.datetime.strptime('20110101', '%Y%m%d')
             if ((epToSub['airdate_daydiff'] > 7 and epToSub['searchcount'] < 2 and now - datetime.datetime.strptime(epToSub['lastsearch'], '%Y-%m-%d %H:%M:%S') > datetime.timedelta(hours=rules['old'][epToSub['searchcount']])) or
@@ -132,15 +167,20 @@ class SubtitlesFinder():
                     logger.log(u'Episode not found', logger.DEBUG)
                     return
                 
+                epObj.refreshSubtitles()
+                if not frozenset(wantedLanguages()).difference(epObj.subtitles):
+                    continue
+
                 previous_subtitles = epObj.subtitles
                 
                 try:
                     epObj.downloadSubtitles()
-                except:
+                except Exception as e:
                     logger.log(u'Unable to find subtitles', logger.DEBUG)
+                    logger.log(str(e), logger.DEBUG)
                     return
 
-                newSubtitles = list(set(epObj.subtitles) - set(previous_subtitles))
+                newSubtitles = frozenset(epObj.subtitles).difference(previous_subtitles)
                 if newSubtitles:
                     logger.log(u'Downloaded subtitles for S%02dE%02d in %s' % (epToSub["season"], epToSub["episode"], ', '.join(newSubtitles)))
 
diff --git a/sickbeard/tv.py b/sickbeard/tv.py
index b0eaf5df5dfbcbba7ae89d9c686385b4ade86f97..976f0fd559735a1cdd1860c38e2cd34612b8a01f 100644
--- a/sickbeard/tv.py
+++ b/sickbeard/tv.py
@@ -458,13 +458,13 @@ class TVShow(object):
                     try:
                         curEpisode.refreshSubtitles()
                     except:
-                        logger.log(str(self.indexerid) + ": Could not refresh subtitles", logger.ERROR)
+                        logger.log("%s: Could not refresh subtitles" % self.indexerid, logger.ERROR)
                         logger.log(traceback.format_exc(), logger.DEBUG)
 
                 sql_l.append(curEpisode.get_sql())
 
 
-        if len(sql_l) > 0:
+        if sql_l:
             myDB = db.DBConnection()
             myDB.mass_action(sql_l)
 
@@ -1099,7 +1099,7 @@ class TVShow(object):
                                 episode) + " doesn't exist, removing it and changing our status to " + statusStrings[sickbeard.EP_DEFAULT_DELETED_STATUS],
                                        logger.DEBUG)
                             curEp.status = sickbeard.EP_DEFAULT_DELETED_STATUS
-                            curEp.subtitles = u''
+                            curEp.subtitles = list()
                             curEp.subtitles_searchcount = 0
                             curEp.subtitles_lastsearch = str(datetime.datetime.min)
                         curEp.location = ''
@@ -1114,21 +1114,22 @@ class TVShow(object):
                     with curEp.lock:
                         curEp.airdateModifyStamp()
 
-        if len(sql_l) > 0:
+        if sql_l:
             myDB = db.DBConnection()
             myDB.mass_action(sql_l)
 
     def downloadSubtitles(self, force=False):
+        # TODO: Add support for force option
         if not ek.ek(os.path.isdir, self._location):
             logger.log(str(self.indexerid) + ": Show dir doesn't exist, can't download subtitles", logger.DEBUG)
             return
 
-        logger.log(str(self.indexerid) + ": Downloading subtitles", logger.DEBUG)
+        logger.log("%s: Downloading subtitles" % self.indexerid, logger.DEBUG)
 
         try:
             episodes = self.getAllEpisodes(has_location=True)
-            if not len(episodes) > 0:
-                logger.log(str(self.indexerid) + ": No episodes to download subtitles for " + self.name, logger.DEBUG)
+            if not episodes:
+                logger.log("%s: No episodes to download subtitles for %s" % (self.indexerid, self.name), logger.DEBUG)
                 return
 
             for episode in episodes:
@@ -1351,7 +1352,7 @@ class TVEpisode(object):
         self._episode = episode
         self._absolute_number = 0
         self._description = ""
-        self._subtitles = u''
+        self._subtitles = list()
         self._subtitles_searchcount = 0
         self._subtitles_lastsearch = str(datetime.datetime.min)
         self._airdate = datetime.date.fromordinal(1)
@@ -1427,7 +1428,6 @@ class TVEpisode(object):
         self.subtitles = subtitles.subtitlesLanguages(self.location)
 
     def downloadSubtitles(self, force=False):
-        # TODO: Add support for force option
         if not ek.ek(os.path.isfile, self.location):
             logger.log(u"%s: Episode file doesn't exist, can't download subtitles for S%02dE%02d" %
                     (self.show.indexerid, self.season, self.episode), logger.DEBUG)
@@ -1435,15 +1435,20 @@ class TVEpisode(object):
 
         logger.log(u"%s: Downloading subtitles for S%02dE%02d" % (self.show.indexerid, self.season, self.episode), logger.DEBUG)
 
+        self.refreshSubtitles()
         previous_subtitles = self.subtitles
 
         try:
             languages = set()
-            for lang in set(sickbeard.SUBTITLES_LANGUAGES) - set(self.subtitles):
-                languages.add(babelfish.Language.fromietf(lang))
+            for language in frozenset(subtitles.wantedLanguages()).difference(self.subtitles):
+                languages.add(babelfish.Language.fromietf(language))
+
+            if not languages:
+                logger.log(u"%s: No missing subtitles for S%02dE%02d" % (self.show.indexerid, self.season, self.episode), logger.DEBUG)
+                return
 
             providers = sickbeard.subtitles.getEnabledServiceList()
-            video = subliminal.scan_video(self.location, subtitles=False, embedded_subtitles=False)
+            video = subliminal.scan_video(self.location, subtitles=not force, embedded_subtitles=not sickbeard.EMBEDDED_SUBTITLES_ALL or not force)
 
             # Let's just bypass this for now, and see if subs are always found from the hash anyways.
             # We can add container/screensize/resolution/video_codec/audio_codec/tvdb_id/imdb_id/year/release_group/format this way
@@ -1462,19 +1467,28 @@ class TVEpisode(object):
                     except ValuError:
                         pass
 
+            # TODO: Add gui option for hearing_impaired parameter ?
             foundSubs = subliminal.download_best_subtitles([video], languages=languages, providers=providers, single=not sickbeard.SUBTITLES_MULTI, hearing_impaired=True)
             if not foundSubs:
                 logger.log(u"%s: No subtitles found for S%02dE%02d on any provider" % (self.show.indexerid, self.season, self.episode), logger.DEBUG)
                 return
 
-            if len(sickbeard.SUBTITLES_DIR) > 1:
-                subs_new_path = ek.ek(os.path.join, os.path.dirname(self.location), sickbeard.SUBTITLES_DIR)
-                dir_exists = helpers.makeDir(subs_new_path)
+            if len(sickbeard.SUBTITLES_DIR):
+                # absolute path (GUI 'Browse' button, or typed absolute path) - sillyness?
+                if ek.ek(os.path.isdir, sickbeard.SUBTITLES_DIR):
+                    subs_new_path = ek.ek(os.path.join, sickbeard.SUBTITLES_DIR, self.show.title)
+                    dir_exists = True
+                else:
+                    # relative to the folder the episode is in - sillyness?
+                    subs_new_path = ek.ek(os.path.join, os.path.dirname(self.location), sickbeard.SUBTITLES_DIR)
+                    dir_exists = helpers.makeDir(subs_new_path)
+
                 if not dir_exists:
                     logger.log(u"Unable to create subtitles folder " + subs_new_path, logger.ERROR)
                 else:
                     helpers.chmodAsParent(subs_new_path)
             else:
+                # let subliminal save the subtitles next to the episode
                 subs_new_path = None
 
             subliminal.save_subtitles(foundSubs, directory=subs_new_path, single=not sickbeard.SUBTITLES_MULTI)
@@ -1489,23 +1503,21 @@ class TVEpisode(object):
         self.subtitles_lastsearch = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
         self.saveToDB()
 
-        newSubtitles = list(set(self.subtitles.split(',')) - set(previous_subtitles.split(',')))
-        if len(newSubtitles):
-            subtitleList = ", ".join([babelfish.Language.fromietf(lang).name for lang in newSubtitles])
+        newSubtitles = frozenset(self.subtitles).difference(previous_subtitles)
+        if newSubtitles:
+            subtitleList = ", ".join([babelfish.Language.fromietf(newSub).name for newSub in newSubtitles])
             logger.log(u"%s: Downloaded %s subtitles for S%02dE%02d" %
-                    (self.show.indexerid, subtitleList, self.season, self.episode), logger.DEBUG)
+                (self.show.indexerid, subtitleList, self.season, self.episode), logger.DEBUG)
 
             notifiers.notify_subtitle_download(self.prettyName(), subtitleList)
-
+            if sickbeard.SUBTITLES_HISTORY:
+                for newSub in newSubtitles:
+                    logger.log(u'history.logSubtitle %s' % babelfish.Language.fromietf(newSub).name, logger.DEBUG)
+                    history.logSubtitle(self.show.indexerid, self.season, self.episode, self.status, newSub)
         else:
             logger.log(u"%s: No subtitles downloaded for S%02dE%02d" %
                     (self.show.indexerid, self.season, self.episode), logger.DEBUG)
 
-        if sickbeard.SUBTITLES_HISTORY:
-            for vid, sub in foundSubs.items():
-                logger.log(u'history.logSubtitle %s' % sub.language.name, logger.DEBUG)
-                history.logSubtitle(self.show.indexerid, self.season, self.episode, self.status, sub.language.name)
-
         return self.subtitles
 
 
@@ -1590,7 +1602,8 @@ class TVEpisode(object):
             self.description = sqlResults[0]["description"]
             if not self.description:
                 self.description = ""
-            self.subtitles = sqlResults[0]["subtitles"] or u''
+            if sqlResults[0]["subtitles"] and sqlResults[0]["subtitles"]:
+                self.subtitles = sqlResults[0]["subtitles"].split(",")
             self.subtitles_searchcount = sqlResults[0]["subtitles_searchcount"]
             self.subtitles_lastsearch = sqlResults[0]["subtitles_lastsearch"]
             self.airdate = datetime.date.fromordinal(int(sqlResults[0]["airdate"]))
@@ -1925,7 +1938,7 @@ class TVEpisode(object):
             self.name) + "\n"
         toReturn += "location: " + str(self.location) + "\n"
         toReturn += "description: " + str(self.description) + "\n"
-        toReturn += "subtitles: " + str(self.subtitles) + "\n"
+        toReturn += "subtitles: " + str(",".join(self.subtitles)) + "\n"
         toReturn += "subtitles_searchcount: " + str(self.subtitles_searchcount) + "\n"
         toReturn += "subtitles_lastsearch: " + str(self.subtitles_lastsearch) + "\n"
         toReturn += "airdate: " + str(self.airdate.toordinal()) + " (" + str(self.airdate) + ")\n"
@@ -1994,16 +2007,16 @@ class TVEpisode(object):
             if not self.dirty and not forceSave:
                 logger.log(str(self.show.indexerid) + u": Not creating SQL queue - record is not dirty", logger.DEBUG)
                 return
-            
+
             myDB = db.DBConnection()
             rows = myDB.select(
                 'SELECT episode_id, subtitles FROM tv_episodes WHERE showid = ? AND season = ? AND episode = ?',
                 [self.show.indexerid, self.season, self.episode])
-            
+
             epID = None
             if rows:
                 epID = int(rows[0]['episode_id'])
-            
+
             if epID:
                 # use a custom update method to get the data into the DB for existing records.
                 # Multi or added subtitle or removed subtitles
@@ -2013,7 +2026,7 @@ class TVEpisode(object):
                         "subtitles_searchcount = ?, subtitles_lastsearch = ?, airdate = ?, hasnfo = ?, hastbn = ?, status = ?, "
                         "location = ?, file_size = ?, release_name = ?, is_proper = ?, showid = ?, season = ?, episode = ?, "
                         "absolute_number = ?, version = ?, release_group = ? WHERE episode_id = ?",
-                        [self.indexerid, self.indexer, self.name, self.description, self.subtitles,
+                        [self.indexerid, self.indexer, self.name, self.description, ",".join(self.subtitles),
                          self.subtitles_searchcount, self.subtitles_lastsearch, self.airdate.toordinal(), self.hasnfo,
                          self.hastbn,
                          self.status, self.location, self.file_size, self.release_name, self.is_proper, self.show.indexerid,
@@ -2039,7 +2052,7 @@ class TVEpisode(object):
                     "((SELECT episode_id FROM tv_episodes WHERE showid = ? AND season = ? AND episode = ?)"
                     ",?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);",
                     [self.show.indexerid, self.season, self.episode, self.indexerid, self.indexer, self.name,
-                     self.description, self.subtitles, self.subtitles_searchcount, self.subtitles_lastsearch,
+                     self.description, ",".join(self.subtitles), self.subtitles_searchcount, self.subtitles_lastsearch,
                      self.airdate.toordinal(), self.hasnfo, self.hastbn, self.status, self.location, self.file_size,
                      self.release_name, self.is_proper, self.show.indexerid, self.season, self.episode,
                      self.absolute_number, self.version, self.release_group]]
@@ -2067,7 +2080,7 @@ class TVEpisode(object):
                         "indexer": self.indexer,
                         "name": self.name,
                         "description": self.description,
-                        "subtitles": self.subtitles,
+                        "subtitles": ",".join(self.subtitles),
                         "subtitles_searchcount": self.subtitles_searchcount,
                         "subtitles_lastsearch": self.subtitles_lastsearch,
                         "airdate": self.airdate.toordinal(),
diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py
index ad9507acff6b104bb7bdbc14782a9a6630e8f2bc..3ae7370d1e357ffd5b2f29928d63c3372d171e8f 100644
--- a/sickbeard/webserve.py
+++ b/sickbeard/webserve.py
@@ -2020,16 +2020,16 @@ class Home(WebRoot):
             return json.dumps({'result': 'failure'})
 
         # return the correct json value
-        newSubtitles = list(set(ep_obj.subtitles.split(',')) - set(previous_subtitles.split(',')))
-        if len(newSubtitles):
-            newLangs = [babelfish.Language.fromietf(x) for x in newSubtitles]
+        newSubtitles = frozenset(ep_obj.subtitles).difference(previous_subtitles)
+        if newSubtitles:
+            newLangs = [babelfish.Language.fromietf(newSub) for newSub in newSubtitles]
             status = 'New subtitles downloaded: %s' % ' '.join([
-                "<img src='" + sickbeard.WEB_ROOT + "/images/flags/" + x.alpha2 +
-                ".png' alt='" + x.name + "'/>" for x in newLangs])
+                "<img src='" + sickbeard.WEB_ROOT + "/images/flags/" + newLang.alpha3 +
+                ".png' alt='" + newLang.name + "'/>" for newLang in newLangs])
         else:
             status = 'No subtitles downloaded'
         ui.notifications.message('Subtitles Search', status)
-        return json.dumps({'result': status, 'subtitles': ','.join(sorted(ep_obj.subtitles.split(',')))})
+        return json.dumps({'result': status, 'subtitles': ','.join(ep_obj.subtitles)})
 
     def setSceneNumbering(self, show, indexer, forSeason=None, forEpisode=None, forAbsolute=None, sceneSeason=None,
                           sceneEpisode=None, sceneAbsolute=None):
@@ -2885,10 +2885,9 @@ class Manage(Home, WebRoot):
         result = {}
         for cur_result in cur_show_results:
             if whichSubs == 'all':
-                if len(set(cur_result["subtitles"].split(',')).intersection(set(subtitles.wantedLanguages()))) >= len(
-                        subtitles.wantedLanguages()):
+                if not frozenset(subtitles.wantedLanguages()).difference(cur_result["subtitles"].split(',')):
                     continue
-            elif whichSubs in cur_result["subtitles"].split(','):
+            elif whichSubs in cur_result["subtitles"]:
                 continue
 
             cur_season = int(cur_result["season"])
@@ -2902,8 +2901,7 @@ class Manage(Home, WebRoot):
 
             result[cur_season][cur_episode]["name"] = cur_result["name"]
 
-            result[cur_season][cur_episode]["subtitles"] = ",".join(subtitle.strip() for subtitle in cur_result["subtitles"].split(',')) if not \
-                cur_result["subtitles"] == '' else ''
+            result[cur_season][cur_episode]["subtitles"] = cur_result["subtitles"]
 
         return json.dumps(result)
 
@@ -2919,17 +2917,19 @@ class Manage(Home, WebRoot):
 
         myDB = db.DBConnection()
         status_results = myDB.select(
-            "SELECT show_name, tv_shows.indexer_id as indexer_id, tv_episodes.subtitles subtitles FROM tv_episodes, tv_shows WHERE tv_shows.subtitles = 1 AND tv_episodes.status LIKE '%4' AND tv_episodes.season != 0 AND tv_episodes.showid = tv_shows.indexer_id ORDER BY show_name")
+            "SELECT show_name, tv_shows.indexer_id as indexer_id, tv_episodes.subtitles subtitles " +
+            "FROM tv_episodes, tv_shows " +
+            "WHERE tv_shows.subtitles = 1 AND tv_episodes.status LIKE '%4' AND tv_episodes.season != 0 " +
+            "AND tv_episodes.showid = tv_shows.indexer_id ORDER BY show_name")
 
         ep_counts = {}
         show_names = {}
         sorted_show_ids = []
         for cur_status_result in status_results:
             if whichSubs == 'all':
-                if len(set(cur_status_result["subtitles"].split(',')).intersection(
-                        set(subtitles.wantedLanguages()))) >= len(subtitles.wantedLanguages()):
+                if not frozenset(subtitles.wantedLanguages()).difference(cur_status_result["subtitles"].split(',')):
                     continue
-            elif whichSubs in cur_status_result["subtitles"].split(','):
+            elif whichSubs in cur_status_result["subtitles"]:
                 continue
 
             cur_indexer_id = int(cur_status_result["indexer_id"])
@@ -3367,33 +3367,33 @@ class Manage(Home, WebRoot):
                 sickbeard.showQueueScheduler.action.downloadSubtitles(showObj)
                 subtitles.append(showObj.name)
 
-        if len(errors) > 0:
+        if errors:
             ui.notifications.error("Errors encountered",
                                    '<br >\n'.join(errors))
 
         messageDetail = ""
 
-        if len(updates) > 0:
+        if updates:
             messageDetail += "<br /><b>Updates</b><br /><ul><li>"
             messageDetail += "</li><li>".join(updates)
             messageDetail += "</li></ul>"
 
-        if len(refreshes) > 0:
+        if refreshes:
             messageDetail += "<br /><b>Refreshes</b><br /><ul><li>"
             messageDetail += "</li><li>".join(refreshes)
             messageDetail += "</li></ul>"
 
-        if len(renames) > 0:
+        if renames:
             messageDetail += "<br /><b>Renames</b><br /><ul><li>"
             messageDetail += "</li><li>".join(renames)
             messageDetail += "</li></ul>"
 
-        if len(subtitles) > 0:
+        if subtitles:
             messageDetail += "<br /><b>Subtitles</b><br /><ul><li>"
             messageDetail += "</li><li>".join(subtitles)
             messageDetail += "</li></ul>"
 
-        if len(updates + refreshes + renames + subtitles) > 0:
+        if updates + refreshes + renames + subtitles:
             ui.notifications.message("The following actions were queued:",
                                      messageDetail)
 
@@ -4857,7 +4857,7 @@ class ConfigSubtitles(Config):
         config.change_SUBTITLES_FINDER_FREQUENCY(subtitles_finder_frequency)
         config.change_USE_SUBTITLES(use_subtitles)
 
-        sickbeard.SUBTITLES_LANGUAGES = [lang.strip() for lang in subtitles_languages.replace(' ', '').split(',')] if subtitles_languages != '' else []
+        sickbeard.SUBTITLES_LANGUAGES = [lang.strip() for lang in subtitles_languages.split(',') if subtitles.isValidLanguage(lang.strip())] if subtitles_languages else []
         sickbeard.SUBTITLES_DIR = subtitles_dir
         sickbeard.SUBTITLES_HISTORY = config.checkbox_to_value(subtitles_history)
         sickbeard.EMBEDDED_SUBTITLES_ALL = config.checkbox_to_value(embedded_subtitles_all)