code: func (b *EtcdBackend) CompareAndSwap(ctx context.Context, expected backend.Item, replaceWith backend.Item) (*backend.Lease, error) {
  	if len(expected.Key) == 0 {
  		return nil, trace.BadParameter("missing parameter Key")
  	}
  	if len(replaceWith.Key) == 0 {
  		return nil, trace.BadParameter("missing parameter Key")
  	}
  	if bytes.Compare(expected.Key, replaceWith.Key) != 0 {
  		return nil, trace.BadParameter("expected and replaceWith keys should match")
  	}
  	var opts []clientv3.OpOption
  	var lease backend.Lease
  	if !replaceWith.Expires.IsZero() {
  		if err := b.setupLease(ctx, replaceWith, &lease, &opts); err != nil {
  			return nil, trace.Wrap(err)
  		}
  	}
  	encodedPrev := base64.StdEncoding.EncodeToString(expected.Value)
  	start := b.clock.Now()
  	re, err := b.client.Txn(ctx).
  		If(clientv3.Compare(clientv3.Value(prependPrefix(expected.Key)), "=", encodedPrev)).
  		Then(clientv3.OpPut(prependPrefix(expected.Key), base64.StdEncoding.EncodeToString(replaceWith.Value), opts...)).
  		Commit()
  	txLatencies.Observe(time.Since(start).Seconds())
  	txRequests.Inc()
  	if err != nil {
  		err = convertErr(err)
  		if trace.IsNotFound(err) {
  			return nil, trace.CompareFailed(err.Error())
  		}
  	}
  	if !re.Succeeded {
  		return nil, trace.CompareFailed("key %q did not match expected value", string(expected.Key))
  	}
  	return &lease, nil
  }
docs: // CompareAndSwap compares item with existing item
  // and replaces is with replaceWith item