ronantakizawa/codereview-bench huggingface dataset:
Repository: syncthing/syncthing
File: lib/connections/service.go (Go)

Code before:
	// kicks in.
	initialRampup := time.Second

	for {
		cfg := s.cfg.RawCopy()
		bestDialerPrio := s.bestDialerPrio(cfg)
		isInitialRampup := initialRampup < stdConnectionLoopSleep

		l.Debugln("Connection loop")
		if isInitialRampup {
			l.Debugln("Connection loop in initial rampup")
		}

		// Used for consistency throughout this loop run, as time passes
		// while we try connections etc.
		now := time.Now()

		// Attempt to dial all devices that are unconnected or can be connection-upgraded
		s.dialDevices(ctx, now, cfg, bestDialerPrio, nextDial, isInitialRampup)

		// The sleep time is until the next dial scheduled in nextDial,
		// clamped by stdConnectionLoopSleep as we don't want to sleep too
		// long (config changes might happen).
		sleep := filterAndFindSleepDuration(nextDial, now)

		// .. unless we are un the initial rampup time, in which case we
		// override the sleep interval for the first few passes through the
		// loop.
		if isInitialRampup {
			sleep = initialRampup
			initialRampup *= 2
		}

		// ... while making sure not to loop to quickly either.
		if sleep < minConnectionLoopSleep {
			sleep = minConnectionLoopSleep
		}

		l.Debugln("Next connection loop in", sleep)

		select {
		case <-time.After(sleep):
		case <-ctx.Done():
			return ctx.Err()
		}
	}
}

func (s *service) bestDialerPrio(cfg config.Configuration) int {
	first := true
	var bestDialerPrio int

Review comment (suggestion):
```suggestion
		// .. unless we are in the initial rampup time, in which case we
```

Code after:
	nextDialAt := make(map[string]time.Time)

	// Used as delay for the first few connection attempts (adjusted up to
	// minConnectionLoopSleep), increased exponentially until it reaches
	// stdConnectionLoopSleep, at which time the normal sleep mechanism
	// kicks in.
	initialRampup := time.Second

	for {
		cfg := s.cfg.RawCopy()
		bestDialerPriority := s.bestDialerPriority(cfg)
		isInitialRampup := initialRampup < stdConnectionLoopSleep

		l.Debugln("Connection loop")
		if isInitialRampup {
			l.Debugln("Connection loop in initial rampup")
		}

		// Used for consistency throughout this loop run, as time passes
		// while we try connections etc.
		now := time.Now()

		// Attempt to dial all devices that are unconnected or can be connection-upgraded
		s.dialDevices(ctx, now, cfg, bestDialerPriority, nextDialAt, isInitialRampup)

		var sleep time.Duration
		if isInitialRampup {
			// We are in the initial rampup time, so we slowly, statically
			// increase the sleep time.
			sleep = initialRampup
			initialRampup *= 2
		} else {
			// The sleep time is until the next dial scheduled in nextDialAt,
			// clamped by stdConnectionLoopSleep as we don't want to sleep too
			// long (config changes might happen).
			sleep = filterAndFindSleepDuration(nextDialAt, now)
		}

		// ... while making sure not to loop too quickly either.
		if sleep < minConnectionLoopSleep {
			sleep = minConnectionLoopSleep
		}

		l.Debugln("Next connection loop in", sleep)

		select {
		case <-time.After(sleep):
		case <-ctx.Done():
			return ctx.Err()
		}
	}
Repository: syncthing/syncthing
File: lib/connections/service.go (Go)

Code before:
		l.Debugln("Connection loop")
		if isInitialRampup {
			l.Debugln("Connection loop in initial rampup")
		}

		// Used for consistency throughout this loop run, as time passes
		// while we try connections etc.
		now := time.Now()

		// Attempt to dial all devices that are unconnected or can be connection-upgraded
		s.dialDevices(ctx, now, cfg, bestDialerPrio, nextDial, isInitialRampup)

		// The sleep time is until the next dial scheduled in nextDial,
		// clamped by stdConnectionLoopSleep as we don't want to sleep too
		// long (config changes might happen).
		sleep := filterAndFindSleepDuration(nextDial, now)

		// .. unless we are un the initial rampup time, in which case we
		// override the sleep interval for the first few passes through the
		// loop.
		if isInitialRampup {
			sleep = initialRampup
			initialRampup *= 2
		}

		// ... while making sure not to loop to quickly either.
		if sleep < minConnectionLoopSleep {
			sleep = minConnectionLoopSleep
		}

		l.Debugln("Next connection loop in", sleep)

		select {
		case <-time.After(sleep):
		case <-ctx.Done():
			return ctx.Err()
		}
	}
}

func (s *service) bestDialerPrio(cfg config.Configuration) int {
	first := true
	var bestDialerPrio int
	for _, df := range dialers {
		if df.Valid(cfg) != nil {
			continue
		}
		if prio := df.Priority(); first || prio < bestDialerPrio {
			first = false
			bestDialerPrio = prio
		}

Review comment (suggestion):
```suggestion
		// ... while making sure not to loop too quickly either.
```

Code after:
	for {
		cfg := s.cfg.RawCopy()
		bestDialerPriority := s.bestDialerPriority(cfg)
		isInitialRampup := initialRampup < stdConnectionLoopSleep

		l.Debugln("Connection loop")
		if isInitialRampup {
			l.Debugln("Connection loop in initial rampup")
		}

		// Used for consistency throughout this loop run, as time passes
		// while we try connections etc.
		now := time.Now()

		// Attempt to dial all devices that are unconnected or can be connection-upgraded
		s.dialDevices(ctx, now, cfg, bestDialerPriority, nextDialAt, isInitialRampup)

		var sleep time.Duration
		if isInitialRampup {
			// We are in the initial rampup time, so we slowly, statically
			// increase the sleep time.
			sleep = initialRampup
			initialRampup *= 2
		} else {
			// The sleep time is until the next dial scheduled in nextDialAt,
			// clamped by stdConnectionLoopSleep as we don't want to sleep too
			// long (config changes might happen).
			sleep = filterAndFindSleepDuration(nextDialAt, now)
		}

		// ... while making sure not to loop too quickly either.
		if sleep < minConnectionLoopSleep {
			sleep = minConnectionLoopSleep
		}

		l.Debugln("Next connection loop in", sleep)

		select {
		case <-time.After(sleep):
		case <-ctx.Done():
			return ctx.Err()
		}
	}
}

func (s *service) bestDialerPriority(cfg config.Configuration) int {
	bestDialerPriority := worstDialerPriority
	for _, df := range dialers {
		if df.Valid(cfg) != nil {
			continue
		}
Repository: syncthing/syncthing
File: lib/connections/service.go (Go)

Code before:
			sleep = minConnectionLoopSleep
		}

		l.Debugln("Next connection loop in", sleep)

		select {
		case <-time.After(sleep):
		case <-ctx.Done():
			return ctx.Err()
		}
	}
}

func (s *service) bestDialerPrio(cfg config.Configuration) int {
	first := true
	var bestDialerPrio int
	for _, df := range dialers {
		if df.Valid(cfg) != nil {
			continue
		}
		if prio := df.Priority(); first || prio < bestDialerPrio {
			first = false
			bestDialerPrio = prio
		}
	}
	return bestDialerPrio
}

func (s *service) dialDevices(ctx context.Context, now time.Time, cfg config.Configuration, bestDialerPrio int, nextDial map[string]time.Time, initial bool) {
	for _, deviceCfg := range cfg.Devices {
		// Don't attempt to connect to ourselves...
		if deviceCfg.DeviceID == s.myID {
			continue
		}

		// Don't attempt to connect to paused devices...
		if deviceCfg.Paused {
			continue
		}

		// Don't connect to devices that are already connected using the
		// best possible dialer priority...
		connection, connected := s.model.Connection(deviceCfg.DeviceID)
		if connected && connection.Priority() == bestDialerPrio {
			continue
		}

		dialTargets := s.resolveDialTargets(ctx, now, cfg, deviceCfg, nextDial, initial)
		if conn, ok := s.dialParallel(ctx, deviceCfg.DeviceID, dialTargets); ok {
			s.conns <- conn
		}

Review comment (suggestion):
This now returns zero for no dialer vs highest possible int32 before. It won't change any behaviour though, as the only condition using `bestDialerPrio` is a `==`, which will never match either 0 or highest int32. Still no dialer resulting in highest prio is a bit surprising.

Code after:
			sleep = filterAndFindSleepDuration(nextDialAt, now)
		}

		// ... while making sure not to loop too quickly either.
		if sleep < minConnectionLoopSleep {
			sleep = minConnectionLoopSleep
		}

		l.Debugln("Next connection loop in", sleep)

		select {
		case <-time.After(sleep):
		case <-ctx.Done():
			return ctx.Err()
		}
	}
}

func (s *service) bestDialerPriority(cfg config.Configuration) int {
	bestDialerPriority := worstDialerPriority
	for _, df := range dialers {
		if df.Valid(cfg) != nil {
			continue
		}
		if prio := df.Priority(); prio < bestDialerPriority {
			bestDialerPriority = prio
		}
	}
	return bestDialerPriority
}

func (s *service) dialDevices(ctx context.Context, now time.Time, cfg config.Configuration, bestDialerPriority int, nextDialAt map[string]time.Time, initial bool) {
	for _, deviceCfg := range cfg.Devices {
		// Don't attempt to connect to ourselves...
		if deviceCfg.DeviceID == s.myID {
			continue
		}

		// Don't attempt to connect to paused devices...
		if deviceCfg.Paused {
			continue
		}

		// See if we are already connected and, if so, what our cutoff is
		// for dialer priority.
		priorityCutoff := worstDialerPriority
		connection, connected := s.model.Connection(deviceCfg.DeviceID)
		if connected {
			priorityCutoff = connection.Priority()
			if bestDialerPriority >= priorityCutoff {
				// Our best dialer is not any better than what we already
Repository: syncthing/syncthing
File: lib/connections/quic_dial.go (Go)

Code before:
// Copyright (C) 2019 The Syncthing Authors.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.

// +build go1.12,!noquic,!go1.16

package connections

import (
	"context"
	"crypto/tls"
	"net"
	"net/url"
	"time"

	"github.com/lucas-clemente/quic-go"
	"github.com/pkg/errors"

	"github.com/syncthing/syncthing/lib/config"
	"github.com/syncthing/syncthing/lib/connections/registry"
	"github.com/syncthing/syncthing/lib/protocol"
)

const (
	quicPriority = 100

	// The timeout for connecting, accepting and creating the various
	// streams.
	quicOperationTimeout = 10 * time.Second
)

Review comment (suggestion):
While at it: Quic/qtls apparently removed support for go1.13 a while ago, so the actual lower bound is now go1.14:

https://github.com/marten-seemann/qtls/commit/6befe96d4cf783737540378ecef36e171cdca49c

Code after:
// Copyright (C) 2019 The Syncthing Authors.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.

// +build go1.14,!noquic,!go1.16

package connections

import (
	"context"
	"crypto/tls"
	"net"
	"net/url"
	"time"

	"github.com/lucas-clemente/quic-go"
	"github.com/pkg/errors"

	"github.com/syncthing/syncthing/lib/config"
	"github.com/syncthing/syncthing/lib/connections/registry"
	"github.com/syncthing/syncthing/lib/protocol"
)

const (
	quicPriority = 100

	// The timeout for connecting, accepting and creating the various
	// streams.
	quicOperationTimeout = 10 * time.Second
)
Repository: syncthing/syncthing
File: lib/connections/quic_unsupported.go (Go)

Code before:
// Copyright (C) 2020 The Syncthing Authors.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/.

// +build noquic go1.16

package connections

func init() {
	for _, scheme := range []string{"quic", "quic4", "quic6"} {
		listeners[scheme] = invalidListener{err: errNotInBuild}
		dialers[scheme] = invalidDialer{err: errNotInBuild}
	}
}


Review comment (suggestion):
```suggestion
// +build noquic !go1.14 go1.16
```

Code after:
// Copyright (C) 2020 The Syncthing Authors.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/.

// +build noquic !go1.14 go1.16

package connections

func init() {
	for _, scheme := range []string{"quic", "quic4", "quic6"} {
		listeners[scheme] = invalidListener{err: errNotInBuild}
		dialers[scheme] = invalidDialer{err: errNotInBuild}
	}
}
Repository: syncthing/syncthing
File: lib/api/api_test.go (Go)

Code before:
		if !m.validToken(t4) {
			t.Fatal("t4 should be valid at iteration", i)
		}
	}

	if m.validToken(t3) {
		t.Fatal("t3 should have expired by now")
	}
}

func TestStopAfterBrokenConfig(t *testing.T) {
	t.Parallel()

	cfg := config.Configuration{
		GUI: config.GUIConfiguration{
			RawAddress: "127.0.0.1:0",
			RawUseTLS:  false,
		},
	}
	w := config.Wrap("/dev/null", cfg, protocol.LocalDeviceID, events.NoopLogger)

	srv := New(protocol.LocalDeviceID, w, "", "syncthing", nil, nil, nil, events.NoopLogger, nil, nil, nil, nil, nil, nil, false).(*service)
	defer os.Remove(token)
	srv.started = make(chan string)

	sup := suture.New("test", util.Spec(func(e suture.Event) { l.Debugln(e) }))
	sup.Add(srv)
	ctx, cancel := context.WithCancel(context.Background())
	sup.ServeBackground(ctx)

	<-srv.started

	// Service is now running, listening on a random port on localhost. Now we
	// request a config change to a completely invalid listen address. The
	// commit will fail and the service will be in a broken state.

	newCfg := config.Configuration{
		GUI: config.GUIConfiguration{
			RawAddress: "totally not a valid address",
			RawUseTLS:  false,
		},
	}
	if err := srv.VerifyConfiguration(cfg, newCfg); err == nil {
		t.Fatal("Verify config should have failed")
	}

	cancel()
}

func TestAssetsDir(t *testing.T) {
	t.Parallel()

Review comment (bug):
I think this would be less ugly if we had:
```
util.SpecWithDebugLogger(l)
util.SpecWithInfoLogger(l)
```
or
```
util.SpecWithLogger(l, log.INFO_LEVEL)
```

Code after:
		if !m.validToken(t4) {
			t.Fatal("t4 should be valid at iteration", i)
		}
	}

	if m.validToken(t3) {
		t.Fatal("t3 should have expired by now")
	}
}

func TestStopAfterBrokenConfig(t *testing.T) {
	t.Parallel()

	cfg := config.Configuration{
		GUI: config.GUIConfiguration{
			RawAddress: "127.0.0.1:0",
			RawUseTLS:  false,
		},
	}
	w := config.Wrap("/dev/null", cfg, protocol.LocalDeviceID, events.NoopLogger)

	srv := New(protocol.LocalDeviceID, w, "", "syncthing", nil, nil, nil, events.NoopLogger, nil, nil, nil, nil, nil, nil, false).(*service)
	defer os.Remove(token)
	srv.started = make(chan string)

	sup := suture.New("test", util.SpecWithDebugLogger(l))
	sup.Add(srv)
	ctx, cancel := context.WithCancel(context.Background())
	sup.ServeBackground(ctx)

	<-srv.started

	// Service is now running, listening on a random port on localhost. Now we
	// request a config change to a completely invalid listen address. The
	// commit will fail and the service will be in a broken state.

	newCfg := config.Configuration{
		GUI: config.GUIConfiguration{
			RawAddress: "totally not a valid address",
			RawUseTLS:  false,
		},
	}
	if err := srv.VerifyConfiguration(cfg, newCfg); err == nil {
		t.Fatal("Verify config should have failed")
	}

	cancel()
}

func TestAssetsDir(t *testing.T) {
	t.Parallel()
Repository: syncthing/syncthing
File: lib/fs/casefs.go (Go)

Code before:
	cache, err := lru.New2Q(caseCacheItemLimit)
	// New2Q only errors if given invalid parameters, which we don't.
	if err != nil {
		panic(err)
	}
	caser := &defaultRealCaser{
		fs:    fs,
		cache: cache,
	}
	return caser
}

func (r *defaultRealCaser) realCase(name string) (string, error) {
	out := "."
	if name == out {
		return out, nil
	}

	var node *caseNode
	for _, comp := range strings.Split(name, string(PathSeparator)) {
		// Check cache
		v, ok := r.cache.Get(out)
		if ok {
			node = v.(*caseNode)
			if node.expires.Before(time.Now()) {
				r.purgeRecursive(out, node.children)
				ok = false
			}
		}

		if !ok {
			// Haven't called DirNames yet, or the node has expired

			dirNames, err := r.fs.DirNames(out)
			if err != nil {
				return "", err
			}

			num := len(dirNames)
			node = &caseNode{
				children:    make(map[string]struct{}, num),
				lowerToReal: make(map[string]string, num),
			}
			lastLower := ""
			for _, n := range dirNames {
				node.children[n] = struct{}{}
				lower := UnicodeLowercase(n)
				if lower != lastLower {
					node.lowerToReal[lower] = n
				}
			}

Review comment (performance):
Technically we only need to purge recursively if the casing actually changed at this level, otherwise we can let child cache entries live on their own... Not sure if that makes anything easier or harder.

Code after:
	cache, err := lru.New2Q(caseCacheItemLimit)
	// New2Q only errors if given invalid parameters, which we don't.
	if err != nil {
		panic(err)
	}
	caser := &defaultRealCaser{
		fs: fs,
		cache: caseCache{
			TwoQueueCache: cache,
		},
	}
	return caser
}

func (r *defaultRealCaser) realCase(name string) (string, error) {
	realName := "."
	if name == realName {
		return realName, nil
	}

	for _, comp := range strings.Split(name, string(PathSeparator)) {
		node := r.cache.getExpireAdd(realName)

		node.once.Do(func() {
			dirNames, err := r.fs.DirNames(realName)
			if err != nil {
				r.cache.Remove(realName)
				node.err = err
				return
			}

			num := len(dirNames)
			node.children = make(map[string]struct{}, num)
			node.lowerToReal = make(map[string]string, num)
			lastLower := ""
			for _, n := range dirNames {
				node.children[n] = struct{}{}
				lower := UnicodeLowercase(n)
				if lower != lastLower {
					node.lowerToReal[lower] = n
					lastLower = n
				}
			}
		})
		if node.err != nil {
			return "", node.err
		}

		// Try to find a direct or case match
		if _, ok := node.children[comp]; !ok {
			comp, ok = node.lowerToReal[UnicodeLowercase(comp)]
Repository: syncthing/syncthing
File: lib/model/folder.go (Go)

Code before:
			scanCancel()
			for range fchan {
			}
			return err
		}

		batchAppend(res.File, snap)
		changes++

		switch f.Type {
		case config.FolderTypeReceiveOnly, config.FolderTypeReceiveEncrypted:
		default:
			if nf, ok := f.findRename(snap, res.File, alreadyUsed); ok {
				batchAppend(nf, snap)
				changes++
			}
		}
	}

	if err := batch.flush(); err != nil {
		return err
	}

	if len(subDirs) == 0 {
		// If we have no specific subdirectories to traverse, set it to one
		// empty prefix so we traverse the entire folder contents once.
		subDirs = []string{""}
	}

	// Do a scan of the database for each prefix, to check for deleted and
	// ignored files.
	var toIgnore []db.FileInfoTruncated
	ignoredParent := ""

	snap.Release()
	snap = f.fset.Snapshot()
	defer snap.Release()

	for _, sub := range subDirs {
		var iterError error

		snap.WithPrefixedHaveTruncated(protocol.LocalDeviceID, sub, func(fi protocol.FileIntf) bool {
			select {
			case <-f.ctx.Done():
				return false
			default:
			}

			file := fi.(db.FileInfoTruncated)

			if err := batch.flushIfFull(); err != nil {

Review comment (suggestion):
I know I'm late to the party, but this doesn't actually do anything, as you can verify using

```
go build -gcflags=-S |& sha256sum
```

with this line active and commented out.

Code after:
			scanCancel()
			for range fchan {
			}
			return err
		}

		batchAppend(res.File, snap)
		changes++

		switch f.Type {
		case config.FolderTypeReceiveOnly, config.FolderTypeReceiveEncrypted:
		default:
			if nf, ok := f.findRename(snap, res.File, alreadyUsedOrExisting); ok {
				batchAppend(nf, snap)
				changes++
			}
		}
	}

	if err := batch.flush(); err != nil {
		return err
	}

	// Might have grown large, isn't used anymore and this function may keep
	// running for some time.
	alreadyUsedOrExisting = nil

	if len(subDirs) == 0 {
		// If we have no specific subdirectories to traverse, set it to one
		// empty prefix so we traverse the entire folder contents once.
		subDirs = []string{""}
	}

	// Do a scan of the database for each prefix, to check for deleted and
	// ignored files.
	var toIgnore []db.FileInfoTruncated
	ignoredParent := ""

	snap.Release()
	snap = f.fset.Snapshot()
	defer snap.Release()

	for _, sub := range subDirs {
		var iterError error

		snap.WithPrefixedHaveTruncated(protocol.LocalDeviceID, sub, func(fi protocol.FileIntf) bool {
			select {
			case <-f.ctx.Done():
				return false
			default:
			}
Repository: syncthing/syncthing
File: lib/protocol/protocol.go (Go)

Code before:
	for {
		select {
		case msg = <-c.inbox:
		case <-c.closed:
			return ErrClosed
		}
		switch msg := msg.(type) {
		case *ClusterConfig:
			l.Debugln("read ClusterConfig message")
			if state == stateInitial {
				state = stateReady
			}
			if err := c.receiver.ClusterConfig(c.id, *msg); err != nil {
				return fmt.Errorf("receiving cluster config: %w", err)
			}

		case *Index:
			l.Debugln("read Index message")
			if state != stateReady {
				return indexError(fmt.Errorf("invalid state %d", state), "index", msg.Folder)
			}
			if err := checkIndexConsistency(msg.Files); err != nil {
				return indexError(err, "index", msg.Folder)
			}
			if err := c.handleIndex(*msg); err != nil {
				return indexError(err, "index", msg.Folder)
			}
			state = stateReady

		case *IndexUpdate:
			l.Debugln("read IndexUpdate message")
			if state != stateReady {
				return indexError(fmt.Errorf("invalid state %d", state), "index update", msg.Folder)
			}
			if err := checkIndexConsistency(msg.Files); err != nil {
				return indexError(err, "index update", msg.Folder)
			}
			if err := c.handleIndexUpdate(*msg); err != nil {
				return indexError(err, "index update", msg.Folder)
			}
			state = stateReady

		case *Request:
			l.Debugln("read Request message")
			if state != stateReady {
				return fmt.Errorf("protocol error: receiving request in state %d", state)
			}
			if err := checkFilename(msg.Name); err != nil {
				return fmt.Errorf(`protocol error: receiving request for "%v" in %v: %w`, msg.Name, msg.Folder, err)
			}
			go c.handleRequest(*msg)

Review comment (suggestion):
The error returns from `handle...` should not be wrapped as `protocol error: ...` I think

Code after:
	for {
		select {
		case msg = <-c.inbox:
		case <-c.closed:
			return ErrClosed
		}

		msgContext, err := messageContext(msg)
		if err != nil {
			return fmt.Errorf("protocol error: %w", err)
		}
		l.Debugf("handle %v message", msgContext)

		switch msg := msg.(type) {
		case *ClusterConfig:
			if state == stateInitial {
				state = stateReady
			}
		case *Close:
			return fmt.Errorf("closed by remote: %v", msg.Reason)
		default:
			if state != stateReady {
				return newProtocolError(fmt.Errorf("invalid state %d", state), msgContext)
			}
		}

		switch msg := msg.(type) {
		case *Index:
			err = checkIndexConsistency(msg.Files)

		case *IndexUpdate:
			err = checkIndexConsistency(msg.Files)

		case *Request:
			err = checkFilename(msg.Name)
		}
		if err != nil {
			return newProtocolError(err, msgContext)
		}

		switch msg := msg.(type) {
		case *ClusterConfig:
			err = c.receiver.ClusterConfig(c.id, *msg)

		case *Index:
			err = c.handleIndex(*msg)

		case *IndexUpdate:
			err = c.handleIndexUpdate(*msg)

		case *Request: