package hugolib
 
 import (
-       "testing"
        "bytes"
+       "testing"
 )
 
 func checkShowPlanExpected(t *testing.T, expected, got string) {
        s := new(Site)
        out := new(bytes.Buffer)
        if err := s.ShowPlan(out); err != nil {
-               t.Errorf("ShowPlan unexpectedly returned an error: %s", err) 
+               t.Errorf("ShowPlan unexpectedly returned an error: %s", err)
        }
        expected := "No source files provided.\n"
        got := out.String()
 
 package target
 
 import (
+       "fmt"
        "io"
+       "path"
 )
 
 type Publisher interface {
        Publish(string, io.Reader) error
 }
+
+type Translator interface {
+       Translate(string) (string, error)
+}
+
+type Filesystem struct {
+       UglyUrls         bool
+       DefaultExtension string
+}
+
+func (fs *Filesystem) Translate(src string) (dest string, err error) {
+       if fs.UglyUrls {
+               return src, nil
+       }
+
+       dir, file := path.Split(src)
+       ext := fs.extension(path.Ext(file))
+       name := filename(file)
+
+       return path.Join(dir, name, fmt.Sprintf("index%s", ext)), nil
+}
+
+func (fs *Filesystem) extension(ext string) string {
+       if ext != "" {
+               return ext
+       }
+
+       if fs.DefaultExtension != "" {
+               return fs.DefaultExtension
+       }
+
+       return ".html"
+}
+
+func filename(f string) string {
+       ext := path.Ext(f)
+       if ext == "" {
+               return f
+       }
+
+       return f[:len(f)-len(ext)]
+}
 
--- /dev/null
+package target
+
+import (
+       "testing"
+)
+
+func TestFileTranslator(t *testing.T) {
+       tests := []struct {
+               content  string
+               expected string
+       }{
+               {"foo", "foo/index.html"},
+               {"foo.html", "foo/index.html"},
+               {"foo.xhtml", "foo/index.xhtml"},
+               {"section/foo", "section/foo/index.html"},
+               {"section/foo.html", "section/foo/index.html"},
+               {"section/foo.rss", "section/foo/index.rss"},
+       }
+
+       for _, test := range tests {
+               f := new(Filesystem)
+               dest, err := f.Translate(test.content)
+               if err != nil {
+                       t.Fatalf("Translate returned and unexpected err: %s", err)
+               }
+
+               if dest != test.expected {
+                       t.Errorf("Tranlate expected return: %s, got: %s", test.expected, dest)
+               }
+       }
+}
+
+func TestTranslateUglyUrls(t *testing.T) {
+       f := &Filesystem{UglyUrls: true}
+       dest, err := f.Translate("foo.html")
+       if err != nil {
+               t.Fatalf("Translate returned an unexpected err: %s", err)
+       }
+
+       if dest != "foo.html" {
+               t.Errorf("Translate expected return: %s, got: %s", "foo.html", dest)
+       }
+}
+
+func TestTranslateDefaultExtension(t *testing.T) {
+       f := &Filesystem{DefaultExtension: ".foobar"}
+       dest, _ := f.Translate("baz")
+       if dest != "baz/index.foobar" {
+               t.Errorf("Translate expected return: %s, got %s", "baz/index.foobar", dest)
+       }
+}