private DocOp composeOperations(DocOp op1, DocOp op2) throws OperationException {
   target = defaultTarget;
   int op1Index = 0;
   int op2Index = 0;
   while (op1Index < op1.size()) {
     op1.applyComponent(op1Index++, target);
     while (target.isPostTarget()) {
       if (op2Index >= op2.size()) {
         throw new OperationException(
             "Document size mismatch: "
                 + "op1 resulting length="
                 + DocOpUtil.resultingDocumentLength(op1)
                 + ", op2 initial length="
                 + DocOpUtil.initialDocumentLength(op2));
       }
       op2.applyComponent(op2Index++, target);
     }
   }
   if (op2Index < op2.size()) {
     target = new FinisherPostTarget();
     while (op2Index < op2.size()) {
       op2.applyComponent(op2Index++, target);
     }
   }
   flushAnnotations();
   return normalizer.finish();
 }
  private static void addDocumentSnapshotToWavelet(DocumentSnapshot snapshot, WaveletData container)
      throws InvalidParticipantAddress {
    DocOp op = CoreWaveletOperationSerializer.deserialize(snapshot.getDocumentOperation());
    DocInitialization docInit = DocOpUtil.asInitialization(op);

    Collection<ParticipantId> contributors = CollectionUtils.newArrayList();
    for (String p : snapshot.getContributorList()) {
      contributors.add(getParticipantId(p));
    }
    container.createDocument(
        snapshot.getDocumentId(),
        getParticipantId(snapshot.getAuthor()),
        contributors,
        docInit,
        snapshot.getLastModifiedTime(),
        snapshot.getLastModifiedVersion());
  }
 /**
  * Returns the composition of an initialization and an operation.
  *
  * <p>This overload of the method returns a more specific subtype than the other one.
  *
  * @param op1 the first operation
  * @param op2 the second operation
  * @return the result of the composition
  * @throws OperationException if applying op1 followed by op2 would be invalid
  */
 public static DocInitialization compose(DocInitialization op1, DocOp op2)
     throws OperationException {
   return DocOpUtil.asInitialization(compose((DocOp) op1, op2));
 }
 /**
  * Creates a document initialization from an operation message.
  *
  * @param message The message representing the document operation.
  * @param checkWellFormed If we should check for well-formedness of deserialised DocOp
  * @return The created operation.
  */
 public static DocInitialization createDocumentInitialization(
     ProtocolDocumentOperation message, boolean checkWellFormed) throws InvalidInputException {
   return DocOpUtil.asInitialization(createDocumentOperation(message, checkWellFormed));
 }