diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..9fce87d
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,46 @@
+
+
+ 4.0.0
+
+ trololo
+ voter
+ 1.0-SNAPSHOT
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.1
+
+ 1.8
+ 1.8
+
+
+
+
+
+
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.2.2
+
+
+
+ com.google.guava
+ guava
+ 14.0.1
+
+
+
+ org.jsoup
+ jsoup
+ 1.7.2
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/voter/Something.java b/src/main/java/voter/Something.java
new file mode 100644
index 0000000..8ab20ac
--- /dev/null
+++ b/src/main/java/voter/Something.java
@@ -0,0 +1,337 @@
+package voter;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Splitter;
+import com.google.common.io.CharStreams;
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.message.BasicNameValuePair;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+
+import static com.google.common.collect.Maps.newHashMap;
+
+public class Something
+{
+ public static final String HTTP_2013_CONFITURA_PL_C4P_VOTING = "http://2013.confitura.pl/c4p/voting/";
+ private final String START_URL = "http://2013.confitura.pl/view/1/v4p";
+
+ private final Map persistentParams = newHashMap();
+ private final Configuration c = new Configuration();
+
+ private final DefaultHttpClient httpClient;
+ private InputCollector inputCollector;
+
+ Stack requestsToPerform = new Stack<>();
+
+ public static void main(String[] args) throws IOException
+ {
+ new Something().doSomething();
+ }
+
+ private void doSomething() throws IOException
+ {
+ initializeFlow();
+ executeFlow();
+ }
+
+ public Something() throws IOException
+ {
+ inputCollector = new InputCollector();
+ httpClient = new DefaultHttpClient();
+ }
+
+ private void initializeFlow()
+ {
+ HttpGet get = new HttpGet(START_URL);
+ requestsToPerform.push(get);
+ }
+
+ void executeFlow() throws IOException
+ {
+ while (true)
+ {
+ if (requestsToPerform.isEmpty())
+ {
+ return;
+ }
+
+ HttpUriRequest request = requestsToPerform.pop();
+ HttpResponse response = httpClient.execute(request);
+
+ Map headers = logHeaders(response);
+
+ String html = readHtml(response);
+ Document document = Jsoup.parse(html);
+ Elements metas = document.select("meta");
+ if (foundRedirects(metas, headers))
+ {
+ continue;
+ }
+
+ Elements form = document.getElementsByTag("form");
+ if (form.isEmpty())
+ {
+ continue;
+ }
+
+ Vote vote = figureOutContent(document.getElementById("page"));
+ simulateVoting(form, vote);
+ }
+ }
+
+ private Vote figureOutContent(Element page) throws IOException
+ {
+ String author = page.getElementsByTag("h3").first().text();
+ String title = page.getElementsByTag("h2").first().text();
+ String text = page.getElementsByAttributeValue("class", "accordion").text();
+
+ return decide(author, title, text);
+ }
+
+ private Vote decide(String author, String title, String text) throws IOException
+ {
+ if (shouldNotBeAccepted(author))
+ {
+ System.out.println(String.format("Short circuiting %s out", author));
+ return Vote.NO_WAY;
+ }
+
+ if (shouldBeAccepted(author))
+ {
+ System.out.println(String.format("Yes, we want %s", author));
+ return Vote.YES;
+ }
+
+ System.out.println("--------------------------------");
+ System.out.println(author);
+ System.out.println(title);
+ System.out.println(Joiner.on("\n").join(Splitter.fixedLength(80).split(text)));
+ System.out.println("--------------------------------");
+
+ Vote vote = inputCollector.collect();
+ System.out.println(String.format("author %s got %s", author, vote));
+ return vote;
+ }
+
+ private boolean shouldBeAccepted(String author)
+ {
+ String[] likeList = new String[]{
+ "Sobótka", "Lawrey", "Margiel"
+ };
+ for (String name : likeList)
+ {
+ if (author.contains(name))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean shouldNotBeAccepted(String author)
+ {
+ String[] hateList = new String[]{
+ // you wish
+ };
+
+ for (String name : hateList)
+ {
+ if (author.contains(name))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void simulateVoting(Elements form, Vote vote) throws UnsupportedEncodingException
+ {
+ List nvps = new ArrayList<>();
+
+ for (Element input : form.select("input"))
+ {
+ if ("hidden".equals(input.attr("type")))
+ {
+ nvps.add(new BasicNameValuePair(input.attr("id"), ""));
+ break;
+ }
+ }
+
+ Map votes = optionsForVotes(form);
+ nvps.add(votes.get(vote));
+
+ String action = form.attr("action");
+ String url = HTTP_2013_CONFITURA_PL_C4P_VOTING + action;
+ HttpPost post = new HttpPost(url);
+ post.setEntity(new UrlEncodedFormEntity(nvps));
+ requestsToPerform.push(post);
+ }
+
+ private Map optionsForVotes(Elements form)
+ {
+ Map votes = newHashMap();
+ for (Element label : form.select("label"))
+ {
+ String text = label.text().toLowerCase();
+ if (text.contains("nie interesuje mnie"))
+ {
+ Element input = label.select("input").first();
+ votes.put(Vote.NO_WAY, new BasicNameValuePair(input.attr("name"), input.val()));
+ }
+ if (text.contains("jeszcze nie wiem"))
+ {
+ Element input = label.select("input").first();
+ votes.put(Vote.MEH, new BasicNameValuePair(input.attr("name"), input.val()));
+ }
+ if (text.contains("chcę zobaczyć"))
+ {
+ Element input = label.select("input").first();
+ votes.put(Vote.YES, new BasicNameValuePair(input.attr("name"), input.val()));
+ }
+ }
+ return votes;
+ }
+
+ private boolean foundRedirects(Elements metas, Map headers) throws IOException
+ {
+ String newUrl = lookForRedirects(metas, headers);
+ if (newUrl.equals(START_URL))
+ {
+ return false;
+ }
+
+ HttpGet httpGet = new HttpGet(newUrl);
+ addPersistentHeaders(httpGet);
+ requestsToPerform.push(httpGet);
+ return true;
+ }
+
+ private void addPersistentHeaders(HttpGet httpGet)
+ {
+ for (Map.Entry entry : persistentParams.entrySet())
+ {
+ httpGet.setHeader(entry.getKey(), entry.getValue());
+ }
+ }
+
+ private String readHtml(HttpResponse response) throws IOException
+ {
+ HttpEntity entity = response.getEntity();
+ InputStream content = entity.getContent();
+ List strings = CharStreams.readLines(new InputStreamReader(content));
+ return Joiner.on("\n").join(strings);
+ }
+
+ private String lookForRedirects(Elements metas, Map headers)
+ {
+ for (Map.Entry header : headers.entrySet())
+ {
+ if ("Location".equalsIgnoreCase(header.getKey()))
+ {
+ String url = header.getValue();
+ System.out.println("Redirecting to: " + url);
+ return url;
+ }
+ }
+ for (Element meta : metas)
+ {
+ if ("REFRESH".equals(meta.attr("http-equiv")))
+ {
+ String content = meta.attr("content");
+ String url = content.substring(content.indexOf("url=") + 4);
+ System.out.println("Redirecting to: " + url);
+ return url;
+ }
+ }
+ return START_URL;
+ }
+
+ private Map logHeaders(HttpResponse response)
+ {
+ Map headers = newHashMap();
+ Header[] allHeaders = response.getAllHeaders();
+ for (Header header : allHeaders)
+ {
+ String name = header.getName();
+ String value = header.getValue();
+ if (name.equals("Set-Cookie"))
+ {
+ persistentParams.put(name, value.substring(value.indexOf(";")));
+ }
+ if (c.shouldPrintHeaders())
+ {
+ System.out.println(name + " " + value);
+ }
+ headers.put(name, value);
+ }
+
+ return headers;
+ }
+}
+
+class Configuration
+{
+ boolean shouldPrintHeaders()
+ {
+ return false;
+ }
+}
+
+enum Vote
+{
+ YES, MEH, NO_WAY;
+}
+
+class InputCollector
+{
+ private final BufferedReader reader;
+
+ InputCollector()
+ {
+ reader = new BufferedReader(new InputStreamReader(System.in));
+ }
+
+ public Vote collect() throws IOException
+ {
+ System.out.println("Z\tX\tC");
+ System.out.println("-1\t0\t+1");
+
+ while (true)
+ {
+ String line = reader.readLine();
+
+ if (line.trim().equalsIgnoreCase("C"))
+ {
+ return Vote.YES;
+ }
+ if (line.trim().equalsIgnoreCase("X"))
+ {
+ return Vote.MEH;
+ }
+ if (line.trim().equalsIgnoreCase("Z"))
+ {
+ return Vote.NO_WAY;
+ }
+ }
+ }
+}
\ No newline at end of file