class AdminTool {

    public void execute( Path homeDir, Path configDir, String... args )
    {
        try
        {
            if ( args.length == 0 )
            {
                badUsage( "you must provide a command" );
                return;
            }

            if ( Args.parse( args ).has( "version") )
            {
                outsideWorld.stdOutLine( "neo4j-admin " + neo4jVersion() );
                success();
                return;
            }

            String name = args[0];
            String[] commandArgs = Arrays.copyOfRange( args, 1, args.length );

            AdminCommand.Provider provider;
            try
            {
                provider = commandLocator.findProvider( name );
                for ( AdminCommand.Blocker blocker : blockerLocator.findBlockers( name ) )
                {
                    if ( blocker.doesBlock( homeDir, configDir ) )
                    {
                        commandFailed( new CommandFailed( blocker.explanation() ) );
                    }
                }
            }
            catch ( NoSuchElementException e )
            {
                badUsage( format( "unrecognized command: %s", name ) );
                return;
            }

            if ( provider == null )
            {
                badUsage( format( "unrecognized command: %s", name ) );
                return;
            }

            if ( Args.parse( commandArgs ).has( "help" ) )
            {
                outsideWorld.stdErrLine( "unknown argument: --help" );
                usage.printUsageForCommand( provider, outsideWorld::stdErrLine );
                failure();
            }
            else
            {
                AdminCommand command = provider.create( homeDir, configDir, outsideWorld );
                try
                {
                    command.execute( commandArgs );
                    success();
                }
                catch ( IncorrectUsage e )
                {
                    badUsage( provider, e );
                }
                catch ( CommandFailed e )
                {
                    commandFailed( e );
                }
            }
        }
        catch ( RuntimeException e )
        {
            unexpected( e );
        }
    }

    public  AdminTool( CommandLocator commandLocator, BlockerLocator blockerLocator, OutsideWorld outsideWorld,
            boolean debug );

}