Index: src/hulu/cz/vity/freerapid/plugins/services/hulu/HuluSettingsConfig.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/hulu/cz/vity/freerapid/plugins/services/hulu/HuluSettingsConfig.java	(revision 4224)
+++ src/hulu/cz/vity/freerapid/plugins/services/hulu/HuluSettingsConfig.java	(revision )
@@ -2,32 +2,19 @@
 
 /**
  * @author tong2shot
+ * @author ntoskrnl
  */
 public class HuluSettingsConfig {
+
     private String username;
     private String password;
-    private int qualityHeightIndex;
-    private int videoFormatIndex;
-    private int cdnIndex;
-    private int portIndex;
+    private VideoQuality videoQuality;
 
-    public static final int MIN_HEIGHT = -2;
-    public static final int MAX_HEIGHT = -1;
-    public static final int MIN_HEIGHT_INDEX = 0;
-    public static final int MAX_HEIGHT_INDEX = 10;
-    public static final int ANY_VIDEO_FORMAT = 0;
-
-    private final int[] qualityHeightMap = {MIN_HEIGHT, 240, 360, 480, MAX_HEIGHT}; //map of qualityHeight
-    private final static int[] qualityHeightIndexMap = {MIN_HEIGHT_INDEX, 1, 2, 3, MAX_HEIGHT_INDEX}; //map of qualityHeightIndex, to anticipate higher quality (576,720,1080,2160,4320,etc) in the future
-    private final String[] videoFormatMap = {"Any", "h264", "vp6"};
-    private final String[] cdnMap = {"akamai", "limelight", "level3"};
-    private final int[] portMap = {1935, 80};
-
     public String getUsername() {
         return username;
     }
 
-    public void setUsername(String username) {
+    public void setUsername(final String username) {
         this.username = username;
     }
 
@@ -35,60 +22,16 @@
         return password;
     }
 
-    public void setPassword(String password) {
+    public void setPassword(final String password) {
         this.password = password;
     }
 
-    public int getQualityHeightIndex() {
-        return qualityHeightIndex;
+    public VideoQuality getVideoQuality() {
+        return videoQuality;
     }
 
-    public void setQualityHeightIndex(int qualityHeightIndex) {
-        this.qualityHeightIndex = qualityHeightIndex;
-    }
-
-    public int getVideoFormatIndex() {
-        return videoFormatIndex;
-    }
-
-    public void setVideoFormatIndex(int videoFormatIndex) {
-        this.videoFormatIndex = videoFormatIndex;
-    }
-
-    public int getPortIndex() {
-        return portIndex;
-    }
-
-    public void setPortIndex(int portIndex) {
-        this.portIndex = portIndex;
-    }
-
-    public int getCdnIndex() {
-        return cdnIndex;
-    }
-
-    public void setCdnIndex(int cdnIndex) {
-        this.cdnIndex = cdnIndex;
-    }
-
-    public int getQualityHeight() {
-        for (int i = 0; i < qualityHeightIndexMap.length; i++) {
-            if (qualityHeightIndexMap[i] == qualityHeightIndex)
-                return qualityHeightMap[i];
-        }
-        return MAX_HEIGHT; //default, the highest
-    }
-
-    public String getVideoFormat() {
-        return videoFormatMap[videoFormatIndex];
-    }
-
-    public String getCdn() {
-        return cdnMap[cdnIndex];
-    }
-
-    public int getPort() {
-        return portMap[portIndex];
+    public void setVideoQuality(final VideoQuality videoQuality) {
+        this.videoQuality = videoQuality;
     }
 
 }
Index: src/hulu/cz/vity/freerapid/plugins/services/hulu/VideoQuality.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/hulu/cz/vity/freerapid/plugins/services/hulu/VideoQuality.java	(revision )
+++ src/hulu/cz/vity/freerapid/plugins/services/hulu/VideoQuality.java	(revision )
@@ -0,0 +1,58 @@
+package cz.vity.freerapid.plugins.services.hulu;
+
+import cz.vity.freerapid.plugins.exceptions.PluginImplementationException;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+/**
+ * @author ntoskrnl
+ */
+public enum VideoQuality {
+
+    MINIMUM("Lowest available"),
+    _288("288p"),
+    _360("360p"),
+    _400("400p"),
+    _480("480p"),
+    _720("720p"),
+    _1080("1080p"),
+    MAXIMUM("Highest available");
+
+    private final String string;
+
+    private VideoQuality(final String string) {
+        this.string = string;
+    }
+
+    @Override
+    public String toString() {
+        return string;
+    }
+
+    public static VideoQuality parse(final int height) throws PluginImplementationException {
+        switch (height) {
+            case 288:
+                return _288;
+            case 360:
+                return _360;
+            case 400:
+                return _400;
+            case 480:
+                return _480;
+            case 720:
+                return _720;
+            case 1080:
+                return _1080;
+            default:
+                throw new PluginImplementationException("Unknown video quality: " + height);
+        }
+    }
+
+    public static VideoQuality[] getItems() {
+        final VideoQuality[] qualities = values();
+        Arrays.sort(qualities, Collections.reverseOrder());
+        return qualities;
+    }
+
+}
Index: src/hulu/cz/vity/freerapid/plugins/services/hulu/HuluSettingsPanel.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/hulu/cz/vity/freerapid/plugins/services/hulu/HuluSettingsPanel.java	(revision 4224)
+++ src/hulu/cz/vity/freerapid/plugins/services/hulu/HuluSettingsPanel.java	(revision )
@@ -4,134 +4,75 @@
 import java.awt.*;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
+import java.awt.event.FocusAdapter;
 import java.awt.event.FocusEvent;
-import java.awt.event.FocusListener;
 
 /**
  * @author tong2shot
+ * @author ntoskrnl
  */
-public class HuluSettingsPanel extends JPanel {
-    private HuluSettingsConfig config;
-    private final static String[] qualityStrings = {"Highest available", "480p", "360p", "240p", "Lowest available"};
-    private final static int[] qualityIndexMap = {HuluSettingsConfig.MAX_HEIGHT_INDEX, 3, 2, 1, HuluSettingsConfig.MIN_HEIGHT_INDEX}; //to anticipate higher quality (576,720,1080,2160,4320,etc) in the future
-    private final static String[] videoFormatStrings = {"Any video format", "H264", "VP6"};
-    private final static String[] cdnStrings = {"Akamai", "Limelight", "Level3"};
-    private final static String[] portStrings = {"1935", "80"};
+class HuluSettingsPanel extends JPanel {
 
+    private final HuluSettingsConfig config;
 
-    public HuluSettingsPanel(HuluServiceImpl service) throws Exception {
-        super();
+    public HuluSettingsPanel(final HuluServiceImpl service) throws Exception {
         config = service.getConfig();
         initPanel();
     }
 
     private void initPanel() {
-        final JLabel lblUsername = new JLabel("Email address:");
-        final JTextField txtfldUsername = new JTextField(40);
-        final JLabel lblPassword = new JLabel("Password:");
-        final JPasswordField pswdfldPassword = new JPasswordField(40);
-        final JLabel lblQuality = new JLabel("Preferred quality level:");
-        final JComboBox cbbQuality = new JComboBox(qualityStrings);
-        final JLabel lblVideoFormat = new JLabel("Preferred video format:");
-        final JComboBox cbbVideoFormat = new JComboBox(videoFormatStrings);
-        final JLabel lblCdn = new JLabel("Preferred CDN:");
-        final JComboBox cbbCdn = new JComboBox(cdnStrings);
-        final JLabel lblPort = new JLabel("Preferred RTMP port:");
-        final JComboBox cbbPort = new JComboBox(portStrings);
+        final JLabel labelUsername = new JLabel("Email address:");
+        final JTextField fieldUsername = new JTextField();
+        final JLabel labelPassword = new JLabel("Password");
+        final JPasswordField fieldPassword = new JPasswordField();
+        final JLabel labelVideoQuality = new JLabel("Preferred video quality:");
+        final JComboBox comboVideoQuality = new JComboBox(VideoQuality.getItems());
 
-        lblUsername.setAlignmentX(Component.LEFT_ALIGNMENT);
-        txtfldUsername.setAlignmentX(Component.LEFT_ALIGNMENT);
-        lblPassword.setAlignmentX(Component.LEFT_ALIGNMENT);
-        pswdfldPassword.setAlignmentX(Component.LEFT_ALIGNMENT);
-        lblQuality.setAlignmentX(Component.LEFT_ALIGNMENT);
-        cbbQuality.setAlignmentX(Component.LEFT_ALIGNMENT);
-        lblVideoFormat.setAlignmentX(Component.LEFT_ALIGNMENT);
-        cbbVideoFormat.setAlignmentX(Component.LEFT_ALIGNMENT);
-        lblCdn.setAlignmentX(Component.LEFT_ALIGNMENT);
-        cbbCdn.setAlignmentX(Component.LEFT_ALIGNMENT);
-        lblPort.setAlignmentX(Component.LEFT_ALIGNMENT);
-        cbbPort.setAlignmentX(Component.LEFT_ALIGNMENT);
+        labelUsername.setLabelFor(fieldUsername);
+        labelPassword.setLabelFor(fieldPassword);
+        labelVideoQuality.setLabelFor(labelVideoQuality);
 
-        txtfldUsername.setText(config.getUsername());
-        pswdfldPassword.setText(config.getPassword());
-        int qs = config.getQualityHeightIndex();
-        for (int i = 0; i < qualityIndexMap.length; i++) {
-            if (qualityIndexMap[i] == qs) {
-                cbbQuality.setSelectedIndex(i);
-                break;
-            }
-        }
-        cbbVideoFormat.setSelectedIndex(config.getVideoFormatIndex());
-        cbbCdn.setSelectedIndex(config.getCdnIndex());
-        cbbPort.setSelectedIndex(config.getPortIndex());
+        labelUsername.setAlignmentX(Component.LEFT_ALIGNMENT);
+        fieldUsername.setAlignmentX(Component.LEFT_ALIGNMENT);
+        labelPassword.setAlignmentX(Component.LEFT_ALIGNMENT);
+        fieldPassword.setAlignmentX(Component.LEFT_ALIGNMENT);
+        labelVideoQuality.setAlignmentX(Component.LEFT_ALIGNMENT);
+        comboVideoQuality.setAlignmentX(Component.LEFT_ALIGNMENT);
 
-        txtfldUsername.addFocusListener(new FocusListener() {
-            @Override
-            public void focusGained(FocusEvent e) {
-                //
-            }
+        fieldUsername.setText(config.getUsername());
+        fieldPassword.setText(config.getPassword());
+        comboVideoQuality.setSelectedItem(config.getVideoQuality());
 
+        fieldUsername.addFocusListener(new FocusAdapter() {
             @Override
             public void focusLost(FocusEvent e) {
-                config.setUsername(txtfldUsername.getText().trim().isEmpty() ? null : txtfldUsername.getText());
+                config.setUsername(fieldUsername.getText().trim().isEmpty() ? null : fieldUsername.getText());
             }
         });
-
-        pswdfldPassword.addFocusListener(new FocusListener() {
+        fieldPassword.addFocusListener(new FocusAdapter() {
             @Override
-            public void focusGained(FocusEvent e) {
-                //
-            }
-
-            @Override
             public void focusLost(FocusEvent e) {
-                config.setPassword((pswdfldPassword.getPassword().length == 0) ? null : new String(pswdfldPassword.getPassword()));
+                config.setPassword((fieldPassword.getPassword().length == 0) ? null : new String(fieldPassword.getPassword()));
             }
         });
-
-        cbbQuality.addActionListener(new ActionListener() {
+        comboVideoQuality.addActionListener(new ActionListener() {
             @Override
             public void actionPerformed(ActionEvent e) {
-                config.setQualityHeightIndex(qualityIndexMap[cbbQuality.getSelectedIndex()]);
+                config.setVideoQuality((VideoQuality) comboVideoQuality.getSelectedItem());
             }
         });
 
-        cbbVideoFormat.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                config.setVideoFormatIndex(cbbVideoFormat.getSelectedIndex());
-            }
-        });
-
-        cbbCdn.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                config.setCdnIndex(cbbCdn.getSelectedIndex());
-            }
-        });
-
-        cbbPort.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                config.setPortIndex(cbbPort.getSelectedIndex());
-            }
-        });
-
-        this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
-        add(lblUsername);
-        add(txtfldUsername);
-        add(lblPassword);
-        add(pswdfldPassword);
-        add(lblQuality);
-        add(cbbQuality);
-        add(lblVideoFormat);
-        add(cbbVideoFormat);
-        add(lblCdn);
-        add(cbbCdn);
-        add(lblPort);
-        add(cbbPort);
-        add(Box.createRigidArea(new Dimension(0, 15)));
+        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+        add(labelUsername);
+        add(fieldUsername);
+        add(Box.createRigidArea(new Dimension(0, 5)));
+        add(labelPassword);
+        add(fieldPassword);
+        add(Box.createRigidArea(new Dimension(0, 10)));
+        add(labelVideoQuality);
+        add(comboVideoQuality);
+        add(Box.createRigidArea(new Dimension(0, 10)));
         setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
-
     }
+
 }
Index: src/hulu/cz/vity/freerapid/plugins/services/hulu/HuluFileRunner.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/hulu/cz/vity/freerapid/plugins/services/hulu/HuluFileRunner.java	(revision 4224)
+++ src/hulu/cz/vity/freerapid/plugins/services/hulu/HuluFileRunner.java	(revision )
@@ -45,7 +45,6 @@
     private final static String DECRYPT_IV = "27b9bedf75ccA2eC";
     private final static String SUBTITLE_DECRYPT_KEY = "4878b22e76379b55c962b18ddbc188d82299f8f52e3e698d0faf29a40ed64b21";
     private final static String SUBTITLE_DECRYPT_IV = "WA7hap7AGUkevuth";
-    private final static int LOWER_QUALITY_PENALTY = 1; //change this to 10 if prefer nearest higher
 
     private final String sessionId = getSessionId();
 
@@ -53,18 +52,15 @@
     private boolean hasSubtitle = false;
     private HuluSettingsConfig config;
 
-
     private void setConfig() throws Exception {
         final HuluServiceImpl service = (HuluServiceImpl) getPluginService();
         config = service.getConfig();
     }
 
-
     @Override
     public void runCheck() throws Exception {
         super.runCheck();
         if (isSubtitle()) return;
-        checkUrl();
         final HttpMethod method = getGetMethod(fileURL);
         //Server sometimes sends a 404 response
         makeRedirectedRequest(method);
@@ -121,7 +117,6 @@
             processSubtitle();
             return;
         }
-        checkUrl();
         logger.info("Starting download in TASK " + fileURL);
         setConfig();
         login();
@@ -178,10 +173,6 @@
         }
     }
 
-    private void checkUrl() {
-        fileURL = fileURL.replaceFirst("//(www\\.)?hulu\\.com", "//new.hulu.com");
-    }
-
     private void checkProblems(final String content) throws ErrorDuringDownloadingException {
         if (content.contains("The page you were looking for doesn't exist")
                 || content.contains("This content is unavailable for playback")) {
@@ -196,114 +187,42 @@
     }
 
     private RtmpSession getStream(final String content) throws ErrorDuringDownloadingException {
-        final Matcher matcher = PlugUtils.matcher("<video server=\"(.+?)\" stream=\"(.+?)\" token=\"(.+?)\" system-bitrate=\"(\\d+?)\".*? height=\"(\\d+?)\".*? file-type=\"\\d+_(.+?)\".*? cdn=\"(.+?)\"", content);
+        final Matcher matcher = PlugUtils.matcher("<video server=\"(.+?)\" stream=\"(.+?)\" token=\"(.+?)\".*? height=\"(\\d+?)\".*? cdn=\"(.+?)\"", content);
         final List<Stream> list = new LinkedList<Stream>();
         while (matcher.find()) {
-            final String cdn = matcher.group(7);
-            list.add(new Stream(matcher.group(1), matcher.group(2), matcher.group(3), Integer.parseInt(matcher.group(4)), Integer.parseInt(matcher.group(5)), matcher.group(6), cdn));
+            if (!"akamai".equals(matcher.group(5))) {
+                logger.info("Ignoring stream not served by Akamai");
+            } else {
+                list.add(new Stream(matcher.group(1), matcher.group(2), matcher.group(3), Integer.parseInt(matcher.group(4))));
-        }
+            }
+        }
         if (list.isEmpty()) {
             throw new PluginImplementationException("No streams found");
         }
-        calcStreamWeight(list);
-        final Stream selectedStream = Collections.max(list);
-        logger.info("Selected stream : " + selectedStream);
-        return selectedStream.getSession();
+        Collections.sort(list);
+        Stream stream;
+        final ListIterator<Stream> it = list.listIterator(list.size());
+        do {
+            stream = it.previous();
+            if (stream.getVideoQuality().compareTo(config.getVideoQuality()) < 0) {
+                if (it.nextIndex() + 1 < list.size()) {
+                    stream = list.get(it.nextIndex() + 1);
-    }
+                }
-
-    private void calcStreamWeight(List<Stream> streamList) {
-        //get the concrete configHeight
-        int configHeightMin = Integer.MAX_VALUE;
-        int configHeightMax = Integer.MIN_VALUE;
-        for (Stream stream : streamList) {
-            if (stream.height < configHeightMin) configHeightMin = stream.height;
-            if (stream.height > configHeightMax) configHeightMax = stream.height;
+                break;
-        }
+            }
-        final int configHeight;
-        if (config.getQualityHeight() == HuluSettingsConfig.MAX_HEIGHT) {
-            configHeight = configHeightMax;
-            logger.info("Config height : the highest available (" + configHeight + ")");
-        } else if (config.getQualityHeight() == HuluSettingsConfig.MIN_HEIGHT) {
-            configHeight = configHeightMin;
-            logger.info("Config height : the lowest available (" + configHeight + ")");
-        } else {
-            configHeight = config.getQualityHeight();
-            logger.info("Config height : " + configHeight);
-        }
+        } while (it.hasPrevious());
 
-        //calc height weight
-        //if the same height (quality) doesn't exist, prefer the neareast one (higher or lower doesn't matter).
-        float heightWeightMax = Float.MIN_VALUE;
-        int selectedHeight = configHeight; //pick any value for initialization, will be changed right away anyway
-        for (Stream stream : streamList) {
-            final int heightDiff = stream.height - configHeight;
-            float heightWeight;
-            if (heightDiff == 0) //same height (quality)
-                heightWeight = 1.0f;
-            else if (heightDiff < 0) //lower
-                heightWeight = (1.0f / (Math.abs(heightDiff) * LOWER_QUALITY_PENALTY));
-            else //higher
-                heightWeight = (1.0f / heightDiff);
-            heightWeight *= 100000;
-            stream.heightWeight = heightWeight;
-            if (heightWeight > heightWeightMax) {
-                heightWeightMax = heightWeight;
-                selectedHeight = stream.height;
+        return stream.getSession();
-            }
+    }
-        }
-        logger.info("Selected height : " + selectedHeight);
 
-        //calc video format weight
-        logger.info("Config video format : " + config.getVideoFormat());
-        if (config.getVideoFormatIndex() != HuluSettingsConfig.ANY_VIDEO_FORMAT) {
-            for (Stream stream : streamList) {
-                float videoFormatWeight = 0f;
-                if (stream.height == selectedHeight) {
-                    //same video format > h264 > vp6
-                    if (stream.videoFormat.equals(config.getVideoFormat()))
-                        videoFormatWeight = 50f;
-                    else if (stream.videoFormat.equals("h264"))
-                        videoFormatWeight = 10f;
-                    else if (stream.videoFormat.equals("vp6"))
-                        videoFormatWeight = 5f;
-                }
-                stream.videoFormatWeight = videoFormatWeight;
-            }
-        }
-
-        //calc cdn weight and total weight
-        logger.info("Config cdn : " + config.getCdn());
-        for (Stream stream : streamList) {
-            float cdnWeight = 0f;
-            if (stream.height == selectedHeight) {
-                //same cdn > akamai > limelight > level3
-                if (stream.cdn.equals(config.getCdn()))
-                    cdnWeight = 15f;
-                if (stream.cdn.equals("akamai"))
-                    cdnWeight = 10f;
-                else if (stream.cdn.equals("limelight"))
-                    cdnWeight = 5f;
-                else if (stream.cdn.equals("level3"))
-                    cdnWeight = 2f;
-            }
-            stream.cdnWeight = cdnWeight;
-            stream.calcWeight();
-            logger.info(stream.toString());
-        }
-    }
-
     private class Stream implements Comparable<Stream> {
         private final String server;
         private final String play;
         private final String app;
-        private final int bitrate;
-        private final int height;
-        private final String videoFormat; // Example : vp6, h264
-        private final String cdn;
-        private float heightWeight, videoFormatWeight, cdnWeight, weight;
+        private final VideoQuality videoQuality;
 
-        public Stream(String server, String stream, String token, int bitrate, int height, String videoFormat, String cdn) throws ErrorDuringDownloadingException {
-            Matcher matcher = PlugUtils.matcher("://(.+?)/(.+)", server);
+        public Stream(String server, String stream, String token, int height) throws ErrorDuringDownloadingException {
+            final Matcher matcher = PlugUtils.matcher("://(.+?)/(.+)", server);
             if (!matcher.find()) {
                 throw new PluginImplementationException("Error parsing stream server");
             }
@@ -312,27 +231,22 @@
             this.server = server;
             this.play = stream;
             this.app = token;
-            this.bitrate = bitrate;
-            this.height = height;
-            this.videoFormat = videoFormat;
-            this.cdn = cdn;
+            this.videoQuality = VideoQuality.parse(height);
             logger.info("Found stream: " + this);
         }
 
+        public VideoQuality getVideoQuality() {
+            return videoQuality;
+        }
+
         public RtmpSession getSession() {
-            final int port = config.getPort();
-            logger.info("Config port : " + port);
             logger.info("Downloading stream: " + this);
-            return new RtmpSession(server, port, app, play, true);
+            return new RtmpSession(server, 1935, app, play, true);
         }
 
-        public void calcWeight() {
-            weight = (10 * heightWeight) + (5 * videoFormatWeight) + cdnWeight;
-        }
-
         @Override
-        public int compareTo(Stream that) {
-            return Float.valueOf(this.weight).compareTo(that.weight);
+        public int compareTo(final Stream that) {
+            return this.videoQuality.compareTo(that.videoQuality);
         }
 
         @Override
@@ -341,14 +255,7 @@
                     "server='" + server + '\'' +
                     ", play='" + play + '\'' +
                     ", app='" + app + '\'' +
-                    ", bitrate=" + bitrate +
-                    ", height=" + height +
-                    ", videoformat=" + videoFormat +
-                    ", cdn='" + cdn + '\'' +
-                    ", heightweight=" + heightWeight +
-                    ", videoformatweight=" + videoFormatWeight +
-                    ", cdnweight=" + cdnWeight +
-                    ", weight=" + weight +
+                    ", videoQuality=" + videoQuality +
                     '}';
         }
     }
\ No newline at end of file
Index: src/hulu/cz/vity/freerapid/plugins/services/hulu/TestApp.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/hulu/cz/vity/freerapid/plugins/services/hulu/TestApp.java	(revision 4224)
+++ src/hulu/cz/vity/freerapid/plugins/services/hulu/TestApp.java	(revision )
@@ -33,11 +33,7 @@
             final HuluSettingsConfig config = new HuluSettingsConfig();
             //config.setUsername("***");
             //config.setPassword("***");
-            //config.setQualityHeightIndex(HuluSettingsConfig.MAX_HEIGHT_INDEX); //highest
-            config.setQualityHeightIndex(1); //240
-            config.setVideoFormatIndex(1); //h264
-            config.setCdnIndex(0); //akamai
-            config.setPortIndex(0); //1935
+            config.setVideoQuality(VideoQuality.MAXIMUM);
             service.setConfig(config);
 
             testRun(service, httpFile, connectionSettings);
\ No newline at end of file
Index: src/hulu/cz/vity/freerapid/plugins/services/hulu/HuluServiceImpl.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/hulu/cz/vity/freerapid/plugins/services/hulu/HuluServiceImpl.java	(revision 4224)
+++ src/hulu/cz/vity/freerapid/plugins/services/hulu/HuluServiceImpl.java	(revision )
@@ -37,29 +37,23 @@
         }
     }
 
-    public HuluSettingsConfig getConfig() throws Exception {
+    HuluSettingsConfig getConfig() throws Exception {
         synchronized (HuluServiceImpl.class) {
             final ConfigurationStorageSupport storage = getPluginContext().getConfigurationStorageSupport();
             if (config == null) {
                 if (!storage.configFileExists(PLUGIN_CONFIG_FILE)) {
                     config = new HuluSettingsConfig();
-                    config.setQualityHeightIndex(HuluSettingsConfig.MAX_HEIGHT_INDEX); //highest
-                    config.setVideoFormatIndex(HuluSettingsConfig.ANY_VIDEO_FORMAT); //any
-                    config.setCdnIndex(0); //akamai
-                    config.setPortIndex(0); //1935
+                    config.setVideoQuality(VideoQuality.MAXIMUM);
                 } else {
                     try {
                         config = storage.loadConfigFromFile(PLUGIN_CONFIG_FILE, HuluSettingsConfig.class);
-                    } catch (java.lang.ClassCastException e) {
+                    } catch (final ClassCastException e) {
                         //old config conversion
                         final PremiumAccount pa = getAccountConfigFromFile(PLUGIN_CONFIG_FILE);
                         config = new HuluSettingsConfig();
                         config.setUsername(pa.getUsername());
                         config.setPassword(pa.getPassword());
-                        config.setQualityHeightIndex(HuluSettingsConfig.MAX_HEIGHT_INDEX); //highest
-                        config.setVideoFormatIndex(HuluSettingsConfig.ANY_VIDEO_FORMAT); //any
-                        config.setCdnIndex(0); //akamai
-                        config.setPortIndex(0); //1935
+                        config.setVideoQuality(VideoQuality.MAXIMUM);
                     }
                 }
             }
@@ -67,7 +61,7 @@
         }
     }
 
-    public void setConfig(HuluSettingsConfig config) {
+    void setConfig(final HuluSettingsConfig config) {
         this.config = config;
     }
 
\ No newline at end of file
