diff --git a/src/main/config/component/focusModifier.xml b/src/main/config/component/focusModifier.xml
index 7a17a81..00e7c43 100644
--- a/src/main/config/component/focusModifier.xml
+++ b/src/main/config/component/focusModifier.xml
@@ -43,5 +43,20 @@
             </description>
             <defaultvalue>""</defaultvalue>
         </property>
+        <property>
+            <name>priority</name>
+            <classname>java.lang.Integer</classname>
+            <description>
+                If there are more components requesting focus, then component with lowest priority will be focused.
+            </description>
+        </property>
+        <property>
+            <name>skipped</name>
+            <classname>boolean</classname>
+            <description>
+                If set to true, component will not be concerned when calculating default focus.
+            </description>
+            <defaultvalue>false</defaultvalue>
+        </property>
     </component>
 </components>
diff --git a/src/main/java/org/richfaces/component/UIFocus.java b/src/main/java/org/richfaces/component/UIFocus.java
index ca2922c..5831592 100644
--- a/src/main/java/org/richfaces/component/UIFocus.java
+++ b/src/main/java/org/richfaces/component/UIFocus.java
@@ -5,32 +5,71 @@ import javax.faces.component.UIComponentBase;
 import javax.faces.component.UIForm;
 import javax.faces.component.UIInput;
 import javax.faces.context.FacesContext;
+import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Set;
 
 public abstract class UIFocus extends UIComponentBase {
+// ------------------------------ FIELDS ------------------------------
+
+    public static final String COMPONENT_FAMILY = "org.richfaces.Focus";
 
     public static final String COMPONENT_TYPE = "org.richfaces.Focus";
 
-    public static final String COMPONENT_FAMILY = "org.richfaces.Focus";
+    public static final int DEFAULT_PRIORITY = Integer.MAX_VALUE;
+
+    public static final String FOCUS_MODIFIER_FACET_NAME = "focusModifier";
 
     public static final String TIMING_ON_LOAD = "onload";
 
-    public static final String FOCUS_MODIFIER_FACET_NAME = "focusModifier";
+// -------------------------- STATIC METHODS --------------------------
 
-    public Integer getDefaultPriority(FacesContext context) {
-        UIComponent parentForm = getParent();
+    public static UIFocusModifier findModifier(UIComponent component) {
+        if (component instanceof UIFocusModifier) {
+            return (UIFocusModifier) component;
+        }
+        UIFocusModifier modifier = (UIFocusModifier) component.getFacet(UIFocus.FOCUS_MODIFIER_FACET_NAME);
+        if (modifier == null) {
+            for (UIComponent child : component.getChildren()) {
+                modifier = findModifier(child);
+                if (modifier != null) {
+                    break;
+                }
+            }
+        }
+        return modifier;
+    }
+
+// -------------------------- OTHER METHODS --------------------------
+
+    public int calculatePriority(UIComponent component) {
+        final UIFocusModifier modifier = findModifier(component);
+        if (modifier != null && modifier.getPriority() != null) {
+            return modifier.getPriority();
+        }
+        UIComponent parentForm = component.getParent();
         while (parentForm != null && !(parentForm instanceof UIForm)) {
             parentForm = parentForm.getParent();
         }
         if (parentForm != null) {
-            return getUIInputChildrenCount(parentForm, getTargetComponentId(context));
+            return getUIInputChildrenCount(parentForm, component.getId());
         } else {
-            return Integer.MAX_VALUE;
+            return DEFAULT_PRIORITY;
         }
     }
 
+    public abstract String getFor();
+
+    public abstract String getName();
+
+    public abstract Integer getPriority();
+
+    public abstract String getSuffix();
+
+    public abstract String getTargetClientId();
+
     public String getTargetComponentId(FacesContext context) {
         String aFor = getFor();
 
@@ -43,68 +82,49 @@ public abstract class UIFocus extends UIComponentBase {
                 while (clientIdsWithMessages.hasNext()) {
                     allowedClientIds.add(clientIdsWithMessages.next());
                 }
-                UIComponent component = getFirstInput(getParentForm(this), allowedClientIds);
-                return component == null ? null : component.getClientId(context);
+                final List<UIInput> inputs = new ArrayList<UIInput>();
+                getInputs(getParentForm(this), allowedClientIds, inputs);
+                UIInput inputWithLowestPriority = null;
+                int lowestPriority = Integer.MAX_VALUE;
+                for (UIInput input : inputs) {
+                    final int priority = calculatePriority(input);
+                    if (priority < lowestPriority) {
+                        inputWithLowestPriority = input;
+                        lowestPriority = priority;
+                    }
+                }
+                return inputWithLowestPriority == null ? null : inputWithLowestPriority.getClientId(context);
             } else {
                 return getParent().getClientId(context);
             }
         }
     }
 
-    private int getUIInputChildrenCount(UIComponent component, String breakOnId) {
-        int inputComponentsCount = 0;
-        for (UIComponent child : component.getChildren()) {
-            if (child.getId().equals(breakOnId)) {
-                break;
-            }
-            if (child instanceof UIInput) {
-                inputComponentsCount++;
-            } else {
-                int uIInputChildrenCount = getUIInputChildrenCount(child, breakOnId);
-                inputComponentsCount += uIInputChildrenCount;
-            }
-        }
-        return inputComponentsCount;
-    }
-
-    public abstract String getFor();
+    public abstract String getTiming();
 
     public abstract void setFor(String value);
 
-    public abstract String getTargetClientId();
-
-    public abstract void setTargetClientId(String targetClientId);
-
-    public abstract String getSuffix();
-
-    public abstract void setSuffix(String value);
-
-    public abstract Integer getPriority();
+    public abstract void setName(String name);
 
     public abstract void setPriority(Integer value);
 
-    public abstract String getTiming();
-
-    public abstract String getName();
+    public abstract void setSuffix(String value);
 
-    public abstract void setName(String name);
+    public abstract void setTargetClientId(String targetClientId);
 
     public abstract void setTiming(String timing);
 
-    private UIComponent getFirstInput(UIComponent parent, Set<String> allowedClientIds) {
-        UIComponent input = null;
+    private void getInputs(UIComponent parent, Set<String> allowedClientIds, List<UIInput> inputs) {
         FacesContext facesContext = getFacesContext();
         for (UIComponent child : parent.getChildren()) {
             if (child instanceof UIInput && (allowedClientIds.size() == 0 || allowedClientIds.contains(child.getClientId(facesContext)))) {
-                return child;
-            } else {
-                input = getFirstInput(child, allowedClientIds);
-                if (input != null) {
-                    break;
+                final UIFocusModifier modifier = findModifier(child);
+                if (modifier == null || !modifier.isSkipped()) {
+                    inputs.add((UIInput) child);
                 }
             }
+            getInputs(child, allowedClientIds, inputs);
         }
-        return input;
     }
 
     private UIForm getParentForm(UIComponent component) {
@@ -118,4 +138,36 @@ public abstract class UIFocus extends UIComponentBase {
             return getParentForm(parent);
         }
     }
+
+    private int getUIInputChildrenCount(UIComponent component, String breakOnId) {
+        final Holder<Integer> childrenCount = new Holder<Integer>();
+        childrenCount.value = 0;
+        getUIInputChildrenCount(component, breakOnId, childrenCount);
+        return childrenCount.value;
+    }
+
+    private boolean getUIInputChildrenCount(UIComponent component, String breakOnId, Holder<Integer> childrenCount) {
+        for (UIComponent child : component.getChildren()) {
+            if (child.getId().equals(breakOnId)) {
+                return true;
+            }
+            if (child instanceof UIInput) {
+                final UIFocusModifier modifier = findModifier(child);
+                if (modifier == null || !modifier.isSkipped()) {
+                    childrenCount.value++;
+                }
+            } else {
+                if (getUIInputChildrenCount(child, breakOnId, childrenCount)) return true;
+            }
+        }
+        return false;
+    }
+
+// -------------------------- INNER CLASSES --------------------------
+
+    private class Holder<T> {
+// ------------------------------ FIELDS ------------------------------
+
+        public T value;
+    }
 }
diff --git a/src/main/java/org/richfaces/component/UIFocusModifier.java b/src/main/java/org/richfaces/component/UIFocusModifier.java
index 387d111..0ce2dfe 100644
--- a/src/main/java/org/richfaces/component/UIFocusModifier.java
+++ b/src/main/java/org/richfaces/component/UIFocusModifier.java
@@ -11,11 +11,19 @@ public abstract class UIFocusModifier extends UIComponentBase {
 
 // -------------------------- OTHER METHODS --------------------------
 
-    public abstract String getTargetClientId();
+    public abstract Integer getPriority();
 
     public abstract String getSuffix();
 
-    public abstract void setTargetClientId(String focusClientId);
+    public abstract String getTargetClientId();
+
+    public abstract boolean isSkipped();
+
+    public abstract void setPriority(Integer priority);
+
+    public abstract void setSkipped(boolean skipped);
 
     public abstract void setSuffix(String value);
+
+    public abstract void setTargetClientId(String focusClientId);
 }
diff --git a/src/main/java/org/richfaces/renderkit/html/HtmlFocusRenderer.java b/src/main/java/org/richfaces/renderkit/html/HtmlFocusRenderer.java
index e76078d..61b7593 100644
--- a/src/main/java/org/richfaces/renderkit/html/HtmlFocusRenderer.java
+++ b/src/main/java/org/richfaces/renderkit/html/HtmlFocusRenderer.java
@@ -32,6 +32,7 @@ import org.richfaces.component.UIFocusModifier;
 
 import javax.faces.FacesException;
 import javax.faces.component.UIComponent;
+import javax.faces.component.UIInput;
 import javax.faces.context.FacesContext;
 import javax.faces.context.ResponseWriter;
 import java.io.IOException;
@@ -58,6 +59,26 @@ public class HtmlFocusRenderer extends HeaderResourcesRendererBase {
         return styles;
     }
 
+    private void checkValidity(FacesContext context, UIFocus component) {
+        String clientId = getUtils().clientId(context, component);
+        String name = component.getName();
+        String timing = component.getTiming();
+        String _for = component.getFor();
+        String targetClientId = component.getTargetClientId();
+        if ((name == null || "".equals(name.trim())) && "onJScall".equals(timing)) {
+            throw new FacesException(
+                "The name attribute of the focus component (id='" + clientId + "') must be specified when timing attribute equals to 'onJScall'");
+        }
+        if (name != null && !"".equals(name.trim()) && !"onJScall".equals(timing)) {
+            throw new FacesException(
+                "The timing attribute of the focus component (id='" + clientId + "') must be set to 'onJScall' when name attribute is specified");
+        }
+        if ((_for == null || "".equals(_for)) && (targetClientId == null || "".equals(targetClientId)) && !(component.getParent() instanceof UIInput)
+            && getUtils().getNestingForm(context, component) == null) {
+            throw new FacesException("Focus component must have either one of 'for' or 'targetClientId' attributes specified or be nested within UIForm or UIInput component");
+        }
+    }
+
     @Override
     protected void doEncodeEnd(ResponseWriter writer, FacesContext context, UIComponent component)
         throws IOException {
@@ -66,11 +87,8 @@ public class HtmlFocusRenderer extends HeaderResourcesRendererBase {
         }
         UIFocus uiFocus = (UIFocus) component;
         final String clientId = getUtils().clientId(context, component);
-        checkValidity(clientId, uiFocus.getName(), uiFocus.getTiming());
+        checkValidity(context, uiFocus);
         Integer priority = uiFocus.getPriority();
-        if (priority == null) {
-            priority = uiFocus.getDefaultPriority(context);
-        }
         String targetClientId = uiFocus.getTargetClientId();
         if (targetClientId == null || "".equals(targetClientId)) {
             String targetComponentId = uiFocus.getTargetComponentId(context);
@@ -83,7 +101,7 @@ public class HtmlFocusRenderer extends HeaderResourcesRendererBase {
                 throw new FacesException("No component with id=" + targetComponentId + " found!");
             }
             targetClientId = forcomp.getClientId(context);
-            UIFocusModifier modifier = findModifier(forcomp);
+            UIFocusModifier modifier = UIFocus.findModifier(forcomp);
             if (modifier != null) {
                 final String modifiedTargetClientId = modifier.getTargetClientId();
                 if (modifiedTargetClientId != null && !modifiedTargetClientId.equals("")) {
@@ -92,6 +110,9 @@ public class HtmlFocusRenderer extends HeaderResourcesRendererBase {
                     suffix = modifier.getSuffix();
                 }
             }
+            if (priority == null) {
+                priority = uiFocus.calculatePriority(forcomp);
+            }
             if (suffix != null && !"".equals(suffix)) {
                 targetClientId += suffix;
             }
@@ -99,6 +120,9 @@ public class HtmlFocusRenderer extends HeaderResourcesRendererBase {
         if (targetClientId == null || targetClientId.equals("")) {
             return;
         }
+        if (priority == null) {
+            priority = UIFocus.DEFAULT_PRIORITY;
+        }
         writer.startElement(RendererUtils.HTML.SCRIPT_ELEM, null);
         writer.writeAttribute(RendererUtils.HTML.TYPE_ATTR, "text/javascript", "type");
         writer.writeAttribute(RendererUtils.HTML.id_ATTRIBUTE, clientId, RendererUtils.HTML.id_ATTRIBUTE);
@@ -119,34 +143,7 @@ public class HtmlFocusRenderer extends HeaderResourcesRendererBase {
         writer.endElement(RendererUtils.HTML.SCRIPT_ELEM);
     }
 
-    private void checkValidity(String clientId, String name, String timing) {
-        if ((name == null || "".equals(name.trim())) && "onJScall".equals(timing)) {
-            throw new FacesException(
-                "The name attribute of the focus component (id='" + clientId + "') must be specified when timing attribute equals to 'onJScall'");
-        }
-        if (name != null && !"".equals(name.trim()) && !"onJScall".equals(timing)) {
-            throw new FacesException(
-                "The timing attribute of the focus component (id='" + clientId + "') must be set to 'onJScall' when name attribute is specified");
-        }
-    }
-
     protected Class<? extends UIComponent> getComponentClass() {
         return UIFocus.class;
     }
-
-    private UIFocusModifier findModifier(UIComponent component) {
-        if (component instanceof UIFocusModifier) {
-            return (UIFocusModifier) component;
-        }
-        UIFocusModifier modifier = (UIFocusModifier) component.getFacet(UIFocus.FOCUS_MODIFIER_FACET_NAME);
-        if (modifier == null) {
-            for (UIComponent child : component.getChildren()) {
-                modifier = findModifier(child);
-                if (modifier != null) {
-                    break;
-                }
-            }
-        }
-        return modifier;
-    }
 }