Resolved conflict with SftpServerWorkerCount
Splitted cleanPath into cleanPacketPath and cleanPath for better handling of slashes in file paths
Added test for cleanPath func
Removed code duplication => filepath.ToSlash(filepath.Clean(...)) => cleanPath(...)
Fixed tests for runLs to match year or time
Renamed constants to fit hound rules
diff --git a/packet-manager.go b/packet-manager.go
index 6d1a8e5..906b3ee 100644
--- a/packet-manager.go
+++ b/packet-manager.go
@@ -25,11 +25,11 @@
 
 func newPktMgr(sender packetSender) packetManager {
 	s := packetManager{
-		requests:  make(chan requestPacket, sftpServerWorkerCount),
-		responses: make(chan responsePacket, sftpServerWorkerCount),
+		requests:  make(chan requestPacket, SftpServerWorkerCount),
+		responses: make(chan responsePacket, SftpServerWorkerCount),
 		fini:      make(chan struct{}),
-		incoming:  make([]uint32, 0, sftpServerWorkerCount),
-		outgoing:  make([]responsePacket, 0, sftpServerWorkerCount),
+		incoming:  make([]uint32, 0, SftpServerWorkerCount),
+		outgoing:  make([]responsePacket, 0, SftpServerWorkerCount),
 		sender:    sender,
 		working:   &sync.WaitGroup{},
 	}
@@ -41,7 +41,7 @@
 // send id of 0 for packets without id
 func (s packetManager) incomingPacket(pkt requestPacket) {
 	s.working.Add(1)
-	s.requests <- pkt // buffer == sftpServerWorkerCount
+	s.requests <- pkt // buffer == SftpServerWorkerCount
 }
 
 // register outgoing packets as being ready
@@ -63,15 +63,15 @@
 // transfers.
 func (s *packetManager) workerChan(runWorker func(requestChan)) requestChan {
 
-	rwChan := make(chan requestPacket, sftpServerWorkerCount)
-	for i := 0; i < sftpServerWorkerCount; i++ {
+	rwChan := make(chan requestPacket, SftpServerWorkerCount)
+	for i := 0; i < SftpServerWorkerCount; i++ {
 		runWorker(rwChan)
 	}
 
 	cmdChan := make(chan requestPacket)
 	runWorker(cmdChan)
 
-	pktChan := make(chan requestPacket, sftpServerWorkerCount)
+	pktChan := make(chan requestPacket, SftpServerWorkerCount)
 	go func() {
 		// start with cmdChan
 		curChan := cmdChan
@@ -147,10 +147,10 @@
 	}
 }
 
-func outfilter(o []responsePacket) []uint32 {
-	res := make([]uint32, 0, len(o))
-	for _, v := range o {
-		res = append(res, v.id())
-	}
-	return res
-}
+//func outfilter(o []responsePacket) []uint32 {
+//	res := make([]uint32, 0, len(o))
+//	for _, v := range o {
+//		res = append(res, v.id())
+//	}
+//	return res
+//}
diff --git a/request-server.go b/request-server.go
index d0b1ba6..9e87559 100644
--- a/request-server.go
+++ b/request-server.go
@@ -131,7 +131,7 @@
 			rs.closeRequest(handle)
 			rpkt = statusFromError(pkt, nil)
 		case *sshFxpRealpathPacket:
-			rpkt = cleanPath(pkt)
+			rpkt = cleanPacketPath(pkt)
 		case isOpener:
 			handle := rs.nextRequest(requestFromPacket(pkt))
 			rpkt = sshFxpHandlePacket{pkt.id(), handle}
@@ -181,25 +181,26 @@
 	return nil
 }
 
-func cleanPath(pkt *sshFxpRealpathPacket) responsePacket {
-	path := pkt.getPath()
-	if !filepath.IsAbs(path) {
-		// prevent double slash (e.g. on windows, / paths are not absolute)
-		path = "/" + strings.TrimPrefix(path, "/")
-	} // all paths are absolute
-
-	cleaned_path := filepath.ToSlash(filepath.Clean(path))
-
+func cleanPacketPath(pkt *sshFxpRealpathPacket) responsePacket {
+	path := cleanPath(pkt.getPath())
 	return &sshFxpNamePacket{
 		ID: pkt.id(),
 		NameAttrs: []sshFxpNameAttr{{
-			Name:     cleaned_path,
-			LongName: cleaned_path,
+			Name:     path,
+			LongName: path,
 			Attrs:    emptyFileStat,
 		}},
 	}
 }
 
+func cleanPath(path string) string {
+	cleanSlashPath := filepath.ToSlash(filepath.Clean(path))
+	if !strings.HasPrefix(cleanSlashPath, "/") {
+		return "/" + cleanSlashPath
+	}
+	return cleanSlashPath
+}
+
 func (rs *RequestServer) handle(request Request, pkt requestPacket) responsePacket {
 	// fmt.Println("Request Method: ", request.Method)
 	rpkt, err := request.handle(rs.Handlers)
diff --git a/request-server_test.go b/request-server_test.go
index ee9621b..b12561d 100644
--- a/request-server_test.go
+++ b/request-server_test.go
@@ -327,3 +327,20 @@
 	names := []string{di[18].Name(), di[81].Name()}
 	assert.Equal(t, []string{"foo_18", "foo_81"}, names)
 }
+
+func TestCleanPath(t *testing.T) {
+	assert.Equal(t, "/", cleanPath("/"))
+	assert.Equal(t, "/", cleanPath("//"))
+	assert.Equal(t, "/a", cleanPath("/a/"))
+	assert.Equal(t, "/a", cleanPath("a/"))
+	assert.Equal(t, "/a/b/c", cleanPath("/a//b//c/"))
+
+	// filepath.ToSlash does not touch \ as char on unix systems, so os.PathSeparator is used for windows compatible tests
+	bslash := string(os.PathSeparator)
+	assert.Equal(t, "/", cleanPath(bslash))
+	assert.Equal(t, "/", cleanPath(bslash+bslash))
+	assert.Equal(t, "/a", cleanPath(bslash+"a"+bslash))
+	assert.Equal(t, "/a", cleanPath("a"+bslash))
+	assert.Equal(t, "/a/b/c", cleanPath(bslash+"a"+bslash+bslash+"b"+bslash+bslash+"c"+bslash))
+
+}
diff --git a/request.go b/request.go
index 5b7502f..ac07475 100644
--- a/request.go
+++ b/request.go
@@ -52,17 +52,17 @@
 		request.Flags = p.Flags
 		request.Attrs = p.Attrs.([]byte)
 	case *sshFxpRenamePacket:
-		request.Target = filepath.ToSlash(filepath.Clean(p.Newpath))
+		request.Target = cleanPath(p.Newpath)
 	case *sshFxpSymlinkPacket:
-		request.Target = filepath.ToSlash(filepath.Clean(p.Linkpath))
+		request.Target = cleanPath(p.Linkpath)
 	}
 	return request
 }
 
 // NewRequest creates a new Request object.
 func NewRequest(method, path string) Request {
-	request := Request{Method: method, Filepath: filepath.ToSlash(filepath.Clean(path))}
-	request.packets = make(chan packet_data, sftpServerWorkerCount)
+	request := Request{Method: method, Filepath: cleanPath(path)}
+	request.packets = make(chan packet_data, SftpServerWorkerCount)
 	request.state = &state{}
 	request.stateLock = &sync.RWMutex{}
 	return request
diff --git a/request_test.go b/request_test.go
index e537fc1..6eda6ff 100644
--- a/request_test.go
+++ b/request_test.go
@@ -65,13 +65,13 @@
 		Method:    method,
 		Attrs:     []byte("foo"),
 		Target:    "foo",
-		packets:   make(chan packet_data, sftpServerWorkerCount),
+		packets:   make(chan packet_data, SftpServerWorkerCount),
 		state:     &state{},
 		stateLock: &sync.RWMutex{},
 	}
 	for _, p := range []packet_data{
-		packet_data{id: 1, data: filecontents[:5], length: 5},
-		packet_data{id: 2, data: filecontents[5:], length: 5, offset: 5}} {
+		{id: 1, data: filecontents[:5], length: 5},
+		{id: 2, data: filecontents[5:], length: 5, offset: 5}} {
 		request.packets <- p
 	}
 	return request
diff --git a/server.go b/server.go
index 9168bc6..80a1288 100644
--- a/server.go
+++ b/server.go
@@ -18,7 +18,7 @@
 )
 
 const (
-	sftpServerWorkerCount = 8
+	SftpServerWorkerCount = 8
 )
 
 // Server is an SSH File Transfer Protocol (sftp) server.
@@ -230,8 +230,7 @@
 		if err != nil {
 			return s.sendError(p, err)
 		}
-		f = filepath.Clean(f)
-		f = filepath.ToSlash(f) // make path more Unix like on windows servers
+		f = cleanPath(f)
 		return s.sendPacket(sshFxpNamePacket{
 			ID: p.ID,
 			NameAttrs: []sshFxpNameAttr{{
diff --git a/server_test.go b/server_test.go
index 87e4022..f2f034a 100644
--- a/server_test.go
+++ b/server_test.go
@@ -10,23 +10,22 @@
 )
 
 const (
-	TYPE_DIRECTORY = "d"
-	TYPE_FILE = "[^d]"
+	typeDirectory = "d"
+	typeFile      = "[^d]"
 )
 
 func TestRunLsWithExamplesDirectory(t *testing.T) {
 	path := "examples"
-	item,_ := os.Stat(path)
+	item, _ := os.Stat(path)
 	result := runLs(path, item)
-	runLsTestHelper(t, result, TYPE_DIRECTORY, path)
+	runLsTestHelper(t, result, typeDirectory, path)
 }
 
-
 func TestRunLsWithLicensesFile(t *testing.T) {
 	path := "LICENSE"
-	item,_ := os.Stat(path)
+	item, _ := os.Stat(path)
 	result := runLs(path, item)
-	runLsTestHelper(t, result, TYPE_FILE, path)
+	runLsTestHelper(t, result, typeFile, path)
 }
 
 /*
@@ -71,83 +70,87 @@
 
 	// permissions (len 10, "drwxr-xr-x")
 	got := result[0:10]
-	if ok, err := regexp.MatchString("^" + expectedType + "[rwx-]{9}$", got); !ok {
-		t.Errorf("runLs(%#v, *FileInfo): permission field mismatch, expected dir, got: %#v, err: %#v", path,  got, err)
+	if ok, err := regexp.MatchString("^"+expectedType+"[rwx-]{9}$", got); !ok {
+		t.Errorf("runLs(%#v, *FileInfo): permission field mismatch, expected dir, got: %#v, err: %#v", path, got, err)
 	}
 
 	// space
 	got = result[10:11]
 	if ok, err := regexp.MatchString("^\\s$", got); !ok {
-		t.Errorf("runLs(%#v, *FileInfo): spacer 1 mismatch, expected whitespace, got: %#v, err: %#v", path,  got, err)
+		t.Errorf("runLs(%#v, *FileInfo): spacer 1 mismatch, expected whitespace, got: %#v, err: %#v", path, got, err)
 	}
 
 	// link count (len 3, number)
 	got = result[12:15]
 	if ok, err := regexp.MatchString("^\\s*[0-9]+$", got); !ok {
-		t.Errorf("runLs(%#v, *FileInfo): link count field mismatch, got: %#v, err: %#v", path,  got, err)
+		t.Errorf("runLs(%#v, *FileInfo): link count field mismatch, got: %#v, err: %#v", path, got, err)
 	}
 
 	// spacer
 	got = result[15:16]
 	if ok, err := regexp.MatchString("^\\s$", got); !ok {
-		t.Errorf("runLs(%#v, *FileInfo): spacer 2 mismatch, expected whitespace, got: %#v, err: %#v", path,  got, err)
+		t.Errorf("runLs(%#v, *FileInfo): spacer 2 mismatch, expected whitespace, got: %#v, err: %#v", path, got, err)
 	}
 
 	// username / uid (len 8, number or string)
 	got = result[16:24]
 	if ok, err := regexp.MatchString("^[^\\s]{1,8}\\s*$", got); !ok {
-		t.Errorf("runLs(%#v, *FileInfo): username / uid mismatch, expected user, got: %#v, err: %#v", path,  got, err)
+		t.Errorf("runLs(%#v, *FileInfo): username / uid mismatch, expected user, got: %#v, err: %#v", path, got, err)
 	}
 
 	// spacer
 	got = result[24:25]
 	if ok, err := regexp.MatchString("^\\s$", got); !ok {
-		t.Errorf("runLs(%#v, *FileInfo): spacer 3 mismatch, expected whitespace, got: %#v, err: %#v", path,  got, err)
+		t.Errorf("runLs(%#v, *FileInfo): spacer 3 mismatch, expected whitespace, got: %#v, err: %#v", path, got, err)
 	}
 
 	// groupname / gid (len 8, number or string)
 	got = result[25:33]
 	if ok, err := regexp.MatchString("^[^\\s]{1,8}\\s*$", got); !ok {
-		t.Errorf("runLs(%#v, *FileInfo): groupname / gid mismatch, expected group, got: %#v, err: %#v", path,  got, err)
+		t.Errorf("runLs(%#v, *FileInfo): groupname / gid mismatch, expected group, got: %#v, err: %#v", path, got, err)
 	}
 
-
 	// spacer
 	got = result[33:34]
 	if ok, err := regexp.MatchString("^\\s$", got); !ok {
-		t.Errorf("runLs(%#v, *FileInfo): spacer 4 mismatch, expected whitespace, got: %#v, err: %#v", path,  got, err)
+		t.Errorf("runLs(%#v, *FileInfo): spacer 4 mismatch, expected whitespace, got: %#v, err: %#v", path, got, err)
 	}
 
 	// filesize (len 8)
 	got = result[34:42]
 	if ok, err := regexp.MatchString("^\\s*[0-9]+$", got); !ok {
-		t.Errorf("runLs(%#v, *FileInfo): filesize field mismatch, expected size in bytes, got: %#v, err: %#v", path,  got, err)
+		t.Errorf("runLs(%#v, *FileInfo): filesize field mismatch, expected size in bytes, got: %#v, err: %#v", path, got, err)
 	}
 
 	// spacer
 	got = result[42:43]
 	if ok, err := regexp.MatchString("^\\s$", got); !ok {
-		t.Errorf("runLs(%#v, *FileInfo): spacer 5 mismatch, expected whitespace, got: %#v, err: %#v", path,  got, err)
+		t.Errorf("runLs(%#v, *FileInfo): spacer 5 mismatch, expected whitespace, got: %#v, err: %#v", path, got, err)
 	}
 
 	// mod time (len 12, e.g. Aug  9 19:46)
 	got = result[43:55]
 	layout := "Jan  2 15:04"
 	_, err := time.Parse(layout, got)
+
 	if err != nil {
-		t.Errorf("runLs(%#v, *FileInfo): mod time field mismatch, expected date layout %s, got: %#v, err: %#v",  path, layout, got, err)
+		layout = "Jan  2 2006"
+		_, err = time.Parse(layout, got)
+	}
+	if err != nil {
+		t.Errorf("runLs(%#v, *FileInfo): mod time field mismatch, expected date layout %s, got: %#v, err: %#v", path, layout, got, err)
 	}
 
 	// spacer
 	got = result[55:56]
 	if ok, err := regexp.MatchString("^\\s$", got); !ok {
-		t.Errorf("runLs(%#v, *FileInfo): spacer 6 mismatch, expected whitespace, got: %#v, err: %#v", path,  got, err)
+		t.Errorf("runLs(%#v, *FileInfo): spacer 6 mismatch, expected whitespace, got: %#v, err: %#v", path, got, err)
 	}
 
 	// filename
 	got = result[56:]
 	if ok, err := regexp.MatchString("^"+path+"$", got); !ok {
-		t.Errorf("runLs(%#v, *FileInfo): name field mismatch, expected examples, got: %#v, err: %#v", path,  got, err)
+		t.Errorf("runLs(%#v, *FileInfo): name field mismatch, expected examples, got: %#v, err: %#v", path, got, err)
 	}
 }