diff --git a/computes/views.py b/computes/views.py
index bb9c55e..7bc7700 100644
--- a/computes/views.py
+++ b/computes/views.py
@@ -177,7 +177,7 @@ def compute_graph(request, compute_id):
     datasets = {}
     cookies = {}
     compute = get_object_or_404(Compute, pk=compute_id)
-    curent_time = time.strftime("%H:%M:%S")
+    current_time = time.strftime("%H:%M:%S")
 
     try:
         conn = wvmHostDetails(compute.hostname,
@@ -208,7 +208,7 @@ def compute_graph(request, compute_id):
         datasets['mem'] = eval(cookies['mem'])
         datasets['timer'] = eval(cookies['timer'])
 
-    datasets['timer'].append(curent_time)
+    datasets['timer'].append(current_time)
     datasets['cpu'].append(int(cpu_usage['usage']))
     datasets['mem'].append(int(mem_usage['usage']) / 1048576)
 
diff --git a/conf/requirements.txt b/conf/requirements.txt
index 49903c0..d8c5a5f 100644
--- a/conf/requirements.txt
+++ b/conf/requirements.txt
@@ -1,7 +1,7 @@
-Django==1.11.14
+Django==1.11.17
 websockify==0.8.0
 gunicorn==19.9.0
-lxml==4.2.3
-libvirt-python==4.4.0
+lxml==4.2.5
+libvirt-python==4.10.0
 pytz
 
diff --git a/create/templates/create_instance.html b/create/templates/create_instance.html
index 34ee73c..bb3b0a2 100644
--- a/create/templates/create_instance.html
+++ b/create/templates/create_instance.html
@@ -441,7 +441,7 @@
                             <label class="col-sm-3 control-label">{% trans "HDD" %}</label>
                             <input id="images" name="images" type="hidden" value=""/>
                             <div class="col-sm-3">
-                                <select id="storage" name="storage" class="form-control" onchange="get_template_vols({{ compute_id }}, value);">
+                                <select class="form-control" onchange="get_template_vols({{ compute_id }}, value);">
                                     {% if storages %}
                                         <option value disabled selected>{% trans "Select pool" %}...</option>
                                         {% for storage in storages %}
@@ -458,6 +458,20 @@
                                 </select>
                             </div>
                         </div>
+                        <div class="form-group">
+                            <label class="col-sm-3 control-label">{% trans "Storage" %}</label>
+                            <div class="col-sm-7">
+                                <select id="storage" name="storage" class="form-control" disabled>
+                                    {% if storages %}
+                                        {% for storage in storages %}
+                                            <option value="{{ storage }}" >{{ storage }}</option>
+                                        {% endfor %}
+                                    {% else %}
+                                        <option value="">{% trans "None" %}</option>
+                                    {% endif %}
+                                </select>
+                            </div>
+                        </div>
                         <div class="form-group meta-prealloc">
                             <label class="col-sm-3 control-label">{% trans "Metadata" %}</label>
                             <div class="col-sm-7">
@@ -697,6 +711,9 @@
             });
         });
         $("#template").removeAttr("disabled");
+        $("#storage").val(pool).change();
+        $("#storage").removeAttr("disabled");
+
     }
 
      function get_disk_bus_choices(compute_id, dev_idx, disk_type){
diff --git a/create/views.py b/create/views.py
index 0bb2133..9bd881a 100644
--- a/create/views.py
+++ b/create/views.py
@@ -134,7 +134,7 @@ def create_instance(request, compute_id):
                                 error_msg = _("Image has already exist. Please check volumes or change instance name")
                                 error_messages.append(error_msg)
                             else:
-                                clone_path = conn.clone_from_template(data['name'], templ_path, metadata=meta_prealloc)
+                                clone_path = conn.clone_from_template(data['name'], templ_path, data['storage'], metadata=meta_prealloc)
                                 volume = dict()
                                 volume['path'] = clone_path
                                 volume['type'] = conn.get_volume_type(clone_path)
diff --git a/instances/templates/add_instance_volume.html b/instances/templates/add_instance_volume.html
index 9cea2fc..6b0fed3 100644
--- a/instances/templates/add_instance_volume.html
+++ b/instances/templates/add_instance_volume.html
@@ -1,6 +1,6 @@
 {% load i18n %}
 {% if request.user.is_superuser %}
-<a href="#addvol" type="button" class="btn btn-success pull-right" data-toggle="modal">
+<a href="#addvol" type="button" class="btn btn-success pull-right" data-toggle="modal" title="Add Volume">
     <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
 </a>
 
diff --git a/instances/templates/instance.html b/instances/templates/instance.html
index f0a6388..bd6bb78 100644
--- a/instances/templates/instance.html
+++ b/instances/templates/instance.html
@@ -40,7 +40,7 @@
                         </div>
                     </div>
                     {% if user_quota_msg %}
-                        <span class="label label-warning">{{ user_quota_msg|capfirst }} quota reached.</span>
+                        <span class="label label-warning">{{ user_quota_msg|capfirst }} {% trans "quota reached" %}.</span>
                     {% endif %}
                     <hr>
                 </div>
@@ -187,23 +187,18 @@
                                                 {% endif %}
                                             {% endifequal %}
                                             {% ifequal status 3 %}
-                                                {% if request.user.is_superuser %}
-                                                    <div role="tabpanel" class="tab-pane tab-pane-bordered active" id="resume">
+                                                <div role="tabpanel" class="tab-pane tab-pane-bordered active" id="resume">
+                                                <form action="" method="post" role="form">{% csrf_token %}
+                                                    {% if request.user.is_superuser %}
                                                         <p>{% trans "This action restore the instance after suspend." %}</p>
-                                                         <form action="" method="post" role="form">{% csrf_token %}
-                                                            <input type="submit" name="resume" class="btn btn-lg btn-success pull-right" value="{% trans "Resume" %}">
-                                                            <div class="clearfix"></div>
-                                                        </form>
-                                                    </div>
-                                                {% else %}
-                                                    <div role="tabpanel" class="tab-pane tab-pane-bordered active" id="resume">
+                                                        <input type="submit" name="resume" class="btn btn-lg btn-success pull-right" value="{% trans "Resume" %}">
+                                                    {% else %}
                                                         <p>{% trans "Administrator blocked your instance." %}</p>
-                                                         <form action="" method="post" role="form">{% csrf_token %}
-                                                            <button class="btn btn-lg btn-success disabled pull-right">{% trans "Resume" %}</button>
-                                                            <div class="clearfix"></div>
-                                                        </form>
-                                                    </div>
-                                                {% endif %}
+                                                        <button class="btn btn-lg btn-success disabled pull-right">{% trans "Resume" %}</button>
+                                                    {% endif %}
+                                                     <div class="clearfix"></div>
+                                                </form>
+                                                </div>
                                             {% endifequal %}
                                             {% ifequal status 5 %}
                                                 <div role="tabpanel" class="tab-pane tab-pane-bordered active" id="boot">
@@ -270,7 +265,6 @@
                                                             <li><a href="#" title="Console port: {{ console_port }}" onclick="open_console('full')">{% trans "Console - Full" %}</a></li>
                                                         </ul>
                                                     </div>
-
                                                 {% else %}
                                                     <button class="btn btn-lg btn-success pull-right disabled">{% trans "Console" %}</button>
                                                 {% endifequal %}
@@ -350,7 +344,7 @@
                                             <div role="tabpanel" class="tab-pane tab-pane-bordered active" id="resizevm">
                                                 {% if request.user.is_superuser or request.user.is_staff or userinstance.is_change %}
                                                     <form class="form-horizontal" method="post" role="form">{% csrf_token %}
-                                                        <p style="font-weight:bold;">{% trans "Logical host CPUs:" %} {{ vcpu_host }}</p>
+                                                        <p style="font-weight:bold;">{% trans "Logical host CPUs" %} : {{ vcpu_host }}</p>
                                                         <div class="form-group">
                                                             <label class="col-sm-4 control-label" style="font-weight:normal;"> {% trans "Current allocation" %}</label>
                                                             <div class="col-sm-4">
@@ -381,8 +375,7 @@
                                                             <div class="col-sm-4 js-custom__container">
                                                                 <select name="cur_memory" class="form-control js-custom__toggle">
                                                                     {% for mem in memory_range %}
-                                                                        <option value="{{ mem }}"
-                                                                                {% if mem == cur_memory %}selected{% endif %}>{{ mem }}</option>
+                                                                        <option value="{{ mem }}" {% if mem == cur_memory %}selected{% endif %}>{{ mem }}</option>
                                                                     {% endfor %}
                                                                 </select>
                                                                 <input type="text" name="cur_memory_custom" class="form-control js-custom__toggle" style="display: none" />
@@ -392,7 +385,6 @@
                                                         <div class="form-group">
                                                             <label class="col-sm-4 control-label"
                                                                    style="font-weight:normal;">{% trans "Maximum allocation" %} ({% trans "MB" %})</label>
-
                                                             <div class="col-sm-4 js-custom__container">
                                                                 <select name="memory" class="form-control js-custom__toggle">
                                                                     {% for mem in memory_range %}
@@ -425,7 +417,6 @@
                                                 {% endif %}
                                                 <div class="clearfix"></div>
                                             </div>
-                                            
                                         </div>
                                     </div>
                                 </div>
@@ -473,11 +464,11 @@
                                                         <div class="table-responsive">
                                                             <table class="table">
                                                                 <thead>
-                                                                <tr>
-                                                                    <th>{% trans "Name" %}</th>
-                                                                    <th>{% trans "Date" %}</th>
-                                                                    <th colspan="2">{% trans "Action" %}</th>
-                                                                </tr>
+                                                                    <tr>
+                                                                        <th>{% trans "Name" %}</th>
+                                                                        <th>{% trans "Date" %}</th>
+                                                                        <th colspan="2">{% trans "Action" %}</th>
+                                                                    </tr>
                                                                 </thead>
                                                                 <tbody>
                                                                 {% for snap in snapshots %}
@@ -526,8 +517,8 @@
                                         <!-- Nav tabs -->
                                         <ul class="nav nav-tabs" role="tablist">
                                             <li role="presentation" class="active">
-                                                <a href="#media" aria-controls="media" role="tab" data-toggle="tab">
-                                                    {% trans "Media" %}
+                                                <a href="#boot_opt" aria-controls="boot" role="tab" data-toggle="tab">
+                                                    {% trans "Boot" %}
                                                 </a>
                                             </li>
                                             <li role="presentation">
@@ -535,13 +526,6 @@
                                                     {% trans "Disk" %}
                                                 </a>
                                             </li>
-                                            {% if request.user.is_superuser %}
-                                                <li role="presentation">
-                                                    <a href="#autostart" aria-controls="autostart" role="tab" data-toggle="tab">
-                                                        {% trans "Autostart" %}
-                                                    </a>
-                                                </li>
-                                            {% endif %}
 
                                             {% if request.user.is_superuser or userinstance.is_vnc %}
                                                 <li role="presentation">
@@ -593,78 +577,150 @@
                                         </ul>
                                         <!-- Tab panes -->
                                         <div class="tab-content">
-                                            <div role="tabpanel" class="tab-pane tab-pane-bordered active" id="media">
-                                            {% if request.user.is_superuser and status == 5 %}
-                                                <form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
-                                                    <div class="form-group">
-                                                        <div class="col-sm-12">
-                                                            <button type="submit" name="add_cdrom" type="button" class="btn btn-success pull-right">
-                                                                <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
-                                                            </button>
-                                                        </div>
-                                                    </div>
-                                                </form>
-                                            {% endif %}
-                                                {% for cd in media %}
+                                            {% if request.user.is_superuser %}
+                                                <div role="tabpanel" class="tab-pane tab-pane-bordered active" id="boot_opt">
+                                                    <p style="font-weight:bold;">{% trans 'Autostart' %}</p>
                                                     <form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
                                                         <div class="form-group">
-                                                            <a class="col-sm-2 control-label"
-                                                                    name="details"
-                                                                    title="{% trans "Details" %}"
-                                                                    tabindex="0"
-                                                                    data-trigger="focus"
-                                                                    data-toggle="popover"
-                                                                    data-html="true"
-                                                                    data-content="<strong>Bus:</strong> {{ cd.bus }} <br/> <strong>Dev:</strong> {{ cd.dev }}">
-                                                                {% trans "CDROM" %} {{ forloop.counter }}
-                                                            </a>
-                                                            {% if not cd.image %}
-                                                                <div class="col-sm-6">
-                                                                    <select name="media" class="form-control">
-                                                                        {% if media_iso %}
-                                                                            {% for iso in media_iso %}
-                                                                                <option value="{{ iso }}">{{ iso }}</option>
-                                                                            {% endfor %}
-                                                                        {% else %}
-                                                                            <option value="none">{% trans "None" %}</option>
-                                                                        {% endif %}
-                                                                    </select>
-                                                                </div>
-                                                                <div class="col-sm-2">
-                                                                    {% if media_iso and allow_admin_or_not_template %}
-                                                                        <button type="submit" class="btn btn-sm btn-success pull-left" name="mount_iso" value="{{ cd.dev }}" style="margin-top: 2px;">{% trans "Mount" %}</button>
-                                                                        {% if status == 5 %}
-                                                                            <button type="submit" class="btn btn-sm btn-danger pull-left" name="detach_cdrom" value="{{ cd.dev }}" style="margin-top: 2px;"><i class="glyphicon glyphicon-remove-circle"></i></button>
-                                                                        {% endif %}
-                                                                    {% else %}
-                                                                        <button class="btn btn-sm btn-success pull-left disabled" style="margin-top: 2px;">{% trans "Mount" %}</button>
-                                                                    {% endif %}
-                                                                </div>
+                                                            <div class="col-sm-12 col-sm-offset-2">
+                                                            <p>{% trans "Autostart your instance when host server is power on " %}
+                                                            {% ifequal autostart 0 %}
+                                                                <input type="submit" class="btn btn-success" name="set_autostart" value="{% trans "Enable" %}">
                                                             {% else %}
-                                                                <div class="col-sm-6">
-                                                                    <input class="form-control" value="{{ cd.image }}" disabled/>
-                                                                </div>
-                                                                <div class="col-sm-2">
-                                                                    <input type="hidden" name="path" value="{{ cd.path }}">
-                                                                    {% if allow_admin_or_not_template %}
-                                                                        <button type="submit" class="btn btn-sm btn-success pull-left" value="{{ cd.dev }}" name="umount_iso" style="margin-top: 2px;">{% trans "Umount" %}</button>
-                                                                    {% else %}
-                                                                        <button class="btn btn-sm btn-success pull-left disabled" value="{{ cd.dev }}" name="umount_iso" style="margin-top: 2px;">{% trans "Umount" %}</button>
-                                                                    {% endif %}
-                                                                </div>
-                                                            {% endif %}
+                                                                <input type="submit" class="btn btn-danger" name="unset_autostart" value="{% trans "Disable" %}">
+                                                            {% endifequal %}
+                                                            </p>
+                                                            </div>
                                                         </div>
                                                     </form>
-                                                {% endfor %}
-                                                <div class="clearfix"></div>
-                                            </div>
-                                            <div role="tabpanel" class="tab-pane tab-pane-bordered" id="disks">
-                                                 <p style="font-weight:bold;">
-                                                     {% trans "Instance Volumes" %}
-                                                     {% include 'add_instance_volume.html' %}
-                                                 </p>
+                                                    <p style="font-weight:bold;">{% trans 'Boot Order' %}</p>
+                                                    <form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
+                                                        <div class="form-group">
+                                                            <div class="col-sm-12 col-sm-offset-2">
+                                                            {% ifequal status 5 %}
+                                                                <p>{% trans "Enable Boot Menu for your instance when it starts up " %}
+                                                                {% ifequal bootmenu 0 %}
+                                                                    <input type="submit" class="btn btn-success" name="set_bootmenu" title="Show boot menu" value="{% trans "Enable" %}">
+                                                                {% else %}
+                                                                    <input type="submit" class="btn btn-danger" name="unset_bootmenu" title="Hide boot menu" value="{% trans "Disable" %}">
+                                                                {% endifequal %}
+                                                            {% else %}
+                                                                <p>{% trans "**** Please shutdown instance to modify boot menu ****" %}
+                                                            {% endifequal %}
+                                                            </p>
+                                                            </div>
+                                                        </div>
+                                                    </form>
+                                                    {% ifequal bootmenu 1  %}
+                                                        <div class="col-sm-6 col-sm-offset-2">
+                                                        <div class="well">
+                                                            {% for idx, val in boot_order.items %}
+                                                                <label>{{ idx|add:1 }}:{{ val.target }}, </label>
+                                                            {% endfor %}
+                                                        </div>
+                                                        </div>
+                                                        <form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
+                                                            <input id="bootorder" name="bootorder" hidden>
+                                                            <div class="form-group">
+                                                                <div class="col-sm-6 col-sm-offset-2">
+                                                                    <div id="b_order" class="multiselect">
+                                                                        {% for disk in disks %}
+                                                                            <label><input type="checkbox" name="disk:{{ disk.dev }}" value="disk:{{ disk.dev }}" onclick="set_orderlist($('#bootorder'))" />{{ disk.dev }} - {{ disk.image }}</label>
+                                                                        {% endfor %}
+                                                                        {% for cd in media %}
+                                                                            <label><input type="checkbox" name="cdrom:{{ cd.dev }}" value="cdrom:{{ cd.dev }}" onclick="set_orderlist($('#bootorder'))"/>{{ cd.dev }} - {{ cd.image }}</label>
+                                                                        {% endfor %}
+                                                                        {% for net in networks %}
+                                                                            <label><input type="checkbox" name="network:{{ net.mac }}" value="network:{{ net.mac }}" onclick="set_orderlist($('#bootorder'))"/>NIC - {{ net.mac|slice:"9:" }}</label>
+                                                                        {% endfor %}
+                                                                    </div>
+                                                                </div>
+                                                                <div class="col-sm-3">
+                                                                    <div class="row" style="margin-top: 2em;">
+                                                                        <a href="#" id="boot_order_up" class="btn btn-default"><span class="glyphicon glyphicon-arrow-up" title="up: move selected devices"></span></a>
+                                                                    </div>
+                                                                    <div class="row" style="margin-top: 1em;">
+                                                                        <a href="#" id="boot_order_down" class="btn btn-default"><span class="glyphicon glyphicon-arrow-down" title="down: move selected devices"></span></a>
+                                                                    </div>
+                                                                </div>
+                                                            </div>
+                                                            <div class="col-sm-6 col-sm-offset-2">
+                                                                <input type="submit" class="btn btn-success btn-block" name="set_bootorder" value="{% trans "Apply" %}">
+                                                            </div>
+                                                        </form>
+                                                    {% endifequal %}
+                                                    <div class="clearfix"></div>
+                                                </div>
+                                                <div role="tabpanel" class="tab-pane tab-pane-bordered" id="disks">
+                                                    {% if status == 5 %}
+                                                        <form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
+                                                            <p style="font-weight:bold;">
+                                                                {% trans "Instance Media" %}
+                                                                <button type="submit" name="add_cdrom" type="button" class="btn btn-success pull-right" title="Add CD-Rom">
+                                                                    <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
+                                                                </button>
+                                                            </p>
+                                                        </form>
+                                                    {% endif %}
+                                                    {% for cd in media %}
+                                                        <form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
+                                                            <div class="form-group">
+                                                                <a class="col-sm-3 control-label"
+                                                                        name="details"
+                                                                        title="{% trans "Details" %}"
+                                                                        tabindex="0"
+                                                                        data-trigger="focus"
+                                                                        data-toggle="popover"
+                                                                        data-html="true"
+                                                                        data-content="<strong>{% trans 'Bus' %}:</strong> {{ cd.bus }} <br/>
+                                                                         <strong>{% trans 'Dev' %}:</strong> {{ cd.dev }}">
+                                                                    {% trans "CDROM" %} {{ forloop.counter }}
+                                                                </a>
+                                                                {% if not cd.image %}
+                                                                    <div class="col-sm-6">
+                                                                        <select name="media" class="form-control">
+                                                                            {% if media_iso %}
+                                                                                {% for iso in media_iso %}
+                                                                                    <option value="{{ iso }}">{{ iso }}</option>
+                                                                                {% endfor %}
+                                                                            {% else %}
+                                                                                <option value="none">{% trans "None" %}</option>
+                                                                            {% endif %}
+                                                                        </select>
+                                                                    </div>
+                                                                    <div class="col-sm-2">
+                                                                        {% if media_iso and allow_admin_or_not_template %}
+                                                                            <button type="submit" class="btn btn-sm btn-success pull-left" name="mount_iso" value="{{ cd.dev }}" style="margin-top: 2px;">{% trans "Mount" %}</button>
+                                                                        {% else %}
+                                                                            <button class="btn btn-sm btn-success pull-left disabled" style="margin-top: 2px;">{% trans "Mount" %}</button>
+                                                                        {% endif %}
+                                                                        {% if status == 5 and allow_admin_or_not_template %}
+                                                                            <button type="submit" class="btn btn-sm btn-danger pull-left" title="Detach CD-Rom (remove device)" name="detach_cdrom" value="{{ cd.dev }}" style="margin-top: 2px;"><i class="glyphicon glyphicon-remove-circle"></i></button>
+                                                                        {% endif %}
+                                                                    </div>
+                                                                {% else %}
+                                                                    <div class="col-sm-6">
+                                                                        <input class="form-control" value="{{ cd.image }}" disabled/>
+                                                                    </div>
+                                                                    <div class="col-sm-2">
+                                                                        <input type="hidden" name="path" value="{{ cd.path }}">
+                                                                        {% if allow_admin_or_not_template %}
+                                                                            <button type="submit" class="btn btn-sm btn-success pull-left" value="{{ cd.dev }}" name="umount_iso" style="margin-top: 2px;">{% trans "Umount" %}</button>
+                                                                        {% else %}
+                                                                            <button class="btn btn-sm btn-success pull-left disabled" value="{{ cd.dev }}" name="umount_iso" style="margin-top: 2px;">{% trans "Umount" %}</button>
+                                                                        {% endif %}
+                                                                    </div>
+                                                                {% endif %}
+                                                            </div>
+                                                        </form>
+                                                    {% endfor %}
 
-                                                 <div class="col-xs-12 col-sm-12">
+                                                    <p style="font-weight:bold;">
+                                                        {% trans "Instance Volume" %}
+                                                        {% include 'add_instance_volume.html' %}
+                                                    </p>
+
+                                                    <div class="col-xs-12 col-sm-12">
                                                     <table class="table table-hover">
                                                         <thead>
                                                             <th>{% trans "Device" %}</th>
@@ -685,7 +741,9 @@
                                                                             data-trigger="focus"
                                                                             data-toggle="popover"
                                                                             data-html="true"
-                                                                            data-content="<strong>Bus:</strong> {{ disk.bus }} <br/> <strong>Format:</strong> {{ disk.format }}">
+                                                                            data-content="<strong>Bus:</strong> {{ disk.bus }} <br/>
+                                                                                          <strong>Format:</strong> {{ disk.format }} <br/>
+                                                                                          <strong>Cache:</strong> {{ disk.cache }}">
                                                                         <i class="fa fa-info"></i>
                                                                     </button>
                                                                     {{ disk.dev }}
@@ -724,21 +782,167 @@
                                                          </tbody>
                                                     </table>
                                                 </div>
-                                                <div class="clearfix"></div>
-                                            </div>
+                                                    <div class="clearfix"></div>
+                                                </div>
+                                                <div role="tabpanel" class="tab-pane tab-pane-bordered" id="network">
+                                                    <p>
+                                                        {% trans "Assign network device to bridge" %}
+                                                        {% include 'add_instance_network_block.html' %}
+                                                    </p>
+                                                    <p style="font-weight:bold;">{% trans "Network devices" %}</p>
+                                                <div class="col-xs-12 col-sm-12">
+                                                    <form method="post" role="form">{% csrf_token %}
+                                                        {% for network in networks %}
+                                                            <div class="panel panel-default">
+                                                                <div class="panel-heading">
+                                                                    <label>eth{{ forloop.counter0 }}({{ network.target|default:"no target" }})</label>
+                                                                </div>
+                                                                <div class="panel-body">
+                                                                    <div class="form-group form-inline">
+                                                                        <label class="col-sm-2 col-sm-offset-1 control-label">{% trans "MAC" %} </label>
+                                                                        <input class="form-control" type="text" value="{{ network.mac }}" readonly/>
+                                                                        <label class="control-label"><em>to</em></label>
+                                                                        <input class="form-control" type="text" name="net-mac-{{ forloop.counter0 }}" value="{{ network.mac }}"/>
+                                                                    </div>
+                                                                    <div class="form-group form-inline">
+                                                                        <label class="col-sm-2 col-sm-offset-1 control-label">{% trans "NIC" %} </label>
+                                                                        <input class="form-control" type="text" value="{{ network.nic }}" readonly/>
+                                                                        <label class="control-label"><em>to</em></label>
+                                                                        <select class="form-control" name="net-source-{{ forloop.counter0 }}">
+                                                                            {% for c_net in compute_networks %}
+                                                                                <option value="net:{{ c_net }}" {% ifequal c_net network.nic %} selected {% endifequal %}>Network {{ c_net }}</option>
+                                                                            {% endfor %}
+                                                                            {% for c_iface in compute_interfaces %}
+                                                                                <option value="iface:{{ c_iface }}" {% ifequal c_iface network.nic %} selected {% endifequal %}>Interface {{ c_iface }}</option>
+                                                                            {% endfor %}
+                                                                        </select>
+                                                                    </div>
+                                                                    <div class="form-group form-inline">
+                                                                        <label class="col-sm-2 col-sm-offset-1">{% trans "Filter" %} </label>
+                                                                        <input class="form-control" type="text" value="{{ network.filterref }}" readonly/>
+                                                                        <label class="control-label"><em>to</em></label>
+                                                                        <select class="form-control" name="net-nwfilter-{{ forloop.counter0 }}">
+                                                                            <option value="">{% trans "None" %}</option>
+                                                                            {% for c_filters in compute_nwfilters %}
+                                                                                <option value="{{ c_filters }}" {% ifequal c_filters network.filterref  %} selected {% endifequal %}>{{ c_filters }}</option>
+                                                                            {% endfor %}
+                                                                        </select>
+                                                                    </div>
+                                                                </div>
 
-                                            {% if request.user.is_superuser %}
-                                                <div role="tabpanel" class="tab-pane tab-pane-bordered" id="autostart">
-                                                    <p>{% trans "Autostart your instance when host server is power on" %}</p>
-                                                    <form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
-                                                        {% ifequal autostart 0 %}
-                                                            <input type="submit" class="btn btn-lg btn-success pull-right" name="set_autostart" value="{% trans "Enable" %}">
+                                                                <div class="panel-footer">
+                                                                    <button class="btn btn-sm btn-primary" name="change_network" title="{% trans "Change" %}">{% trans "Change" %}</button>
+                                                                    <button class="btn btn-sm pull-right btn-danger" value="{{ network.mac }}" name="delete_network" title="{% trans "Delete" %}" onclick="return confirm('{% trans "Are you sure?" %}')">{% trans "Delete" %}</button>
+                                                                </div>
+                                                            </div>
+                                                        {% endfor %}
+                                                    </form>
+                                                </div>
+                                                    <div class="clearfix"></div>
+
+                                                </div>
+                                                <div role="tabpanel" class="tab-pane tab-pane-bordered" id="migrate">
+                                                    <p>{% trans "For migration both host servers must have equal settings and OS type" %}</p>
+                                                    <form class="form-horizontal" method="post" role="form">{% csrf_token %}
+                                                        <div class="form-group">
+                                                            <label class="col-sm-3 control-label">{% trans "Original host" %}</label>
+                                                            <div class="col-sm-6">
+                                                                <p style="margin: 10px -10px 0 0;">{{ compute.name }}</p>
+                                                            </div>
+                                                        </div>
+                                                        <div class="form-group">
+                                                            <label class="col-sm-3 control-label">{% trans "Host migration" %}</label>
+                                                            <div class="col-sm-6">
+                                                                <select name="compute_id" class="form-control">
+                                                                    {% if computes_count != 1 %}
+                                                                        {% for comp in computes %}
+                                                                            {% if comp.id != compute.id %}
+                                                                                <option value="{{ comp.id }}">{{ comp.name }}</option>
+                                                                            {% endif %}
+                                                                        {% endfor %}
+                                                                    {% endif %}
+                                                                </select>
+                                                            </div>
+                                                        </div>
+                                                        <div class="form-group">
+                                                            <label class="col-sm-3 control-label">{% trans "Live migration" %}</label>
+                                                            <div class="col-sm-6">
+                                                                <input type="checkbox" name="live_migrate" value="true" id="vm_live_migrate" {% ifequal status 1 %}checked{% endifequal %}>
+                                                            </div>
+                                                        </div>
+                                                        <div class="form-group">
+                                                            <label class="col-sm-3 control-label">{% trans "Unsafe migration" %}</label>
+                                                            <div class="col-sm-6">
+                                                                <input type="checkbox" name="unsafe_migrate" value="true" id="vm_unsafe_migrate">
+                                                            </div>
+                                                        </div>
+                                                        <div class="form-group">
+                                                            <label class="col-sm-3 control-label">{% trans "Delete original" %}</label>
+                                                            <div class="col-sm-6">
+                                                                <input type="checkbox" name="xml_delete" value="true" id="xml_delete" checked>
+                                                            </div>
+                                                        </div>
+                                                        <div class="form-group">
+                                                            <label class="col-sm-3 control-label">{% trans "Offline migration" %}</label>
+                                                            <div class="col-sm-6">
+                                                                <input type="checkbox" name="offline_migrate" value="true" id="offline_migrate" {% ifequal status 5 %}checked{% endifequal %}>
+                                                            </div>
+                                                        </div>
+                                                        {% if computes_count != 1 %}
+                                                            <button type="submit" class="btn btn-lg btn-success pull-right" name="migrate" onclick="showPleaseWaitDialog();">{% trans "Migrate" %}</button>
                                                         {% else %}
-                                                            <input type="submit" class="btn btn-lg btn-success pull-right" name="unset_autostart" value="{% trans "Disable" %}">
+                                                            <button class="btn btn-lg btn-success pull-right disabled">{% trans "Migrate" %}</button>
+                                                        {% endif %}
+                                                    </form>
+                                                    <div class="clearfix"></div></p>
+                                                </div>
+                                                <div role="tabpanel" class="tab-pane tab-pane-bordered" id="xmledit">
+                                                    <p>{% trans "If you need to edit xml please Power Off the instance" %}</p>
+                                                    <form class="form-horizontal" method="post" role="form">{% csrf_token %}
+                                                        <div class="col-sm-12" id="xmlheight">
+                                                            <textarea id="editor">{{ inst_xml }}</textarea>
+                                                        </div>
+                                                        {% ifequal status 5 %}
+                                                            <input type="hidden" name="inst_xml">
+                                                            <button type="submit" class="btn btn-lg btn-success pull-right" name="change_xml">
+                                                                {% trans "Change" %}
+                                                            </button>
+                                                        {% else %}
+                                                            <button class="btn btn-lg btn-success pull-right disabled">
+                                                                {% trans "Change" %}
+                                                            </button>
                                                         {% endifequal %}
                                                     </form>
                                                     <div class="clearfix"></div>
                                                 </div>
+                                                <div role="tabpanel" class="tab-pane tab-pane-bordered" id="users">
+                                                    <div>
+                                                    <p style="font-weight:bold;">
+                                                        {% trans "Instance owners" %}
+                                                        {% include 'add_instance_owner_block.html' %}
+                                                    </p>
+                                                    </div>
+                                                    <div class="table-responsive">
+                                                        <table class="table table-striped sortable-theme-bootstrap" data-sortable>
+                                                            <tbody class="searchable">
+                                                            {% for userinstance in userinstances %}
+                                                                <tr>
+                                                                    <td><a href="{% url 'account' userinstance.user.id %}">{{ userinstance.user }}</a></td>
+                                                                    <td style="width:30px;">
+                                                                        <form action="" method="post" style="height:10px" role="form">{% csrf_token %}
+                                                                            <input type="hidden" name="userinstance" value="{{ userinstance.pk }}">
+                                                                            <button type="submit" class="btn btn-sm btn-default" name="del_owner" title="{% trans "Delete" %}">
+                                                                                <i class="fa fa-trash"></i>
+                                                                            </button>
+                                                                        </form>
+                                                                    </td>
+                                                                </tr>
+                                                            {% endfor %}
+                                                            </tbody>
+                                                        </table>
+                                                    </div>
+                                                    <div class="clearfix"></div>
+                                                </div>
                                             {% endif %}
                                             {% if request.user.is_superuser or userinstance.is_vnc %}
                                                 <div role="tabpanel" class="tab-pane tab-pane-bordered" id="vncsettings">
@@ -855,65 +1059,6 @@
                                                     <div class="clearfix"></div>
                                                 </div>
                                             {% endif %}
-                                            {% if request.user.is_superuser %}
-                                                <div role="tabpanel" class="tab-pane tab-pane-bordered" id="network">
-                                                    <p>
-                                                        {% trans "Assign network device to bridge" %}
-                                                        {% include 'add_instance_network_block.html' %}
-                                                    </p>
-                                                    <p style="font-weight:bold;">{% trans "Network devices" %}</p>
-                                                <div class="col-xs-12 col-sm-12">
-                                                    <form method="post" role="form">{% csrf_token %}
-                                                        {% for network in networks %}
-                                                            <div class="panel panel-default">
-                                                                <div class="panel-heading">
-                                                                    <label>eth{{ forloop.counter0 }}({{ network.target|default:"no target" }})</label>
-                                                                </div>
-                                                                <div class="panel-body">
-                                                                    <div class="form-group form-inline">
-                                                                        <label class="col-sm-2 col-sm-offset-1 control-label">{% trans "MAC" %} </label>
-                                                                        <input class="form-control" type="text" value="{{ network.mac }}" readonly/>
-                                                                        <label class="control-label"><em>to</em></label>
-                                                                        <input class="form-control" type="text" name="net-mac-{{ forloop.counter0 }}" value="{{ network.mac }}"/>
-                                                                    </div>
-                                                                    <div class="form-group form-inline">
-                                                                        <label class="col-sm-2 col-sm-offset-1 control-label">{% trans "NIC" %} </label>
-                                                                        <input class="form-control" type="text" value="{{ network.nic }}" readonly/>
-                                                                        <label class="control-label"><em>to</em></label>
-                                                                        <select class="form-control" name="net-source-{{ forloop.counter0 }}">
-                                                                            {% for c_net in compute_networks %}
-                                                                                <option value="net:{{ c_net }}" {% ifequal c_net network.nic %} selected {% endifequal %}>Network {{ c_net }}</option>
-                                                                            {% endfor %}
-                                                                            {% for c_iface in compute_interfaces %}
-                                                                                <option value="iface:{{ c_iface }}" {% ifequal c_iface network.nic %} selected {% endifequal %}>Interface {{ c_iface }}</option>
-                                                                            {% endfor %}
-                                                                        </select>
-                                                                    </div>
-                                                                    <div class="form-group form-inline">
-                                                                        <label class="col-sm-2 col-sm-offset-1">{% trans "Filter" %} </label>
-                                                                        <input class="form-control" type="text" value="{{ network.filterref }}" readonly/>
-                                                                        <label class="control-label"><em>to</em></label>
-                                                                        <select class="form-control" name="net-nwfilter-{{ forloop.counter0 }}">
-                                                                            <option value="">{% trans "None" %}</option>
-                                                                            {% for c_filters in compute_nwfilters %}
-                                                                                <option value="{{ c_filters }}" {% ifequal c_filters network.filterref  %} selected {% endifequal %}>{{ c_filters }}</option>
-                                                                            {% endfor %}
-                                                                        </select>
-                                                                    </div>
-                                                                </div>
-
-                                                                <div class="panel-footer">
-                                                                    <button class="btn btn-sm btn-primary" name="change_network" title="{% trans "Change" %}">{% trans "Change" %}</button>
-                                                                    <button class="btn btn-sm pull-right btn-danger" value="{{ network.mac }}" name="delete_network" title="{% trans "Delete" %}" onclick="return confirm('{% trans "Are you sure?" %}')">{% trans "Delete" %}</button>
-                                                                </div>
-                                                            </div>
-                                                        {% endfor %}
-                                                    </form>
-                                                </div>
-                                                    <div class="clearfix"></div>
-
-                                                </div>
-                                            {% endif %}
                                             {% if request.user.is_superuser or request.user.userattributes.can_clone_instances %}
                                                 <div role="tabpanel" class="tab-pane tab-pane-bordered" id="clone">
                                                     <p style="font-weight:bold;">{% trans "Create a clone" %}</p>
@@ -921,25 +1066,25 @@
                                                         <div class="form-group">
                                                             <label class="col-sm-3 control-label" style="font-weight:normal;">{% trans "Clone Name" %}</label>
                                                             {% if request.user.is_superuser %}
-                                                            <div class="col-sm-4">
-                                                                <input id="clone_name" type="text" class="form-control" name="name" value="{{ vname }}-clone"/>
-                                                            </div>
-                                                            <div class="col-sm-4">
-                                                                <button type="button" class="btn btn-sm btn-success pull-left" name="guess-clone-name"
-                                                                        onclick="guess_clone_name()" style="margin-top: 2px;">{% trans "Guess" %}</button>
-                                                            </div>
+                                                                <div class="col-sm-4">
+                                                                    <input id="clone_name" type="text" class="form-control" name="name" value="{{ vname }}-clone"/>
+                                                                </div>
+                                                                <div class="col-sm-4">
+                                                                    <button type="button" class="btn btn-sm btn-success pull-left" name="guess-clone-name"
+                                                                            onclick="guess_clone_name()" style="margin-top: 2px;">{% trans "Guess" %}</button>
+                                                                </div>
                                                             {% elif clone_instance_auto_name %}
-                                                            <div class="col-sm-4">
-                                                                <input id="clone_instance_auto_name" type="text" class="form-control" name="auto_name" value="Automatic" disabled/>
-                                                            </div>
+                                                                <div class="col-sm-4">
+                                                                    <input id="clone_instance_auto_name" type="text" class="form-control" name="auto_name" value="Automatic" disabled/>
+                                                                </div>
                                                             {% else %}
-                                                            <div class="col-sm-4">
-                                                                <select id="select_clone_name" class="form-control" name="name" size="1"/>
-                                                                {% for name in clone_free_names %}
-                                                                    <option value="{{ name }}">{{ name }}</option>
-                                                                {% endfor %}
-                                                                </select>
-                                                            </div>
+                                                                <div class="col-sm-4">
+                                                                    <select id="select_clone_name" class="form-control" name="name" size="1"/>
+                                                                    {% for name in clone_free_names %}
+                                                                        <option value="{{ name }}">{{ name }}</option>
+                                                                    {% endfor %}
+                                                                    </select>
+                                                                </div>
                                                             {% endif %}
                                                         </div>
                                                         {% if request.user.is_superuser %}
@@ -1004,84 +1149,6 @@
                                                     </form>
                                                     <div class="clearfix"></div>
                                                 </div>
-                                            {% endif %}
-                                            {% if request.user.is_superuser %}
-                                                <div role="tabpanel" class="tab-pane tab-pane-bordered" id="migrate">
-                                                    <p>{% trans "For migration both host servers must have equal settings and OS type" %}</p>
-                                                    <form class="form-horizontal" method="post" role="form">{% csrf_token %}
-                                                        <div class="form-group">
-                                                            <label class="col-sm-3 control-label">{% trans "Original host" %}</label>
-                                                            <div class="col-sm-6">
-                                                                <p style="margin: 10px -10px 0 0;">{{ compute.name }}</p>
-                                                            </div>
-                                                        </div>
-                                                        <div class="form-group">
-                                                            <label class="col-sm-3 control-label">{% trans "Host migration" %}</label>
-                                                            <div class="col-sm-6">
-                                                                <select name="compute_id" class="form-control">
-                                                                    {% if computes_count != 1 %}
-                                                                        {% for comp in computes %}
-                                                                            {% if comp.id != compute.id %}
-                                                                                <option value="{{ comp.id }}">{{ comp.name }}</option>
-                                                                            {% endif %}
-                                                                        {% endfor %}
-                                                                    {% endif %}
-                                                                </select>
-                                                            </div>
-                                                        </div>
-                                                        <div class="form-group">
-                                                            <label class="col-sm-3 control-label">{% trans "Live migration" %}</label>
-                                                            <div class="col-sm-6">
-                                                                <input type="checkbox" name="live_migrate" value="true" id="vm_live_migrate" {% ifequal status 1 %}checked{% endifequal %}>
-                                                            </div>
-                                                        </div>
-                                                        <div class="form-group">
-                                                            <label class="col-sm-3 control-label">{% trans "Unsafe migration" %}</label>
-                                                            <div class="col-sm-6">
-                                                                <input type="checkbox" name="unsafe_migrate" value="true" id="vm_unsafe_migrate">
-                                                            </div>
-                                                        </div>
-                                                        <div class="form-group">
-                                                            <label class="col-sm-3 control-label">{% trans "Delete original" %}</label>
-                                                            <div class="col-sm-6">
-                                                                <input type="checkbox" name="xml_delete" value="true" id="xml_delete" checked>
-                                                            </div>
-                                                        </div>
-                                                        <div class="form-group">
-                                                            <label class="col-sm-3 control-label">{% trans "Offline migration" %}</label>
-                                                            <div class="col-sm-6">
-                                                                <input type="checkbox" name="offline_migrate" value="true" id="offline_migrate" {% ifequal status 5 %}checked{% endifequal %}>
-                                                            </div>
-                                                        </div>
-                                                        {% if computes_count != 1 %}
-                                                            <button type="submit" class="btn btn-lg btn-success pull-right" name="migrate" onclick="showPleaseWaitDialog();">{% trans "Migrate" %}</button>
-                                                        {% else %}
-                                                            <button class="btn btn-lg btn-success pull-right disabled">{% trans "Migrate" %}</button>
-                                                        {% endif %}
-                                                    </form>
-                                                    <div class="clearfix"></div></p>
-                                                </div>
-                                                <div role="tabpanel" class="tab-pane tab-pane-bordered" id="xmledit">
-                                                    <p>{% trans "If you need to edit xml please Power Off the instance" %}</p>
-                                                    <form class="form-horizontal" method="post" role="form">{% csrf_token %}
-                                                        <div class="col-sm-12" id="xmlheight">
-                                                            <textarea id="editor">{{ inst_xml }}</textarea>
-                                                        </div>
-                                                        {% ifequal status 5 %}
-                                                            <input type="hidden" name="inst_xml">
-                                                            <button type="submit" class="btn btn-lg btn-success pull-right" name="change_xml">
-                                                                {% trans "Change" %}
-                                                            </button>
-                                                        {% else %}
-                                                            <button class="btn btn-lg btn-success pull-right disabled">
-                                                                {% trans "Change" %}
-                                                            </button>
-                                                        {% endifequal %}
-                                                    </form>
-                                                    <div class="clearfix"></div>
-                                                </div>
-                                            {% endif %}
-                                            {% if request.user.is_superuser or request.user.userattributes.can_clone_instances %}
                                                 <div role="tabpanel" class="tab-pane tab-pane-bordered" id="options">
                                                     <form class="form-horizontal" action="" method="post" role="form">{% csrf_token %}
                                                         <div class="form-group">
@@ -1111,36 +1178,6 @@
                                                     <div class="clearfix"></div>
                                                 </div>
                                             {% endif %}
-                                            {% if request.user.is_superuser %}
-                                                <div role="tabpanel" class="tab-pane tab-pane-bordered" id="users">
-                                                    <div>
-                                                    <p style="font-weight:bold;">
-                                                        {% trans "Instance owners" %}
-                                                        {% include 'add_instance_owner_block.html' %}
-                                                    </p>
-                                                    </div>
-                                                    <div class="table-responsive">
-                                                        <table class="table table-striped sortable-theme-bootstrap" data-sortable>
-                                                            <tbody class="searchable">
-                                                            {% for userinstance in userinstances %}
-                                                                <tr>
-                                                                    <td><a href="{% url 'account' userinstance.user.id %}">{{ userinstance.user }}</a></td>
-                                                                    <td style="width:30px;">
-                                                                        <form action="" method="post" style="height:10px" role="form">{% csrf_token %}
-                                                                            <input type="hidden" name="userinstance" value="{{ userinstance.pk }}">
-                                                                            <button type="submit" class="btn btn-sm btn-default" name="del_owner" title="{% trans "Delete" %}">
-                                                                                <i class="fa fa-trash"></i>
-                                                                            </button>
-                                                                        </form>
-                                                                    </td>
-                                                                </tr>
-                                                            {% endfor %}
-                                                            </tbody>
-                                                        </table>
-                                                    </div>
-                                                    <div class="clearfix"></div>
-                                                </div>
-                                            {% endif %}
                                         </div>
                                     </div>
                                 </div>
@@ -1215,7 +1252,7 @@
                                                             </tr>
                                                         </thead>
                                                         <tbody class="searchable">
-                                                            <tr><td colspan="3"><i>None ...</i></td></tr>
+                                                            <tr><td colspan="3"><i>{% trans 'None' %}...</i></td></tr>
                                                         </tbody>
                                                     </table>
                                                 </div>
@@ -1269,8 +1306,6 @@
 <script src="{% static "js/ace.js" %}" type="text/javascript" charset="utf-8"></script>
 <script>
     function get_volumes(compute_id, pool) {
-
-
         get_vol_url = "/computes/" + compute_id + "/storage/" + pool + "/volumes";
         $.getJSON(get_vol_url, function (data) {
             $("#vols").find('option').remove();
@@ -1279,8 +1314,7 @@
             $.each(data['vols'], function(i, item) {
                 $("#vols").append('<option value=' + item +'>' + item + '</option>');
 
-            });
-
+            })
         });
 
         var sto_drop = document.getElementById('select_storage');
@@ -1290,7 +1324,6 @@
         var sto_input = document.getElementById('selected_storage');
         sto_input.value = pool;
         sto_input.innerHTML = pool;
-
     }
 </script>
 
@@ -1413,7 +1446,6 @@
     });
     $(document).ready(function () {
         // set vdi url
-
         $.get("{% url 'vdi_url' vname %}", function(data) {
             $("#vdi_url_input").attr("value", data);
             $("#vdi_url").attr("href", data);
@@ -1443,6 +1475,69 @@ $(document).ready(function(){
     });
 });
 </script>
+<script>
+    function set_orderlist(obj){
+        var result = '';
+        $('#b_order label input:checked').each(function () {
+            if (result != '') result += ',';
+            result += $(this).val();
+        });
+        obj.val(result);
+    }
+$(document).ready(function () {
+    {# Boot Order Arragements #}
+    jQuery.fn.multiselect = function() {
+        $(this).each(function() {
+            var checkboxes = $(this).find("input:checkbox");
+            checkboxes.each(function() {
+                var checkbox = $(this);
+                // Highlight pre-selected checkboxes
+                if (checkbox.prop("checked"))
+                    checkbox.parent().addClass("multiselect-on");
+                // Highlight checkboxes that the user selects
+                checkbox.click(function() {
+                    if (checkbox.prop("checked"))
+                        checkbox.parent().addClass("multiselect-on");
+                    else
+                        checkbox.parent().removeClass("multiselect-on");
+                });
+            });
+        });
+    };
+    $(function() {
+     $(".multiselect").multiselect();
+    });
+
+    $('#boot_order_up').bind('click', function() {
+        $('#b_order label input:checked').each( function() {
+            var label = $(this).parent();
+            var newPos = label.index() - 1;
+            if (newPos > -1) {
+                 $('#b_order label').eq(newPos).before("<label><input type='checkbox' value='"+$(this).val()+"' name='"+$(this).val()+"' checked>"+$(this).parent().text()+"</label>");
+                 label.remove();
+            }
+            $(".multiselect").multiselect();
+        });
+        set_orderlist($("#bootorder"));
+    });
+
+    $('#boot_order_down').bind('click', function() {
+        var countOptions = $('#b_order label').size();
+        var countSelected = $('#b_order label input:checked').size();
+        $('#b_order label input:checked').each( function() {
+            var label = $(this).parent();
+            var newPos = label.index() + countSelected;
+            if (newPos < countOptions) {
+                $('#b_order label').eq(newPos).after("<label><input type='checkbox' value='"+$(this).val()+"' name='"+$(this).val()+"' checked>"+$(this).parent().text()+"</label>");
+                label.remove();
+            }
+            $(".multiselect").multiselect();
+        });
+       set_orderlist($("#bootorder"));
+    });
+
+});
+</script>
 <script>
     $(function () {
         $('.js-custom__checkbox').change(function () {
@@ -1617,7 +1712,7 @@ $(document).ready(function(){
             }
         });
     }
-    if (~$.inArray(hash, ['#media', "#disks", '#network', '#clone', '#autostart', '#xmledit', '#vncsettings', '#migrate', '#options', '#users'])) {
+    if (~$.inArray(hash, ['#boot_opt', "#disks", '#network', '#clone', '#xmledit', '#vncsettings', '#migrate', '#options', '#users'])) {
         var btnsect = $('#navbtn>li>a');
         $(btnsect).each(function () {
             if ($(this).attr('href') === '#settings') {
diff --git a/instances/views.py b/instances/views.py
index 9ee9540..e3c7628 100644
--- a/instances/views.py
+++ b/instances/views.py
@@ -52,16 +52,16 @@ def allinstances(request):
     else:
         for comp in computes:
             try:
-                all_host_vms.update(get_host_instances(request,comp))
+                all_host_vms.update(get_host_instances(request, comp))
             except libvirtError as lib_err:
                 error_messages.append(lib_err)
 
     if request.method == 'POST':
         try:
-            instances_actions(request)
+            return instances_actions(request)
         except libvirtError as lib_err:
             error_messages.append(lib_err)
-            addlogmsg(request.user.username, instance.name, lib_err.message)
+            addlogmsg(request.user.username, request.POST.get("name", "instance"), lib_err.message)
 
     view_style = settings.VIEW_INSTANCES_LIST_STYLE
 
@@ -88,10 +88,10 @@ def instances(request, compute_id):
 
     if request.method == 'POST':
         try:
-            instances_actions(request)
+            return instances_actions(request)
         except libvirtError as lib_err:
             error_messages.append(lib_err)
-            addlogmsg(request.user.username, instance.name, lib_err.message)
+            addlogmsg(request.user.username, request.POST.get("name", "instance"), lib_err.message)
 
     return render(request, 'instances.html', locals())
 
@@ -255,6 +255,8 @@ def instance(request, compute_id, vname):
         compute_nwfilters = conn.get_nwfilters()
         status = conn.get_status()
         autostart = conn.get_autostart()
+        bootmenu = conn.get_bootmenu()
+        boot_order = conn.get_bootorder()
         vcpu = conn.get_vcpu()
         cur_vcpu = conn.get_cur_vcpu()
         uuid = conn.get_uuid()
@@ -525,7 +527,7 @@ def instance(request, compute_id, vname):
                 conn.attach_disk("", target, device='cdrom', cache='none', targetbus=bus)
                 msg = _('Add CD-Rom: ' + target)
                 addlogmsg(request.user.username, instance.name, msg)
-                return HttpResponseRedirect(request.get_full_path() + '#media')
+                return HttpResponseRedirect(request.get_full_path() + '#disks')
 
             if 'detach_cdrom' in request.POST and allow_admin_or_not_template:
                 dev = request.POST.get('detach_cdrom', '')
@@ -533,7 +535,7 @@ def instance(request, compute_id, vname):
                 conn.detach_disk(dev)
                 msg = _('Detach CD-Rom: ' + dev)
                 addlogmsg(request.user.username, instance.name, msg)
-                return HttpResponseRedirect(request.get_full_path() + '#media')
+                return HttpResponseRedirect(request.get_full_path() + '#disks')
 
             if 'umount_iso' in request.POST and allow_admin_or_not_template:
                 image = request.POST.get('path', '')
@@ -541,7 +543,7 @@ def instance(request, compute_id, vname):
                 conn.umount_iso(dev, image)
                 msg = _("Mount media: " + dev)
                 addlogmsg(request.user.username, instance.name, msg)
-                return HttpResponseRedirect(request.get_full_path() + '#media')
+                return HttpResponseRedirect(request.get_full_path() + '#disks')
 
             if 'mount_iso' in request.POST and allow_admin_or_not_template:
                 image = request.POST.get('media', '')
@@ -549,7 +551,7 @@ def instance(request, compute_id, vname):
                 conn.mount_iso(dev, image)
                 msg = _("Umount media: " + dev)
                 addlogmsg(request.user.username, instance.name, msg)
-                return HttpResponseRedirect(request.get_full_path() + '#media')
+                return HttpResponseRedirect(request.get_full_path() + '#disks')
 
             if 'snapshot' in request.POST and allow_admin_or_not_template:
                 name = request.POST.get('name', '')
@@ -591,13 +593,37 @@ def instance(request, compute_id, vname):
                     conn.set_autostart(1)
                     msg = _("Set autostart")
                     addlogmsg(request.user.username, instance.name, msg)
-                    return HttpResponseRedirect(request.get_full_path() + '#autostart')
+                    return HttpResponseRedirect(request.get_full_path() + '#boot_opt')
 
                 if 'unset_autostart' in request.POST:
                     conn.set_autostart(0)
                     msg = _("Unset autostart")
                     addlogmsg(request.user.username, instance.name, msg)
-                    return HttpResponseRedirect(request.get_full_path() + '#autostart')
+                    return HttpResponseRedirect(request.get_full_path() + '#boot_opt')
+
+                if 'set_bootmenu' in request.POST:
+                    conn.set_bootmenu(1)
+                    msg = _("Enable boot menu")
+                    addlogmsg(request.user.username, instance.name, msg)
+                    return HttpResponseRedirect(request.get_full_path() + '#boot_opt')
+
+                if 'unset_bootmenu' in request.POST:
+                    conn.set_bootmenu(0)
+                    msg = _("Disable boot menu")
+                    addlogmsg(request.user.username, instance.name, msg)
+                    return HttpResponseRedirect(request.get_full_path() + '#boot_opt')
+
+                if 'set_bootorder' in request.POST:
+                    bootorder = request.POST.get('bootorder', '')
+                    if bootorder:
+                        order_list = {}
+                        for idx, val in enumerate(bootorder.split(',')):
+                            type, dev = val.split(':', 1)
+                            order_list[idx] = {"type": type, "dev": dev}
+                        conn.set_bootorder(order_list)
+                        msg = _("Set boot order")
+                        addlogmsg(request.user.username, instance.name, msg)
+                    return HttpResponseRedirect(request.get_full_path() + '#boot_opt')
 
                 if 'change_xml' in request.POST:
                     exit_xml = request.POST.get('inst_xml', '')
@@ -802,7 +828,6 @@ def instance(request, compute_id, vname):
                     msg = _("Edit options")
                     addlogmsg(request.user.username, instance.name, msg)
                     return HttpResponseRedirect(request.get_full_path() + '#options')
-
         conn.close()
 
     except libvirtError as lib_err:
@@ -837,7 +862,7 @@ def inst_status(request, compute_id, vname):
     return response
 
 
-def get_host_instances(request,comp):
+def get_host_instances(request, comp):
 
     def refresh_instance_database(comp, inst_name, info):
         def get_userinstances_info(instance):
@@ -883,7 +908,6 @@ def get_host_instances(request,comp):
     status = connection_manager.host_is_up(comp.type, comp.hostname)
 
     if status:
-
         conn = wvmHostDetails(comp, comp.login, comp.password, comp.type)
         comp_node_info = conn.get_node_info()
         comp_mem = conn.get_memory_usage()
@@ -907,6 +931,7 @@ def get_host_instances(request,comp):
 
     return all_host_vms
 
+
 def get_user_instances(request):
     all_user_vms = {}
     user_instances = UserInstance.objects.filter(user_id=request.user.id)
@@ -975,7 +1000,6 @@ def instances_actions(request):
         return response
 
     if request.user.is_superuser:
-
         if 'suspend' in request.POST:
             msg = _("Suspend")
             addlogmsg(request.user.username, instance.name, msg)
@@ -1003,7 +1027,7 @@ def inst_graph(request, compute_id, vname):
     datasets_net = {}
     cookies = {}
     points = 5
-    curent_time = time.strftime("%H:%M:%S")
+    current_time = time.strftime("%H:%M:%S")
     compute = get_object_or_404(Compute, pk=compute_id)
     response = HttpResponse()
     response['Content-Type'] = "text/javascript"
@@ -1030,18 +1054,15 @@ def inst_graph(request, compute_id, vname):
             cookies['net'] = request.COOKIES['net']
             cookies['timer'] = request.COOKIES['timer']
         except KeyError:
-            cookies['cpu'] = None
-            cookies['blk'] = None
-            cookies['net'] = None
+            cookies['cpu'] = cookies['blk'] = cookies['net'] = None
 
         if not cookies['cpu']:
-            datasets['cpu'] = [0] * points
-            datasets['timer'] = [0] * points
+            datasets['timer'] = datasets['cpu'] = [0] * points
         else:
             datasets['cpu'] = eval(cookies['cpu'])
             datasets['timer'] = eval(cookies['timer'])
 
-        datasets['timer'].append(curent_time)
+        datasets['timer'].append(current_time)
         datasets['cpu'].append(int(cpu_usage['cpu']))
 
         datasets['timer'] = check_points(datasets['timer'])
@@ -1049,8 +1070,7 @@ def inst_graph(request, compute_id, vname):
 
         for blk in blk_usage:
             if not cookies['blk']:
-                datasets_wr = [0] * points
-                datasets_rd = [0] * points
+                datasets_rd = datasets_wr = [0] * points
             else:
                 datasets['blk'] = eval(cookies['blk'])
                 datasets_rd = datasets['blk'][blk['dev']][0]
@@ -1067,8 +1087,7 @@ def inst_graph(request, compute_id, vname):
 
         for net in net_usage:
             if not cookies['net']:
-                datasets_rx = [0] * points
-                datasets_tx = [0] * points
+                datasets_tx = datasets_rx = [0] * points
             else:
                 datasets['net'] = eval(cookies['net'])
                 datasets_rx = datasets['net'][net['dev']][0]
@@ -1133,7 +1152,7 @@ def _get_random_mac_address():
 
 @login_required
 def random_mac_address(request):
-    data = {}
+    data = dict()
     data['mac'] = _get_random_mac_address()
     return HttpResponse(json.dumps(data))
 
@@ -1157,9 +1176,9 @@ def guess_clone_name(request):
 
 @login_required
 def check_instance(request, vname):
-    check_instance = Instance.objects.filter(name=vname)
+    instance = Instance.objects.filter(name=vname)
     data = {'vname': vname, 'exists': False}
-    if check_instance:
+    if instance:
         data['exists'] = True
     return HttpResponse(json.dumps(data))
 
diff --git a/networks/templates/modify_fixed_address.html b/networks/templates/modify_fixed_address.html
new file mode 100644
index 0000000..63c42f4
--- /dev/null
+++ b/networks/templates/modify_fixed_address.html
@@ -0,0 +1,53 @@
+{% load i18n %}
+{% if request.user.is_superuser %}
+    <a href="#AddFixedNet" type="button" class="btn btn-success pull-right" data-toggle="modal">
+        <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
+    </a>
+
+    <!-- Modal pool -->
+    <div class="modal fade" id="AddFixedNet" tabindex="-1" role="dialog" aria-labelledby="AddFixedNetLabel" aria-hidden="true">
+        <div class="modal-dialog">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+                    <h4 class="modal-title">{% trans "Add Fixed Address" %}</h4>
+                </div>
+                <form  method="post" action="" role="form">{% csrf_token %}
+                <div class="modal-body">
+                    <div class="row">
+                        <div class="form-group">
+                            <label class="col-sm-4 control-label">{% trans "Subnet Pool" %}</label>
+                            <div class="col-sm-6">
+                                <input type="text" readonly class="form-control" name="subnet" value="{{ ipv4_network }}" required pattern="[0-9\/\.]+">
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <label class="col-sm-4 control-label">{% trans "Name" %}</label>
+                            <div class="col-sm-6">
+                                <input type="text" class="form-control" name="name" required pattern="[a-zA-Z0-9_]+">
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <label class="col-sm-4 control-label">{% trans "Address" %}</label>
+                            <div class="col-sm-6">
+                                <input type="text" class="form-control" name="address" required pattern="[0-9\/\.]+">
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <label class="col-sm-4 control-label">{% trans "MAC" %}</label>
+                            <div class="col-sm-6">
+                                <input type="text" class="form-control" name="mac" required pattern="[0-9\/\:]+">
+                            </div>
+                        </div>
+
+                    </div>
+                </div>
+                 <div class="modal-footer">
+                    <button type="button" class="btn btn-default" data-dismiss="modal">{% trans "Close" %}</button>
+                    <button type="submit" class="btn btn-primary" name="modify_fixed_address">{% trans "Create" %}</button>
+                </div>
+                </form>
+            </div> <!-- /.modal-content -->
+        </div> <!-- /.modal-dialog -->
+    </div> <!-- /.modal -->
+{% endif %}
\ No newline at end of file
diff --git a/networks/templates/network.html b/networks/templates/network.html
index 6fa0c2e..450c393 100644
--- a/networks/templates/network.html
+++ b/networks/templates/network.html
@@ -34,6 +34,7 @@
             <!-- /.row -->
 
             {% include 'errors_block.html' %}
+            {% include 'messages_block.html' %}
 
             <div class="row">
                 <div class="col-xs-6 col-sm-4">
@@ -66,9 +67,11 @@
                     </p>
                 </div>
             </div>
-            {% if state %}
+            {#{% if state %}#}
+                <div class="row">
+                    <h3 class="page-header">{% trans "IPv4 Configuration" %}</h3>
+                </div>
                 <div class="row">
-                    <h3 class="page-header">{% trans "IPv4 configuration" %}</h3>
                     <div class="col-xs-6 col-sm-4">
                         <p>{% trans "IPv4 Forwarding:" %}</p>
                         <p>{% trans "Network:" %}</p>
@@ -102,43 +105,81 @@
                             {% endif %}
                         </p>
                         {% if ipv4_dhcp_range_start and ipv4_dhcp_range_end %}
-                            <p>{{ ipv4_dhcp_range_start }}</p>
-                            <p>{{ ipv4_dhcp_range_end }}</p>
+                            <form method="post" role="form">{% csrf_token %}
+                                {% if state %}
+                                    <p>{{ ipv4_dhcp_range_start }}</p>
+                                    <p>{{ ipv4_dhcp_range_end }}</p>
+                                {%  else %}
+                                    <p><input name="range_start" value="{{ ipv4_dhcp_range_start }}"/></p>
+                                    <p><input name="range_end" value="{{ ipv4_dhcp_range_end }}"/></p>
+                                    <div class="col-xs-10 col-sm-8">
+                                        <input type="submit" class="btn btn-primary btn-block" value="Apply"
+                                               name="modify_dhcp_range"
+                                               title="Edit DHCP Range" onclick="return confirm('{% trans "Are you sure?" %}')"/>
+                                    </div>
+                                {% endif %}
+                            </form>
                         {% endif %}
                     </div>
                 </div>
-                {% if fixed_address %}
+                {% ifequal ipv4_forward.0 'nat' %}
+                    {% if state %}
+                        {% include 'modify_fixed_address.html' %}
+                    {% endif %}
                     <div class="row">
                         <h3 class="page-header">{% trans "Fixed Address" %}</h3>
+                    </div>
+                {% endifequal %}
+                {% if fixed_address %}
+                    <div class="row">
                         <div class="col-xs-12">
                             <div class="panel-group" id="accordion">
                                 <div class="panel panel-default">
                                     <div class="panel-heading">
                                         <a data-toggle="collapse" data-parent="#accordion" href="#collapseOne">
-                                            Show
+                                            {% trans 'Show' %}
                                         </a>
                                     </div>
                                     <div id="collapseOne" class="panel-collapse collapse">
                                         <div class="panel-body">
-                                            <div class="input-append form-inline pull-right" style="">
+
+                                            <div class="input-append form-inline pull-right">
                                                 <div class="form-group">
                                                     <input type="text" class="form-control" id="filter_input">
                                                 </div>
                                                 <input type="button" class="btn btn-default" id="filter_button" value="Filter">
-                                                <button type="button" class="btn btn-default" id="filter_clear">Clear</button>
+                                                <button type="button" class="btn btn-default" id="filter_clear">{% trans 'Clear' %}</button>
                                             </div>
                                             <table class="table table-hover">
                                                 <thead>
                                                 <tr>
-                                                    <th style="text-align: center">{% trans "Address" %}</th>
                                                     <th style="text-align: center">{% trans "MAC" %}</th>
+                                                    <th style="text-align: center">{% trans "Address" %}</th>
+                                                    <th style="text-align: center">{% trans "Name" %}</th>
+                                                    <th style="text-align: center">{% trans "Action" %}</th>
                                                 </tr>
                                                 </thead>
                                                 <tbody style="text-align: center">
                                                 {% for fix in fixed_address %}
                                                     <tr>
-                                                        <td>{{ fix.host }}</td>
-                                                        <td>{{ fix.mac }}</td>
+                                                    <form method="post" role="form">{% csrf_token %}
+                                                        <td><label class="form-control" disabled="true">{{ fix.mac }}</label></td>
+                                                        <td><input class="form-control" value="{{ fix.ip }}" name="address" /></td>
+                                                        <td><input class="form-control" value="{{ fix.name }}" name="name" /></td>
+                                                            <td>
+                                                                <input hidden name="mac" value="{{ fix.mac }}"/>
+                                                                <button type="submit" class="btn btn-sm btn-primary"
+                                                                        name="modify_fixed_address"
+                                                                        title="Edit entry" onclick="return confirm('{% trans "Are you sure?" %}')">
+                                                                    <i class="glyphicon glyphicon-save"></i>
+                                                                </button>
+                                                                <button type="submit" class="btn btn-sm btn-danger"
+                                                                        name="delete_fixed_address"
+                                                                        title="Delete entry" onclick="return confirm('{% trans "Are you sure?" %}')">
+                                                                    <i class="glyphicon glyphicon-trash"></i>
+                                                                </button>
+                                                            </td>
+                                                        </form>
                                                     </tr>
                                                 {% endfor %}
                                                 </tbody>
@@ -149,7 +190,7 @@
                             </div>
                         </div>
                     </div>
-                {% endif %}
+                {#{% endif %}#}
             {% endif %}
 {% endblock %}
 {% block script %}
@@ -175,7 +216,6 @@
                 $('tbody tr:not(:Contains(\'' + filter_val + '\'))').hide();
             }
         });
-
         // add event button labeled "clear"
         $('#filter_clear').click(function (event) {
             $('#filter_input').val('');
diff --git a/networks/views.py b/networks/views.py
index 24d6bc6..ee61043 100644
--- a/networks/views.py
+++ b/networks/views.py
@@ -8,6 +8,7 @@ from networks.forms import AddNetPool
 from vrtManager.network import wvmNetwork, wvmNetworks
 from vrtManager.network import network_size
 from libvirt import libvirtError
+from django.contrib import messages
 
 
 @login_required
@@ -121,6 +122,33 @@ def network(request, compute_id, pool):
                 return HttpResponseRedirect(request.get_full_path())
             except libvirtError as lib_err:
                 error_messages.append(lib_err.message)
+        if 'modify_fixed_address' in request.POST:
+            name = request.POST.get('name', '')
+            address = request.POST.get('address', '')
+            mac = request.POST.get('mac', '')
+            try:
+                ret_val = conn.modify_fixed_address(name, address, mac)
+                messages.success(request, "Fixed Address Operation Completed.")
+                return HttpResponseRedirect(request.get_full_path())
+            except libvirtError as lib_err:
+                error_messages.append(lib_err.message)
+            except ValueError as val_err:
+                error_messages.append(val_err.message)
+        if 'delete_fixed_address' in request.POST:
+            mac = request.POST.get('mac', '')
+            conn.delete_fixed_address(mac)
+            messages.success(request, "Fixed Address is Deleted.")
+            return HttpResponseRedirect(request.get_full_path())
+
+        if 'modify_dhcp_range' in request.POST:
+            range_start = request.POST.get('range_start', '')
+            range_end = request.POST.get('range_end', '')
+            try:
+                conn.modify_dhcp_range(range_start, range_end)
+                messages.success(request, "DHCP Range is Changed.")
+                return HttpResponseRedirect(request.get_full_path())
+            except libvirtError as lib_err:
+                error_messages.append(lib_err.message)
 
     conn.close()
 
diff --git a/static/css/webvirtcloud.css b/static/css/webvirtcloud.css
index 542e8b9..2149dea 100644
--- a/static/css/webvirtcloud.css
+++ b/static/css/webvirtcloud.css
@@ -133,3 +133,21 @@ p {
     display: inline;
     min-width: 250px;
 }
+
+.multiselect {
+    width:27em;
+    height:10em;
+    border:solid 2px #c0c0c0;
+    overflow:auto;
+    padding: 0 1em;
+    margin: 0.9em;
+}
+
+.multiselect label {
+    display:block;
+}
+
+.multiselect-on {
+    color:#ffffff;
+    background-color:#000099;
+}
\ No newline at end of file
diff --git a/vrtManager/IPy.py b/vrtManager/IPy.py
index 393e468..1dba7b2 100644
--- a/vrtManager/IPy.py
+++ b/vrtManager/IPy.py
@@ -3,15 +3,14 @@ IPy - class and tools for handling of IPv4 and IPv6 addresses and networks.
 See README file for learn how to use IPy.
 
 Further Information might be available at:
-http://software.inl.fr/trac/trac.cgi/wiki/IPy
+https://github.com/haypo/python-ipy
 """
 
-# $HeadURL: https://svn.inl.fr/inl-svn/src/tools/ipy/tags/IPy-0.70/IPy.py $
-# $Id: IPy.py 19309 2009-10-29 10:21:13Z haypo $
-
-__rcsid__ = '$Id: IPy.py 19309 2009-10-29 10:21:13Z haypo $'
-__version__ = '0.70'
+__version__ = '0.83'
 
+import bisect
+import collections
+import sys
 import types
 
 # Definition of the Ranges for IPv4 IPs
@@ -21,58 +20,117 @@ IPv4ranges = {
     '0': 'PUBLIC',  # fall back
     '00000000': 'PRIVATE',  # 0/8
     '00001010': 'PRIVATE',  # 10/8
+    '0110010001': 'CARRIER_GRADE_NAT',  # 100.64/10
     '01111111': 'PRIVATE',  # 127.0/8
     '1': 'PUBLIC',  # fall back
     '1010100111111110': 'PRIVATE',  # 169.254/16
     '101011000001': 'PRIVATE',  # 172.16/12
     '1100000010101000': 'PRIVATE',  # 192.168/16
-    '11011111': 'RESERVED',  # 223/8
-    '111': 'RESERVED'  # 224/3
+    '111': 'RESERVED',  # 224/3
 }
 
 # Definition of the Ranges for IPv6 IPs
-# see also www.iana.org/assignments/ipv6-address-space,
-# www.iana.org/assignments/ipv6-tla-assignments,
-# www.iana.org/assignments/ipv6-multicast-addresses,
-# www.iana.org/assignments/ipv6-anycast-addresses
+# http://www.iana.org/assignments/ipv6-address-space/
+# http://www.iana.org/assignments/ipv6-unicast-address-assignments/
+# http://www.iana.org/assignments/ipv6-multicast-addresses/
 IPv6ranges = {
     '00000000': 'RESERVED',  # ::/8
-    '00000001': 'UNASSIGNED',  # 100::/8
-    '0000001': 'NSAP',  # 200::/7
-    '0000010': 'IPX',  # 400::/7
-    '0000011': 'UNASSIGNED',  # 600::/7
-    '00001': 'UNASSIGNED',  # 800::/5
-    '0001': 'UNASSIGNED',  # 1000::/4
-    '0010000000000000': 'RESERVED',  # 2000::/16 Reserved
-    '0010000000000001': 'ASSIGNABLE',  # 2001::/16 Sub-TLA Assignments [RFC2450]
-    '00100000000000010000000': 'ASSIGNABLE IANA',  # 2001:0000::/29 - 2001:01F8::/29 IANA
-    '00100000000000010000001': 'ASSIGNABLE APNIC',  # 2001:0200::/29 - 2001:03F8::/29 APNIC
-    '00100000000000010000010': 'ASSIGNABLE ARIN',  # 2001:0400::/29 - 2001:05F8::/29 ARIN
-    '00100000000000010000011': 'ASSIGNABLE RIPE',  # 2001:0600::/29 - 2001:07F8::/29 RIPE NCC
-    '0010000000000010': '6TO4',  # 2002::/16 "6to4" [RFC3056]
-    '0011111111111110': '6BONE',  # 3FFE::/16 6bone Testing [RFC2471]
-    '0011111111111111': 'RESERVED',  # 3FFF::/16 Reserved
-    '010': 'GLOBAL-UNICAST',  # 4000::/3
-    '011': 'UNASSIGNED',  # 6000::/3
-    '100': 'GEO-UNICAST',  # 8000::/3
-    '101': 'UNASSIGNED',  # A000::/3
-    '110': 'UNASSIGNED',  # C000::/3
-    '1110': 'UNASSIGNED',  # E000::/4
-    '11110': 'UNASSIGNED',  # F000::/5
-    '111110': 'UNASSIGNED',  # F800::/6
-    '1111110': 'UNASSIGNED',  # FC00::/7
-    '111111100': 'UNASSIGNED',  # FE00::/9
-    '1111111010': 'LINKLOCAL',  # FE80::/10
-    '1111111011': 'SITELOCAL',  # FEC0::/10
-    '11111111': 'MULTICAST',  # FF00::/8
-    '0' * 96: 'IPV4COMP',  # ::/96
-    '0' * 80 + '1' * 16: 'IPV4MAP',  # ::FFFF:0:0/96
+    '0' * 96: 'RESERVED',  # ::/96 Formerly IPV4COMP [RFC4291]
     '0' * 128: 'UNSPECIFIED',  # ::/128
-    '0' * 127 + '1': 'LOOPBACK'  # ::1/128
+    '0' * 127 + '1': 'LOOPBACK',  # ::1/128
+    '0' * 80 + '1' * 16: 'IPV4MAP',  # ::ffff:0:0/96
+    '00000000011001001111111110011011' + '0' * 64: 'WKP46TRANS',  # 0064:ff9b::/96 Well-Known-Prefix [RFC6052]
+    '00000001': 'UNASSIGNED',  # 0100::/8
+    '0000001': 'RESERVED',  # 0200::/7 Formerly NSAP [RFC4048]
+    '0000010': 'RESERVED',  # 0400::/7 Formerly IPX [RFC3513]
+    '0000011': 'RESERVED',  # 0600::/7
+    '00001': 'RESERVED',  # 0800::/5
+    '0001': 'RESERVED',  # 1000::/4
+    '001': 'GLOBAL-UNICAST',  # 2000::/3 [RFC4291]
+    '00100000000000010000000': 'SPECIALPURPOSE',  # 2001::/23 [RFC4773]
+    '00100000000000010000000000000000': 'TEREDO',  # 2001::/32 [RFC4380]
+    '00100000000000010000000000000010' + '0' * 16: 'BMWG',  # 2001:0002::/48 Benchmarking [RFC5180]
+    '0010000000000001000000000001': 'ORCHID',  # 2001:0010::/28 (Temp until 2014-03-21) [RFC4843]
+    '00100000000000010000001': 'ALLOCATED APNIC',  # 2001:0200::/23
+    '00100000000000010000010': 'ALLOCATED ARIN',  # 2001:0400::/23
+    '00100000000000010000011': 'ALLOCATED RIPE NCC',  # 2001:0600::/23
+    '00100000000000010000100': 'ALLOCATED RIPE NCC',  # 2001:0800::/23
+    '00100000000000010000101': 'ALLOCATED RIPE NCC',  # 2001:0a00::/23
+    '00100000000000010000110': 'ALLOCATED APNIC',  # 2001:0c00::/23
+    '00100000000000010000110110111000': 'DOCUMENTATION',  # 2001:0db8::/32 [RFC3849]
+    '00100000000000010000111': 'ALLOCATED APNIC',  # 2001:0e00::/23
+    '00100000000000010001001': 'ALLOCATED LACNIC',  # 2001:1200::/23
+    '00100000000000010001010': 'ALLOCATED RIPE NCC',  # 2001:1400::/23
+    '00100000000000010001011': 'ALLOCATED RIPE NCC',  # 2001:1600::/23
+    '00100000000000010001100': 'ALLOCATED ARIN',  # 2001:1800::/23
+    '00100000000000010001101': 'ALLOCATED RIPE NCC',  # 2001:1a00::/23
+    '0010000000000001000111': 'ALLOCATED RIPE NCC',  # 2001:1c00::/22
+    '00100000000000010010': 'ALLOCATED RIPE NCC',  # 2001:2000::/20
+    '001000000000000100110': 'ALLOCATED RIPE NCC',  # 2001:3000::/21
+    '0010000000000001001110': 'ALLOCATED RIPE NCC',  # 2001:3800::/22
+    '0010000000000001001111': 'RESERVED',  # 2001:3c00::/22 Possible future allocation to RIPE NCC
+    '00100000000000010100000': 'ALLOCATED RIPE NCC',  # 2001:4000::/23
+    '00100000000000010100001': 'ALLOCATED AFRINIC',  # 2001:4200::/23
+    '00100000000000010100010': 'ALLOCATED APNIC',  # 2001:4400::/23
+    '00100000000000010100011': 'ALLOCATED RIPE NCC',  # 2001:4600::/23
+    '00100000000000010100100': 'ALLOCATED ARIN',  # 2001:4800::/23
+    '00100000000000010100101': 'ALLOCATED RIPE NCC',  # 2001:4a00::/23
+    '00100000000000010100110': 'ALLOCATED RIPE NCC',  # 2001:4c00::/23
+    '00100000000000010101': 'ALLOCATED RIPE NCC',  # 2001:5000::/20
+    '0010000000000001100': 'ALLOCATED APNIC',  # 2001:8000::/19
+    '00100000000000011010': 'ALLOCATED APNIC',  # 2001:a000::/20
+    '00100000000000011011': 'ALLOCATED APNIC',  # 2001:b000::/20
+    '0010000000000010': '6TO4',  # 2002::/16 "6to4" [RFC3056]
+    '001000000000001100': 'ALLOCATED RIPE NCC',  # 2003::/18
+    '001001000000': 'ALLOCATED APNIC',  # 2400::/12
+    '001001100000': 'ALLOCATED ARIN',  # 2600::/12
+    '00100110000100000000000': 'ALLOCATED ARIN',  # 2610::/23
+    '00100110001000000000000': 'ALLOCATED ARIN',  # 2620::/23
+    '001010000000': 'ALLOCATED LACNIC',  # 2800::/12
+    '001010100000': 'ALLOCATED RIPE NCC',  # 2a00::/12
+    '001011000000': 'ALLOCATED AFRINIC',  # 2c00::/12
+    '00101101': 'RESERVED',  # 2d00::/8
+    '0010111': 'RESERVED',  # 2e00::/7
+    '0011': 'RESERVED',  # 3000::/4
+    '010': 'RESERVED',  # 4000::/3
+    '011': 'RESERVED',  # 6000::/3
+    '100': 'RESERVED',  # 8000::/3
+    '101': 'RESERVED',  # a000::/3
+    '110': 'RESERVED',  # c000::/3
+    '1110': 'RESERVED',  # e000::/4
+    '11110': 'RESERVED',  # f000::/5
+    '111110': 'RESERVED',  # f800::/6
+    '1111110': 'ULA',  # fc00::/7 [RFC4193]
+    '111111100': 'RESERVED',  # fe00::/9
+    '1111111010': 'LINKLOCAL',  # fe80::/10
+    '1111111011': 'RESERVED',  # fec0::/10 Formerly SITELOCAL [RFC4291]
+    '11111111': 'MULTICAST',  # ff00::/8
+    '1111111100000001': 'NODE-LOCAL MULTICAST',  # ff01::/16
+    '1111111100000010': 'LINK-LOCAL MULTICAST',  # ff02::/16
+    '1111111100000100': 'ADMIN-LOCAL MULTICAST',  # ff04::/16
+    '1111111100000101': 'SITE-LOCAL MULTICAST',  # ff05::/16
+    '1111111100001000': 'ORG-LOCAL MULTICAST',  # ff08::/16
+    '1111111100001110': 'GLOBAL MULTICAST',  # ff0e::/16
+    '1111111100001111': 'RESERVED MULTICAST',  # ff0f::/16
+    '111111110011': 'PREFIX-BASED MULTICAST',  # ff30::/12 [RFC3306]
+    '111111110111': 'RP-EMBEDDED MULTICAST',  # ff70::/12 [RFC3956]
 }
 
+MAX_IPV4_ADDRESS = 0xffffffff
+MAX_IPV6_ADDRESS = 0xffffffffffffffffffffffffffffffff
+IPV6_TEST_MAP = 0xffffffffffffffffffffffff00000000
+IPV6_MAP_MASK = 0x00000000000000000000ffff00000000
 
-class IPint:
+if sys.version_info >= (3,):
+    INT_TYPES = (int,)
+    STR_TYPES = (str,)
+    xrange = range
+else:
+    INT_TYPES = (int, long)
+    STR_TYPES = (str, unicode)
+
+
+class IPint(object):
     """Handling of IP addresses returning integers.
 
     Use class IP instead because some features are not implemented for
@@ -95,13 +153,13 @@ class IPint:
         If make_net is True, an IP address will be transformed into the network
         address by applying the specified netmask.
 
-        >>> print IP('127.0.0.0/8')
+        >>> print(IP('127.0.0.0/8'))
         127.0.0.0/8
-        >>> print IP('127.0.0.0/255.0.0.0')
+        >>> print(IP('127.0.0.0/255.0.0.0'))
         127.0.0.0/8
-        >>> print IP('127.0.0.0-127.255.255.255')
+        >>> print(IP('127.0.0.0-127.255.255.255'))
         127.0.0.0/8
-        >>> print IP('127.0.0.1/255.0.0.0', make_net=True)
+        >>> print(IP('127.0.0.1/255.0.0.0', make_net=True))
         127.0.0.0/8
 
         See module documentation for more examples.
@@ -117,19 +175,23 @@ class IPint:
         prefixlen = -1
 
         # handling of non string values in constructor
-        if type(data) == types.IntType or type(data) == types.LongType:
-            self.ip = long(data)
+        if isinstance(data, INT_TYPES):
+            self.ip = int(data)
             if ipversion == 0:
-                if self.ip < 0x100000000L:
+                if self.ip <= MAX_IPV4_ADDRESS:
                     ipversion = 4
                 else:
                     ipversion = 6
             if ipversion == 4:
+                if self.ip > MAX_IPV4_ADDRESS:
+                    raise ValueError("IPv4 Address can't be larger than %x: %x" % (MAX_IPV4_ADDRESS, self.ip))
                 prefixlen = 32
             elif ipversion == 6:
+                if self.ip > MAX_IPV6_ADDRESS:
+                    raise ValueError("IPv6 Address can't be larger than %x: %x" % (MAX_IPV6_ADDRESS, self.ip))
                 prefixlen = 128
             else:
-                raise ValueError, "only IPv4 and IPv6 supported"
+                raise ValueError("only IPv4 and IPv6 supported")
             self._ipversion = ipversion
             self._prefixlen = prefixlen
         # handle IP instance as an parameter
@@ -137,7 +199,7 @@ class IPint:
             self._ipversion = data._ipversion
             self._prefixlen = data._prefixlen
             self.ip = data.ip
-        else:
+        elif isinstance(data, STR_TYPES):
             # TODO: refactor me!
             # splitting of a string into IP and prefixlen et. al.
             x = data.split('-')
@@ -146,20 +208,19 @@ class IPint:
                 (ip, last) = x
                 (self.ip, parsedVersion) = parseAddress(ip)
                 if parsedVersion != 4:
-                    raise ValueError, "first-last notation only allowed for IPv4"
+                    raise ValueError("first-last notation only allowed for IPv4")
                 (last, lastversion) = parseAddress(last)
                 if lastversion != 4:
-                    raise ValueError, "last address should be IPv4, too"
+                    raise ValueError("last address should be IPv4, too")
                 if last < self.ip:
-                    raise ValueError, "last address should be larger than first"
+                    raise ValueError("last address should be larger than first")
                 size = last - self.ip
                 netbits = _count1Bits(size)
                 # make sure the broadcast is the same as the last ip
                 # otherwise it will return /16 for something like:
                 # 192.168.0.0-192.168.191.255
                 if IP('%s/%s' % (ip, 32 - netbits)).broadcast().int() != last:
-                    raise ValueError, \
-                        "the range %s is not on a network boundary." % data
+                    raise ValueError("the range %s is not on a network boundary." % data)
             elif len(x) == 1:
                 x = data.split('/')
                 # if no prefix is given use defaults
@@ -167,7 +228,7 @@ class IPint:
                     ip = x[0]
                     prefixlen = -1
                 elif len(x) > 2:
-                    raise ValueError, "only one '/' allowed in IP Address"
+                    raise ValueError("only one '/' allowed in IP Address")
                 else:
                     (ip, prefixlen) = x
                     if prefixlen.find('.') != -1:
@@ -175,23 +236,19 @@ class IPint:
                         # a.b.c.d/255.255.255.0
                         (netmask, vers) = parseAddress(prefixlen)
                         if vers != 4:
-                            raise ValueError, "netmask must be IPv4"
+                            raise ValueError("netmask must be IPv4")
                         prefixlen = _netmaskToPrefixlen(netmask)
             elif len(x) > 2:
-                raise ValueError, "only one '-' allowed in IP Address"
+                raise ValueError("only one '-' allowed in IP Address")
             else:
-                raise ValueError, "can't parse"
+                raise ValueError("can't parse")
 
             (self.ip, parsedVersion) = parseAddress(ip)
             if ipversion == 0:
                 ipversion = parsedVersion
             if prefixlen == -1:
-                if ipversion == 4:
-                    prefixlen = 32 - netbits
-                elif ipversion == 6:
-                    prefixlen = 128 - netbits
-                else:
-                    raise ValueError, "only IPv4 and IPv6 supported"
+                bits = _ipVersionToLen(ipversion)
+                prefixlen = bits - netbits
             self._ipversion = ipversion
             self._prefixlen = int(prefixlen)
 
@@ -200,7 +257,9 @@ class IPint:
 
             if not _checkNetaddrWorksWithPrefixlen(self.ip,
                                                    self._prefixlen, self._ipversion):
-                raise ValueError, "%s has invalid prefix length (%s)" % (repr(self), self._prefixlen)
+                raise ValueError("%s has invalid prefix length (%s)" % (repr(self), self._prefixlen))
+        else:
+            raise TypeError("Unsupported data type: %s" % type(data))
 
     def int(self):
         """Return the first / base / network addess as an (long) integer.
@@ -267,8 +326,7 @@ class IPint:
             if want == 2:
                 # this should work with IP and IPint
                 netmask = self.netmask()
-                if type(netmask) != types.IntType \
-                        and type(netmask) != types.LongType:
+                if not isinstance(netmask, INT_TYPES):
                     netmask = netmask.int()
                 return "/%s" % (intToIp(netmask, self._ipversion))
             elif want == 3:
@@ -279,27 +337,23 @@ class IPint:
         else:
             return ''
 
-            # We have different flavours to convert to:
-            # strFullsize   127.0.0.1    2001:0658:022a:cafe:0200:c0ff:fe8d:08fa
-            # strNormal     127.0.0.1    2001:658:22a:cafe:200:c0ff:fe8d:08fa
-            # strCompressed 127.0.0.1    2001:658:22a:cafe::1
-            # strHex        0x7F000001L  0x20010658022ACAFE0200C0FFFE8D08FA
-            # strDec        2130706433   42540616829182469433547974687817795834
+        # We have different flavours to convert to:
+        # strFullsize   127.0.0.1    2001:0658:022a:cafe:0200:c0ff:fe8d:08fa
+        # strNormal     127.0.0.1    2001:658:22a:cafe:200:c0ff:fe8d:08fa
+        # strCompressed 127.0.0.1    2001:658:22a:cafe::1
+        # strHex        0x7F000001   0x20010658022ACAFE0200C0FFFE8D08FA
+        # strDec        2130706433   42540616829182469433547974687817795834
 
     def strBin(self, wantprefixlen=None):
         """Return a string representation as a binary value.
 
-        >>> print IP('127.0.0.1').strBin()
+        >>> print(IP('127.0.0.1').strBin())
         01111111000000000000000000000001
+        >>> print(IP('2001:0658:022a:cafe:0200::1').strBin())
+        00100000000000010000011001011000000000100010101011001010111111100000001000000000000000000000000000000000000000000000000000000001
         """
 
-        if self._ipversion == 4:
-            bits = 32
-        elif self._ipversion == 6:
-            bits = 128
-        else:
-            raise ValueError, "only IPv4 and IPv6 supported"
-
+        bits = _ipVersionToLen(self._ipversion)
         if self.WantPrefixLen == None and wantprefixlen == None:
             wantprefixlen = 0
         ret = _intToBin(self.ip)
@@ -323,7 +377,7 @@ class IPint:
             return self.strFullsize(wantprefixlen)
         else:
             if self.ip >> 32 == 0xffff:
-                ipv4 = intToIp(self.ip & 0xffffffff, 4)
+                ipv4 = intToIp(self.ip & MAX_IPV4_ADDRESS, 4)
                 text = "::ffff:" + ipv4 + self._printPrefix(wantprefixlen)
                 return text
             # find the longest sequence of '0'
@@ -331,7 +385,7 @@ class IPint:
             # every element of followingzeros will contain the number of zeros
             # following the corresponding element of hextets
             followingzeros = [0] * 8
-            for i in range(len(hextets)):
+            for i in xrange(len(hextets)):
                 followingzeros[i] = _countFollowingZeros(hextets[i:])
             # compressionpos is the position where we can start removing zeros
             compressionpos = followingzeros.index(max(followingzeros))
@@ -353,9 +407,9 @@ class IPint:
     def strNormal(self, wantprefixlen=None):
         """Return a string representation in the usual format.
 
-        >>> print IP('127.0.0.1').strNormal()
+        >>> print(IP('127.0.0.1').strNormal())
         127.0.0.1
-        >>> print IP('2001:0658:022a:cafe:0200::1').strNormal()
+        >>> print(IP('2001:0658:022a:cafe:0200::1').strNormal())
         2001:658:22a:cafe:200:0:0:1
         """
 
@@ -365,73 +419,69 @@ class IPint:
         if self._ipversion == 4:
             ret = self.strFullsize(0)
         elif self._ipversion == 6:
-            ret = ':'.join([hex(x)[2:] for x in [int(x, 16) for x in self.strFullsize(0).split(':')]])
+            ret = ':'.join(["%x" % x for x in [int(x, 16) for x in self.strFullsize(0).split(':')]])
         else:
-            raise ValueError, "only IPv4 and IPv6 supported"
+            raise ValueError("only IPv4 and IPv6 supported")
 
         return ret + self._printPrefix(wantprefixlen)
 
     def strFullsize(self, wantprefixlen=None):
         """Return a string representation in the non-mangled format.
 
-        >>> print IP('127.0.0.1').strFullsize()
+        >>> print(IP('127.0.0.1').strFullsize())
         127.0.0.1
-        >>> print IP('2001:0658:022a:cafe:0200::1').strFullsize()
+        >>> print(IP('2001:0658:022a:cafe:0200::1').strFullsize())
         2001:0658:022a:cafe:0200:0000:0000:0001
         """
 
         if self.WantPrefixLen == None and wantprefixlen == None:
             wantprefixlen = 1
 
-        return intToIp(self.ip, self._ipversion).lower() + self._printPrefix(wantprefixlen)
+        return intToIp(self.ip, self._ipversion) + self._printPrefix(wantprefixlen)
 
     def strHex(self, wantprefixlen=None):
         """Return a string representation in hex format in lower case.
 
-        >>> IP('127.0.0.1').strHex()
-        '0x7f000001'
-        >>> IP('2001:0658:022a:cafe:0200::1').strHex()
-        '0x20010658022acafe0200000000000001'
+        >>> print(IP('127.0.0.1').strHex())
+        0x7f000001
+        >>> print(IP('2001:0658:022a:cafe:0200::1').strHex())
+        0x20010658022acafe0200000000000001
         """
 
         if self.WantPrefixLen == None and wantprefixlen == None:
             wantprefixlen = 0
 
-        x = hex(self.ip)
-        if x[-1] == 'L':
-            x = x[:-1]
-        return x.lower() + self._printPrefix(wantprefixlen)
+        x = '0x%x' % self.ip
+        return x + self._printPrefix(wantprefixlen)
 
     def strDec(self, wantprefixlen=None):
         """Return a string representation in decimal format.
 
-        >>> print IP('127.0.0.1').strDec()
+        >>> print(IP('127.0.0.1').strDec())
         2130706433
-        >>> print IP('2001:0658:022a:cafe:0200::1').strDec()
+        >>> print(IP('2001:0658:022a:cafe:0200::1').strDec())
         42540616829182469433547762482097946625
         """
 
         if self.WantPrefixLen == None and wantprefixlen == None:
             wantprefixlen = 0
 
-        x = str(self.ip)
-        if x[-1] == 'L':
-            x = x[:-1]
+        x = '%d' % self.ip
         return x + self._printPrefix(wantprefixlen)
 
     def iptype(self):
-        """Return a description of the IP type ('PRIVATE', 'RESERVERD', etc).
+        """Return a description of the IP type ('PRIVATE', 'RESERVED', etc).
 
-        >>> print IP('127.0.0.1').iptype()
+        >>> print(IP('127.0.0.1').iptype())
         PRIVATE
-        >>> print IP('192.168.1.1').iptype()
+        >>> print(IP('192.168.1.1').iptype())
         PRIVATE
-        >>> print IP('195.185.1.2').iptype()
+        >>> print(IP('195.185.1.2').iptype())
         PUBLIC
-        >>> print IP('::1').iptype()
+        >>> print(IP('::1').iptype())
         LOOPBACK
-        >>> print IP('2001:0658:022a:cafe:0200::1').iptype()
-        ASSIGNABLE RIPE
+        >>> print(IP('2001:0658:022a:cafe:0200::1').iptype())
+        ALLOCATED RIPE NCC
 
         The type information for IPv6 is out of sync with reality.
         """
@@ -443,15 +493,14 @@ class IPint:
         elif self._ipversion == 6:
             iprange = IPv6ranges
         else:
-            raise ValueError, "only IPv4 and IPv6 supported"
+            raise ValueError("only IPv4 and IPv6 supported")
 
         bits = self.strBin()
-        for i in range(len(bits), 0, -1):
-            if iprange.has_key(bits[:i]):
+        for i in xrange(len(bits), 0, -1):
+            if bits[:i] in iprange:
                 return iprange[bits[:i]]
         return "unknown"
 
-
     def netmask(self):
         """Return netmask as an integer.
 
@@ -460,53 +509,41 @@ class IPint:
         """
 
         # TODO: unify with prefixlenToNetmask?
-        if self._ipversion == 4:
-            locallen = 32 - self._prefixlen
-        elif self._ipversion == 6:
-            locallen = 128 - self._prefixlen
-        else:
-            raise ValueError, "only IPv4 and IPv6 supported"
-
-        return ((2L ** self._prefixlen) - 1) << locallen
+        bits = _ipVersionToLen(self._ipversion)
+        locallen = bits - self._prefixlen
 
+        return ((2 ** self._prefixlen) - 1) << locallen
 
     def strNetmask(self):
         """Return netmask as an string. Mostly useful for IPv6.
 
-        >>> print IP('195.185.0.0/16').strNetmask()
+        >>> print(IP('195.185.0.0/16').strNetmask())
         255.255.0.0
-        >>> print IP('2001:0658:022a:cafe::0/64').strNetmask()
+        >>> print(IP('2001:0658:022a:cafe::0/64').strNetmask())
         /64
         """
 
         # TODO: unify with prefixlenToNetmask?
+        # Note: call to _ipVersionToLen() also validates version is 4 or 6
+        bits = _ipVersionToLen(self._ipversion)
         if self._ipversion == 4:
-            locallen = 32 - self._prefixlen
-            return intToIp(((2L ** self._prefixlen) - 1) << locallen, 4)
+            locallen = bits - self._prefixlen
+            return intToIp(((2 ** self._prefixlen) - 1) << locallen, 4)
         elif self._ipversion == 6:
-            locallen = 128 - self._prefixlen
             return "/%d" % self._prefixlen
-        else:
-            raise ValueError, "only IPv4 and IPv6 supported"
 
     def len(self):
         """Return the length of a subnet.
 
-        >>> print IP('195.185.1.0/28').len()
+        >>> print(IP('195.185.1.0/28').len())
         16
-        >>> print IP('195.185.1.0/24').len()
+        >>> print(IP('195.185.1.0/24').len())
         256
         """
 
-        if self._ipversion == 4:
-            locallen = 32 - self._prefixlen
-        elif self._ipversion == 6:
-            locallen = 128 - self._prefixlen
-        else:
-            raise ValueError, "only IPv4 and IPv6 supported"
-
-        return 2L ** locallen
-
+        bits = _ipVersionToLen(self._ipversion)
+        locallen = bits - self._prefixlen
+        return 2 ** locallen
 
     def __nonzero__(self):
         """All IPy objects should evaluate to true in boolean context.
@@ -514,27 +551,49 @@ class IPint:
         0.0.0.0/0, the __len__() of the object becomes 0, which is used
         as the boolean value of the object.
         """
-        return 1
-
+        return True
 
     def __len__(self):
-        """Return the length of a subnet.
+        """
+        Return the length of a subnet.
 
         Called to implement the built-in function len().
-        It breaks with IPv6 Networks. Anybody knows how to fix this."""
+        It will break with large IPv6 Networks.
+        Use the object's len() instead.
+        """
+        return self.len()
 
-        # Python < 2.2 has this silly restriction which breaks IPv6
-        # how about Python >= 2.2 ... ouch - it persists!
-
-        return int(self.len())
+    def __add__(self, other):
+        """Emulate numeric objects through network aggregation"""
+        if self._ipversion != other._ipversion:
+            raise ValueError("Only networks with the same IP version can be added.")
+        if self._prefixlen != other._prefixlen:
+            raise ValueError("Only networks with the same prefixlen can be added.")
+        if self._prefixlen < 1:
+            raise ValueError("Networks with a prefixlen longer than /1 can't be added.")
+        if self > other:
+            # fixed by Skinny Puppy <skin_pup-IPy@happypoo.com>
+            return other.__add__(self)
+        if other.int() - self[-1].int() != 1:
+            raise ValueError("Only adjacent networks can be added together.")
+        ret = IP(self.int(), ipversion=self._ipversion)
+        ret._prefixlen = self.prefixlen() - 1
+        if not _checkNetaddrWorksWithPrefixlen(ret.ip, ret._prefixlen,
+                                               ret._ipversion):
+            raise ValueError("The resulting %s has invalid prefix length (%s)"
+                             % (repr(ret), ret._prefixlen))
+        return ret
 
+    def __sub__(self, other):
+        """Return the prefixes that are in this IP but not in the other"""
+        return _remove_subprefix(self, other)
 
     def __getitem__(self, key):
         """Called to implement evaluation of self[key].
 
         >>> ip=IP('127.0.0.0/30')
         >>> for x in ip:
-        ...  print repr(x)
+        ...  print(repr(x))
         ...
         IP('127.0.0.0')
         IP('127.0.0.1')
@@ -546,7 +605,9 @@ class IPint:
         IP('127.0.0.3')
         """
 
-        if type(key) != types.IntType and type(key) != types.LongType:
+        if isinstance(key, slice):
+            return [self.ip + int(x) for x in xrange(*key.indices(len(self)))]
+        if not isinstance(key, INT_TYPES):
             raise TypeError
         if key < 0:
             if abs(key) <= self.len():
@@ -557,8 +618,7 @@ class IPint:
             if key >= self.len():
                 raise IndexError
 
-        return self.ip + long(key)
-
+        return self.ip + int(key)
 
     def __contains__(self, item):
         """Called to implement membership test operators.
@@ -568,20 +628,23 @@ class IPint:
 
         >>> IP('195.185.1.1').strHex()
         '0xc3b90101'
-        >>> 0xC3B90101L in IP('195.185.1.0/24')
-        1
+        >>> 0xC3B90101 in IP('195.185.1.0/24')
+        True
         >>> '127.0.0.1' in IP('127.0.0.0/24')
-        1
+        True
         >>> IP('127.0.0.0/24') in IP('127.0.0.0/25')
-        0
+        False
         """
 
-        item = IP(item)
-        if item.ip >= self.ip and item.ip < self.ip + self.len() - item.len() + 1:
-            return 1
+        if isinstance(item, IP):
+            if item._ipversion != self._ipversion:
+                return False
         else:
-            return 0
-
+            item = IP(item)
+        if item.ip >= self.ip and item.ip < self.ip + self.len() - item.len() + 1:
+            return True
+        else:
+            return False
 
     def overlaps(self, item):
         """Check if two IP address ranges overlap.
@@ -599,7 +662,8 @@ class IPint:
         -1
         """
 
-        item = IP(item)
+        if not isinstance(item, IP):
+            item = IP(item)
         if item.ip >= self.ip and item.ip < self.ip + self.len():
             return 1
         elif self.ip >= item.ip and self.ip < item.ip + item.len():
@@ -607,7 +671,6 @@ class IPint:
         else:
             return 0
 
-
     def __str__(self):
         """Dispatch to the prefered String Representation.
 
@@ -615,7 +678,6 @@ class IPint:
 
         return self.strCompressed()
 
-
     def __repr__(self):
         """Print a representation of the Object.
 
@@ -623,69 +685,77 @@ class IPint:
         to an identical Object (without the wantprefixlen stuff - see
         module docstring.
 
-        >>> print repr(IP('10.0.0.0/24'))
+        >>> print(repr(IP('10.0.0.0/24')))
         IP('10.0.0.0/24')
         """
 
         return ("IPint('%s')" % (self.strCompressed(1)))
 
-
     def __cmp__(self, other):
         """Called by comparison operations.
 
         Should return a negative integer if self < other, zero if self
         == other, a positive integer if self > other.
 
-        Networks with different prefixlen are considered non-equal.
-        Networks with the same prefixlen and differing addresses are
-        considered non equal but are compared by their base address
-        integer value to aid sorting of IP objects.
+        Order is first determined by the address family. IPv4 addresses
+        are always smaller than IPv6 addresses:
 
-        The version of Objects is not put into consideration.
+        >>> IP('10.0.0.0') < IP('2001:db8::')
+        1
+
+        Then the first address is compared. Lower addresses are
+        always smaller:
+
+        >>> IP('10.0.0.0') > IP('10.0.0.1')
+        0
+        >>> IP('10.0.0.0/24') > IP('10.0.0.1')
+        0
+        >>> IP('10.0.1.0') > IP('10.0.0.0/24')
+        1
+        >>> IP('10.0.1.0/24') > IP('10.0.0.0/24')
+        1
+        >>> IP('10.0.1.0/24') > IP('10.0.0.0')
+        1
+
+        Then the prefix length is compared. Shorter prefixes are
+        considered smaller than longer prefixes:
 
         >>> IP('10.0.0.0/24') > IP('10.0.0.0')
-        1
-        >>> IP('10.0.0.0/24') < IP('10.0.0.0')
         0
-        >>> IP('10.0.0.0/24') < IP('12.0.0.0/24')
-        1
-        >>> IP('10.0.0.0/24') > IP('12.0.0.0/24')
+        >>> IP('10.0.0.0/24') > IP('10.0.0.0/25')
         0
+        >>> IP('10.0.0.0/24') > IP('10.0.0.0/23')
+        1
 
         """
+        if not isinstance(other, IPint):
+            raise TypeError
 
-        # Im not really sure if this is "the right thing to do"
-        if self._prefixlen < other.prefixlen():
-            return (other.prefixlen() - self._prefixlen)
-        elif self._prefixlen > other.prefixlen():
+        # Lower version -> lower result
+        if self._ipversion != other._ipversion:
+            return self._ipversion < other._ipversion and -1 or 1
 
-            # Fixed bySamuel Krempp <krempp@crans.ens-cachan.fr>:
+        # Lower start address -> lower result
+        if self.ip != other.ip:
+            return self.ip < other.ip and -1 or 1
 
-            # The bug is quite obvious really (as 99% bugs are once
-            # spotted, isn't it ? ;-) Because of precedence of
-            # multiplication by -1 over the substraction, prefixlen
-            # differences were causing the __cmp__ function to always
-            # return positive numbers, thus the function was failing
-            # the basic assumptions for a __cmp__ function.
+        # Shorter prefix length -> lower result
+        if self._prefixlen != other._prefixlen:
+            return self._prefixlen < other._prefixlen and -1 or 1
 
-            # Namely we could have (a > b AND b > a), when the
-            # prefixlen of a and b are different.  (eg let
-            # a=IP("1.0.0.0/24"); b=IP("2.0.0.0/16");) thus, anything
-            # could happen when launching a sort algorithm..
-            # everything's in order with the trivial, attached patch.
+        # No differences found
+        return 0
 
-            return (self._prefixlen - other.prefixlen()) * -1
-        else:
-            if self.ip < other.ip:
-                return -1
-            elif self.ip > other.ip:
-                return 1
-            elif self._ipversion != other._ipversion:
-                # IP('0.0.0.0'), IP('::/0')
-                return cmp(self._ipversion, other._ipversion)
-            else:
-                return 0
+    def __eq__(self, other):
+        if not isinstance(other, IPint):
+            return False
+        return self.__cmp__(other) == 0
 
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+    def __lt__(self, other):
+        return self.__cmp__(other) < 0
 
     def __hash__(self):
         """Called for the key object for dictionary operations, and by
@@ -736,8 +806,17 @@ class IP(IPint):
         >>> IP('10.0.0.0/8').netmask()
         IP('255.0.0.0')
          """
-        return IP(IPint.netmask(self))
+        return IP(IPint.netmask(self), ipversion=self._ipversion)
 
+    def _getIPv4Map(self):
+        if self._ipversion != 6:
+            return None
+        if (self.ip >> 32) != 0xffff:
+            return None
+        ipv4 = self.ip & MAX_IPV4_ADDRESS
+        if self._prefixlen != 128:
+            ipv4 = '%s/%s' % (ipv4, 32 - (128 - self._prefixlen))
+        return IP(ipv4, ipversion=4)
 
     def reverseNames(self):
         """Return a list with values forming the reverse lookup.
@@ -768,30 +847,30 @@ class IP(IPint):
             if self.len() < 2 ** 8:
                 for x in self:
                     ret.append(x.reverseName())
-            elif self.len() < 2 ** 16L:
-                for i in range(0, self.len(), 2 ** 8):
+            elif self.len() < 2 ** 16:
+                for i in xrange(0, self.len(), 2 ** 8):
                     ret.append(self[i].reverseName()[2:])
-            elif self.len() < 2 ** 24L:
-                for i in range(0, self.len(), 2 ** 16):
+            elif self.len() < 2 ** 24:
+                for i in xrange(0, self.len(), 2 ** 16):
                     ret.append(self[i].reverseName()[4:])
             else:
-                for i in range(0, self.len(), 2 ** 24):
+                for i in xrange(0, self.len(), 2 ** 24):
                     ret.append(self[i].reverseName()[6:])
             return ret
         elif self._ipversion == 6:
-            s = hex(self.ip)[2:].lower()
-            if s[-1] == 'l':
-                s = s[:-1]
+            ipv4 = self._getIPv4Map()
+            if ipv4 is not None:
+                return ipv4.reverseNames()
+            s = "%x" % self.ip
             if self._prefixlen % 4 != 0:
-                raise NotImplementedError, "can't create IPv6 reverse names at sub nibble level"
+                raise NotImplementedError("can't create IPv6 reverse names at sub nibble level")
             s = list(s)
             s.reverse()
             s = '.'.join(s)
-            first_nibble_index = int(32 - (self._prefixlen / 4)) * 2
+            first_nibble_index = int(32 - (self._prefixlen // 4)) * 2
             return ["%s.ip6.arpa." % s[first_nibble_index:]]
         else:
-            raise ValueError, "only IPv4 and IPv6 supported"
-
+            raise ValueError("only IPv4 and IPv6 supported")
 
     def reverseName(self):
         """Return the value for reverse lookup/PTR records as RFC 2317 look alike.
@@ -800,24 +879,24 @@ class IP(IPint):
         for /23. Do not use it. Better set up a zone for every
         address. See reverseName for a way to achieve that.
 
-        >>> print IP('195.185.1.1').reverseName()
+        >>> print(IP('195.185.1.1').reverseName())
         1.1.185.195.in-addr.arpa.
-        >>> print IP('195.185.1.0/28').reverseName()
+        >>> print(IP('195.185.1.0/28').reverseName())
         0-15.1.185.195.in-addr.arpa.
         >>> IP('::1:2').reverseName()
-        '2.0.0.0.1.ip6.arpa.'
+        '2.0.0.0.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.'
+        >>> IP('ff02::/64').reverseName()
+        '0.0.0.0.0.0.0.0.0.0.0.0.2.0.f.f.ip6.arpa.'
         """
 
         if self._ipversion == 4:
             s = self.strFullsize(0)
             s = s.split('.')
             s.reverse()
-            first_byte_index = int(4 - (self._prefixlen / 8))
+            first_byte_index = int(4 - (self._prefixlen // 8))
             if self._prefixlen % 8 != 0:
                 nibblepart = "%s-%s" % (
-                s[3 - (self._prefixlen / 8)], intToIp(self.ip + self.len() - 1, 4).split('.')[-1])
-                if nibblepart[-1] == 'l':
-                    nibblepart = nibblepart[:-1]
+                s[3 - (self._prefixlen // 8)], intToIp(self.ip + self.len() - 1, 4).split('.')[-1])
                 nibblepart += '.'
             else:
                 nibblepart = ""
@@ -826,23 +905,22 @@ class IP(IPint):
             return "%s%s.in-addr.arpa." % (nibblepart, s)
 
         elif self._ipversion == 6:
-            s = hex(self.ip)[2:].lower()
-            if s[-1] == 'l':
-                s = s[:-1]
+            ipv4 = self._getIPv4Map()
+            if ipv4 is not None:
+                return ipv4.reverseName()
+            s = '%032x' % self.ip
             if self._prefixlen % 4 != 0:
-                nibblepart = "%s-%s" % (s[self._prefixlen:], hex(self.ip + self.len() - 1)[2:].lower())
-                if nibblepart[-1] == 'l':
-                    nibblepart = nibblepart[:-1]
+                nibblepart = "%s-%x" % (s[self._prefixlen:], self.ip + self.len() - 1)
                 nibblepart += '.'
             else:
                 nibblepart = ""
             s = list(s)
             s.reverse()
             s = '.'.join(s)
-            first_nibble_index = int(32 - (self._prefixlen / 4)) * 2
+            first_nibble_index = int(32 - (self._prefixlen // 4)) * 2
             return "%s%s.ip6.arpa." % (nibblepart, s[first_nibble_index:])
         else:
-            raise ValueError, "only IPv4 and IPv6 supported"
+            raise ValueError("only IPv4 and IPv6 supported")
 
     def make_net(self, netmask):
         """Transform a single IP address into a network specification by
@@ -850,11 +928,11 @@ class IP(IPint):
 
         Returns a new IP instance.
 
-        >>> print IP('127.0.0.1').make_net('255.0.0.0')
+        >>> print(IP('127.0.0.1').make_net('255.0.0.0'))
         127.0.0.0/8
         """
         if '/' in str(netmask):
-            raise ValueError, "invalid netmask (%s)" % netmask
+            raise ValueError("invalid netmask (%s)" % netmask)
         return IP('%s/%s' % (self, netmask), make_net=True)
 
     def __getitem__(self, key):
@@ -862,18 +940,20 @@ class IP(IPint):
 
         >>> ip=IP('127.0.0.0/30')
         >>> for x in ip:
-        ...  print str(x)
+        ...  print(str(x))
         ...
         127.0.0.0
         127.0.0.1
         127.0.0.2
         127.0.0.3
-        >>> print str(ip[2])
+        >>> print(str(ip[2]))
         127.0.0.2
-        >>> print str(ip[-1])
+        >>> print(str(ip[-1]))
         127.0.0.3
         """
-        return IP(IPint.__getitem__(self, key))
+        if isinstance(key, slice):
+            return [IP(IPint.__getitem__(self, x), ipversion=self._ipversion) for x in xrange(*key.indices(len(self)))]
+        return IP(IPint.__getitem__(self, key), ipversion=self._ipversion)
 
     def __repr__(self):
         """Print a representation of the Object.
@@ -884,76 +964,302 @@ class IP(IPint):
 
         return ("IP('%s')" % (self.strCompressed(1)))
 
-    def __add__(self, other):
-        """Emulate numeric objects through network aggregation"""
-        if self.prefixlen() != other.prefixlen():
-            raise ValueError, "Only networks with the same prefixlen can be added."
-        if self.prefixlen < 1:
-            raise ValueError, "Networks with a prefixlen longer than /1 can't be added."
-        if self.version() != other.version():
-            raise ValueError, "Only networks with the same IP version can be added."
-        if self > other:
-            # fixed by Skinny Puppy <skin_pup-IPy@happypoo.com>
-            return other.__add__(self)
+    def get_mac(self):
+        """
+        Get the 802.3 MAC address from IPv6 RFC 2464 address, in lower case.
+        Return None if the address is an IPv4 or not a IPv6 RFC 2464 address.
+
+        >>> IP('fe80::f66d:04ff:fe47:2fae').get_mac()
+        'f4:6d:04:47:2f:ae'
+        """
+        if self._ipversion != 6:
+            return None
+        if (self.ip & 0x20000ffff000000) != 0x20000fffe000000:
+            return None
+        return '%02x:%02x:%02x:%02x:%02x:%02x' % (
+            (((self.ip >> 56) & 0xff) & 0xfd),
+            (self.ip >> 48) & 0xff,
+            (self.ip >> 40) & 0xff,
+            (self.ip >> 16) & 0xff,
+            (self.ip >> 8) & 0xff,
+            self.ip & 0xff,
+        )
+
+    def v46map(self):
+        """
+        Returns the IPv6 mapped address of an IPv4 address, or the corresponding
+        IPv4 address if the IPv6 address is in the appropriate range.
+        Raises a ValueError if the IPv6 address is not translatable. See RFC 4291.
+
+        >>> IP('192.168.1.1').v46map()
+        IP('::ffff:192.168.1.1')
+        >>> IP('::ffff:192.168.1.1').v46map()
+        IP('192.168.1.1')
+        """
+        if self._ipversion == 4:
+            return IP(str(IPV6_MAP_MASK + self.ip) +
+                      "/%s" % (self._prefixlen + 96))
         else:
-            ret = IP(self.int())
-            ret._prefixlen = self.prefixlen() - 1
-            return ret
+            if self.ip & IPV6_TEST_MAP == IPV6_MAP_MASK:
+                return IP(str(self.ip - IPV6_MAP_MASK) +
+                          "/%s" % (self._prefixlen - 96))
+        raise ValueError("%s cannot be converted to an IPv4 address."
+                         % repr(self))
+
+
+class IPSet(collections.MutableSet):
+    def __init__(self, iterable=[]):
+        # Make sure it's iterable, otherwise wrap
+        if not isinstance(iterable, collections.Iterable):
+            raise TypeError("'%s' object is not iterable" % type(iterable).__name__)
+
+        # Make sure we only accept IP objects
+        for prefix in iterable:
+            if not isinstance(prefix, IP):
+                raise ValueError('Only IP objects can be added to an IPSet')
+
+        # Store and optimize
+        self.prefixes = iterable[:]
+        self.optimize()
+
+    def __contains__(self, ip):
+        valid_masks = self.prefixtable.keys()
+        if isinstance(ip, IP):
+            # Don't dig through more-specific ranges
+            ip_mask = ip._prefixlen
+            valid_masks = [x for x in valid_masks if x <= ip_mask]
+        for mask in sorted(valid_masks):
+            i = bisect.bisect(self.prefixtable[mask], ip)
+            # Because of sorting order, a match can only occur in the prefix
+            # that comes before the result of the search.
+            if i and ip in self.prefixtable[mask][i - 1]:
+                return True
+
+    def __iter__(self):
+        for prefix in self.prefixes:
+            yield prefix
+
+    def __len__(self):
+        return self.len()
+
+    def __add__(self, other):
+        return IPSet(self.prefixes + other.prefixes)
+
+    def __sub__(self, other):
+        new = IPSet(self.prefixes)
+        for prefix in other:
+            new.discard(prefix)
+        return new
+
+    def __and__(self, other):
+        left = iter(self.prefixes)
+        right = iter(other.prefixes)
+        result = []
+        try:
+            l = next(left)
+            r = next(right)
+            while True:
+                # iterate over prefixes in order, keeping the smaller of the
+                # two if they overlap
+                if l in r:
+                    result.append(l)
+                    l = next(left)
+                    continue
+                elif r in l:
+                    result.append(r)
+                    r = next(right)
+                    continue
+                if l < r:
+                    l = next(left)
+                else:
+                    r = next(right)
+        except StopIteration:
+            return IPSet(result)
+
+    def __repr__(self):
+        return '%s([' % self.__class__.__name__ + ', '.join(map(repr, self.prefixes)) + '])'
+
+    def len(self):
+        return sum(prefix.len() for prefix in self.prefixes)
+
+    def add(self, value):
+        # Make sure it's iterable, otherwise wrap
+        if not isinstance(value, collections.Iterable):
+            value = [value]
+
+        # Check type
+        for prefix in value:
+            if not isinstance(prefix, IP):
+                raise ValueError('Only IP objects can be added to an IPSet')
+
+        # Append and optimize
+        self.prefixes.extend(value)
+        self.optimize()
+
+    def discard(self, value):
+        # Make sure it's iterable, otherwise wrap
+        if not isinstance(value, collections.Iterable):
+            value = [value]
+
+        # This is much faster than iterating over the addresses
+        if isinstance(value, IPSet):
+            value = value.prefixes
+
+        # Remove
+        for del_prefix in value:
+            if not isinstance(del_prefix, IP):
+                raise ValueError('Only IP objects can be removed from an IPSet')
+
+            # First check if this prefix contains anything in our list
+            found = False
+            d = 0
+            for i in range(len(self.prefixes)):
+                if self.prefixes[i - d] in del_prefix:
+                    self.prefixes.pop(i - d)
+                    d = d + 1
+                    found = True
+
+            if found:
+                # If the prefix was bigger than an existing prefix, then it's
+                # certainly not a subset of one, so skip the rest
+                continue
+
+            # Maybe one of our prefixes contains this prefix
+            found = False
+            for i in range(len(self.prefixes)):
+                if del_prefix in self.prefixes[i]:
+                    self.prefixes[i:i + 1] = self.prefixes[i] - del_prefix
+                    break
+
+        self.optimize()
+
+    def isdisjoint(self, other):
+        left = iter(self.prefixes)
+        right = iter(other.prefixes)
+        try:
+            l = next(left)
+            r = next(right)
+            while True:
+                if l in r or r in l:
+                    return False
+                if l < r:
+                    l = next(left)
+                else:
+                    r = next(right)
+        except StopIteration:
+            return True
+
+    def optimize(self):
+        # The algorithm below *depends* on the sort order
+        self.prefixes.sort()
+
+        # First eliminate all values that are a subset of other values
+        addrlen = len(self.prefixes)
+        i = 0
+        while i < addrlen:
+            # Everything that might be inside this prefix follows
+            # directly behind it
+            j = i + 1
+            while j < addrlen and self.prefixes[j] in self.prefixes[i]:
+                # Mark for deletion by overwriting with None
+                self.prefixes[j] = None
+                j += 1
+
+            # Continue where we left off
+            i = j
+
+        # Try to merge as many prefixes as possible
+        run_again = True
+        while run_again:
+            # Filter None values. This happens when a subset is eliminated
+            # above, or when two prefixes are merged below
+            self.prefixes = [a for a in self.prefixes if a is not None]
+
+            # We'll set run_again to True when we make changes that require
+            # re-evaluation of the whole list
+            run_again = False
+
+            # We can merge two prefixes that have the same version, same
+            # prefix length and differ only on the last bit of the prefix
+            addrlen = len(self.prefixes)
+            i = 0
+            while i < addrlen - 1:
+                j = i + 1
+
+                try:
+                    # The next line will throw an exception when merging
+                    # is not possible
+                    self.prefixes[i] += self.prefixes[j]
+                    self.prefixes[j] = None
+                    i = j + 1
+                    run_again = True
+                except ValueError:
+                    # Can't be merged, see if position j can be merged
+                    i = j
+
+        # O(n) insertion now by prefix means faster searching on __contains__
+        # when lots of ranges with the same length exist
+        self.prefixtable = {}
+        for address in self.prefixes:
+            try:
+                self.prefixtable[address._prefixlen].append(address)
+            except KeyError:
+                self.prefixtable[address._prefixlen] = [address]
 
 
 def _parseAddressIPv6(ipstr):
     """
     Internal function used by parseAddress() to parse IPv6 address with ':'.
 
-    >>> _parseAddressIPv6('::')
-    0L
-    >>> _parseAddressIPv6('::1')
-    1L
-    >>> _parseAddressIPv6('0:0:0:0:0:0:0:1')
-    1L
-    >>> _parseAddressIPv6('0:0:0::0:0:1')
-    1L
-    >>> _parseAddressIPv6('0:0:0:0:0:0:0:0')
-    0L
-    >>> _parseAddressIPv6('0:0:0::0:0:0')
-    0L
+    >>> print(_parseAddressIPv6('::'))
+    0
+    >>> print(_parseAddressIPv6('::1'))
+    1
+    >>> print(_parseAddressIPv6('0:0:0:0:0:0:0:1'))
+    1
+    >>> print(_parseAddressIPv6('0:0:0::0:0:1'))
+    1
+    >>> print(_parseAddressIPv6('0:0:0:0:0:0:0:0'))
+    0
+    >>> print(_parseAddressIPv6('0:0:0::0:0:0'))
+    0
 
-    >>> _parseAddressIPv6('FEDC:BA98:7654:3210:FEDC:BA98:7654:3210')
-    338770000845734292534325025077361652240L
-    >>> _parseAddressIPv6('1080:0000:0000:0000:0008:0800:200C:417A')
-    21932261930451111902915077091070067066L
-    >>> _parseAddressIPv6('1080:0:0:0:8:800:200C:417A')
-    21932261930451111902915077091070067066L
-    >>> _parseAddressIPv6('1080:0::8:800:200C:417A')
-    21932261930451111902915077091070067066L
-    >>> _parseAddressIPv6('1080::8:800:200C:417A')
-    21932261930451111902915077091070067066L
-    >>> _parseAddressIPv6('FF01:0:0:0:0:0:0:43')
-    338958331222012082418099330867817087043L
-    >>> _parseAddressIPv6('FF01:0:0::0:0:43')
-    338958331222012082418099330867817087043L
-    >>> _parseAddressIPv6('FF01::43')
-    338958331222012082418099330867817087043L
-    >>> _parseAddressIPv6('0:0:0:0:0:0:13.1.68.3')
-    218186755L
-    >>> _parseAddressIPv6('::13.1.68.3')
-    218186755L
-    >>> _parseAddressIPv6('0:0:0:0:0:FFFF:129.144.52.38')
-    281472855454758L
-    >>> _parseAddressIPv6('::FFFF:129.144.52.38')
-    281472855454758L
-    >>> _parseAddressIPv6('1080:0:0:0:8:800:200C:417A')
-    21932261930451111902915077091070067066L
-    >>> _parseAddressIPv6('1080::8:800:200C:417A')
-    21932261930451111902915077091070067066L
-    >>> _parseAddressIPv6('::1:2:3:4:5:6')
-    1208962713947218704138246L
-    >>> _parseAddressIPv6('1:2:3:4:5:6::')
-    5192455318486707404433266432802816L
+    >>> print(_parseAddressIPv6('FEDC:BA98:7654:3210:FEDC:BA98:7654:3210'))
+    338770000845734292534325025077361652240
+    >>> print(_parseAddressIPv6('1080:0000:0000:0000:0008:0800:200C:417A'))
+    21932261930451111902915077091070067066
+    >>> print(_parseAddressIPv6('1080:0:0:0:8:800:200C:417A'))
+    21932261930451111902915077091070067066
+    >>> print(_parseAddressIPv6('1080:0::8:800:200C:417A'))
+    21932261930451111902915077091070067066
+    >>> print(_parseAddressIPv6('1080::8:800:200C:417A'))
+    21932261930451111902915077091070067066
+    >>> print(_parseAddressIPv6('FF01:0:0:0:0:0:0:43'))
+    338958331222012082418099330867817087043
+    >>> print(_parseAddressIPv6('FF01:0:0::0:0:43'))
+    338958331222012082418099330867817087043
+    >>> print(_parseAddressIPv6('FF01::43'))
+    338958331222012082418099330867817087043
+    >>> print(_parseAddressIPv6('0:0:0:0:0:0:13.1.68.3'))
+    218186755
+    >>> print(_parseAddressIPv6('::13.1.68.3'))
+    218186755
+    >>> print(_parseAddressIPv6('0:0:0:0:0:FFFF:129.144.52.38'))
+    281472855454758
+    >>> print(_parseAddressIPv6('::FFFF:129.144.52.38'))
+    281472855454758
+    >>> print(_parseAddressIPv6('1080:0:0:0:8:800:200C:417A'))
+    21932261930451111902915077091070067066
+    >>> print(_parseAddressIPv6('1080::8:800:200C:417A'))
+    21932261930451111902915077091070067066
+    >>> print(_parseAddressIPv6('::1:2:3:4:5:6'))
+    1208962713947218704138246
+    >>> print(_parseAddressIPv6('1:2:3:4:5:6::'))
+    5192455318486707404433266432802816
     """
 
     # Split string into a list, example:
-    # '1080:200C::417A' => ['1080', '200C', '417A'] and fill_pos=2
+    #   '1080:200C::417A' => ['1080', '200C', '417A'] and fill_pos=2
     # and fill_pos is the position of '::' in the list
     items = []
     index = 0
@@ -987,7 +1293,7 @@ def _parseAddressIPv6(ipstr):
 
     if items and '.' in items[-1]:
         # IPv6 ending with IPv4 like '::ffff:192.168.0.1'
-        if not (fill_pos <= len(items) - 1):
+        if (fill_pos is not None) and not (fill_pos <= len(items) - 1):
             # Invalid IPv6: 'ffff:192.168.0.1::'
             raise ValueError("%r: Invalid IPv6 address: '::' after IPv4" % ipstr)
         value = parseAddress(items[-1])[0]
@@ -1007,12 +1313,12 @@ def _parseAddressIPv6(ipstr):
         raise ValueError("%r: Invalid IPv6 address: should have 8 hextets" % ipstr)
 
     # Convert strings to long integer
-    value = 0L
+    value = 0
     index = 0
     for item in items:
         try:
             item = int(item, 16)
-            error = not (0 <= item <= 0xFFFF)
+            error = not (0 <= item <= 0xffff)
         except ValueError:
             error = True
         if error:
@@ -1029,99 +1335,122 @@ def parseAddress(ipstr):
 
     Following address formats are recognized:
 
-    >>> parseAddress('0x0123456789abcdef')           # IPv4 if <= 0xffffffff else IPv6
-    (81985529216486895L, 6)
-    >>> parseAddress('123.123.123.123')              # IPv4
-    (2071690107L, 4)
-    >>> parseAddress('123.123')                      # 0-padded IPv4
-    (2071658496L, 4)
-    >>> parseAddress('1080:0000:0000:0000:0008:0800:200C:417A')
-    (21932261930451111902915077091070067066L, 6)
-    >>> parseAddress('1080:0:0:0:8:800:200C:417A')
-    (21932261930451111902915077091070067066L, 6)
-    >>> parseAddress('1080:0::8:800:200C:417A')
-    (21932261930451111902915077091070067066L, 6)
-    >>> parseAddress('::1')
-    (1L, 6)
-    >>> parseAddress('::')
-    (0L, 6)
-    >>> parseAddress('0:0:0:0:0:FFFF:129.144.52.38')
-    (281472855454758L, 6)
-    >>> parseAddress('::13.1.68.3')
-    (218186755L, 6)
-    >>> parseAddress('::FFFF:129.144.52.38')
-    (281472855454758L, 6)
+    >>> def testParseAddress(address):
+    ...     ip, version = parseAddress(address)
+    ...     print(("%s (IPv%s)" % (ip, version)))
+    ...
+    >>> testParseAddress('0x0123456789abcdef')           # IPv4 if <= 0xffffffff else IPv6
+    81985529216486895 (IPv6)
+    >>> testParseAddress('123.123.123.123')              # IPv4
+    2071690107 (IPv4)
+    >>> testParseAddress('123.123')                      # 0-padded IPv4
+    2071658496 (IPv4)
+    >>> testParseAddress('127')
+    2130706432 (IPv4)
+    >>> testParseAddress('255')
+    4278190080 (IPv4)
+    >>> testParseAddress('256')
+    256 (IPv4)
+    >>> testParseAddress('108000000000000000080800200C417A')
+    21932261930451111902915077091070067066 (IPv6)
+    >>> testParseAddress('0x108000000000000000080800200C417A')
+    21932261930451111902915077091070067066 (IPv6)
+    >>> testParseAddress('1080:0000:0000:0000:0008:0800:200C:417A')
+    21932261930451111902915077091070067066 (IPv6)
+    >>> testParseAddress('1080:0:0:0:8:800:200C:417A')
+    21932261930451111902915077091070067066 (IPv6)
+    >>> testParseAddress('1080:0::8:800:200C:417A')
+    21932261930451111902915077091070067066 (IPv6)
+    >>> testParseAddress('::1')
+    1 (IPv6)
+    >>> testParseAddress('::')
+    0 (IPv6)
+    >>> testParseAddress('0:0:0:0:0:FFFF:129.144.52.38')
+    281472855454758 (IPv6)
+    >>> testParseAddress('::13.1.68.3')
+    218186755 (IPv6)
+    >>> testParseAddress('::FFFF:129.144.52.38')
+    281472855454758 (IPv6)
     """
 
-    if ipstr.startswith('0x'):
-        ret = long(ipstr[2:], 16)
-        if ret > 0xffffffffffffffffffffffffffffffffL:
-            raise ValueError, "%r: IP Address can't be bigger than 2^128" % (ipstr)
-        if ret < 0x100000000L:
-            return (ret, 4)
+    try:
+        hexval = int(ipstr, 16)
+    except ValueError:
+        hexval = None
+    try:
+        intval = int(ipstr, 10)
+    except ValueError:
+        intval = None
+
+    if ipstr.startswith('0x') and hexval is not None:
+        if hexval > MAX_IPV6_ADDRESS:
+            raise ValueError("IP Address can't be larger than %x: %x" % (MAX_IPV6_ADDRESS, hexval))
+        if hexval <= MAX_IPV4_ADDRESS:
+            return (hexval, 4)
         else:
-            return (ret, 6)
+            return (hexval, 6)
 
     if ipstr.find(':') != -1:
         return (_parseAddressIPv6(ipstr), 6)
 
-    elif len(ipstr) == 32:
+    elif len(ipstr) == 32 and hexval is not None:
         # assume IPv6 in pure hexadecimal notation
-        return (long(ipstr, 16), 6)
+        return (hexval, 6)
 
-    elif ipstr.find('.') != -1 or (len(ipstr) < 4 and int(ipstr) < 256):
+    elif ipstr.find('.') != -1 or (intval is not None and intval < 256):
         # assume IPv4  ('127' gets interpreted as '127.0.0.0')
         bytes = ipstr.split('.')
         if len(bytes) > 4:
-            raise ValueError, "IPv4 Address with more than 4 bytes"
+            raise ValueError("IPv4 Address with more than 4 bytes")
         bytes += ['0'] * (4 - len(bytes))
-        bytes = [long(x) for x in bytes]
+        bytes = [int(x) for x in bytes]
         for x in bytes:
             if x > 255 or x < 0:
-                raise ValueError, "%r: single byte must be 0 <= byte < 256" % (ipstr)
+                raise ValueError("%r: single byte must be 0 <= byte < 256" % (ipstr))
         return ((bytes[0] << 24) + (bytes[1] << 16) + (bytes[2] << 8) + bytes[3], 4)
 
-    else:
+    elif intval is not None:
         # we try to interprete it as a decimal digit -
         # this ony works for numbers > 255 ... others
         # will be interpreted as IPv4 first byte
-        ret = long(ipstr, 10)
-        if ret > 0xffffffffffffffffffffffffffffffffL:
-            raise ValueError, "IP Address can't be bigger than 2^128"
-        if ret <= 0xffffffffL:
-            return (ret, 4)
+        if intval > MAX_IPV6_ADDRESS:
+            raise ValueError("IP Address can't be larger than %x: %x" % (MAX_IPV6_ADDRESS, intval))
+        if intval <= MAX_IPV4_ADDRESS:
+            return (intval, 4)
         else:
-            return (ret, 6)
+            return (intval, 6)
+
+    raise ValueError("IP Address format was invalid: %s" % ipstr)
 
 
 def intToIp(ip, version):
     """Transform an integer string into an IP address."""
 
-    # just to be sure and hoping for Python 2.22
-    ip = long(ip)
+    # just to be sure and hoping for Python 2.2
+    ip = int(ip)
 
     if ip < 0:
-        raise ValueError, "IPs can't be negative: %d" % (ip)
+        raise ValueError("IPs can't be negative: %d" % (ip))
 
     ret = ''
     if version == 4:
-        if ip > 0xffffffffL:
-            raise ValueError, "IPv4 Addresses can't be larger than 0xffffffff: %s" % (hex(ip))
-        for l in range(4):
-            ret = str(ip & 0xffL) + '.' + ret
+        if ip > MAX_IPV4_ADDRESS:
+            raise ValueError("IPv4 Address can't be larger than %x: %x" % (MAX_IPV4_ADDRESS, ip))
+        for l in xrange(4):
+            ret = str(ip & 0xff) + '.' + ret
             ip = ip >> 8
         ret = ret[:-1]
     elif version == 6:
-        if ip > 0xffffffffffffffffffffffffffffffffL:
-            raise ValueError, "IPv6 Addresses can't be larger than 0xffffffffffffffffffffffffffffffff: %s" % (hex(ip))
-        l = '0' * 32 + hex(ip)[2:-1]
-        for x in range(1, 33):
+        if ip > MAX_IPV6_ADDRESS:
+            raise ValueError("IPv6 Address can't be larger than %x: %x" % (MAX_IPV6_ADDRESS, ip))
+        l = "%032x" % ip
+        for x in xrange(1, 33):
             ret = l[-x] + ret
             if x % 4 == 0:
                 ret = ':' + ret
         ret = ret[1:]
     else:
-        raise ValueError, "only IPv4 and IPv6 supported"
+        raise ValueError("only IPv4 and IPv6 supported")
 
     return ret
 
@@ -1137,7 +1466,7 @@ def _ipVersionToLen(version):
     Traceback (most recent call last):
       File "<stdin>", line 1, in ?
       File "IPy.py", line 1076, in _ipVersionToLen
-        raise ValueError, "only IPv4 and IPv6 supported"
+        raise ValueError("only IPv4 and IPv6 supported")
     ValueError: only IPv4 and IPv6 supported
     """
 
@@ -1146,7 +1475,7 @@ def _ipVersionToLen(version):
     elif version == 6:
         return 128
     else:
-        raise ValueError, "only IPv4 and IPv6 supported"
+        raise ValueError("only IPv4 and IPv6 supported")
 
 
 def _countFollowingZeros(l):
@@ -1169,15 +1498,10 @@ def _intToBin(val):
     """Return the binary representation of an integer as string."""
 
     if val < 0:
-        raise ValueError, "Only positive values allowed"
-    s = hex(val).lower()
+        raise ValueError("Only positive values allowed")
+    s = "%x" % val
     ret = ''
-    if s[-1] == 'l':
-        s = s[:-1]
-    for x in s[2:]:
-        if __debug__:
-            if not _BitTable.has_key(x):
-                raise AssertionError, "hex() returned strange result"
+    for x in s:
         ret += _BitTable[x]
     # remove leading zeros
     while ret[0] == '0' and len(ret) > 1:
@@ -1197,10 +1521,10 @@ def _count1Bits(num):
 def _count0Bits(num):
     """Find the highest bit set to 0 in an integer."""
 
-    # this could be so easy if _count1Bits(~long(num)) would work as excepted
-    num = long(num)
+    # this could be so easy if _count1Bits(~int(num)) would work as excepted
+    num = int(num)
     if num < 0:
-        raise ValueError, "Only positive Numbers please: %s" % (num)
+        raise ValueError("Only positive Numbers please: %s" % (num))
     ret = 0
     while num > 0:
         if num & 1 == 1:
@@ -1216,13 +1540,13 @@ def _checkPrefix(ip, prefixlen, version):
     Checks if the variant part of a prefix only has 0s, and the length is
     correct.
 
-    >>> _checkPrefix(0x7f000000L, 24, 4)
+    >>> _checkPrefix(0x7f000000, 24, 4)
     1
-    >>> _checkPrefix(0x7f000001L, 24, 4)
+    >>> _checkPrefix(0x7f000001, 24, 4)
     0
-    >>> repr(_checkPrefix(0x7f000001L, -1, 4))
+    >>> repr(_checkPrefix(0x7f000001, -1, 4))
     'None'
-    >>> repr(_checkPrefix(0x7f000001L, 33, 4))
+    >>> repr(_checkPrefix(0x7f000001, 33, 4))
     'None'
     """
 
@@ -1245,7 +1569,7 @@ def _checkPrefix(ip, prefixlen, version):
 def _checkNetmask(netmask, masklen):
     """Checks if a netmask is expressable as a prefixlen."""
 
-    num = long(netmask)
+    num = int(netmask)
     bits = masklen
 
     # remove zero bits at the end
@@ -1257,17 +1581,17 @@ def _checkNetmask(netmask, masklen):
     # now check if the rest consists only of ones
     while bits > 0:
         if (num & 1) == 0:
-            raise ValueError, "Netmask %s can't be expressed as an prefix." % (hex(netmask))
+            raise ValueError("Netmask 0x%x can't be expressed as an prefix." % netmask)
         num = num >> 1
         bits -= 1
 
 
 def _checkNetaddrWorksWithPrefixlen(net, prefixlen, version):
     """Check if a base addess of a network is compatible with a prefixlen"""
-    if net & _prefixlenToNetmask(prefixlen, version) == net:
-        return 1
-    else:
-        return 0
+    try:
+        return (net & _prefixlenToNetmask(prefixlen, version) == net)
+    except ValueError:
+        return False
 
 
 def _netmaskToPrefixlen(netmask):
@@ -1292,8 +1616,28 @@ def _prefixlenToNetmask(prefixlen, version):
     if prefixlen == 0:
         return 0
     elif prefixlen < 0:
-        raise ValueError, "Prefixlen must be > 0"
-    return ((2L << prefixlen - 1) - 1) << (_ipVersionToLen(version) - prefixlen)
+        raise ValueError("Prefixlen must be > 0")
+    return ((2 << prefixlen - 1) - 1) << (_ipVersionToLen(version) - prefixlen)
+
+
+def _remove_subprefix(prefix, subprefix):
+    if prefix in subprefix:
+        # Nothing left
+        return IPSet()
+
+    if subprefix not in prefix:
+        # That prefix isn't even in here
+        return IPSet([IP(prefix)])
+
+    # Start cutting in half, recursively
+    prefixes = [
+        IP('%s/%d' % (prefix[0], prefix._prefixlen + 1)),
+        IP('%s/%d' % (prefix[int(prefix.len() / 2)], prefix._prefixlen + 1)),
+    ]
+    if subprefix in prefixes[0]:
+        return _remove_subprefix(prefixes[0], subprefix) + IPSet([prefixes[1]])
+    else:
+        return IPSet([prefixes[0]]) + _remove_subprefix(prefixes[1], subprefix)
 
 
 if __name__ == "__main__":
diff --git a/vrtManager/create.py b/vrtManager/create.py
index 5a41a6a..fd3203a 100644
--- a/vrtManager/create.py
+++ b/vrtManager/create.py
@@ -118,9 +118,13 @@ class wvmCreate(wvmConnect):
         vol = self.get_volume_by_path(vol_path)
         return vol.storagePoolLookupByVolume()
 
-    def clone_from_template(self, clone, template, metadata=False, owner=default_owner):
+    def clone_from_template(self, clone, template, storage=None, metadata=False, owner=default_owner):
         vol = self.get_volume_by_path(template)
-        stg = vol.storagePoolLookupByVolume()
+        if not storage:
+            stg = vol.storagePoolLookupByVolume()
+        else:
+            stg = self.get_storage(storage)
+
         storage_type = util.get_xml_path(stg.XMLDesc(0), "/pool/@type")
         format = util.get_xml_path(vol.XMLDesc(0), "/volume/target/format/@type")
         if storage_type == 'dir':
diff --git a/vrtManager/instance.py b/vrtManager/instance.py
index 6ebb5c8..143465b 100644
--- a/vrtManager/instance.py
+++ b/vrtManager/instance.py
@@ -201,7 +201,6 @@ class wvmInstance(wvmConnect):
 
         return util.get_xml_path(self._XMLDesc(0), func=filterrefs)
 
-
     def get_description(self):
         description = util.get_xml_path(self._XMLDesc(0), "/domain/description")
         return description if description else ''
@@ -248,13 +247,8 @@ class wvmInstance(wvmConnect):
     def get_disk_devices(self):
         def disks(doc):
             result = []
-            dev = None
-            volume = None
-            storage = None
-            src_fl = None
-            disk_format = None
-            used_size = None
-            disk_size = None
+            dev = volume = storage = src_file = None
+            disk_format = used_size = disk_size = disk_cache = None
             
             for disk in doc.xpath('/domain/devices/disk'):
                 device = disk.xpath('@device')[0]
@@ -262,13 +256,17 @@ class wvmInstance(wvmConnect):
                     try:
                         dev = disk.xpath('target/@dev')[0]
                         bus = disk.xpath('target/@bus')[0]
-                        src_fl = disk.xpath('source/@file|source/@dev|source/@name|source/@volume')[0]
+                        src_file = disk.xpath('source/@file|source/@dev|source/@name|source/@volume')[0]
                         try:
                             disk_format = disk.xpath('driver/@type')[0]
                         except:
                             pass
                         try:
-                            vol = self.get_volume_by_path(src_fl)
+                            disk_cache = disk.xpath('driver/@cache')[0]
+                        except:
+                            pass
+                        try:
+                            vol = self.get_volume_by_path(src_file)
                             volume = vol.name()
 
                             disk_size = vol.info()[1]
@@ -276,13 +274,13 @@ class wvmInstance(wvmConnect):
                             stg = vol.storagePoolLookupByVolume()
                             storage = stg.name()
                         except libvirtError:
-                            volume = src_fl
+                            volume = src_file
                     except:
                         pass
                     finally:
                         result.append(
-                            {'dev': dev, 'bus': bus, 'image': volume, 'storage': storage, 'path': src_fl,
-                             'format': disk_format, 'size': disk_size, 'used': used_size})
+                            {'dev': dev, 'bus': bus, 'image': volume, 'storage': storage, 'path': src_file,
+                             'format': disk_format, 'size': disk_size, 'used': used_size, 'cache': disk_cache})
             return result
 
         return util.get_xml_path(self._XMLDesc(0), func=disks)
@@ -290,10 +288,8 @@ class wvmInstance(wvmConnect):
     def get_media_devices(self):
         def disks(doc):
             result = []
-            dev = None
-            volume = None
-            storage = None
-            src_fl = None
+            dev = volume = storage = None
+            src_file = None
             for media in doc.xpath('/domain/devices/disk'):
                 device = media.xpath('@device')[0]
                 if device == 'cdrom':
@@ -301,22 +297,137 @@ class wvmInstance(wvmConnect):
                         dev = media.xpath('target/@dev')[0]
                         bus = media.xpath('target/@bus')[0]
                         try:
-                            src_fl = media.xpath('source/@file')[0]
-                            vol = self.get_volume_by_path(src_fl)
+                            src_file = media.xpath('source/@file')[0]
+                            vol = self.get_volume_by_path(src_file)
                             volume = vol.name()
                             stg = vol.storagePoolLookupByVolume()
                             storage = stg.name()
                         except:
-                            src_fl = None
-                            volume = src_fl
+                            src_file = None
+                            volume = src_file
                     except:
                         pass
                     finally:
-                        result.append({'dev': dev, 'image': volume, 'storage': storage, 'path': src_fl, 'bus': bus})
+                        result.append({'dev': dev, 'image': volume, 'storage': storage, 'path': src_file, 'bus': bus})
             return result
 
         return util.get_xml_path(self._XMLDesc(0), func=disks)
 
+    def get_bootmenu(self):
+        menu = util.get_xml_path(self._XMLDesc(0), "/domain/os/bootmenu/@enable")
+        return True if menu == 'yes' else False
+
+    def set_bootmenu(self, flag):
+        tree = ElementTree.fromstring(self._XMLDesc(0))
+        os = tree.find('os')
+        menu = os.find("bootmenu")
+
+        if menu == None:
+            bootmenu = ElementTree.fromstring("<bootmenu enable='yes'/>")
+            os.append(bootmenu)
+            menu = os.find("bootmenu")
+
+        if flag == 0:  # Disable
+            menu.attrib['enable'] = 'no'
+        elif flag == 1:  # Enable
+            menu.attrib['enable'] = 'yes'
+        elif flag == -1:  # Remove
+            os.remove(menu)
+        else:
+            raise Exception('Unknown boot menu option, please choose one of 0:disable, 1:enable, -1:remove')
+
+        xmldom = ElementTree.tostring(tree)
+        self._defineXML(xmldom)
+
+    def get_bootorder(self):
+        boot_order = {}
+        tree = ElementTree.fromstring(self._XMLDesc(0))
+        os = tree.find('os')
+        boot = os.findall('boot')
+
+        for idx, b in enumerate(boot):
+            dev = b.get('dev')
+            if dev == 'hd':
+                target = "disk"
+                type = "file"
+            elif dev == 'fd':
+                target = "floppy"
+                type = "file"
+            elif dev == 'cdrom':
+                target = "cdrom"
+                type = "file"
+            elif dev == 'network':
+                target = "network"
+                type = "network"
+            boot_order[idx] = {"type": type, "dev": dev, "target": target}
+
+        devices = tree.find('devices')
+        for dev in devices:
+            dev_target = dev_type = dev_device = dev_alias = None
+            boot_dev = dev.find('boot')
+            if boot_dev != None:
+                idx = boot_dev.get('order')
+                dev_type = dev.get('type')
+                dev_device = dev.get('device')
+
+                if dev_type == 'file':
+                    dev_target = dev.find('target').get('dev')
+
+                elif dev_type == 'network':
+                    dev_mac = dev.find('mac').get('address')
+                    dev_device = "network"
+                    dev_target = "nic-{}".format(dev_mac[9:])
+                elif dev_type == 'usb':
+                    pass
+
+                boot_order[int(idx)-1] = {"type": dev_type, "dev": dev_device, "target": dev_target}
+
+        return boot_order
+
+    def set_bootorder(self, devorder):
+        if not devorder:
+            return
+
+        def remove_bootorder():
+            tree = ElementTree.fromstring(self._XMLDesc(0))
+            os = tree.find('os')
+            boot = os.findall('boot')
+            # Remove old style boot order
+            for b in boot:
+                os.remove(b)
+            # Remove rest of them
+            for dev in tree.find('devices'):
+                boot_dev = dev.find('boot')
+                if boot_dev != None:
+                    dev.remove(boot_dev)
+            return tree
+
+        tree = remove_bootorder()
+
+        for idx, dev in devorder.items():
+            order = ElementTree.fromstring("<boot order='{}'/>".format(idx + 1))
+            if dev['type'] == 'disk':
+                devices = tree.findall("./devices/disk[@device='disk']")
+                for d in devices:
+                    device = d.find("./target[@dev='{}']".format(dev['dev']))
+                    if device != None:
+                        d.append(order)
+            elif dev['type'] == 'cdrom':
+                devices = tree.findall("./devices/disk[@device='cdrom']")
+                for d in devices:
+                    device = d.find("./target[@dev='{}']".format(dev['dev']))
+                    if device != None:
+                        d.append(order)
+            elif dev['type'] == 'network':
+                devices = tree.findall("./devices/interface[@type='network']")
+                for d in devices:
+                    device = d.find("mac[@address='{}']".format(dev['dev']))
+                    if device != None:
+                        d.append(order)
+            else:
+                raise Exception('Invalid Device Type for boot order')
+        self._defineXML(ElementTree.tostring(tree))
+
     def mount_iso(self, dev, image):
         def attach_iso(dev, disk, vol):
             if disk.get('device') == 'cdrom':
@@ -490,11 +601,9 @@ class wvmInstance(wvmConnect):
         return telnet_port
 
     def get_console_listen_addr(self):
-        listen_addr = util.get_xml_path(self._XMLDesc(0),
-                                        "/domain/devices/graphics/@listen")
+        listen_addr = util.get_xml_path(self._XMLDesc(0), "/domain/devices/graphics/@listen")
         if listen_addr is None:
-            listen_addr = util.get_xml_path(self._XMLDesc(0),
-                                            "/domain/devices/graphics/listen/@address")
+            listen_addr = util.get_xml_path(self._XMLDesc(0), "/domain/devices/graphics/listen/@address")
             if listen_addr is None:
                     return "127.0.0.1"
         return listen_addr
diff --git a/vrtManager/network.py b/vrtManager/network.py
index c1de4f3..32b0819 100644
--- a/vrtManager/network.py
+++ b/vrtManager/network.py
@@ -1,6 +1,10 @@
 from vrtManager import util
 from vrtManager.IPy import IP
 from vrtManager.connection import wvmConnect
+from xml.etree import ElementTree
+from libvirt import VIR_NETWORK_SECTION_IP_DHCP_HOST, VIR_NETWORK_SECTION_IP_DHCP_RANGE
+from libvirt import VIR_NETWORK_UPDATE_COMMAND_ADD_LAST, VIR_NETWORK_UPDATE_COMMAND_DELETE, VIR_NETWORK_UPDATE_COMMAND_MODIFY
+from libvirt import VIR_NETWORK_UPDATE_AFFECT_LIVE, VIR_NETWORK_UPDATE_AFFECT_CONFIG
 
 
 def network_size(net, dhcp=None):
@@ -106,6 +110,9 @@ class wvmNetwork(wvmConnect):
     def delete(self):
         self.net.undefine()
 
+    def update(self, command, section, parentIndex, xml, flags=0):
+        return self.net.update(command, section, parentIndex, xml, flags)
+
     def get_ipv4_network(self):
         xml = self._XMLDesc(0)
         if util.get_xml_path(xml, "/network/ip") is None:
@@ -169,9 +176,57 @@ class wvmNetwork(wvmConnect):
         def network(doc):
             result = []
             for net in doc.xpath('/network/ip/dhcp/host'):
-                host = net.xpath('@ip')[0]
+                ip = net.xpath('@ip')[0]
                 mac = net.xpath('@mac')[0]
-                result.append({'host': host, 'mac': mac})
+                name = net.xpath('@name')[0]
+                result.append({'ip': ip, 'mac': mac, 'name': name})
             return result
 
         return util.get_xml_path(self._XMLDesc(0), func=network)
+    
+    def modify_fixed_address(self, name, address, mac):
+        util.validate_macaddr(mac)
+        new_xml = '<host mac="{}" name="{}" ip="{}"/>'.format(mac, name, IP(address))
+        new_host_xml = ElementTree.fromstring(new_xml)
+
+        tree = ElementTree.fromstring(self._XMLDesc(0))
+        hosts = tree.findall("./ip/dhcp/host")
+
+        host = None
+        for h in hosts:
+            if h.get('mac') == mac:
+                host = h
+                break
+        if host is None:
+            self.update(VIR_NETWORK_UPDATE_COMMAND_ADD_LAST, VIR_NETWORK_SECTION_IP_DHCP_HOST, -1, new_xml,
+                        VIR_NETWORK_UPDATE_AFFECT_LIVE|VIR_NETWORK_UPDATE_AFFECT_CONFIG)
+        else:
+            # change the host
+            if host.get('name') == new_host_xml.get('name') and host.get('ip') == new_host_xml.get('ip'):
+                return False
+            else:
+                self.update(VIR_NETWORK_UPDATE_COMMAND_MODIFY, VIR_NETWORK_SECTION_IP_DHCP_HOST, -1, new_xml,
+                            VIR_NETWORK_UPDATE_AFFECT_LIVE|VIR_NETWORK_UPDATE_AFFECT_CONFIG)
+
+    def delete_fixed_address(self, mac):
+        util.validate_macaddr(mac)
+        tree = ElementTree.fromstring(self._XMLDesc(0))
+        hosts = tree.findall("./ip/dhcp/host")
+
+        for h in hosts:
+            if h.get('mac') == mac:
+                new_xml = '<host mac="{}" name="{}" ip="{}"/>'.format(mac, h.get('name'), h.get('ip'))
+                self.update(VIR_NETWORK_UPDATE_COMMAND_DELETE, VIR_NETWORK_SECTION_IP_DHCP_HOST, -1, new_xml,
+                            VIR_NETWORK_UPDATE_AFFECT_LIVE|VIR_NETWORK_UPDATE_AFFECT_CONFIG)
+                break
+
+    def modify_dhcp_range(self, range_start, range_end):
+        if not self.is_active():
+            new_range = '<range start="{}" end="{}"/>'.format(range_start, range_end)
+            tree = ElementTree.fromstring(self._XMLDesc(0))
+            dhcp = tree.find("./ip/dhcp")
+            old_range = dhcp.find('range')
+            dhcp.remove(old_range)
+            dhcp.append(ElementTree.fromstring(new_range))
+
+            self.wvm.networkDefineXML(ElementTree.tostring(tree))
diff --git a/vrtManager/util.py b/vrtManager/util.py
index 840e6a5..b4aa949 100644
--- a/vrtManager/util.py
+++ b/vrtManager/util.py
@@ -153,3 +153,15 @@ def validate_uuid(val):
             val = (val[0:8] + "-" + val[8:12] + "-" + val[12:16] +
                    "-" + val[16:20] + "-" + val[20:32])
     return val
+
+
+def validate_macaddr(val):
+    if val is None:
+        return
+
+    if not (isinstance(val, str) or isinstance(val, basestring)):
+        raise ValueError("MAC address must be a string.")
+
+    form = re.match("^([0-9a-fA-F]{1,2}:){5}[0-9a-fA-F]{1,2}$", val)
+    if form is None:
+        raise ValueError("MAC address must be of the format AA:BB:CC:DD:EE:FF, was '%s'" % val)