class PushToCloudCommand implements AdminCommand {

    @Override
    public void execute( String[] args ) throws IncorrectUsage, CommandFailed
    {
        Args arguments = Args.parse( args );
        boolean verbose = arguments.getBoolean( ARG_VERBOSE );
        try
        {
            String passwordFromArg = arguments.get( ARG_PASSWORD );
            String username = arguments.get( ARG_USERNAME );

            String usernameFromEnv = System.getenv( ENV_USERNAME );
            String passwordFromEnv = System.getenv( ENV_PASSWORD );

            // the strategy here is to have a priority of ways to pass in username/password
            // 1. highest priority is cli argument, e.g. --username
            // 2. priority is the environment variable, e.g. ENV_USERNAME
            // if 1. and 2. is not configured, prompt for input.
            if ( username == null )
            {
                if ( usernameFromEnv != null )
                {
                    username = usernameFromEnv;
                }
                else
                {
                    username = outsideWorld.promptLine( "Neo4j Aura database username (default: neo4j): " );
                }
            }
            // default username to neo4j if user pressed 'enter' during the prompt
            if ( username == null || "".equals( username ) )
            {
                username = "neo4j";
            }

            char[] password;
            if ( passwordFromArg != null )
            {
                password = passwordFromArg.toCharArray();
            }
            else
            {
                if ( passwordFromEnv != null )
                {
                    password = passwordFromEnv.toCharArray();
                }
                else
                {
                    password = outsideWorld.promptPassword( format( "Neo4j Aura database password for %s: ", username ) );
                }
            }

            String boltURI = arguments.get( ARG_BOLT_URI );
            if ( boltURI == null || "".equals( boltURI ) )
            {
                boltURI = outsideWorld.promptLine( "Neo4j Aura database Bolt URI: " );
            }
            if ( boltURI == null || "".equals( boltURI ) )
            {
                throw new IncorrectUsage( "Please provide a Neo4j Aura Bolt URI of the target location to push the database to, " +
                        "using the --bolt-uri argument." );
            }
            String confirmationViaArgument = arguments.get( ARG_OVERWRITE, "false", "true" );

            String consoleURL = buildConsoleURI( boltURI );
            String bearerToken = copier.authenticate( verbose, consoleURL, username, password, "true".equals( confirmationViaArgument ) );

            Path source = initiateSource( arguments );
            // only mark dump to delete after processing, if we just created it
            boolean deleteDump = arguments.get( ARG_DUMP ) == null;

            copier.copy( verbose, consoleURL, boltURI, source, deleteDump, bearerToken );
        }
        catch ( Exception e )
        {
            if ( verbose )
            {
                outsideWorld.printStacktrace( e );
            }
            throw e;
        }
    }

    public  PushToCloudCommand( Path homeDir, Path configDir, OutsideWorld outsideWorld, Copier copier, DumpCreator dumpCreator );

}