Add "markdown" path.
diff --git a/handlers.go b/handlers.go
index c0d11a9..8c69ec8 100644
--- a/handlers.go
+++ b/handlers.go
@@ -55,6 +55,9 @@
 	if s.readyPath != "" {
 		h.mux.HandleFunc(s.readyPath, s.handleReady)
 	}
+	if s.markdownPath != "" {
+		h.mux.HandleFunc(s.markdownPath, s.handleMarkdown)
+	}
 	return h
 }
 
@@ -76,6 +79,11 @@
 handleHealth only fails if the user's health check function tells us.
 */
 func (s *HTTPScaffold) handleHealth(resp http.ResponseWriter, req *http.Request) {
+	if req.Method != "GET" {
+		resp.WriteHeader(http.StatusMethodNotAllowed)
+		return
+	}
+
 	status, healthErr := s.callHealthCheck()
 
 	if status == Failed {
@@ -90,6 +98,11 @@
 tells us.
 */
 func (s *HTTPScaffold) handleReady(resp http.ResponseWriter, req *http.Request) {
+	if req.Method != "GET" {
+		resp.WriteHeader(http.StatusMethodNotAllowed)
+		return
+	}
+
 	status, healthErr := s.callHealthCheck()
 	if status == OK {
 		healthErr = s.tracker.markedDown()
@@ -105,6 +118,22 @@
 	}
 }
 
+/*
+handleMarkdown handles a request to mark down the server.
+*/
+func (s *HTTPScaffold) handleMarkdown(resp http.ResponseWriter, req *http.Request) {
+	if req.Method != s.markdownMethod {
+		resp.WriteHeader(http.StatusMethodNotAllowed)
+		return
+	}
+
+	req.Body.Close()
+	s.tracker.markDown()
+	if s.markdownHandler != nil {
+		s.markdownHandler()
+	}
+}
+
 func writeUnavailable(
 	resp http.ResponseWriter, req *http.Request,
 	stat HealthStatus, err error) {
diff --git a/scaffold.go b/scaffold.go
index 1a07320..cc64cc1 100644
--- a/scaffold.go
+++ b/scaffold.go
@@ -31,6 +31,11 @@
 var ErrManualStop = errors.New("Shutdown called")
 
 /*
+ErrMarkedDown is used after being marked down but before being shut down.
+*/
+var ErrMarkedDown = errors.New("Marked down")
+
+/*
 HealthStatus is a type of response from a health check.
 */
 type HealthStatus int
@@ -58,6 +63,15 @@
 type HealthChecker func() (HealthStatus, error)
 
 /*
+MarkdownHandler is a type of function that an user may implement in order to
+be notified when the server is marked down. The function may do anything
+it needs to do in response to a markdown request. However, markdown will
+proceed even if the function fails. In case the function takes a long time,
+the scaffold will always invoke it inside a new goroutine.
+*/
+type MarkdownHandler func()
+
+/*
 An HTTPScaffold provides a set of features on top of a standard HTTP
 listener. It includes an HTTP handler that may be plugged in to any
 standard Go HTTP server. It is intended to be placed before any other
@@ -73,6 +87,9 @@
 	healthCheck        HealthChecker
 	healthPath         string
 	readyPath          string
+	markdownPath       string
+	markdownMethod     string
+	markdownHandler    MarkdownHandler
 }
 
 /*
@@ -155,6 +172,28 @@
 }
 
 /*
+SetMarkdown sets up a URI that will cause the server to mark it
+self down. However, this URI will not cause the server to actually shut
+down. Once any HTTP request is received on this path with a matching
+method, the server will be marked down. (the "readyPath" will respond
+with 503, and all other HTTP calls other than the "healthPath" will
+also respond with 503. The "healthPath" will still respond with 200.)
+If "handler" is not nil, the handler will be invoked and the API call
+will not return until the handler has returned. Because of that, the
+handler should return in a timely manner. (For instance, it should return
+in less than 30 seconds if Kubernetes is used unless the "grace period"
+is extended.)
+This makes this function the right thing to use
+as a "preStop" method in Kubernetes, so that the server can take action
+after shutdown to indicate that it has been deleted on purpose.
+*/
+func (s *HTTPScaffold) SetMarkdown(method, path string, handler MarkdownHandler) {
+	s.markdownPath = path
+	s.markdownMethod = method
+	s.markdownHandler = handler
+}
+
+/*
 SetHealthChecker specifies a function that the scaffold will call every time
 "HealthPath" or "ReadyPath" is invoked.
 */
diff --git a/scaffold_test.go b/scaffold_test.go
index e4fe194..4a82a62 100644
--- a/scaffold_test.go
+++ b/scaffold_test.go
@@ -6,6 +6,7 @@
 	"fmt"
 	"io/ioutil"
 	"net/http"
+	"strings"
 	"sync/atomic"
 	"time"
 
@@ -123,6 +124,60 @@
 		}, time.Second).Should(BeFalse())
 	})
 
+	It("Markdown", func() {
+		var markedDown int32
+
+		s := CreateHTTPScaffold()
+		s.SetHealthPath("/health")
+		s.SetReadyPath("/ready")
+		s.SetMarkdown("POST", "/markdown", func() {
+			atomic.StoreInt32(&markedDown, 1)
+		})
+
+		stopChan := make(chan error)
+		err := s.Open()
+		Expect(err).Should(Succeed())
+
+		go func() {
+			listenErr := s.Listen(&testHandler{})
+			stopChan <- listenErr
+		}()
+
+		// Just make sure server is listening
+		Eventually(func() bool {
+			return testGet(s, "")
+		}, 5*time.Second).Should(BeTrue())
+
+		// Ensure that we are healthy and ready
+		code, _ := getText(fmt.Sprintf("http://%s/health", s.InsecureAddress()))
+		Expect(code).Should(Equal(200))
+		code, _ = getText(fmt.Sprintf("http://%s/ready", s.InsecureAddress()))
+		Expect(code).Should(Equal(200))
+
+		// Mark the server down, but don't stop it
+		resp, err := http.Post(fmt.Sprintf("http://%s/markdown", s.InsecureAddress()),
+			"text/plain", strings.NewReader("Goodbye!"))
+		Expect(err).Should(Succeed())
+		resp.Body.Close()
+		Expect(resp.StatusCode).Should(Equal(200))
+
+		// Server should immediately be marked down, not ready, but healthy
+		Expect(atomic.LoadInt32(&markedDown)).Should(BeEquivalentTo(1))
+		code, _ = getText(fmt.Sprintf("http://%s", s.InsecureAddress()))
+		Expect(code).Should(Equal(503))
+		code, _ = getText(fmt.Sprintf("http://%s/ready", s.InsecureAddress()))
+		Expect(code).Should(Equal(503))
+		code, _ = getText(fmt.Sprintf("http://%s/health", s.InsecureAddress()))
+		Expect(code).Should(Equal(200))
+
+		// Server should not have stopped yet
+		Consistently(stopChan).ShouldNot(Receive())
+
+		stopErr := errors.New("Test stop")
+		s.Shutdown(stopErr)
+		Eventually(stopChan).Should(Receive(Equal(stopErr)))
+	})
+
 	It("Health Check Functions", func() {
 		status := int32(OK)
 		var healthErr = &atomic.Value{}
diff --git a/tracker.go b/tracker.go
index 0f9c9ea..72e1b69 100644
--- a/tracker.go
+++ b/tracker.go
@@ -16,6 +16,15 @@
 )
 
 /*
+values for the shutdown state
+*/
+const (
+	running    int32 = iota
+	markedDown int32 = iota
+	shutDown   int32 = iota
+)
+
+/*
 The requestTracker keeps track of HTTP requests. In normal operations it
 just counts. Once the server has been marked for shutdown, however, it
 counts down to zero and returns a shutdown indication when that
@@ -26,7 +35,7 @@
 	// If "shutdown" is never called then this will never happen.
 	C              chan error
 	shutdownWait   time.Duration
-	shuttingDown   int32
+	shutdownState  int32
 	shutdownReason *atomic.Value
 	commandChan    chan int
 }
@@ -40,6 +49,7 @@
 	rt := &requestTracker{
 		C:              make(chan error, 1),
 		commandChan:    make(chan int, 100),
+		shutdownState:  running,
 		shutdownWait:   shutdownWait,
 		shutdownReason: &atomic.Value{},
 	}
@@ -74,8 +84,8 @@
 "Shutdown" method.
 */
 func (t *requestTracker) markedDown() error {
-	sd := atomic.LoadInt32(&t.shuttingDown)
-	if sd != 0 {
+	ss := atomic.LoadInt32(&t.shutdownState)
+	if ss != running {
 		reason := t.shutdownReason.Load().(*error)
 		if reason == nil {
 			return nil
@@ -95,6 +105,11 @@
 	t.commandChan <- shutdown
 }
 
+func (t *requestTracker) markDown() {
+	t.shutdownReason.Store(&ErrMarkedDown)
+	atomic.StoreInt32(&t.shutdownState, markedDown)
+}
+
 func (t *requestTracker) sendStop(sent bool) bool {
 	if !sent {
 		reason := t.shutdownReason.Load().(*error)
@@ -128,7 +143,7 @@
 				}
 			case shutdown:
 				stopping = true
-				atomic.StoreInt32(&t.shuttingDown, 1)
+				atomic.StoreInt32(&t.shutdownState, shutDown)
 				if activeRequests <= 0 {
 					sentStop = t.sendStop(sentStop)
 				} else {