public static void main(String[] args) {
		// Set up our router object, this is responsible for routing incoming
		// and outgoing messages
		router = new CommandRouter();
		try {
			// setup our socket connection to the tv, but don't connect yet
			conn = new Connection(HOST, PORT, router);

			// Tell out router which network connection to use
			router.setConnection(conn);

			// setup a handler for incoming GrantedSessionCommand message
			// objects
			try {
				router.registerCommandSubscriber(new ICommandSubscriber() {
					public void onCommandReceived(AbstractCommand command) {
						// Filter out the messages we care about
						if (command instanceof GrantedSessionCommand) {
							// Print our our unique key, this will be used for
							// subsequent connections
							Utilities.log("Your instanceId is " + ((GrantedSessionCommand) command).getInstanceId());


							try {
								//let's make the dock show up on the TV
								router.publishCommand(new NavigationInputCommand("press_yahoo"));

								Thread.sleep(2000); //sleep for 2 seconds so the animation to dock finishes

								// Lets do something cool, like tell the TV to navigate to the right. Then do a little dance
								// This is the same as pressing "right" on your remote
								router.publishCommand(new NavigationInputCommand("press_right"));

								Thread.sleep(1000);

								// slide to the left
								router.publishCommand(new NavigationInputCommand("press_left"));

								Thread.sleep(1000);

								//slide to the right
								router.publishCommand(new NavigationInputCommand("press_right"));

								Thread.sleep(1000);

								//take it back now, y'all
								router.publishCommand(new NavigationInputCommand("press_left"));

								//cha cha cha
								router.publishCommand(new NavigationInputCommand("press_up"));
								Thread.sleep(1000);
								router.publishCommand(new NavigationInputCommand("press_down"));
								Thread.sleep(1000);
								router.publishCommand(new NavigationInputCommand("press_up"));
								Thread.sleep(1000);
								router.publishCommand(new NavigationInputCommand("press_down"));
							} catch (InterruptedException e) {
								Utilities.log("Problem writing to the network connection");
								conn.close();
								System.exit(-1);
							}

							// Notify the main thread that everything we wanted to
							// do is done.
							synchronized (conn) {
								conn.notifyAll();
							}
						} else { // print out the others for educational purposes
							Utilities.log("Received: " + command.toString());
						}
					}

					public void onConnectionLost(Connection conn) {
						Utilities.log("Connection Lost!");
					}
				}, GrantedSessionCommand.class);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			try {
				// Establish a connection
				conn.establish();
				// Since this is the first time we are connecting, we must
				// create a new session
				router.publishCommand(new CreateSessionCommand(APP_ID, CONSUMER_KEY, SECRET, APP_NAME));

				String message = getUserInput("Code: ");
				router.publishCommand(new AuthSessionCommand(message, conn.getPeerCertificate()));

				// Let's wait until everything is done. This thread will get
				// notified once we are ready to clean up
				try {
					synchronized (conn) {
						conn.wait();
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			} catch (IOException ioe) {
				Utilities.log("Error establishing connection to " + HOST + ":" + PORT);
			} catch (InterruptedException e) {
				Utilities.log("Error establishing connection to " + HOST + ":" + PORT);
			}

			// It is always good practice to clean up after yourself
			conn.close();

		} catch (UnknownHostException e) {
			Utilities.log("Error resolving " + HOST);
			System.exit(-1);
		} catch (IOException e) {
			Utilities.log("Problem writing to the network connection");
			e.printStackTrace();
			System.exit(-1);
		}

		System.exit(1);
	}