class BridgeSupport {

    public Integer voteFederationChange(Transaction tx, ABICallSpec callSpec) {
        // Must be on one of the allowed functions
        if (!FEDERATION_CHANGE_FUNCTIONS.contains(callSpec.getFunction())) {
            return FEDERATION_CHANGE_GENERIC_ERROR_CODE;
        }

        AddressBasedAuthorizer authorizer = bridgeConstants.getFederationChangeAuthorizer();

        // Must be authorized to vote (checking for signature)
        if (!authorizer.isAuthorized(tx)) {
            return FEDERATION_CHANGE_GENERIC_ERROR_CODE;
        }

        // Try to do a dry-run and only register the vote if the
        // call would be successful
        ABICallVoteResult result;
        try {
            result = executeVoteFederationChangeFunction(true, callSpec);
        } catch (IOException e) {
            result = new ABICallVoteResult(false, FEDERATION_CHANGE_GENERIC_ERROR_CODE);
        } catch (BridgeIllegalArgumentException e) {
            result = new ABICallVoteResult(false, FEDERATION_CHANGE_GENERIC_ERROR_CODE);
        }

        // Return if the dry run failed or we are on a reversible execution
        if (!result.wasSuccessful()) {
            return (Integer) result.getResult();
        }

        ABICallElection election = provider.getFederationElection(authorizer);
        // Register the vote. It is expected to succeed, since all previous checks succeeded
        if (!election.vote(callSpec, tx.getSender())) {
            logger.warn("Unexpected federation change vote failure");
            return FEDERATION_CHANGE_GENERIC_ERROR_CODE;
        }

        // If enough votes have been reached, then actually execute the function
        ABICallSpec winnerSpec = election.getWinner();
        if (winnerSpec != null) {
            try {
                result = executeVoteFederationChangeFunction(false, winnerSpec);
            } catch (IOException e) {
                logger.warn("Unexpected federation change vote exception: {}", e.getMessage());
                return FEDERATION_CHANGE_GENERIC_ERROR_CODE;
            } finally {
                // Clear the winner so that we don't repeat ourselves
                election.clearWinners();
            }
        }

        return (Integer) result.getResult();
    }

    public  BridgeSupport(
            UscSystemProperties config,
            Repository repository,
            BridgeEventLogger eventLogger,
            BridgeConstants bridgeConstants,
            BridgeStorageProvider provider,
            UldBlockstoreWithCache uldBlockStore,
            UldBlockChain uldBlockChain,
            Block executionBlock);
    public  BridgeSupport(
            UscSystemProperties config,
            Repository repository,
            BridgeEventLogger eventLogger,
            UscAddress contractAddress,
            Block uscExecutionBlock);
    public  BridgeSupport(
            UscSystemProperties config,
            Repository repository,
            BridgeEventLogger eventLogger,
            BridgeStorageProvider provider,
            Block uscExecutionBlock);
    private  BridgeSupport(
            Repository repository,
            BridgeStorageProvider provider,
            Block executionBlock,
            UscSystemProperties config,
            BridgeConstants bridgeConstants,
            BridgeEventLogger eventLogger,
            Context uldContext,
            UldBlockstoreWithCache uldBlockStore,
            UldBlockChain uldBlockChain);
    public  BridgeSupport(
            Repository repository,
            BridgeStorageProvider provider,
            Block executionBlock,
            UscSystemProperties config,
            BridgeConstants bridgeConstants,
            BridgeEventLogger eventLogger,
            Context uldContext,
            FederationSupport federationSupport,
            UldBlockstoreWithCache uldBlockStore,
            UldBlockChain uldBlockChain);

}