content: 
  property vpn_names : {}
  property application_ : ""
  
  on run
  	local result_
  	set vpn_names to get_vpn_names()
  	
  	if (count of vpn_names) is 0 then
  		log "No applications running"
  		set result_ to {}
  		
  		repeat with app_ in {"com.feingeist.Shimo", "com.viscosityvpn.Viscosity", "net.tunnelblick.tunnelblick"}
  			set path_to_app to find_application(app_)
  			log "Path " & app_ & ":" & |path| of path_to_app
  			if path_to_app is not equal to null then set end of result_ to path_to_app
  		end repeat
  		
  		set end of result_ to {title:"No VPN application running.", icon:"NotFound.icns"}
  		return result_
  	else
  		set result_ to parse_name_and_state(vpn_names)
  		
  		-- First sort by the name, then by connection state.
  		customBubbleSort(result_, byName)
  		customBubbleSort(result_, byState)
  		return result_
  	end if
  	
  	return {title:"Something wrong happened... Stupid machine. :(", subtitle:"Enter to create issue on GitHub", |url|:"https://github.com/hlissner/lb6-actions/issues"}
  end run
  
  (* Not required
  
  on handle_string(_string)
  	return [{title:"1 string passed"}, {title:_string}]
  end handle_string
  *)
  
  -- Handles the VPN item passed to script according to app and state.
  on run_with_vpn(the_vpn_item)
  	local result_
  	copy the_vpn_item to result_
  	
  	log "Running for account: " & title of the_vpn_item & " application: " & badge of the_vpn_item
  	-- Select the appropriate application, and then connect or diconnect accroding to the state
  	if (badge of the_vpn_item) is equal to "Shimo" then
  		tell application "Shimo"
  			set bool_state to (connected of every account where name is equal to (title of the_vpn_item)) as boolean
  			
  			if bool_state is false then
  				connect account (title of the_vpn_item)
  			else
  				disconnect account (title of the_vpn_item)
  				delay 0.1
  			end if
  			set bool_state to (connected of every account where name is equal to (title of the_vpn_item))
  			tell me to set state_ to is_connected(bool_state)
  		end tell
  	else if (badge of the_vpn_item) is equal to "Viscosity" then
  		tell application "Viscosity"
  			set state_ to (state of connections where name is equal to (title of the_vpn_item)) as text
  			if state_ is equal to "Disconnected" then
  				connect (title of the_vpn_item)
  			else
  				disconnect (title of the_vpn_item)
  				delay 0.1
  			end if
  			set state_ to (state of connections where name is equal to (title of the_vpn_item)) as text
  		end tell
  	else if (badge of the_vpn_item) is equal to "Tunnelblick" then
  		tell application "Tunnelblick"
  			set state_ to (state of configurations where name is equal to (title of the_vpn_item)) as text
  			if state_ is "EXITING" then
  				connect (title of the_vpn_item)
  			else
  				disconnect (title of the_vpn_item)
  				delay 0.1
  			end if
  			set state_ to (state of configurations where name is equal to (title of the_vpn_item)) as text
  		end tell
  	end if
  	
  	set subtitle of result_ to state_
  	log result_
  	tell application "LaunchBar" to hide
  	return result_
  end run_with_vpn
  
  -- Gets the VPN names from the running application, and set the global property to the application.
  on get_vpn_names()
  	local result_
  	set result_ to {}
  	
  	if application "Shimo" is running then
  		tell application "Shimo"
  			set result_ to name of every account
  			set application_ to "Shimo"
  		end tell
  	else if application "Viscosity" is running then
  		tell application "Viscosity"
  			set result_ to name of connections
  			set application_ to "Viscosity"
  		end tell
  	else if application "Tunnelblick" is running then
  		tell application "Tunnelblick"
  			set result_ to name of configurations
  			set application_ to "Tunnelblick"
  		end tell
  	end if
  	log "No. of VPN accounts found: " & (count of result_)
  	
  	return result_
  end get_vpn_names
  
  -- Parses the VPN and it's repective state in a JSON format to return to LaunchBar.
  -- Also adds the action to run when the vpn is selected by the user.
  -- actionRunsInBackground: true/false
  on parse_name_and_state(names_)
  	local result_
  	set result_ to {}
  	
  	if application_ is "Shimo" then
  		repeat with vpn_name in names_
  			tell application "Shimo"
  				local bool_state
  				set bool_state to (connected of every account where name is equal to vpn_name) as string
  				tell me to set state_ to is_connected(bool_state)
  				set end of result_ to {title:vpn_name as text, subtitle:state_, badge:application_, alwaysShowSubtitle:true, action:"run_with_vpn", actionRunsInBackground:true}
  			end tell
  		end repeat
  	else if application_ is "Viscosity" then
  		repeat with vpn_name in names_
  			tell application "Viscosity"
  				set state_ to (state of connections where name is equal to vpn_name) as text
  				set end of result_ to {title:vpn_name as text, subtitle:state_, badge:"Viscosity", alwaysShowsSubtitle:true, action:"run_with_vpn", actionRunsInBackground:true}
  			end tell
  		end repeat
  	else if application_ is "Tunnelblick" then
  		repeat with vpn_name in names_
  			tell application "Tunnelblick"
  				set state_ to (state of configurations where name is equal to vpn_name) as text
  				set end of result_ to {title:vpn_name as text, subtitle:state_, badge:"Tunnelblick", alwaysShowsSubtitle:true, action:"run_with_vpn", actionRunsInBackground:true}
  			end tell
  		end repeat
  	end if
  	
  	return result_
  end parse_name_and_state
  
  on is_connected(_state)
  	
  	if _state is "true" then
  		set result_ to "Connected"
  	else
  		set result_ to "Disconnected"
  	end if
  	
  	return result_
  end is_connected
  
  -- Checks if application exits and return path to it.
  on find_application(bundle_identifier)
  	try
  		tell application "Finder"
  			set path_to_app to POSIX path of (application file id bundle_identifier as alias) as text
  			return {|path|:path_to_app}
  		end tell
  	on error err_msg number err_num
  		return null
  	end try
  end find_application
  
  -- Sort so that the connected VPN's are on the top.
  -- Thanks to Nigel Garvey for this idea on Mac Scripter. 
  -- Link to post: http://macscripter.net/viewtopic.php?pid=130910#p130910
  on customBubbleSort(thelist, compObj)
  	script o
  		property lst : thelist
  	end script
  	
  	repeat with i from (count thelist) to 2 by -1
  		set a to beginning of o's lst
  		repeat with j from 2 to i
  			set b to item j of o's lst
  			if (compObj's isGreater(a, b)) then
  				set item (j - 1) of o's lst to b
  				set item j of o's lst to a
  			else
  				set a to b
  			end if
  		end repeat
  	end repeat
  end customBubbleSort
  
  script byState
  	on isGreater(a, b)
  		(a's subtitle > b's subtitle)
  	end isGreater
  end script
  
  script byName
  	on isGreater(a, b)
  		(a's title > b's title)
  	end isGreater
  end script
  