// Because Copy is defined to read from src until EOF, it does
 // not treat an EOF from Read as an error to be reported.
 //
-// If dst implements the ReaderFrom interface,
-// the copy is implemented by calling dst.ReadFrom(src).
-// Otherwise, if src implements the WriterTo interface,
+// If src implements the WriterTo interface,
 // the copy is implemented by calling src.WriteTo(dst).
+// Otherwise, if dst implements the ReaderFrom interface,
+// the copy is implemented by calling dst.ReadFrom(src).
 func Copy(dst Writer, src Reader) (written int64, err error) {
-       // If the writer has a ReadFrom method, use it to do the copy.
+       // If the reader has a WriteTo method, use it to do the copy.
        // Avoids an allocation and a copy.
-       if rt, ok := dst.(ReaderFrom); ok {
-               return rt.ReadFrom(src)
-       }
-       // Similarly, if the reader has a WriteTo method, use it to do the copy.
        if wt, ok := src.(WriterTo); ok {
                return wt.WriteTo(dst)
        }
+       // Similarly, if the writer has a ReadFrom method, use it to do the copy.
+       if rt, ok := dst.(ReaderFrom); ok {
+               return rt.ReadFrom(src)
+       }
        buf := make([]byte, 32*1024)
        for {
                nr, er := src.Read(buf)
 
        }
 }
 
+// Version of bytes.Buffer that checks whether WriteTo was called or not
+type writeToChecker struct {
+       bytes.Buffer
+       writeToCalled bool
+}
+
+func (wt *writeToChecker) WriteTo(w Writer) (int64, error) {
+       wt.writeToCalled = true
+       return wt.Buffer.WriteTo(w)
+}
+
+// It's preferable to choose WriterTo over ReaderFrom, since a WriterTo can issue one large write,
+// while the ReaderFrom must read until EOF, potentially allocating when running out of buffer.
+// Make sure that we choose WriterTo when both are implemented.
+func TestCopyPriority(t *testing.T) {
+       rb := new(writeToChecker)
+       wb := new(bytes.Buffer)
+       rb.WriteString("hello, world.")
+       Copy(wb, rb)
+       if wb.String() != "hello, world." {
+               t.Errorf("Copy did not work properly")
+       } else if !rb.writeToCalled {
+               t.Errorf("WriteTo was not prioritized over ReadFrom")
+       }
+}
+
 func TestCopyN(t *testing.T) {
        rb := new(Buffer)
        wb := new(Buffer)