 
 (s/def ::delta/operation (s/multi-spec operation-spec (fn [o _] o)))
 
-(defn unconform-operation
-  ""
+(defn- unconform-operation
+  "Given `conformed-operation`, the result of of conforming a value to
+  `::delta/operation`, returns a raw operation.
+  "
   [conformed-operation]
   (if (::delta/insert conformed-operation)
     (update conformed-operation ::delta/insert val)
     conformed-operation))
 
+(defn- conformed-operation-length
+  "Given `conformed-operation`, the result of of conforming a value to
+  `::delta/operation`, returns the operation’s length in characters.
+  "
+  [conformed-operation]
+  (-> conformed-operation
+      unconform-operation
+      operation/length))
+
 (s/def ::delta/delta (s/coll-of ::delta/operation))
 
 (s/fdef operation/length

(s/fdef operation/drop
  :args (s/cat :n int? :operation ::delta/operation)
  :ret (s/nilable ::delta/operation)
  :fn (s/or :nil (s/and #(>= (-> % :args :n) (-> % :args :operation unconform-operation operation/length))
                        #(-> % :ret nil?))
            :non-nil (s/and #(< (-> % :args :n) (-> % :args :operation unconform-operation operation/length))
                            operation-type-preserved?
                            attributes-preserved?
                            length-shortened-by-n?
                            #(text-preserved? string/ends-with? %))))

(s/fdef operation/delete
  :args (s/cat :n int?)
  :ret (s/nilable (s/and ::delta/operation
                         #(::delta/delete %)))
  :fn (s/or :nil (s/and #(-> % :args :n pos? not)
                        #(-> % :ret nil?))
            :non-nil (s/and #(-> % :args :n pos?)
                            #(= (-> % :args :n)
                                (-> % :ret operation/length)))))

(defn- operation-contents-preserved?
  ""
  [{:keys [args ret]}]
  (let [type (operation/type ret)]
    (= (type ret)
       (-> args :operation type))))

(defn- attributes-set?
  ""
  [{:keys [args ret]}]
  (let [arg-attrs (-> args :attributes)
        ret-attrs (-> ret ::delta/attributes)]

            :non-nil (s/and #(-> % :args :n pos?)
                            operation-type-preserved?
                            attributes-preserved?
                            operation-shortenend-to-n?
                            #(text-preserved? string/starts-with? %))))

(defn- length-shortened-by-n?
  "True if the instrumented function shortened its `operation` argument
  by `n` characters (`n` is also an argument).
  "
  [{:keys [args ret]}]
  (= (- (-> args :operation conformed-operation-length) (-> args :n (max 0)))
     (-> ret conformed-operation-length)))

(s/fdef operation/drop'
  :args (s/and (s/cat :n nat-int? :operation ::delta/operation)
               #(not (= :embed (some-> % :operation ::delta/insert key)))
               #(< (:n %) (-> % :operation conformed-operation-length dec)))
  :ret ::delta/operation
  :fn (s/and operation-type-preserved?
             attributes-preserved?
