// Path: lib/src/main/java/com/google/capillary/Config.java
// public final class Config {
// 
//   /**
//    * Initializes the Capillary library.
//    *
//    * <p>This should be called before using any functionality provided by Capillary.
//    *
//    * @throws GeneralSecurityException if the initialization fails.
//    */
//   public static void initialize() throws GeneralSecurityException {
//     com.google.crypto.tink.Config.register(SignatureConfig.TINK_1_1_0);
//     com.google.crypto.tink.Config.register(AeadConfig.TINK_1_1_0);
//   }
// }
// 
// Path: lib/src/main/java/com/google/capillary/RsaEcdsaEncrypterManager.java
// public final class RsaEcdsaEncrypterManager extends EncrypterManager {
// 
//   private final PublicKeySign senderSigner;
// 
//   /**
//    * Constructs a new RSA-ECDSA EncrypterManager.
//    *
//    * <p>Please note that the {@link InputStream} {@code senderSigningKey} will not be closed.
//    *
//    * @param senderSigningKey the serialized Tink signing key.
//    * @throws GeneralSecurityException if the initialization fails.
//    * @throws IOException if the given sender signing key cannot be read.
//    */
//   public RsaEcdsaEncrypterManager(InputStream senderSigningKey)
//       throws GeneralSecurityException, IOException {
//     KeysetHandle signingKeyHandle = CleartextKeysetHandle
//         .read(BinaryKeysetReader.withInputStream(senderSigningKey));
//     senderSigner = PublicKeySignFactory.getPrimitive(signingKeyHandle);
//   }
// 
//   @Override
//   HybridEncrypt rawLoadPublicKey(byte[] publicKey) throws GeneralSecurityException {
//     WrappedRsaEcdsaPublicKey wrappedRsaEcdsaPublicKey;
//     try {
//       wrappedRsaEcdsaPublicKey = WrappedRsaEcdsaPublicKey.parseFrom(publicKey);
//     } catch (InvalidProtocolBufferException e) {
//       throw new GeneralSecurityException("unable to parse public key", e);
//     }
//     PublicKey recipientPublicKey = KeyFactory.getInstance("RSA").generatePublic(
//         new X509EncodedKeySpec(wrappedRsaEcdsaPublicKey.getKeyBytes().toByteArray()));
//     return new RsaEcdsaHybridEncrypt.Builder()
//         .withSenderSigner(senderSigner)
//         .withRecipientPublicKey(recipientPublicKey)
//         .withPadding(RsaEcdsaConstants.Padding.valueOf(wrappedRsaEcdsaPublicKey.getPadding()))
//         .build();
//   }
// }
// 
// Path: lib/src/main/java/com/google/capillary/WebPushEncrypterManager.java
// public final class WebPushEncrypterManager extends EncrypterManager {
// 
//   @Override
//   HybridEncrypt rawLoadPublicKey(byte[] publicKey) throws GeneralSecurityException {
//     WrappedWebPushPublicKey wrappedWebPushPublicKey;
//     try {
//       wrappedWebPushPublicKey = WrappedWebPushPublicKey.parseFrom(publicKey);
//     } catch (InvalidProtocolBufferException e) {
//       throw new GeneralSecurityException("unable to parse public key", e);
//     }
//     return new WebPushHybridEncrypt.Builder()
//         .withAuthSecret(wrappedWebPushPublicKey.getAuthSecret().toByteArray())
//         .withRecipientPublicKey(wrappedWebPushPublicKey.getKeyBytes().toByteArray())
//         .build();
//   }
// }


import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import com.google.capillary.Config;
import com.google.capillary.RsaEcdsaEncrypterManager;
import com.google.capillary.WebPushEncrypterManager;
import io.grpc.BindableService;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.sql.SQLException;
import java.util.logging.Logger;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;

    CommandLineParser cmdLineParser = new DefaultParser();
    return cmdLineParser.parse(options, commandLineArguments);
  }

  private void start(CommandLine cmd) throws IOException, GeneralSecurityException, SQLException {
    // The port on which the server should run.
    int port = Integer.valueOf(cmd.getOptionValue(PORT_OPTION));
    // The FCM message sender.
    FcmSender fcmSender = new FcmSender(
        cmd.getOptionValue(FIREBASE_PROJECT_ID_OPTION),
        cmd.getOptionValue(SERVICE_ACCOUNT_CREDENTIALS_PATH_OPTION));
    // The Capillary encrypter managers.
    RsaEcdsaEncrypterManager rsaEcdsaEncrypterManager;
    try (FileInputStream senderSigningKey =
        new FileInputStream(cmd.getOptionValue(ECDSA_PRIVATE_KEY_PATH_OPTION))) {
      rsaEcdsaEncrypterManager = new RsaEcdsaEncrypterManager(senderSigningKey);
    }
    WebPushEncrypterManager webPushEncrypterManager = new WebPushEncrypterManager();
    // The {certificate, private key} pair to use for gRPC TLS.
    File tlsCertFile = new File(cmd.getOptionValue(TLS_CERT_PATH_OPTION));
    File tlsPrivateKeyFile = new File(cmd.getOptionValue(TLS_PRIVATE_KEY_PATH_OPTION));
    // The interface to demo SQLite DB.
    DemoDb db = new DemoDb(
        "jdbc:sqlite:" + cmd.getOptionValue(DATABASE_PATH_OPTION));
    // The demo service.
    BindableService demoService =
        new DemoServiceImpl(db, rsaEcdsaEncrypterManager, webPushEncrypterManager, fcmSender);
    // Create and start the gRPC server instance.
    server = ServerBuilder.forPort(port)
// Path: lib/src/main/java/com/google/capillary/Config.java
// public final class Config {
// 
//   /**
//    * Initializes the Capillary library.
//    *
//    * <p>This should be called before using any functionality provided by Capillary.
//    *
//    * @throws GeneralSecurityException if the initialization fails.
//    */
//   public static void initialize() throws GeneralSecurityException {
//     com.google.crypto.tink.Config.register(SignatureConfig.TINK_1_1_0);
//     com.google.crypto.tink.Config.register(AeadConfig.TINK_1_1_0);
//   }
// }
// 
// Path: lib/src/main/java/com/google/capillary/RsaEcdsaEncrypterManager.java
// public final class RsaEcdsaEncrypterManager extends EncrypterManager {
// 
//   private final PublicKeySign senderSigner;
// 
//   /**
//    * Constructs a new RSA-ECDSA EncrypterManager.
//    *
//    * <p>Please note that the {@link InputStream} {@code senderSigningKey} will not be closed.
//    *
//    * @param senderSigningKey the serialized Tink signing key.
//    * @throws GeneralSecurityException if the initialization fails.
//    * @throws IOException if the given sender signing key cannot be read.
//    */
//   public RsaEcdsaEncrypterManager(InputStream senderSigningKey)
//       throws GeneralSecurityException, IOException {
//     KeysetHandle signingKeyHandle = CleartextKeysetHandle
//         .read(BinaryKeysetReader.withInputStream(senderSigningKey));
//     senderSigner = PublicKeySignFactory.getPrimitive(signingKeyHandle);
//   }
// 
//   @Override
//   HybridEncrypt rawLoadPublicKey(byte[] publicKey) throws GeneralSecurityException {
//     WrappedRsaEcdsaPublicKey wrappedRsaEcdsaPublicKey;
//     try {
//       wrappedRsaEcdsaPublicKey = WrappedRsaEcdsaPublicKey.parseFrom(publicKey);
//     } catch (InvalidProtocolBufferException e) {
//       throw new GeneralSecurityException("unable to parse public key", e);
//     }
//     PublicKey recipientPublicKey = KeyFactory.getInstance("RSA").generatePublic(
//         new X509EncodedKeySpec(wrappedRsaEcdsaPublicKey.getKeyBytes().toByteArray()));
//     return new RsaEcdsaHybridEncrypt.Builder()
//         .withSenderSigner(senderSigner)
//         .withRecipientPublicKey(recipientPublicKey)
//         .withPadding(RsaEcdsaConstants.Padding.valueOf(wrappedRsaEcdsaPublicKey.getPadding()))
//         .build();
//   }
// }
// 
// Path: lib/src/main/java/com/google/capillary/WebPushEncrypterManager.java
// public final class WebPushEncrypterManager extends EncrypterManager {
// 
//   @Override
//   HybridEncrypt rawLoadPublicKey(byte[] publicKey) throws GeneralSecurityException {
//     WrappedWebPushPublicKey wrappedWebPushPublicKey;
//     try {
//       wrappedWebPushPublicKey = WrappedWebPushPublicKey.parseFrom(publicKey);
//     } catch (InvalidProtocolBufferException e) {
//       throw new GeneralSecurityException("unable to parse public key", e);
//     }
//     return new WebPushHybridEncrypt.Builder()
//         .withAuthSecret(wrappedWebPushPublicKey.getAuthSecret().toByteArray())
//         .withRecipientPublicKey(wrappedWebPushPublicKey.getKeyBytes().toByteArray())
//         .build();
//   }
// }


// Path: demo/server/src/main/java/com/google/capillary/demo/server/DemoServer.java
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import com.google.capillary.Config;
import com.google.capillary.RsaEcdsaEncrypterManager;
import com.google.capillary.WebPushEncrypterManager;
import io.grpc.BindableService;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.sql.SQLException;
import java.util.logging.Logger;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;


    CommandLineParser cmdLineParser = new DefaultParser();
    return cmdLineParser.parse(options, commandLineArguments);
  }

  private void start(CommandLine cmd) throws IOException, GeneralSecurityException, SQLException {
    // The port on which the server should run.
    int port = Integer.valueOf(cmd.getOptionValue(PORT_OPTION));
    // The FCM message sender.
    FcmSender fcmSender = new FcmSender(
        cmd.getOptionValue(FIREBASE_PROJECT_ID_OPTION),
        cmd.getOptionValue(SERVICE_ACCOUNT_CREDENTIALS_PATH_OPTION));
    // The Capillary encrypter managers.
    RsaEcdsaEncrypterManager rsaEcdsaEncrypterManager;
    try (FileInputStream senderSigningKey =
        new FileInputStream(cmd.getOptionValue(ECDSA_PRIVATE_KEY_PATH_OPTION))) {
      rsaEcdsaEncrypterManager = new RsaEcdsaEncrypterManager(senderSigningKey);
    }
    WebPushEncrypterManager webPushEncrypterManager = new WebPushEncrypterManager();
    // The {certificate, private key} pair to use for gRPC TLS.
    File tlsCertFile = new File(cmd.getOptionValue(TLS_CERT_PATH_OPTION));
    File tlsPrivateKeyFile = new File(cmd.getOptionValue(TLS_PRIVATE_KEY_PATH_OPTION));
    // The interface to demo SQLite DB.
    DemoDb db = new DemoDb(
        "jdbc:sqlite:" + cmd.getOptionValue(DATABASE_PATH_OPTION));
    // The demo service.
    BindableService demoService =
        new DemoServiceImpl(db, rsaEcdsaEncrypterManager, webPushEncrypterManager, fcmSender);
    // Create and start the gRPC server instance.
    server = ServerBuilder.forPort(port)
        .useTransportSecurity(tlsCertFile, tlsPrivateKeyFile)