deltacloud-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mfoj...@redhat.com
Subject [PATCH core 03/26] Core: Replaced obsolete or unused Deltacloud code
Date Tue, 15 May 2012 15:15:35 GMT
From: Michal Fojtik <mfojtik@redhat.com>


Signed-off-by: Michal fojtik <mfojtik@redhat.com>
---
 server/lib/deltacloud/backend_capability.rb        |   42 --
 server/lib/deltacloud/base_driver.rb               |   18 -
 server/lib/deltacloud/base_driver/mock_driver.rb   |   78 ----
 server/lib/deltacloud/collections/instances.rb     |    3 +
 server/lib/deltacloud/core_ext.rb                  |   21 -
 .../lib/deltacloud/drivers/ec2/ec2_mock_driver.rb  |  186 ---------
 server/lib/deltacloud/hardware_profile.rb          |  192 ---------
 server/lib/deltacloud/helpers.rb                   |    2 -
 .../lib/deltacloud/helpers/application_helper.rb   |  238 -----------
 server/lib/deltacloud/helpers/auth_helper.rb       |   73 ++++
 server/lib/deltacloud/helpers/blob_stream.rb       |  213 ----------
 .../lib/deltacloud/helpers/blob_stream_helper.rb   |  214 ++++++++++
 server/lib/deltacloud/helpers/conversion_helper.rb |   43 --
 server/lib/deltacloud/helpers/deltacloud_helper.rb |  273 ++++++++++++
 server/lib/deltacloud/helpers/driver_helper.rb     |   57 +++
 .../deltacloud/helpers/hardware_profiles_helper.rb |   50 ---
 server/lib/deltacloud/helpers/json_helper.rb       |   31 --
 server/lib/deltacloud/helpers/rabbit_helper.rb     |   34 ++
 server/lib/deltacloud/helpers/url_helper.rb        |  112 +++++
 server/lib/deltacloud/method_serializer.rb         |   83 ----
 server/lib/deltacloud/models/instance.rb           |    2 -
 server/lib/deltacloud/models/key.rb                |    4 +
 server/lib/deltacloud/validation.rb                |  100 -----
 server/lib/sinatra/lazy_auth.rb                    |   75 ----
 server/lib/sinatra/rabbit.rb                       |  441 --------------------
 server/lib/sinatra/rack_accept.rb                  |    4 -
 server/lib/sinatra/rack_cimi.rb                    |   33 --
 server/lib/sinatra/rack_matrix_params.rb           |    4 +-
 server/lib/sinatra/rack_runtime.rb                 |   47 ---
 server/lib/sinatra/rack_syslog.rb                  |   93 -----
 server/lib/sinatra/sinatra_verbose.rb              |   73 ----
 server/lib/sinatra/static_assets.rb                |   99 -----
 server/lib/sinatra/url_for.rb                      |   93 -----
 server/views/addresses/show.html.haml              |    2 +-
 server/views/api/show.html.haml                    |    7 +-
 server/views/error.html.haml                       |    4 +-
 server/views/instances/new.html.haml               |   12 +-
 server/views/instances/show.xml.haml               |    2 +-
 server/views/layout.html.haml                      |    6 +-
 server/views/root/index.html.haml                  |    2 +-
 40 files changed, 789 insertions(+), 2277 deletions(-)
 delete mode 100644 server/lib/deltacloud/backend_capability.rb
 delete mode 100644 server/lib/deltacloud/base_driver.rb
 delete mode 100644 server/lib/deltacloud/base_driver/mock_driver.rb
 delete mode 100644 server/lib/deltacloud/core_ext.rb
 delete mode 100644 server/lib/deltacloud/drivers/ec2/ec2_mock_driver.rb
 delete mode 100644 server/lib/deltacloud/hardware_profile.rb
 delete mode 100644 server/lib/deltacloud/helpers/application_helper.rb
 create mode 100644 server/lib/deltacloud/helpers/auth_helper.rb
 delete mode 100644 server/lib/deltacloud/helpers/blob_stream.rb
 create mode 100644 server/lib/deltacloud/helpers/blob_stream_helper.rb
 delete mode 100644 server/lib/deltacloud/helpers/conversion_helper.rb
 create mode 100644 server/lib/deltacloud/helpers/deltacloud_helper.rb
 create mode 100644 server/lib/deltacloud/helpers/driver_helper.rb
 delete mode 100644 server/lib/deltacloud/helpers/hardware_profiles_helper.rb
 delete mode 100644 server/lib/deltacloud/helpers/json_helper.rb
 create mode 100644 server/lib/deltacloud/helpers/rabbit_helper.rb
 create mode 100644 server/lib/deltacloud/helpers/url_helper.rb
 delete mode 100644 server/lib/deltacloud/method_serializer.rb
 delete mode 100644 server/lib/deltacloud/validation.rb
 delete mode 100644 server/lib/sinatra/lazy_auth.rb
 delete mode 100644 server/lib/sinatra/rabbit.rb
 delete mode 100644 server/lib/sinatra/rack_cimi.rb
 delete mode 100644 server/lib/sinatra/rack_runtime.rb
 delete mode 100644 server/lib/sinatra/rack_syslog.rb
 delete mode 100644 server/lib/sinatra/sinatra_verbose.rb
 delete mode 100644 server/lib/sinatra/static_assets.rb
 delete mode 100644 server/lib/sinatra/url_for.rb

diff --git a/server/lib/deltacloud/backend_capability.rb b/server/lib/deltacloud/backend_capability.rb
deleted file mode 100644
index 7f19007..0000000
--- a/server/lib/deltacloud/backend_capability.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.  The
-# ASF licenses this file to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance with the
-# License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-module Deltacloud::BackendCapability
-
-  attr_reader :capability
-
-  def with_capability(capability)
-    @capability = capability
-  end
-
-  def has_capability?(backend)
-    !capability or backend.has_capability?(capability)
-  end
-
-  def check_capability(backend)
-    if !has_capability?(backend)
-      raise Deltacloud::ExceptionHandler::NotSupported.new("#{capability} capability not supported by backend #{backend.class.name}")
-    end
-  end
-
-  module Helpers
-    def operations_for_collection(collection)
-      collections[collection].operations.values.select { |op| op.has_capability?(driver) }
-    end
-  end
-
-  helpers Helpers
-end
diff --git a/server/lib/deltacloud/base_driver.rb b/server/lib/deltacloud/base_driver.rb
deleted file mode 100644
index 77cdc84..0000000
--- a/server/lib/deltacloud/base_driver.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.  The
-# ASF licenses this file to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance with the
-# License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-require 'deltacloud/base_driver/base_driver'
-require 'deltacloud/base_driver/features'
diff --git a/server/lib/deltacloud/base_driver/mock_driver.rb b/server/lib/deltacloud/base_driver/mock_driver.rb
deleted file mode 100644
index 7956281..0000000
--- a/server/lib/deltacloud/base_driver/mock_driver.rb
+++ /dev/null
@@ -1,78 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.  The
-# ASF licenses this file to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance with the
-# License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-require 'deltacloud/method_serializer'
-
-# Create 'mock' version of original driver client/gem:
-
-# Initialize driver and include Deltacloud
-include Deltacloud
-driver
-
-module Mock
-
-  class Ec2 < Aws::Ec2
-
-    include MethodSerializer::Cache
-
-    def self.cached_methods
-      [
-        :describe_images,
-        :describe_images_by_owner,
-        :describe_availability_zones,
-        :launch_instances,
-        :describe_instances,
-        :reboot_instances,
-        :create_tag,
-        :delete_tag,
-        :describe_tags,
-        :terminate_instances,
-        :describe_key_pairs,
-        :create_key_pair,
-        :delete_key_pair,
-        :create_volume,
-        :get_console_output,
-        :describe_volumes,
-        :delete_volume,
-        :attach_volume,
-        :detach_volume,
-        :describe_snapshots,
-        :associate_address,
-        :try_create_snapshot,
-      ]
-    end
-
-    MethodSerializer::Cache::wrap_methods(self, :cache_dir => File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'tests', 'ec2', 'support'))
-  end
-
-end
-
-
-# Replace original client with mock client
-Deltacloud::Drivers::EC2::EC2Driver.class_eval do
-  alias_method :original_new_client, :new_client
-
-  def new_client(credentials, provider = :ec2)
-    auth_credentials = { :access_key_id => credentials.user, :secret_access_key => credentials.password}
-    if provider == :elb
-      Mock::ELB.new(auth_credentials)
-    elsif provider == :s3
-      Mock::S3.new(auth_credentials)
-    else
-      Mock::Ec2.new(auth_credentials[:access_key_id], auth_credentials[:secret_access_key])
-    end
-  end
-
-end
diff --git a/server/lib/deltacloud/collections/instances.rb b/server/lib/deltacloud/collections/instances.rb
index 5202149..0da94f2 100644
--- a/server/lib/deltacloud/collections/instances.rb
+++ b/server/lib/deltacloud/collections/instances.rb
@@ -27,6 +27,9 @@ module Deltacloud::Collections
       @hardware_profiles = driver.hardware_profiles(credentials, :architecture => @image.architecture )
       @realms = [Realm.new(:id => params[:realm_id])] if params[:realm_id]
       @realms ||= driver.realms(credentials)
+      if driver.class.has_feature? :instances, :authentication_key
+        @keys = driver.keys(credentials)
+      end
     end
 
     collection :instances do
diff --git a/server/lib/deltacloud/core_ext.rb b/server/lib/deltacloud/core_ext.rb
deleted file mode 100644
index fedbc18..0000000
--- a/server/lib/deltacloud/core_ext.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.  The
-# ASF licenses this file to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance with the
-# License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-require 'deltacloud/core_ext/string'
-require 'deltacloud/core_ext/integer'
-require 'deltacloud/core_ext/hash'
-require 'deltacloud/core_ext/array'
-require 'deltacloud/core_ext/proc'
diff --git a/server/lib/deltacloud/drivers/ec2/ec2_mock_driver.rb b/server/lib/deltacloud/drivers/ec2/ec2_mock_driver.rb
deleted file mode 100644
index 03db2c1..0000000
--- a/server/lib/deltacloud/drivers/ec2/ec2_mock_driver.rb
+++ /dev/null
@@ -1,186 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.  The
-# ASF licenses this file to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance with the
-# License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-module RightAws
-  class MockEc2
-
-    def initialize(opts={})
-    end
-
-    def describe_images(id)
-      load_fixtures_for(:images).select { |i| i[:aws_id].eql?(id) }
-    end
-
-    def describe_images_by_owner(id)
-      load_fixtures_for(:images).select { |i| i[:aws_owner].eql?(id) }
-    end
-
-    def describe_images(opts={})
-      load_fixtures_for(:images)
-    end
-
-    def describe_availability_zones(opts={})
-      load_fixtures_for(:realms)
-    end
-
-    def describe_instances(opts={})
-      instances = load_fixtures_for(:instances)
-      instances.each_with_index do |instance, i|
-        instances[i] = update_delayed_state(instance)
-        return [instance] if opts and opts[:id] and instance[:aws_instance_id].eql?(opts[:id])
-      end
-      update_fixtures_for(:instances, instances)
-      instances
-    end
-
-    def run_instances(image_id, min_count, max_count, group_ids, key_name, user_data='', addressing_type = nil, instance_type = nil, kernel_id = nil, ramdisk_id = nil, availability_zone = nil, block_device_mappings = nil)
-
-      instances = load_fixtures_for(:instances)
-      image = load_fixtures_for(:images).select { |img| img[:aws_id].eql?(image_id) }.first
-
-      if availability_zone
-        realm = load_fixtures_for(:realms).select { |realm| realm[:zone_name].eql?(availability_zone) }.first
-      else
-        realm = load_fixtures_for(:realms).first
-      end
-
-      raise Exception unless image
-      raise Exception unless realm
-
-      instance = { }
-      instance[:aws_image_id] = image[:aws_id]
-      instance[:aws_availability_zone] = realm[:zone_name]
-      instance[:aws_instance_type] = instance_type
-      instance[:aws_owner] = user_data
-      instance[:aws_state] = 'pending'
-      instance[:aws_reason] = ''
-      instance[:dns_name] = "#{random_dns}-01-C9.usma2.compute.amazonaws.com"
-      instance[:private_dns_name] = "#{random_dns}-02-P9.usma2.compute.amazonaws.com"
-      instance[:aws_state_code] = "0"
-      instance[:aws_key_name] = "staging"
-      instance[:aws_kernel_id] = "aki-be3adfd7"
-      instance[:aws_ramdisk_id] = "ari-ce34gad7"
-      instance[:aws_groups] = ["default"]
-      instance[:aws_instance_id] = random_instance_id
-      instance[:aws_reservation_id] = "r-aabbccdd"
-      instance[:aws_launch_time] = instance_time_format
-
-      instances << instance
-
-      update_fixtures_for(:instances, instances)
-
-      return [instance]
-    end
-
-
-    def terminate_instances(id)
-      update_instance_state(id, 'stopping', '80')
-    end
-
-    def reboot_instances(id)
-      update_instance_state(id, 'pending', '0')
-    end
-
-    alias :destroy_instance :terminate_instances
-
-    def describe_snapshots(opts={})
-      load_fixtures_for(:storage_snapshot)
-    end
-
-    def describe_volumes(opts={})
-      load_fixtures_for(:storage_volume)
-    end
-
-    private
-
-    def driver_dir
-      File::expand_path(File::join(File::dirname(__FILE__), '../../../../features/support/ec2'))
-    end
-
-    def fixtures_path
-      File::expand_path(File::join(driver_dir, 'fixtures'))
-    end
-
-    def load_fixtures_for(collection)
-      YAML.load_file(File::join(fixtures_path, "#{collection}.yaml"))
-    end
-
-    def update_fixtures_for(collection, new_data)
-      File.open(File::join(fixtures_path, "#{collection}.yaml"), 'w' ) do |out|
-        YAML.dump(new_data, out)
-      end
-      return new_data
-    end
-
-    def instance_time_format
-      DateTime.now.to_s.gsub(/\+(.+)$/, '.000Z')
-    end
-
-    def random_instance_id
-      id_1 = ("%.4s" % Time.now.to_i.to_s.reverse).reverse
-      id_2 = ("%.3s" % Time.now.to_i.to_s.reverse)
-      "i-#{id_1}f#{id_2}"
-    end
-
-    def random_dns
-      "domU-#{rand(90)+10}-#{rand(90)+10}-#{rand(90)+10}-#{rand(90)+10}"
-    end
-
-    def update_delayed_state(instance)
-      time = DateTime.now - DateTime.parse(instance[:aws_launch_time])
-      hours, minutes, seconds, frac = Date.day_fraction_to_time(time)
-
-      if (minutes>(rand(2)+1) or hours>0) and instance[:aws_state].eql?('pending')
-        instance[:aws_state], instance[:aws_state_code] = 'running', '16'
-      end
-
-      if (minutes>(rand(1)+1) or hours>0) and instance[:aws_state].eql?('stopping')
-        instance[:aws_state], instance[:aws_state_code] = 'stopped', '80'
-      end
-
-      return instance
-    end
-
-    def update_instance_state(id, state, state_code)
-      instance = describe_instances(:id => id).first
-      if instance
-        instance[:aws_state], instance[:aws_state_code] = state, state_code
-        instance[:aws_launch_time] = instance_time_format
-        instances = load_fixtures_for(:instances)
-        instances.each_with_index do |inst, i|
-          instances[i] = instance if inst[:aws_instance_id].eql?(id)
-        end
-        update_fixtures_for(:instances, instances)
-        return instance
-      else
-        raise Exception
-      end
-    end
-
-  end
-end
-
-Deltacloud::Drivers::EC2::EC2Driver.class_eval do
-  alias_method :original_new_client, :new_client
-
-  def new_client(credentials, opts={})
-    if credentials.user != 'mockuser' and credentials.password != 'mockpassword'
-      raise "AuthFailure"
-    end
-    RightAws::MockEc2.new
-  end
-
-end
diff --git a/server/lib/deltacloud/hardware_profile.rb b/server/lib/deltacloud/hardware_profile.rb
deleted file mode 100644
index 162f7af..0000000
--- a/server/lib/deltacloud/hardware_profile.rb
+++ /dev/null
@@ -1,192 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.  The
-# ASF licenses this file to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance with the
-# License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-module Deltacloud
-  class HardwareProfile
-
-    UNITS = {
-      :memory => "MB",
-      :storage => "GB",
-      :architecture => "label",
-      :cpu => "count"
-    }
-
-    def self.unit(name)
-      UNITS[name]
-    end
-
-    class Property
-      attr_reader :name, :kind, :default
-      # kind == :range
-      attr_reader :first, :last
-      # kind == :enum
-      attr_reader :values
-      # kind == :fixed
-      attr_reader :value
-
-      def initialize(name, values, opts = {})
-        @name = name
-        if values.is_a?(Range)
-          @kind = :range
-          @first = values.first
-          @last = values.last
-          @default = values.first
-        elsif values.is_a?(Array)
-          @kind = :enum
-          @values = values
-          @default = values.first
-        else
-          @kind = :fixed
-          @value = values
-          @default = @value
-        end
-        @default = opts[:default] if opts[:default]
-      end
-
-      def unit
-        HardwareProfile.unit(name)
-      end
-
-      def param
-        :"hwp_#{name}"
-      end
-
-      def fixed?
-        kind == :fixed
-      end
-
-      def valid?(v)
-        v = convert_property_value_type(v)
-        case kind
-          # NOTE:
-          # Currently we cannot validate fixed values because of UI
-          # limitation. In UI we have multiple hwp_* properties which overide
-          # each other.
-          # Then provider have one 'static' hardware profile and one
-          # 'customizable' when user select the static one the UI also send
-          # values from the customizable one (which will lead to a validation
-          # error because validation algorith will think that client want to
-          # overide fixed values.
-          #
-          # when :fixed then (v == @default.to_s)
-          when :fixed then true
-          when :range then match_type?(first, v) and (first..last).include?(v)
-          when :enum then match_type?(values.first, v) and values.include?(v)
-          else false
-        end
-      end
-
-      def to_param
-        Validation::Param.new([param, :string, :optional, []])
-      end
-
-      def include?(v)
-        if kind == :fixed
-          return v == value
-        else
-          return values.include?(v)
-        end
-      end
-
-      private
-
-      def match_type?(reference, value)
-        true if reference.class == value.class
-      end
-
-      def convert_property_value_type(v)
-        return v.to_f if v =~ /(\d+)\.(\d+)/
-        return v.to_i if v =~ /(\d+)/
-        v.to_s
-      end
-    end
-
-    class << self
-      def property(prop)
-        define_method(prop) do |*args|
-          values, opts, *ignored = *args
-          instvar = :"@#{prop}"
-          unless values.nil?
-            @properties[prop] = Property.new(prop, values, opts || {})
-          end
-          @properties[prop]
-        end
-      end
-    end
-
-    attr_reader :name
-    property :cpu
-    property :architecture
-    property :memory
-    property :storage
-
-    def initialize(name,&block)
-      @properties   = {}
-      @name         = name
-      instance_eval &block if block_given?
-    end
-
-    def each_property(&block)
-      @properties.each_value { |prop| yield prop }
-    end
-
-    def properties
-      @properties.values
-    end
-
-    def property(name)
-      @properties[name.to_sym]
-    end
-
-    def default?(prop, v)
-      p = @properties[prop.to_sym]
-      p && p.default.to_s == v
-    end
-
-    def to_hash
-      props = []
-      self.each_property do |p|
-        if p.kind.eql? :fixed
-          props << { :kind => p.kind, :value => p.value, :name => p.name, :unit => p.unit }
-        else
-          param = { :operation => "create", :method => "post", :name => p.name }
-          if p.kind.eql? :range
-            param[:range] = { :first => p.first, :last => p.last }
-          elsif p.kind.eql? :enum
-            param[:enum] = p.values.collect { |v| { :entry => v } }
-          end
-          param
-          props << { :kind => p.kind, :value => p.default, :name => p.name, :unit => p.unit, :param => param }
-        end
-      end
-      {
-        :id => self.name,
-        :properties => props
-      }
-    end
-
-    def include?(prop, v)
-      p = @properties[prop]
-      p.nil? || p.include?(v)
-    end
-
-    def params
-      @properties.values.inject([]) { |m, prop|
-        m << prop.to_param
-      }.compact
-    end
-  end
-end
diff --git a/server/lib/deltacloud/helpers.rb b/server/lib/deltacloud/helpers.rb
index 73f79ec..dc382bd 100644
--- a/server/lib/deltacloud/helpers.rb
+++ b/server/lib/deltacloud/helpers.rb
@@ -17,7 +17,6 @@
 require_relative 'helpers/driver_helper'
 require_relative 'helpers/auth_helper'
 require_relative 'helpers/url_helper'
-require_relative 'helpers/assets_helper'
 require_relative 'helpers/deltacloud_helper'
 require_relative 'helpers/rabbit_helper'
 require_relative 'helpers/blob_stream_helper'
@@ -36,7 +35,6 @@ module Deltacloud::Collections
     helpers Deltacloud::Helpers::Drivers
     helpers Sinatra::AuthHelper
     helpers Sinatra::UrlForHelper
-    helpers Sinatra::StaticAssets::Helpers
     helpers Rack::RespondTo::Helpers
     helpers Deltacloud::Helpers::Application
 
diff --git a/server/lib/deltacloud/helpers/application_helper.rb b/server/lib/deltacloud/helpers/application_helper.rb
deleted file mode 100644
index 7a0d58b..0000000
--- a/server/lib/deltacloud/helpers/application_helper.rb
+++ /dev/null
@@ -1,238 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.  The
-# ASF licenses this file to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance with the
-# License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-# Methods added to this helper will be available to all templates in the application.
-
-require 'benchmark'
-
-module ApplicationHelper
-
-  include Deltacloud
-
-  def instance_action_method(action)
-    action_method(action, :instances)
-  end
-
-  def action_method(action, collection)
-    collections[collection].operations[action.to_sym].method
-  end
-
-  def driver_has_feature?(feature_name, collection_name = :instances)
-    driver.features(collection_name).any? { |f| f.name == feature_name }
-  end
-
-  def driver_has_auth_features?
-    driver_has_feature?(:authentication_password) || driver_has_feature?(:authentication_key)
-  end
-
-  def driver_auth_feature_name
-    'key' if driver_has_feature?(:authentication_key)
-    'password' if driver_has_feature?(:authentication_password)
-  end
-
-  def filter_all(model)
-      filter = {}
-      filter.merge!(:id => params[:id]) if params[:id]
-      filter.merge!(:architecture => params[:architecture]) if params[:architecture]
-      filter.merge!(:owner_id => params[:owner_id]) if params[:owner_id]
-      filter.merge!(:state => params[:state]) if params[:state]
-      filter = {} if filter.keys.size.eql?(0)
-      singular = model.to_s.singularize.to_sym
-      begin
-       @benchmark = Benchmark.measure do
-          @elements = driver.send(model.to_sym, credentials, filter)
-        end
-      rescue
-        @exception = $!
-      end
-      if @elements
-        headers['X-Backend-Runtime'] = @benchmark.real.to_s
-        instance_variable_set(:"@#{model}", @elements)
-        respond_to do |format|
-          format.html { haml :"#{model}/index" }
-          format.xml { haml :"#{model}/index" }
-          format.json { convert_to_json(singular, @elements) }
-        end
-      else
-        report_error(@exception.code)
-      end
-  end
-
-  def show(model)
-    @benchmark = Benchmark.measure do
-      @element = driver.send(model, credentials, { :id => params[:id]} )
-    end
-    headers['X-Backend-Runtime'] = @benchmark.real.to_s
-    instance_variable_set("@#{model}", @element)
-    if @element
-      respond_to do |format|
-        format.html { haml :"#{model.to_s.pluralize}/show" }
-        format.xml { haml :"#{model.to_s.pluralize}/show" }
-        format.json { convert_to_json(model, @element) }
-      end
-    else
-      report_error(404)
-    end
-  end
-
-  def report_error(code=nil)
-    @error, @code = (request.env['sinatra.error'] || @exception), code
-    @code = 500 if not @code and not @error.class.method_defined? :code
-    response.status = @code || @error.code
-    respond_to do |format|
-      format.xml {  haml :"errors/#{@code || @error.code}", :layout => false }
-      format.json { json_return_error(@error) }
-      format.html { haml :"errors/#{@code || @error.code}", :layout => :error }
-    end
-  end
-
-  def instance_action(name)
-    original_instance = driver.instance(credentials, :id => params[:id])
-
-    # If original instance doesn't include called action
-    # return with 405 error (Method is not Allowed)
-    unless driver.instance_actions_for(original_instance.state).include?(name.to_sym)
-      return report_error(405)
-    end
-
-    @benchmark = Benchmark.measure do
-      @instance = driver.send(:"#{name}_instance", credentials, params[:id])
-    end
-
-    headers['X-Backend-Runtime'] = @benchmark.real.to_s
-
-    if name == :reboot
-      status 202
-    end
-
-    if name == :destroy
-      respond_to do |format|
-        format.xml { return 204 }
-        format.json { return 204 }
-        format.html { return redirect(instances_url) }
-      end
-    end
-
-    if @instance.class != Instance
-      response['Location'] = instance_url(params[:id])
-      halt
-    end
-
-    respond_to do |format|
-      format.xml { haml :"instances/show" }
-      format.html { haml :"instances/show" }
-      format.json {convert_to_json(:instance, @instance) }
-    end
-  end
-
-  def cdata(text = nil, &block)
-    text ||= capture_haml(&block)
-    "<![CDATA[#{text.strip}]]>"
-  end
-
-  def render_cdata(text)
-    "<![CDATA[#{text.strip}]]>"
-  end
-
-  def link_to_action(action, url, method)
-    capture_haml do
-      haml_tag :form, :method => :post, :action => url, :class => [:link, method], :'data-ajax' => 'false' do
-        haml_tag :input, :type => :hidden, :name => '_method', :value => method
-        haml_tag :button, :type => :submit, :'data-ajax' => 'false', :'data-inline' => "true" do
-          haml_concat action
-        end
-      end
-    end
-  end
-
-  def link_to_format(format)
-    return unless request.env['REQUEST_URI']
-    uri = request.env['REQUEST_URI']
-    return if uri.include?('format=')
-    uri += uri.include?('?') ? "&format=#{format}" : "?format=#{format}"
-    capture_haml do
-      haml_tag :a, :href => uri, :'data-ajax' => 'false', :'data-icon' => 'grid' do
-        haml_concat format.to_s.upcase
-      end
-    end
-  end
-
-  def image_for_state(state)
-    state_img = "stopped" if (state!='RUNNING' or state!='PENDING')
-    capture_haml do
-      haml_tag :img, :src => "/images/#{state}" % state.downcase, :title => state
-    end
-  end
-
-  # Reverse the entrypoints hash for a driver from drivers.yaml; note that
-  # +d+ is a hash, not an actual driver object
-  def driver_provider(d)
-    result = {}
-    if d[:entrypoints]
-      d[:entrypoints].each do |kind, details|
-        details.each do |prov, url|
-          result[prov] ||= {}
-          result[prov][kind] = url
-        end
-      end
-    end
-    result
-  end
-
-  def header(title, opts={}, &block)
-    opts[:theme] ||= 'b'
-    opts[:back] ||= 'true'
-    capture_haml do
-      haml_tag :div, :'data-role' => :header, :'data-theme' => opts[:theme], :'data-add-back-btn' => opts[:back] do
-        haml_tag :a, :'data-rel' => :back do
-          haml_concat "Back"
-        end if opts[:back] == 'true'
-        haml_tag :h1 do
-          haml_concat title
-        end
-        block.call if block_given?
-      end
-    end
-  end
-
-  def subheader(title, opts={})
-    opts[:theme] ||= 'a'
-    capture_haml do
-      haml_tag :div, :'data-role' => :header, :'data-theme' => opts[:theme] do
-        haml_tag :p, :class => 'inner-right' do
-          haml_concat title
-        end
-      end
-    end
-  end
-
-  def translate_error_code(code)
-    case code
-      when 400; { :message => "Bad Request" }
-      when 401; { :message => "Unauthorized" }
-      when 403; { :message => "Forbidden" }
-      when 404; { :message => "Not Found" }
-      when 405; { :message => "Method Not Allowed" }
-      when 406; { :message => "Not Acceptable" }
-      when 500; { :message => "Internal Server Error" }
-      when 502; { :message => "Backend Server Error" }
-      when 501; { :message => "Not Supported" }
-    end
-  end
-
-  def new_blob_form_url(bucket)
-    bucket_url(@bucket.name) + "/" + NEW_BLOB_FORM_ID
-  end
-end
diff --git a/server/lib/deltacloud/helpers/auth_helper.rb b/server/lib/deltacloud/helpers/auth_helper.rb
new file mode 100644
index 0000000..eef2521
--- /dev/null
+++ b/server/lib/deltacloud/helpers/auth_helper.rb
@@ -0,0 +1,73 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+# Lazy Basic HTTP authentication. Authentication is only forced when the
+# credentials are actually needed.
+
+module Sinatra
+  module AuthHelper
+    class LazyCredentials
+      def initialize(app)
+        @app = app
+        @provided = false
+      end
+
+      def user
+        credentials!
+        @user
+      end
+
+      def password
+        credentials!
+        @password
+      end
+
+      def provided?
+        @provided
+      end
+
+      private
+      def credentials!
+        if ENV["API_USER"] && ENV["API_PASSWORD"]
+          @user = ENV["API_USER"]
+          @password = ENV["API_PASSWORD"]
+          @provided = true
+        end
+        unless provided?
+          auth = Rack::Auth::Basic::Request.new(@app.request.env)
+          @app.authorize! unless auth.provided? && auth.basic? && auth.credentials
+          @user = auth.credentials[0]
+          @password = auth.credentials[1]
+          @provided = true
+        end
+      end
+
+    end
+
+    def authorize!
+      r = "#{Thread.current[:driver]}-deltacloud@#{ENV['HOSTNAME']}"
+      response['WWW-Authenticate'] = %(Basic realm="#{r}")
+      throw(:halt, [401, report_error(401)])
+    end
+
+    # Request the current user's credentials. Actual credentials are only
+    # requested when an attempt is made to get the user name or password
+    def credentials
+      LazyCredentials.new(self)
+    end
+  end
+
+end
diff --git a/server/lib/deltacloud/helpers/blob_stream.rb b/server/lib/deltacloud/helpers/blob_stream.rb
deleted file mode 100644
index df5cdc6..0000000
--- a/server/lib/deltacloud/helpers/blob_stream.rb
+++ /dev/null
@@ -1,213 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.  The
-# ASF licenses this file to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance with the
-# License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-include Deltacloud
-begin
-  require 'eventmachine'
-  #--
-  # based on the example from
-  #   http://macournoyer.com/blog/2009/06/04/pusher-and-async-with-thin/
-  #--
-  class BlobStream
-    AsyncResponse = [-1, {}, []].freeze
-    def self.call(env, credentials, params)
-      body = DeferrableBody.new
-      #Get the headers out asap. Don't specify a content-type let
-      #the client guess and if they can't they SHOULD default to
-      #'application/octet-stream' anyway as per:
-      #http://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.2.1
-      EM.next_tick { env['async.callback'].call [200, {
-        'Content-Type' => "#{params['content_type']}",
-        'Content-Disposition' => params["content_disposition"],
-        'Content-Length' => "#{params['content_length']}"}, body]
-      }
-      #call the driver from here. the driver method yields for every chunk
-      #of blob it receives. Then use body.call to write that chunk as received.
-      driver.blob_data(credentials, params[:bucket], params[:blob], params) {|chunk| body.call ["#{chunk}"]} #close blob_data block
-      body.succeed
-      AsyncResponse # Tell Thin to not close connection & work other requests
-    end
-  end
-
-  class DeferrableBody
-    include EventMachine::Deferrable
-
-    def call(body)
-      body.each do |chunk|
-        @body_callback.call(chunk)
-      end
-    end
-
-    def each(&blk)
-      @body_callback = blk
-    end
-  end
-rescue LoadError => e
-  # EventMachine isn't available, disable blob streaming
-  class BlobStream
-    def self.call(env, credentials, params)
-      raise NotImplementedError.new("Blob streaming is only supported under Thin")
-    end
-  end
-end
-
-module BlobHelper
-
-  def self.extract_blob_metadata_hash(env_hash)
-    meta_array = env_hash.select{|k,v| k.match(/^HTTP[-_]X[-_]Deltacloud[-_]Blobmeta[-_]/i)}
-    metadata = meta_array.inject({}){ |result, array| result[array.first.upcase] = array.last; result}
-    metadata
-  end
-
-DELTACLOUD_BLOBMETA_HEADER = /HTTP[-_]X[-_]Deltacloud[-_]Blobmeta[-_]/i
-
-  #e.g. from HTTP-X-Deltacloud-Blobmeta-FOO:BAR to amz-meta-FOO:BAR
-  def self.rename_metadata_headers(metadata, rename_to)
-    metadata.gsub_keys(DELTACLOUD_BLOBMETA_HEADER, rename_to)
-  end
-
-end
-
-#Monkey patch for streaming blobs:
-# Normally a client will upload a blob to deltacloud and thin will put
-# this into a tempfile. Then deltacloud would stream up to the provider:
-#   i.e.  client =-->>TEMP_FILE-->> deltacloud =-->>STREAM-->> provider
-# Instead we want to recognise that this is a 'PUT blob' operation and
-# start streaming to the provider as the request is received:
-#   i.e.  client =-->>STREAM-->> deltacloud =-->>STREAM-->> provider
-module Thin
-  class Request
-
-    alias_method :move_body_to_tempfile_orig, :move_body_to_tempfile if defined?(Thin::Response)
-    private
-      def move_body_to_tempfile
-        if BlobStreamIO::is_put_blob(self)
-          @body = BlobStreamIO.new(self)
-        else
-          move_body_to_tempfile_orig
-        end
-      end
-
-  end
-end
-
-require 'net/http'
-require 'net/https'
-#monkey patch for Net:HTTP
-module Net
-  class HTTP
-
-    alias :request_orig :request
-
-    def request(req, body = nil, blob_stream = nil, &block)
-      unless blob_stream
-        return request_orig(req, body, &block)
-      end
-      @blob_req = req
-      do_start #start the connection
-
-      req.set_body_internal body
-      begin_transport req
-      req.write_header_m @socket,@curr_http_version, edit_path(req.path)
-      @socket
-    end
-
-    class Put < HTTPRequest
-      def write_header_m(sock, ver, path)
-        write_header(sock, ver, path)
-      end
-    end
-
-    def end_request
-      begin
-        res = HTTPResponse.read_new(@socket)
-      end while res.kind_of?(HTTPContinue)
-      res.reading_body(@socket, @blob_req.response_body_permitted?) {
-                                          yield res if block_given? }
-      end_transport @blob_req, res
-      do_finish
-      res
-    end
-  end
-
-end
-
-require 'base64'
-class BlobStreamIO
-
-  attr_accessor :size, :provider, :sock
-
-  def initialize(request)
-    @client_request = request
-    @size = 0
-    bucket, blob = parse_bucket_blob(request.env["PATH_INFO"])
-    user, password = parse_credentials(request.env['HTTP_AUTHORIZATION'])
-    content_type = request.env['CONTENT_TYPE'] || ""
-    #deal with blob_metadata: (X-Deltacloud-Blobmeta-name: value)
-    user_meta = BlobHelper::extract_blob_metadata_hash(request.env)
-    @content_length = request.env['CONTENT_LENGTH']
-    @http, provider_request = driver.blob_stream_connection({:user=>user,
-       :password=>password, :bucket=>bucket, :blob=>blob, :metadata=> user_meta,
-       :content_type=>content_type, :content_length=>@content_length })
-    @content_length = @content_length.to_i #for comparison of size in '<< (data)'
-    @sock = @http.request(provider_request, nil, true)
-  end
-
-  def << (data)
-    @sock.write(data)
-    @size += data.length
-    if (@size >= @content_length)
-      result = @http.end_request
-      if result.is_a?(Net::HTTPSuccess)
-        @client_request.env["BLOB_SUCCESS"] = "true"
-      else
-        @client_request.env["BLOB_FAIL"] = result.body
-      end
-    end
-  end
-
-  def rewind
-  end
-
-  #use the Request.env hash (populated by the ThinParser) to determine whether
-  #this is a post blob operation. By definition, only get here with a body of
-  # > 112kbytes - thin/lib/thin/request.rb:12 MAX_BODY = 1024 * (80 + 32)
-  def self.is_put_blob(request = nil)
-    path = request.env['PATH_INFO']
-    method = request.env['REQUEST_METHOD']
-    if ( path =~ /^#{Regexp.escape(settings.root_url)}\/buckets/ && method == 'PUT' )
-      return true
-    else
-      return false
-    end
-  end
-
-  private
-
-  def parse_bucket_blob(request_string)
-    array = request_string.split("/")
-    blob = array.pop
-    bucket = array.pop
-    return bucket, blob
-  end
-
-  def parse_credentials(request_string)
-    decoded = Base64.decode64(request_string.split('Basic ').last)
-    key = decoded.split(':').first
-    pass = decoded.split(':').last
-    return key, pass
-  end
-
-end
diff --git a/server/lib/deltacloud/helpers/blob_stream_helper.rb b/server/lib/deltacloud/helpers/blob_stream_helper.rb
new file mode 100644
index 0000000..3830c60
--- /dev/null
+++ b/server/lib/deltacloud/helpers/blob_stream_helper.rb
@@ -0,0 +1,214 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+include Deltacloud
+
+begin
+  require 'eventmachine'
+  #--
+  # based on the example from
+  #   http://macournoyer.com/blog/2009/06/04/pusher-and-async-with-thin/
+  #--
+  class BlobStream
+    AsyncResponse = [-1, {}, []].freeze
+    def self.call(env, credentials, params)
+      body = DeferrableBody.new
+      #Get the headers out asap. Don't specify a content-type let
+      #the client guess and if they can't they SHOULD default to
+      #'application/octet-stream' anyway as per:
+      #http://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.2.1
+      EM.next_tick { env['async.callback'].call [200, {
+        'Content-Type' => "#{params['content_type']}",
+        'Content-Disposition' => params["content_disposition"],
+        'Content-Length' => "#{params['content_length']}"}, body]
+      }
+      #call the driver from here. the driver method yields for every chunk
+      #of blob it receives. Then use body.call to write that chunk as received.
+      driver.blob_data(credentials, params[:bucket], params[:blob], params) {|chunk| body.call ["#{chunk}"]} #close blob_data block
+      body.succeed
+      AsyncResponse # Tell Thin to not close connection & work other requests
+    end
+  end
+
+  class DeferrableBody
+    include EventMachine::Deferrable
+
+    def call(body)
+      body.each do |chunk|
+        @body_callback.call(chunk)
+      end
+    end
+
+    def each(&blk)
+      @body_callback = blk
+    end
+  end
+rescue LoadError => e
+  # EventMachine isn't available, disable blob streaming
+  class BlobStream
+    def self.call(env, credentials, params)
+      raise NotImplementedError.new("Blob streaming is only supported under Thin")
+    end
+  end
+end
+
+module BlobHelper
+
+  def self.extract_blob_metadata_hash(env_hash)
+    meta_array = env_hash.select{|k,v| k.match(/^HTTP[-_]X[-_]Deltacloud[-_]Blobmeta[-_]/i)}
+    metadata = meta_array.inject({}){ |result, array| result[array.first.upcase] = array.last; result}
+    metadata
+  end
+
+DELTACLOUD_BLOBMETA_HEADER = /HTTP[-_]X[-_]Deltacloud[-_]Blobmeta[-_]/i
+
+  #e.g. from HTTP-X-Deltacloud-Blobmeta-FOO:BAR to amz-meta-FOO:BAR
+  def self.rename_metadata_headers(metadata, rename_to)
+    metadata.gsub_keys(DELTACLOUD_BLOBMETA_HEADER, rename_to)
+  end
+
+end
+
+#Monkey patch for streaming blobs:
+# Normally a client will upload a blob to deltacloud and thin will put
+# this into a tempfile. Then deltacloud would stream up to the provider:
+#   i.e.  client =-->>TEMP_FILE-->> deltacloud =-->>STREAM-->> provider
+# Instead we want to recognise that this is a 'PUT blob' operation and
+# start streaming to the provider as the request is received:
+#   i.e.  client =-->>STREAM-->> deltacloud =-->>STREAM-->> provider
+module Thin
+  class Request
+
+    alias_method :move_body_to_tempfile_orig, :move_body_to_tempfile if defined?(Thin::Response)
+    private
+      def move_body_to_tempfile
+        if BlobStreamIO::is_put_blob(self)
+          @body = BlobStreamIO.new(self)
+        else
+          move_body_to_tempfile_orig
+        end
+      end
+
+  end
+end
+
+require 'net/http'
+require 'net/https'
+#monkey patch for Net:HTTP
+module Net
+  class HTTP
+
+    alias :request_orig :request
+
+    def request(req, body = nil, blob_stream = nil, &block)
+      unless blob_stream
+        return request_orig(req, body, &block)
+      end
+      @blob_req = req
+      do_start #start the connection
+
+      req.set_body_internal body
+      begin_transport req
+      req.write_header_m @socket,@curr_http_version, edit_path(req.path)
+      @socket
+    end
+
+    class Put < HTTPRequest
+      def write_header_m(sock, ver, path)
+        write_header(sock, ver, path)
+      end
+    end
+
+    def end_request
+      begin
+        res = HTTPResponse.read_new(@socket)
+      end while res.kind_of?(HTTPContinue)
+      res.reading_body(@socket, @blob_req.response_body_permitted?) {
+                                          yield res if block_given? }
+      end_transport @blob_req, res
+      do_finish
+      res
+    end
+  end
+
+end
+
+require 'base64'
+class BlobStreamIO
+
+  attr_accessor :size, :provider, :sock
+
+  def initialize(request)
+    @client_request = request
+    @size = 0
+    bucket, blob = parse_bucket_blob(request.env["PATH_INFO"])
+    user, password = parse_credentials(request.env['HTTP_AUTHORIZATION'])
+    content_type = request.env['CONTENT_TYPE'] || ""
+    #deal with blob_metadata: (X-Deltacloud-Blobmeta-name: value)
+    user_meta = BlobHelper::extract_blob_metadata_hash(request.env)
+    @content_length = request.env['CONTENT_LENGTH']
+    @http, provider_request = driver.blob_stream_connection({:user=>user,
+       :password=>password, :bucket=>bucket, :blob=>blob, :metadata=> user_meta,
+       :content_type=>content_type, :content_length=>@content_length })
+    @content_length = @content_length.to_i #for comparison of size in '<< (data)'
+    @sock = @http.request(provider_request, nil, true)
+  end
+
+  def << (data)
+    @sock.write(data)
+    @size += data.length
+    if (@size >= @content_length)
+      result = @http.end_request
+      if result.is_a?(Net::HTTPSuccess)
+        @client_request.env["BLOB_SUCCESS"] = "true"
+      else
+        @client_request.env["BLOB_FAIL"] = result.body
+      end
+    end
+  end
+
+  def rewind
+  end
+
+  #use the Request.env hash (populated by the ThinParser) to determine whether
+  #this is a post blob operation. By definition, only get here with a body of
+  # > 112kbytes - thin/lib/thin/request.rb:12 MAX_BODY = 1024 * (80 + 32)
+  def self.is_put_blob(request = nil)
+    path = request.env['PATH_INFO']
+    method = request.env['REQUEST_METHOD']
+    if ( path =~ /^#{Regexp.escape(Deltacloud::API.settings.root_url)}\/buckets/ && method == 'PUT' )
+      return true
+    else
+      return false
+    end
+  end
+
+  private
+
+  def parse_bucket_blob(request_string)
+    array = request_string.split("/")
+    blob = array.pop
+    bucket = array.pop
+    return bucket, blob
+  end
+
+  def parse_credentials(request_string)
+    decoded = Base64.decode64(request_string.split('Basic ').last)
+    key = decoded.split(':').first
+    pass = decoded.split(':').last
+    return key, pass
+  end
+
+end
diff --git a/server/lib/deltacloud/helpers/conversion_helper.rb b/server/lib/deltacloud/helpers/conversion_helper.rb
deleted file mode 100644
index 310ba4b..0000000
--- a/server/lib/deltacloud/helpers/conversion_helper.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.  The
-# ASF licenses this file to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance with the
-# License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-
-require 'deltacloud/base_driver'
-
-module ConversionHelper
-
-  def convert_to_json(type, obj)
-    if ( [ :image, :realm, :instance, :storage_volume, :storage_snapshot, :hardware_profile, :key, :bucket, :blob, :firewall, :load_balancer, :address ].include?( type ) )
-      if Array.eql?(obj.class)
-        data = obj.collect do |o|
-          o.to_hash.merge({ :href => self.send(:"#{type}_url", type.eql?(:hardware_profile) ? o.name : o.id ) })
-        end
-        type = type.to_s.pluralize
-      else
-        data = obj.to_hash
-        if type == :blob
-          data.merge!({ :href => self.send(:"bucket_url", "#{data[:bucket]}/#{data[:id]}" ) })
-        else
-          data.merge!({ :href => self.send(:"#{type}_url", data[:id]) })
-          if data.has_key?(:hardware_profiles)
-            data[:hardware_profiles] = data[:hardware_profiles].inject([]){|res, hwp| res << {hwp.name => {:href => self.send(:"hardware_profile_url", hwp.name)}}; res }
-          end
-        end
-      end
-      return { :"#{type}" => data }.to_json
-    end
-  end
-
-end
diff --git a/server/lib/deltacloud/helpers/deltacloud_helper.rb b/server/lib/deltacloud/helpers/deltacloud_helper.rb
new file mode 100644
index 0000000..83741f9
--- /dev/null
+++ b/server/lib/deltacloud/helpers/deltacloud_helper.rb
@@ -0,0 +1,273 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Helpers
+  module Application
+
+    require 'benchmark'
+
+    def self.included(klass)
+      klass.class_eval do
+        set :root_url, API_ROOT_URL
+        include Sinatra::Rabbit
+        Sinatra::Rabbit.set :root_path, root_url+'/'
+      end
+    end
+
+    def instance_action_method(action)
+      action_method(action, Sinatra::Rabbit::InstancesCollection)
+    end
+
+    def action_method(action, collection)
+      http_method = collection.operation(action).http_method
+      http_method || Sinatra::Rabbit::BaseCollection.http_method_for(action)
+    end
+
+    def filter_all(model)
+      filter = {}
+      filter.merge!(:id => params[:id]) if params[:id]
+      filter.merge!(:architecture => params[:architecture]) if params[:architecture]
+      filter.merge!(:owner_id => params[:owner_id]) if params[:owner_id]
+      filter.merge!(:state => params[:state]) if params[:state]
+      filter = {} if filter.keys.size.eql?(0)
+      singular = model.to_s.singularize.to_sym
+      begin
+        @benchmark = Benchmark.measure do
+          @elements = driver.send(model.to_sym, credentials, filter)
+        end
+      rescue
+        @exception = $!
+      end
+      if @elements
+        headers['X-Backend-Runtime'] = @benchmark.real.to_s
+        instance_variable_set(:"@#{model}", @elements)
+        respond_to do |format|
+          format.html { haml :"#{model}/index" }
+          format.xml { haml :"#{model}/index" }
+          format.json { @media_type=:xml; to_json(haml(:"#{model}/index")) }
+        end
+      else
+        report_error(@exception.respond_to?(:code) ? @exception.code : 500)
+      end
+    end
+
+    def xml_to_json(model)
+      @media_type = :xml
+      to_json(haml(:"#{model}"))
+    end
+
+    def to_json(xml)
+      Crack::XML.parse(xml).to_json
+    end
+
+    def show(model)
+      @benchmark = Benchmark.measure do
+        @element = driver.send(model, credentials, { :id => params[:id]} )
+      end
+      headers['X-Backend-Runtime'] = @benchmark.real.to_s
+      instance_variable_set("@#{model}", @element)
+      if @element
+        respond_to do |format|
+          format.html { haml :"#{model.to_s.pluralize}/show" }
+          format.xml { haml :"#{model.to_s.pluralize}/show" }
+          format.json { @media_type=:xml; to_json(haml(:"#{model.to_s.pluralize}/show")) }
+        end
+      else
+        report_error(404)
+      end
+    end
+
+    def report_error(code=nil)
+      @error, @code = (request.env['sinatra.error'] || @exception), code
+      @code = 500 if not @code and not @error.class.method_defined? :code
+      response.status = @code || @error.code
+      respond_to do |format|
+        format.xml {  haml :"errors/#{@code || @error.code}", :layout => false }
+        format.html { haml :"errors/#{@code || @error.code}", :layout => :error }
+      end
+    end
+
+    def instance_action(name)
+      original_instance = driver.instance(credentials, :id => params[:id])
+
+      # If original instance doesn't include called action
+      # return with 405 error (Method is not Allowed)
+      unless driver.instance_actions_for(original_instance.state).include?(name.to_sym)
+        return report_error(405)
+      end
+
+      @benchmark = Benchmark.measure do
+        @instance = driver.send(:"#{name}_instance", credentials, params[:id])
+      end
+
+      headers['X-Backend-Runtime'] = @benchmark.real.to_s
+      status 202
+
+      if name == :destroy
+        respond_to do |format|
+          format.xml { return 204 }
+          format.json { return 204 }
+          format.html { return redirect(instances_url) }
+        end
+      end
+
+      if @instance.class != Instance
+        response['Location'] = instance_url(params[:id])
+        halt
+      end
+
+      respond_to do |format|
+        format.xml { haml :"instances/show" }
+        format.html { haml :"instances/show" }
+        format.json {convert_to_json(:instance, @instance) }
+      end
+    end
+
+    def cdata(text = nil, &block)
+      text ||= capture_haml(&block)
+      "<![CDATA[#{text.strip}]]>"
+    end
+
+    def render_cdata(text)
+      "<![CDATA[#{text.strip}]]>"
+    end
+
+    def link_to_action(action, url, method)
+      capture_haml do
+        haml_tag :form, :method => :post, :action => url, :class => [:link, method], :'data-ajax' => 'false' do
+          haml_tag :input, :type => :hidden, :name => '_method', :value => method
+          haml_tag :button, :type => :submit, :'data-ajax' => 'false', :'data-inline' => "true" do
+            haml_concat action
+          end
+        end
+      end
+    end
+
+    def link_to_format(format)
+      return unless request.env['REQUEST_URI']
+      uri = request.env['REQUEST_URI']
+      return if uri.include?('format=')
+      uri += uri.include?('?') ? "&format=#{format}" : "?format=#{format}"
+      capture_haml do
+        haml_tag :a, :href => uri, :'data-ajax' => 'false', :'data-icon' => 'grid' do
+          haml_concat format.to_s.upcase
+        end
+      end
+    end
+
+    def image_for_state(state)
+      state_img = "stopped" if (state!='RUNNING' or state!='PENDING')
+      capture_haml do
+        haml_tag :img, :src => "/images/#{state}" % state.downcase, :title => state
+      end
+    end
+
+    # Reverse the entrypoints hash for a driver from drivers.yaml; note that
+    # +d+ is a hash, not an actual driver object
+    def driver_provider(d)
+      result = {}
+      if d[:entrypoints]
+        d[:entrypoints].each do |kind, details|
+          details.each do |prov, url|
+            result[prov] ||= {}
+            result[prov][kind] = url
+          end
+        end
+      end
+      result
+    end
+
+    def header(title, opts={}, &block)
+      opts[:theme] ||= 'b'
+      opts[:back] ||= 'true'
+      capture_haml do
+        haml_tag :div, :'data-role' => :header, :'data-theme' => opts[:theme], :'data-add-back-btn' => opts[:back] do
+          haml_tag :a, :'data-rel' => :back do
+            haml_concat "Back"
+          end if opts[:back] == 'true'
+          haml_tag :h1 do
+            haml_concat title
+          end
+          block.call if block_given?
+        end
+      end
+    end
+
+    def subheader(title, opts={})
+      opts[:theme] ||= 'a'
+      capture_haml do
+        haml_tag :div, :'data-role' => :header, :'data-theme' => opts[:theme] do
+          haml_tag :p, :class => 'inner-right' do
+            haml_concat title
+          end
+        end
+      end
+    end
+
+    def translate_error_code(code)
+      case code
+      when 400; { :message => "Bad Request" }
+      when 401; { :message => "Unauthorized" }
+      when 403; { :message => "Forbidden" }
+      when 404; { :message => "Not Found" }
+      when 405; { :message => "Method Not Allowed" }
+      when 406; { :message => "Not Acceptable" }
+      when 500; { :message => "Internal Server Error" }
+      when 502; { :message => "Backend Server Error" }
+      when 501; { :message => "Not Supported" }
+      end
+    end
+
+    def new_blob_form_url(bucket)
+      bucket_url(@bucket.name) + "/" + NEW_BLOB_FORM_ID
+    end
+
+    def format_hardware_property(prop)
+      return "&empty;" unless prop
+      u = hardware_property_unit(prop)
+      case prop.kind
+      when :range
+        "#{prop.first} #{u} - #{prop.last} #{u} (default: #{prop.default} #{u})"
+      when :enum
+        prop.values.collect{ |v| "#{v} #{u}"}.join(', ') + " (default: #{prop.default} #{u})"
+      else
+        "#{prop.value} #{u}"
+      end
+    end
+
+    def format_instance_profile(ip)
+      o = ip.overrides.collect do |p, v|
+        u = hardware_property_unit(p)
+        "#{p} = #{v} #{u}"
+      end
+      if o.empty?
+        ""
+      else
+        "with #{o.join(", ")}"
+      end
+    end
+
+    private
+    def hardware_property_unit(prop)
+      u = ::Deltacloud::HardwareProfile::unit(prop)
+      u = "" if ["label", "count"].include?(u)
+      u = "vcpus" if prop == :cpu
+      u
+    end
+
+
+
+  end
+end
diff --git a/server/lib/deltacloud/helpers/driver_helper.rb b/server/lib/deltacloud/helpers/driver_helper.rb
new file mode 100644
index 0000000..f620744
--- /dev/null
+++ b/server/lib/deltacloud/helpers/driver_helper.rb
@@ -0,0 +1,57 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+module Deltacloud::Helpers
+
+  module Drivers
+
+    def driver_symbol
+      driver_name.to_sym
+    end
+
+    def driver_name
+      Thread.current[:driver] ||= ENV['API_DRIVER']
+    end
+
+    def driver_class_name
+      driver_name.camelize
+    end
+
+    def driver_source_name
+      File.join('..', 'drivers', driver_name, driver_name + '_driver.rb')
+    end
+
+    def driver_class
+      begin
+        m = Deltacloud::Drivers.const_get(driver_class_name)
+        m.const_get(driver_class_name + "Driver").new
+      rescue NameError
+        raise "[ERROR] The driver class name is not defined as #{driver_class_name}Driver"
+      end
+    end
+
+    def driver
+      $:.unshift File.join(File.dirname(__FILE__), '..', '..')
+      begin
+        require_relative driver_source_name
+        driver_class
+      rescue LoadError
+        raise "[ERROR] The driver '#{driver_name}' is unknown or not installed (#{driver_source_name})"
+      end
+    end
+
+  end
+
+end
diff --git a/server/lib/deltacloud/helpers/hardware_profiles_helper.rb b/server/lib/deltacloud/helpers/hardware_profiles_helper.rb
deleted file mode 100644
index af2100e..0000000
--- a/server/lib/deltacloud/helpers/hardware_profiles_helper.rb
+++ /dev/null
@@ -1,50 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.  The
-# ASF licenses this file to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance with the
-# License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-module HardwareProfilesHelper
-
-  def format_hardware_property(prop)
-    return "&empty;" unless prop
-    u = hardware_property_unit(prop)
-    case prop.kind
-      when :range
-      "#{prop.first} #{u} - #{prop.last} #{u} (default: #{prop.default} #{u})"
-      when :enum
-      prop.values.collect{ |v| "#{v} #{u}"}.join(', ') + " (default: #{prop.default} #{u})"
-      else
-      "#{prop.value} #{u}"
-    end
-  end
-
-  def format_instance_profile(ip)
-    o = ip.overrides.collect do |p, v|
-      u = hardware_property_unit(p)
-      "#{p} = #{v} #{u}"
-    end
-    if o.empty?
-      nil
-    else
-      "with #{o.join(", ")}"
-    end
-  end
-
-  private
-  def hardware_property_unit(prop)
-    u = ::Deltacloud::HardwareProfile::unit(prop)
-    u = "" if ["label", "count"].include?(u)
-    u = "vcpus" if prop == :cpu
-    u
-  end
-end
diff --git a/server/lib/deltacloud/helpers/json_helper.rb b/server/lib/deltacloud/helpers/json_helper.rb
deleted file mode 100644
index aea16b6..0000000
--- a/server/lib/deltacloud/helpers/json_helper.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.  The
-# ASF licenses this file to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance with the
-# License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-module JSONHelper
-
-  def json_features_for_entrypoint(entrypoint)
-    features = driver.features(entrypoint.first).collect { |feature| feature.name }
-    features.empty? ? {} : { :features => features }
-  end
-
-  def json_return_error(error)
-    error_output=Hash.new
-    error_output[:url]    =request.env['REQUEST_URI']
-    error_output[:status] =response.status
-    error_output[:message]=error.message if error
-    error_output.to_json
-  end
-
-end
diff --git a/server/lib/deltacloud/helpers/rabbit_helper.rb b/server/lib/deltacloud/helpers/rabbit_helper.rb
new file mode 100644
index 0000000..252abe2
--- /dev/null
+++ b/server/lib/deltacloud/helpers/rabbit_helper.rb
@@ -0,0 +1,34 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+
+Sinatra::Rabbit::Collection.class_eval do
+
+  def self.standard_index_operation
+    collection_name = @collection_name
+    operation :index, :with_capability => collection_name do
+      control { filter_all collection_name }
+    end
+  end
+
+  def self.standard_show_operation
+    collection_name = @collection_name
+    operation :show, :with_capability => collection_name do
+      control { show collection_name.to_s.singularize.intern }
+    end
+  end
+
+end
+
diff --git a/server/lib/deltacloud/helpers/url_helper.rb b/server/lib/deltacloud/helpers/url_helper.rb
new file mode 100644
index 0000000..87bc93e
--- /dev/null
+++ b/server/lib/deltacloud/helpers/url_helper.rb
@@ -0,0 +1,112 @@
+#
+# Based on https://github.com/emk/sinatra-url-for/
+# Commit 1df339284203f8f6ed8d
+#
+# Original license:
+# Copyright (C) 2009 Eric Kidd
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to permit
+# persons to whom the Software is furnished to do so, subject to the
+# following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+# NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+# USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+module Sinatra
+  module UrlForHelper
+
+    require 'uri'
+
+    def method_missing(name, *args)
+      if name.to_s =~ /^([\w\_]+)_url$/
+        if args.size > 0
+          t = $1
+          if t =~ /^(stop|reboot|destroy|start|attach|detach)_/
+            api_url_for(t.pluralize.split('_').last + '/' + args.first + '/' + $1, :full)
+          else
+            api_url_for(t.pluralize, :full) + '/' + "#{args.first}"
+          end
+        else
+          api_url_for($1, :full)
+        end
+      else
+        super
+      end
+    end
+
+    def api_url_for(url_fragment, mode=:path_only)
+      matrix_params = ''
+      if request.params['api']
+        matrix_params += ";provider=%s" % request.params['api']['provider'] if request.params['api']['provider']
+        matrix_params += ";driver=%s" % request.params['api']['driver'] if request.params['api']['driver']
+      end
+      url_fragment = "/#{url_fragment}" unless url_fragment =~ /^\// # There is no need to prefix URI with '/'
+      if mode == :path_only
+        url_for "#{settings.root_url}#{matrix_params}#{url_fragment}", mode
+      else
+        url_for "#{matrix_params}#{url_fragment}", :full
+      end
+    end
+
+    # Construct a link to +url_fragment+, which should be given relative to
+    # the base of this Sinatra app.  The mode should be either
+    # <code>:path_only</code>, which will generate an absolute path within
+    # the current domain (the default), or <code>:full</code>, which will
+    # include the site name and port number.  (The latter is typically
+    # necessary for links in RSS feeds.)  Example usage:
+    #
+    #   url_for "/"            # Returns "/myapp/"
+    #   url_for "/foo"         # Returns "/myapp/foo"
+    #   url_for "/foo", :full  # Returns "http://example.com/myapp/foo"
+    #--
+    # See README.rdoc for a list of some of the people who helped me clean
+    # up earlier versions of this code.
+    def url_for url_fragment, mode=:path_only
+      case mode
+      when :path_only
+        base = request.script_name
+      when :full
+        scheme = request.scheme
+        port = request.port
+        request_host = request.host
+        if request.env['HTTP_X_FORWARDED_FOR']
+          scheme = request.env['HTTP_X_FORWARDED_SCHEME'] || scheme
+          port = request.env['HTTP_X_FORWARDED_PORT']
+          request_host = request.env['HTTP_X_FORWARDED_HOST']
+        end
+        if (port.nil? || port == "" ||
+            (scheme == 'http' && port.to_s == '80') ||
+            (scheme == 'https' && port.to_s == '443'))
+          port = ""
+        else
+          port = ":#{port}"
+        end
+        base = "#{scheme}://#{request_host}#{port}#{request.script_name}"
+      else
+        raise TypeError, "Unknown url_for mode #{mode}"
+      end
+      uri_parser = URI.const_defined?(:Parser) ? URI::Parser.new : URI
+      url_escape = uri_parser.escape(url_fragment)
+      # Don't add the base fragment if url_for gets called more than once
+      # per url or the url_fragment passed in is an absolute url
+      if url_escape.match(/^#{base}/) or url_escape.match(/^http/)
+        url_escape
+      else
+        "#{base}#{url_escape}"
+      end
+    end
+  end
+
+end
diff --git a/server/lib/deltacloud/method_serializer.rb b/server/lib/deltacloud/method_serializer.rb
deleted file mode 100644
index eec9abe..0000000
--- a/server/lib/deltacloud/method_serializer.rb
+++ /dev/null
@@ -1,83 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.  The
-# ASF licenses this file to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance with the
-# License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-require 'base64'
-require 'digest'
-
-module MethodSerializer
-
-  module Cache
-
-    def cache_dir
-      storage_dir = $methods_cache_dir || File.join(File.dirname(__FILE__), 'cache')
-      class_dir = self.class.name.split('::').last
-      class_dir ||= self.class.name
-      File.join(storage_dir, class_dir.downcase)
-    end
-
-    def serialize_data(method_name, args, data)
-      File.open(cache_file_name(method_name, args), 'w') do |f|
-        f.puts(Base64.encode64(Marshal.dump(data)))
-      end
-      return data
-    end
-
-    def deserialize_data(method_name, args)
-      begin
-        data = File.readlines(cache_file_name(method_name, args)).join
-        Marshal.load(Base64.decode64(data))
-      rescue Errno::ENOENT
-        return false
-      end
-    end
-
-    def args_hash(args)
-      if args.class == Hash
-        args = args.to_a.collect {|i| [i[0].to_s, i[1]]}.sort
-      end
-      Digest::SHA1.hexdigest(args.to_s)
-    end
-
-    def cache_file_name(method_name, args)
-      FileUtils.mkdir_p(cache_dir) unless File.directory?(cache_dir)
-      method_name = $scenario_prefix ? "#{$scenario_prefix}_#{method_name}" : method_name
-      File.join(cache_dir, "#{method_name}.#{args_hash(args)}")
-    end
-
-    def self.wrap_methods(c, opts={})
-      $methods_cache_dir = opts[:cache_dir]
-      $scenario_prefix = nil
-      c.class_eval do
-        cached_methods.each do |m|
-          next if c.instance_methods(false).include?("original_#{m}")
-          alias_method "original_#{m}".to_sym, m.to_sym
-          define_method m.to_sym do |*args|
-            args = args.first if args.size.eql?(1) and not args.first.class.eql?(Array)
-            output = deserialize_data(m, args)
-            unless output
-              output = method("original_#{m}".to_sym).to_proc[args]
-              return serialize_data(m, args, output)
-            else
-              return output
-            end
-          end
-        end
-      end
-    end
-
-  end
-
-end
diff --git a/server/lib/deltacloud/models/instance.rb b/server/lib/deltacloud/models/instance.rb
index c6835a9..c2cc0e3 100644
--- a/server/lib/deltacloud/models/instance.rb
+++ b/server/lib/deltacloud/models/instance.rb
@@ -16,8 +16,6 @@
 
 class Instance < BaseModel
 
-  include ApplicationHelper
-
   attr_accessor :owner_id
   attr_accessor :image_id
   attr_accessor :name
diff --git a/server/lib/deltacloud/models/key.rb b/server/lib/deltacloud/models/key.rb
index 86a6283..64c4cc7 100644
--- a/server/lib/deltacloud/models/key.rb
+++ b/server/lib/deltacloud/models/key.rb
@@ -23,6 +23,10 @@ class Key < BaseModel
   attr_accessor :pem_rsa_key
   attr_accessor :state
 
+  def name
+    @name || @id
+  end
+
   def is_password?
     true if @credential_type.eql?(:password)
   end
diff --git a/server/lib/deltacloud/validation.rb b/server/lib/deltacloud/validation.rb
deleted file mode 100644
index 3d29225..0000000
--- a/server/lib/deltacloud/validation.rb
+++ /dev/null
@@ -1,100 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.  The
-# ASF licenses this file to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance with the
-# License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-module Deltacloud::Validation
-
-  class Param
-    attr_reader :name, :klass, :type, :options, :description
-
-    def initialize(args)
-      @name = args[0]
-      @klass = args[1] || :string
-      @type = args[2] || :optional
-      @options = args[3] || []
-      @description = args[4] || ''
-    end
-
-    def required?
-      type.eql?(:required)
-    end
-
-    def optional?
-      type.eql?(:optional)
-    end
-
-    def valid_value?(value)
-      true if (options.kind_of?(Range) or options.kind_of?(Array)) and options.include?(value)
-      true if options.kind_of?(String) and not options.empty?
-    end
-
-    def valid_hwp_value?(profile, value)
-      profile.property(@name.to_s.gsub(/^hwp_/, '')).valid?(value)
-    end
-
-    def hwp_property?
-      true if name.to_s =~ /^hwp_(cpu|memory|storage|architecture)/
-    end
-  end
-
-  def param(*args)
-    raise "Duplicate param #{args[0]} #{params.inspect} #{self.class.name}" if params[args[0]]
-    p = Param.new(args)
-    params[p.name] = p
-  end
-
-  def params
-    @params ||= {}
-    @params
-  end
-
-  # Add the parameters in hash +new+ to already existing parameters. If
-  # +new+ contains a parameter with an already existing name, the old
-  # definition is clobbered.
-  def add_params(new)
-    # We do not check for duplication on purpose: multiple calls
-    # to add_params should be cumulative
-    new.each { |p|  @params[p.name] = p }
-  end
-
-  def each_param(&block)
-    params.each_value { |p| yield p }
-  end
-
-  def validate(current_driver, all_params, values, credentials)
-    all_params.each do |key, p|
-      if p.required? and not values[p.name]
-        raise validation_exception "Required parameter #{p.name} not found"
-      end
-      next unless values[p.name]
-      if p.hwp_property?
-        profile = current_driver.hardware_profile(credentials, values['hwp_id'])
-        raise validation_exception("Unknown hardware profile selected #{values['hwp_id']}") unless profile
-        unless p.valid_hwp_value?(profile, values[p.name])
-          raise validation_exception("Hardware profile property #{p.name} has invalid value #{values[p.name]}")
-        end
-      else
-        if not p.options.empty? and p.valid_value?(values[p.name])
-          raise validation_exception("Parameter #{p.name} has value #{values[p.name]} which is not in #{p.options.join(", ")}")
-        end
-      end
-    end
-  end
-
-  def validation_exception(message)
-    Deltacloud::ExceptionHandler::ValidationFailure.new(StandardError.new(message))
-  end
-
-end
diff --git a/server/lib/sinatra/lazy_auth.rb b/server/lib/sinatra/lazy_auth.rb
deleted file mode 100644
index fb94dd9..0000000
--- a/server/lib/sinatra/lazy_auth.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.  The
-# ASF licenses this file to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance with the
-# License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-require 'sinatra/base'
-
-# Lazy Basic HTTP authentication. Authentication is only forced when the
-# credentials are actually needed.
-module Sinatra
-  module LazyAuth
-    class LazyCredentials
-      def initialize(app)
-        @app = app
-        @provided = false
-      end
-
-      def user
-        credentials!
-        @user
-      end
-
-      def password
-        credentials!
-        @password
-      end
-
-      def provided?
-        @provided
-      end
-
-      private
-      def credentials!
-        if ENV["API_USER"] && ENV["API_PASSWORD"]
-          @user = ENV["API_USER"]
-          @password = ENV["API_PASSWORD"]
-          @provided = true
-        end
-        unless provided?
-          auth = Rack::Auth::Basic::Request.new(@app.request.env)
-          @app.authorize! unless auth.provided? && auth.basic? && auth.credentials
-          @user = auth.credentials[0]
-          @password = auth.credentials[1]
-          @provided = true
-        end
-      end
-
-    end
-
-    def authorize!
-      r = "#{driver_symbol}-deltacloud@#{HOSTNAME}"
-      response['WWW-Authenticate'] = %(Basic realm="#{r}")
-      throw(:halt, [401, report_error(401)])
-    end
-
-    # Request the current user's credentials. Actual credentials are only
-    # requested when an attempt is made to get the user name or password
-    def credentials
-      LazyCredentials.new(self)
-    end
-  end
-
-  helpers LazyAuth
-end
diff --git a/server/lib/sinatra/rabbit.rb b/server/lib/sinatra/rabbit.rb
deleted file mode 100644
index 5c63fd9..0000000
--- a/server/lib/sinatra/rabbit.rb
+++ /dev/null
@@ -1,441 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.  The
-# ASF licenses this file to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance with the
-# License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-require 'sinatra/base'
-require 'sinatra/url_for'
-require 'deltacloud/validation'
-require 'deltacloud/backend_capability'
-
-module Sinatra
-
-  module Rabbit
-
-    def self.routes
-      @routes ||= []
-    end
-
-    class DuplicateParamException < Deltacloud::ExceptionHandler::DeltacloudException; end
-    class DuplicateOperationException < Deltacloud::ExceptionHandler::DeltacloudException; end
-    class DuplicateCollectionException < Deltacloud::ExceptionHandler::DeltacloudException; end
-    class UnsupportedCollectionException < Deltacloud::ExceptionHandler::DeltacloudException
-      def initialize
-        # The server understood the request, but is refusing to fulfill it. Authorization will not help and the request
-        # SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request
-        # has not been fulfilled, it SHOULD describe the reason for the refusal in the entity. If the server does not wish
-        # to make this information available to the client, the status code 404 (Not Found) can be used instead.
-        super(403, 'UnsupportedCollection', "Requested collection is not supported for current provider", [])
-      end
-    end
-
-    class Operation
-      attr_reader :name, :method, :collection, :member
-
-      include ::Deltacloud::BackendCapability
-      include ::Deltacloud::Validation
-      include ::ApplicationHelper
-
-      STANDARD = {
-        :new => { :method => :get, :member => false, :form => true },
-        :index => { :method => :get, :member => false },
-        :show =>  { :method => :get, :member => true },
-        :create => { :method => :post, :member => false },
-        :update => { :method => :put, :member => true },
-        :destroy => { :method => :delete, :member => true }
-      }
-
-      def initialize(coll, name, opts, &block)
-        @name = name.to_sym
-        opts = STANDARD[@name].merge(opts) if standard?
-        @path_generator = opts[:path_generator]
-        @collection, @standard = coll, opts[:standard]
-        raise "No method for operation #{name}" unless opts[:method]
-        @method = opts[:method].to_sym
-        @member = opts[:member]
-        @description = ""
-        instance_eval(&block) if block_given?
-        generate_documentation
-        generate_options
-      end
-
-      def http_method
-        @method
-      end
-
-      def standard?
-        STANDARD.keys.include?(name) || @standard
-      end
-
-      def form?
-        STANDARD[name] and STANDARD[name][:form]
-      end
-
-      def description(text="")
-        return @description if text.blank?
-        @description = text
-      end
-
-      def generate_documentation
-        coll, oper = @collection, self
-        Rabbit::routes << [:get, "#{settings.root_url}/docs/#{@collection.name}/#{@name}"]
-        ::Sinatra::Application.get("#{settings.root_url}/docs/#{@collection.name}/#{@name}") do
-          @collection, @operation = coll, oper
-          @features = driver.features_for_operation(coll.name, oper.name)
-          respond_to do |format|
-            format.html { haml :'docs/operation' }
-            format.xml { haml :'docs/operation' }
-          end
-        end
-      end
-
-      def generate_options
-        current_operation = self
-        Rabbit::routes << [:options, "#{settings.root_url}/#{current_operation.collection.name}/#{current_operation.name}"]
-        ::Sinatra::Application.options("#{settings.root_url}/#{current_operation.collection.name}/#{current_operation.name}") do
-          required_params = current_operation.effective_params(driver).collect do |name, validation|
-            name.to_s if validation.type.eql?(:required)
-          end.compact.join(',')
-          optional_params = current_operation.effective_params(driver).collect do |name, validation|
-            name.to_s if validation.type.eql?(:optional)
-          end.compact.join(',')
-          headers 'X-Required-Parameters' => required_params
-          headers 'X-Optional-Parameters' => optional_params
-          [200, '']
-        end
-      end
-
-      def control(&block)
-        op = self
-        @control = Proc.new do
-          op.collection.check_supported(driver)
-          op.check_capability(driver)
-          op.validate(driver, op.effective_params(driver), params, credentials)
-          instance_eval(&block)
-        end
-      end
-
-      def member?
-        if standard?
-          @member || STANDARD[name][:member]
-        else
-          @member
-        end
-      end
-
-      def path(args = {})
-        return @path_generator.call(self) if @path_generator
-        if member?
-          if standard?
-            "#{@collection.name}/:id"
-          else
-            "#{@collection.name}/:id/#{name}"
-          end
-        else
-          if form?
-            "#{@collection.name}/#{name}"
-          else
-            "#{@collection.name}"
-          end
-        end
-      end
-
-      def generate
-        Rabbit::routes << [@method, "#{settings.root_url}/#{path}"]
-        ::Sinatra::Application.send(@method, "#{settings.root_url}/#{path}", {}, &@control)
-        # Set up some Rails-like URL helpers
-        if name == :index
-          gen_route "#{@collection.name}_url"
-        elsif name == :show
-          gen_route "#{@collection.name.to_s.singularize}_url"
-        else
-          gen_route "#{name}_#{@collection.name.to_s.singularize}_url"
-        end
-      end
-
-      # Return a hash of all params, the params statically defined for this
-      # operation plus the params defined by any features in the +driver+
-      # that might modify this operation
-      def effective_params(driver)
-        driver.features(@collection.name).collect do |f|
-          f.decl.operation(@name)
-        end.flatten.select { |op| op }.inject(params.dup) do |result, fop|
-          fop.params.each_key do |k|
-            if result.has_key?(k)
-              raise DuplicateParamException, "Parameter '#{k}' for operation #{fop.name} in collection #{@collection.name}"
-            else
-              result[k] = fop.params[k]
-            end
-          end
-          result
-        end
-      end
-
-      private
-      def gen_route(name)
-        route_url = path
-        if @member
-          ::Sinatra::Application.send(:define_method, name) do |id, *args|
-            url = query_url(route_url, args[0])
-            api_url_for url.gsub(/:id/, id.to_s), :full
-          end
-        else
-          ::Sinatra::Application.send(:define_method, name) do |*args|
-            url = query_url(route_url, args[0])
-            api_url_for url, :full
-          end
-        end
-      end
-    end
-
-    class Collection
-      attr_reader :name, :operations, :subcollections
-
-      def initialize(name, options={}, &block)
-        @name = name
-        @description = ""
-        @operations, @subcollections = {}, {}
-        @global = options[:global] || false
-        instance_eval(&block) if block_given?
-        generate_documentation
-        generate_head
-        generate_options
-      end
-
-      def subcollection?
-        self.class == SubCollection
-      end
-
-      # Set/Return description for collection
-      # If first parameter is not present, full description will be
-      # returned.
-      def description(text='')
-        return @description if text.blank?
-        @description = text
-      end
-
-      # Mark this collection as global, i.e. independent of any specific
-      # driver
-      def global!
-        @global = true
-      end
-
-      # Return +true+ if this collection is global, i.e. independent of any
-      # specific driver
-      def global?
-        @global
-      end
-
-      def generate_head
-        current_collection = self
-        Rabbit::routes << [:head, "#{settings.root_url}/#{name}"]
-        ::Sinatra::Application.head("#{settings.root_url}/#{name}") do
-          methods_allowed = current_collection.operations.collect { |o| o[1].method.to_s.upcase }.uniq.join(',')
-          headers 'Allow' => "HEAD,OPTIONS,#{methods_allowed}"
-          [200, '']
-        end
-      end
-
-      def generate_options
-        current_collection = self
-        Rabbit::routes << [:options, "#{settings.root_url}/#{name}"]
-        ::Sinatra::Application.options("#{settings.root_url}/#{name}") do
-          operations_allowed = current_collection.operations.collect { |o| o[0] }.join(',')
-          headers 'X-Operations-Allowed' => operations_allowed
-          [200, '']
-        end
-      end
-
-      def generate_documentation
-        coll = self
-        Rabbit::routes << [:get, "#{settings.root_url}/docs/#{@name}"]
-        ::Sinatra::Application.get("#{settings.root_url}/docs/#{@name}") do
-          coll.check_supported(driver)
-          @collection = coll
-          @operations = coll.operations
-          @features = driver.features(coll.name)
-          respond_to do |format|
-            format.html { haml :'docs/collection' }
-            format.xml { haml :'docs/collection' }
-          end
-        end
-      end
-
-      # Add a new operation for this collection. For the standard REST
-      # operations :index, :show, :update, and :destroy, we already know
-      # what method to use and whether this is an operation on the URL for
-      # individual elements or for the whole collection.
-      #
-      # For non-standard operations, options must be passed:
-      #  :method : one of the HTTP methods
-      #  :member : whether this is an operation on the collection or an
-      #            individual element (FIXME: custom operations on the
-      #            collection will use a nonsensical URL) The URL for the
-      #            operation is the element URL with the name of the operation
-      #            appended
-      #
-      # This also defines a helper method like show_instance_url that returns
-      # the URL to this operation (in request context)
-      def operation(name, opts = {}, &block)
-        if @operations.keys.include?(name)
-          raise DuplicateOperationException::new(500, "DuplicateOperation", "Operation #{name} is already defined", [])
-        end
-        @operations[name] = Operation.new(self, name, opts, &block)
-      end
-
-      def collection(name, opts={}, &block)
-        if subcollections.keys.include?(name)
-          raise DuplicateOperationException::new(500, "DuplicateSubcollection", "Subcollection #{name} is already defined", [])
-        end
-        subcollections[name] = SubCollection.new(self, name, opts, &block)
-        subcollections[name].generate
-      end
-
-      def generate
-        operations.values.reject { |op| op.member }.each { |o| o.generate }
-        operations.values.select { |op| op.member }.each { |o| o.generate }
-        app = ::Sinatra::Application
-        collname = name # Work around Ruby's weird scoping/capture
-        app.send(:define_method, "#{name.to_s.singularize}_url") do |id|
-          api_url_for "#{collname}/#{id}", :full
-        end
-        if index_op = operations[:index]
-          app.send(:define_method, "#{name}_url") do
-            api_url_for index_op.path.gsub(/\/\?$/,''), :full
-          end
-        end
-      end
-
-      def check_supported(driver)
-        unless global? || driver.has_collection?(@name) || self.kind_of?(Sinatra::Rabbit::SubCollection)
-          raise UnsupportedCollectionException
-        end
-      end
-    end
-
-    class SubCollection < Collection
-
-      attr_accessor :parent
-
-      def initialize(parent, name, opts={}, &block)
-        self.parent = parent
-        super(name, &block)
-      end
-
-      def operation(name, opts = {}, &block)
-        if @operations.keys.include?(name)
-          raise DuplicateOperationException::new(500, "DuplicateOperation", "Operation #{name} is already defined", [])
-        end
-        # Preserve self as local variable to workaround Ruby namespace
-        # weirdness
-        c = self
-        path_generator = Proc.new do |obj|
-          if obj.member?
-            if obj.standard?
-              "#{parent.name}/:#{parent.name.to_s.singularize}/:#{c.name.to_s.singularize}"
-            else
-              "#{parent.name}/:#{parent.name.to_s.singularize}/:#{c.name.to_s.singularize}/#{name}"
-            end
-          else
-            if obj.form?
-              "#{parent.name}/:id/:#{parent.name.to_s.singularize}/#{obj.name}"
-            else
-              "#{parent.name}/:#{parent.name.to_s.singularize}"
-            end
-          end
-        end
-        opts.merge!({
-          :path_generator => path_generator
-        })
-        @operations[name] = Operation.new(self, name, opts, &block)
-      end
-
-      def generate
-        operations.values.reject { |op| op.member }.each { |o| o.generate }
-        operations.values.select { |op| op.member }.each { |o| o.generate }
-        app = ::Sinatra::Application
-        collname = name # Work around Ruby's weird scoping/capture
-        app.send(:define_method, "#{parent.name.to_s}_#{name.to_s.singularize}_url") do |id, subid|
-          api_url_for "#{collname}/#{id}/#{subid}", :full
-        end
-        if index_op = operations[:index]
-          app.send(:define_method, "#{parent.name.to_s}_#{name}_url") do
-            api_url_for index_op.path.gsub(/\/\?$/,''), :full
-          end
-        end
-      end
-
-    end
-
-    def collections
-      @collections ||= {}
-    end
-
-    # Create a new collection. NAME should be the pluralized name of the
-    # collection.
-    #
-    # Adds a helper method #{name}_url which returns the URL to the :index
-    # operation on this collection.
-    def collection(name, &block)
-      raise DuplicateCollectionException if collections[name]
-      collections[name] = Collection.new(name, &block)
-      collections[name].generate
-    end
-
-    def global_collection(name, &block)
-      raise DuplicateCollectionException if collections[name]
-      collections[name] = Collection.new(name, { :global => true }, &block)
-      collections[name].generate
-    end
-
-    # Make sure this collection can be accessed, regardless of whether the
-    # driver supports it or not
-    def global_collection(name, &block)
-      raise DuplicateCollectionException if collections[name]
-      collections[name] = Collection.new(name, :global => true, &block)
-      collections[name].generate
-    end
-  end
-
-  module RabbitHelper
-    def query_url(url, params)
-      return url if params.nil? || params.empty?
-      url + "?#{URI.escape(params.collect{|k,v| "#{k}=#{v}"}.join('&'))}"
-    end
-
-    def entry_points
-      collections.values.select { |coll|
-        coll.global? || driver.has_collection?(coll.name)
-      }.inject([]) do |m, coll|
-        url = api_url_for coll.operations[:index].path, :full
-        m << [ coll.name, url ]
-      end
-    end
-  end
-
-  register Rabbit
-  helpers RabbitHelper
-end
-
-# In Sinatra < 1.2 there was no helper to create OPTIONS route
-unless Sinatra::Base.respond_to? :options
-  configure do
-    class << Sinatra::Base
-      def options(path, opts={}, &block)
-        route 'OPTIONS', path, opts, &block
-      end
-    end
-    Sinatra::Delegator.delegate :options
-  end
-end
diff --git a/server/lib/sinatra/rack_accept.rb b/server/lib/sinatra/rack_accept.rb
index 2ad52c7..e4a0f1f 100644
--- a/server/lib/sinatra/rack_accept.rb
+++ b/server/lib/sinatra/rack_accept.rb
@@ -12,11 +12,8 @@
 # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
 
-require 'sinatra/base'
 require 'rack/accept'
 
-use Rack::Accept
-
 module Rack
 
   module RespondTo
@@ -26,7 +23,6 @@ module Rack
     # We need to overide the default render method to supply correct path to the
     # template, since Sinatra is by default looking in the current __FILE__ path
     def self.registered(app)
-      app.helpers Rack::RespondTo::Helpers
       app.class_eval do
         alias :render_without_format :render
         def render(*args, &block)
diff --git a/server/lib/sinatra/rack_cimi.rb b/server/lib/sinatra/rack_cimi.rb
deleted file mode 100644
index 6d5ea78..0000000
--- a/server/lib/sinatra/rack_cimi.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.  The
-# ASF licenses this file to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance with the
-# License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-module Rack
-  # Automatically sets the X-CIMI-Specification-Version header on all responses.
-  #
-  class CIMI
-
-    def initialize(app, no_cache_control = nil, cache_control = nil)
-      @app = app
-    end
-
-    def call(env)
-      status, headers, body = @app.call(env)
-      headers['X-CIMI-Specification-Version'] = '0.0.66'
-      [status, headers, body]
-    end
-
-  end
-end
-
diff --git a/server/lib/sinatra/rack_matrix_params.rb b/server/lib/sinatra/rack_matrix_params.rb
index 177e745..0d9339b 100644
--- a/server/lib/sinatra/rack_matrix_params.rb
+++ b/server/lib/sinatra/rack_matrix_params.rb
@@ -51,9 +51,7 @@ module Rack
         while param=sub_components.pop do
           if value
             matrix_params[sub_components.first] ||= {}
-            matrix_params[sub_components.first].merge!(
-                                                       param => value
-                                                       )
+            matrix_params[sub_components.first].merge!(param => value)
             value=nil
             next
           else
diff --git a/server/lib/sinatra/rack_runtime.rb b/server/lib/sinatra/rack_runtime.rb
deleted file mode 100644
index dc56fc7..0000000
--- a/server/lib/sinatra/rack_runtime.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright (c) 2008 The Committers
-
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-# THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-module Rack
-  # Sets an "X-Runtime" response header, indicating the response
-  # time of the request, in seconds
-  #
-  # You can put it right before the application to see the processing
-  # time, or before all the other middlewares to include time for them,
-  # too.
-  class Runtime
-    def initialize(app, name = nil)
-      @app = app
-      @header_name = "X-Runtime"
-      @header_name << "-#{name}" if name
-    end
-
-    def call(env)
-      start_time = Time.now
-      status, headers, body = @app.call(env)
-      request_time = Time.now - start_time
-
-      if !headers.has_key?(@header_name)
-        headers[@header_name] = "%0.6f" % request_time
-      end
-
-      [status, headers, body]
-    end
-  end
-end
-
diff --git a/server/lib/sinatra/rack_syslog.rb b/server/lib/sinatra/rack_syslog.rb
deleted file mode 100644
index 5565179..0000000
--- a/server/lib/sinatra/rack_syslog.rb
+++ /dev/null
@@ -1,93 +0,0 @@
-begin
-  require 'syslog'
-  USE_SYSLOG = true
-rescue LoadError => e
-  USE_SYSLOG = false
-end
-
-require 'sinatra/body_proxy'
-
-class SyslogFile < File
-
-  def initialize
-    @log = USE_SYSLOG ? Syslog.open($0, Syslog::LOG_PID | Syslog::LOG_LOCAL5) : Logger.new(STDOUT)
-  end
-
-  def write(string)
-    @log.warning(string) if string.strip.length > 0
-    return string.chars.count
-  end
-
-  def info(msg)
-    @log.info("%s" % msg)
-  end
-
-  def err(msg)
-    @log.err("%s" % msg)
-  end
-
-  alias :warning :err
-
-end
-
-# Code bellow was originaly copied from Rack::CommonLogger
-# https://raw.github.com/rack/rack/master/lib/rack/commonlogger.rb
-
-module Rack
-  # Rack::CommonLogger forwards every request to an +app+ given, and
-  # logs a line in the Apache common log format to the +logger+, or
-  # rack.errors by default.
-  class SyslogLogger
-
-    # Common Log Format: http://httpd.apache.org/docs/1.3/logs.html#common
-    # lilith.local - - [07/Aug/2006 23:58:02] "GET / HTTP/1.1" 500 -
-    #             %{%s - %s [%s] "%s %s%s %s" %d %s\n} %
-    FORMAT = %{%s - %s [%s] "%s %s%s %s" %d %s %0.4f}
-
-    def initialize(app, logger=nil)
-      @app = app
-      @logger = logger || @app.settings.logger || $stdout
-    end
-
-    def call(env)
-      began_at = Time.now
-      status, header, body = @app.call(env)
-      header = Utils::HeaderHash.new(header)
-      body = Rack::BodyProxy.new(body) do
-        log(env, status, header, began_at)
-      end
-      body.close
-      [status, header, body]
-    end
-
-    def log(env, status, header, began_at)
-      now = Time.now
-      length = extract_content_length(header)
-
-      if status.to_s =~ /5(\d{2})/
-        method = :err
-      else
-        method = :info
-      end
-
-      logger = @logger
-      logger.send(method, FORMAT % [
-        env['HTTP_X_FORWARDED_FOR'] || env["REMOTE_ADDR"] || "-",
-        env["REMOTE_USER"] || "-",
-        now.strftime("%d/%b/%Y %H:%M:%S"),
-        env["REQUEST_METHOD"],
-        env["PATH_INFO"],
-        env["QUERY_STRING"].empty? ? "" : "?"+env["QUERY_STRING"],
-        env["HTTP_VERSION"],
-        status.to_s[0..3],
-        length,
-        now - began_at ])
-    end
-
-    def extract_content_length(headers)
-      value = headers['Content-Length'] or return '-'
-      value.to_s == '0' ? '-' : value
-    end
-  end
-end
-
diff --git a/server/lib/sinatra/sinatra_verbose.rb b/server/lib/sinatra/sinatra_verbose.rb
deleted file mode 100644
index c016ec0..0000000
--- a/server/lib/sinatra/sinatra_verbose.rb
+++ /dev/null
@@ -1,73 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.  The
-# ASF licenses this file to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance with the
-# License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-require 'sinatra/base'
-
-module Sinatra
-  module VerboseLogger
-
-    module Helpers
-
-      def info(message)
-        puts sprintf("\033[1;34m[INFO: #{caller_method_name}]\033[0m: %s", message.inspect)
-      end
-
-      alias :debug :info
-
-      def warn(message)
-        puts sprintf("\033[1;31m[WARN: #{caller_method_name}]\033[0m: %s", message.inspect)
-      end
-
-      private
-
-      def caller_method_name
-        caller(2).first
-      end
-
-    end
-
-    def enable_verbose_logging!
-      disable :logging
-      before {
-        puts sprintf("\n\033[1;29mProcessing %s\033[0m (for %s at #{Time.now}) [%s] [\033[1;29m%s\033[0m]",
-                     request.path_info, request.ip, request.request_method, driver_name)
-        puts "Parameters: #{params.inspect}"
-        if provider=Thread::current[:provider] || ENV['API_PROVIDER']
-          puts "Provider: #{provider}"
-        end
-        puts "Authentication: #{request.env['HTTP_AUTHORIZATION'].split(' ').first}" if request.env['HTTP_AUTHORIZATION']
-        puts "Server: #{request.env['SERVER_SOFTWARE']}"
-        puts "Accept: #{request.env['HTTP_ACCEPT']}"
-        puts
-      }
-      after {
-        puts sprintf("\nCompleted in \033[1;29m%4f\033[0m | %4f | %s | \033[1;36m%s\033[0m | %s\n",
-                     response.header['X-Backend-Runtime'] || 0, response.header['X-Runtime'] || 0, response.status, response.content_type, request.url)
-      }
-    end
-
-    def self.registered(app)
-      app.helpers VerboseLogger::Helpers
-      app.enable_verbose_logging! if ENV['API_VERBOSE']
-    end
-  end
-end
-
-Sinatra::Application.register Sinatra::VerboseLogger
-
-Deltacloud::BaseDriver.class_eval do
-  include Sinatra::VerboseLogger::Helpers
-end
diff --git a/server/lib/sinatra/static_assets.rb b/server/lib/sinatra/static_assets.rb
deleted file mode 100644
index 5233965..0000000
--- a/server/lib/sinatra/static_assets.rb
+++ /dev/null
@@ -1,99 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.  The
-# ASF licenses this file to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance with the
-# License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-require 'sinatra/base'
-require 'sinatra/url_for'
-
-module Sinatra
-  module StaticAssets
-    module Helpers
-      # In HTML <link> and <img> tags have no end tag.
-      # In XHTML, on the contrary, these tags must be properly closed.
-      #
-      # We can choose the appropriate behaviour with +closed+ option:
-      #
-      #   image_tag "/images/foo.png", :alt => "Foo itself", :closed => true
-      #
-      # The default value of +closed+ option is +false+.
-      #
-      def image_tag(source, options = {})
-        options[:src] = url_for(source)
-        tag("img", options)
-      end
-
-      def stylesheet_link_tag(*sources)
-        list, options = extract_options(sources)
-        list.collect { |source| stylesheet_tag(source, options) }.join("\n")
-      end
-
-      def javascript_script_tag(*sources)
-        list, options = extract_options(sources)
-        list.collect { |source| javascript_tag(source, options) }.join("\n")
-      end
-
-      def link_to(desc, url, options = {})
-        tag("a", options.merge(:href => url_for(url))) do
-          desc
-        end
-      end
-
-      private
-
-      def tag(name, local_options = {})
-        start_tag = "<#{name}#{tag_options(local_options) if local_options}"
-        if block_given?
-          content = yield
-          "#{start_tag}>#{content}</#{name}>"
-        else
-          "#{start_tag}#{"/" if settings.xhtml}>"
-        end
-      end
-
-      def tag_options(options)
-        unless options.empty?
-          attrs = []
-          attrs = options.map { |key, value| %(#{key}="#{Rack::Utils.escape_html(value)}") }
-          " #{attrs.sort * ' '}" unless attrs.empty?
-        end
-      end
-
-      def stylesheet_tag(source, options = {})
-        tag("link", { :type => "text/css",
-            :charset => "utf-8", :media => "screen", :rel => "stylesheet",
-            :href => url_for(source) }.merge(options))
-      end
-
-      def javascript_tag(source, options = {})
-        tag("script", { :type => "text/javascript", :charset => "utf-8",
-            :src => url_for(source) }.merge(options)) do
-            end
-      end
-
-      def extract_options(a)
-        opts = a.last.is_a?(::Hash) ? a.pop : {}
-        [a, opts]
-      end
-
-    end
-
-    def self.registered(app)
-      app.helpers StaticAssets::Helpers
-      app.disable :xhtml
-    end
-  end
-
-  register StaticAssets
-end
diff --git a/server/lib/sinatra/url_for.rb b/server/lib/sinatra/url_for.rb
deleted file mode 100644
index fba6668..0000000
--- a/server/lib/sinatra/url_for.rb
+++ /dev/null
@@ -1,93 +0,0 @@
-#
-# Based on https://github.com/emk/sinatra-url-for/
-# Commit 1df339284203f8f6ed8d
-#
-# Original license:
-# Copyright (C) 2009 Eric Kidd
-#
-# Permission is hereby granted, free of charge, to any person obtaining a
-# copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to permit
-# persons to whom the Software is furnished to do so, subject to the
-# following conditions:
-#
-# The above copyright notice and this permission notice shall be included
-# in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-# NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-# USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-require 'uri'
-
-module Sinatra
-  module UrlForHelper
-
-    def api_url_for(url_fragment, mode=:path_only)
-      matrix_params = ''
-      if request.params['api']
-        matrix_params += ";provider=%s" % request.params['api']['provider'] if request.params['api']['provider']
-        matrix_params += ";driver=%s" % request.params['api']['driver'] if request.params['api']['driver']
-      end
-      url_fragment = "/#{url_fragment}" unless url_fragment =~ /^\// # There is no need to prefix URI with '/'
-      url_for "#{settings.root_url}#{matrix_params}#{url_fragment}", mode
-    end
-
-    # Construct a link to +url_fragment+, which should be given relative to
-    # the base of this Sinatra app.  The mode should be either
-    # <code>:path_only</code>, which will generate an absolute path within
-    # the current domain (the default), or <code>:full</code>, which will
-    # include the site name and port number.  (The latter is typically
-    # necessary for links in RSS feeds.)  Example usage:
-    #
-    #   url_for "/"            # Returns "/myapp/"
-    #   url_for "/foo"         # Returns "/myapp/foo"
-    #   url_for "/foo", :full  # Returns "http://example.com/myapp/foo"
-    #--
-    # See README.rdoc for a list of some of the people who helped me clean
-    # up earlier versions of this code.
-    def url_for url_fragment, mode=:path_only
-      case mode
-      when :path_only
-        base = request.script_name
-      when :full
-        scheme = request.scheme
-        port = request.port
-        request_host = request.host
-        if request.env['HTTP_X_FORWARDED_FOR']
-          scheme = request.env['HTTP_X_FORWARDED_SCHEME'] || scheme
-          port = request.env['HTTP_X_FORWARDED_PORT']
-          request_host = request.env['HTTP_X_FORWARDED_HOST']
-        end
-        if (port.nil? || port == "" ||
-            (scheme == 'http' && port.to_s == '80') ||
-            (scheme == 'https' && port.to_s == '443'))
-          port = ""
-        else
-          port = ":#{port}"
-        end
-        base = "#{scheme}://#{request_host}#{port}#{request.script_name}"
-      else
-        raise TypeError, "Unknown url_for mode #{mode}"
-      end
-      url_escape = URI.escape(url_fragment)
-      # Don't add the base fragment if url_for gets called more than once
-      # per url or the url_fragment passed in is an absolute url
-      if url_escape.match(/^#{base}/) or url_escape.match(/^http/)
-        url_escape
-      else
-        "#{base}#{url_escape}"
-      end
-    end
-  end
-
-
-
-  helpers UrlForHelper
-end
diff --git a/server/views/addresses/show.html.haml b/server/views/addresses/show.html.haml
index b646bf4..ab4b4e2 100644
--- a/server/views/addresses/show.html.haml
+++ b/server/views/addresses/show.html.haml
@@ -13,7 +13,7 @@
     %li
       %div{ :'data-role' => 'controlgroup', :'data-type' => "horizontal" }
         - if @address.associated?
-          =link_to @address.instance_id, instance_url(@address.instance_id)
+          %a{:href => instance_url(@address.instance_id) }=@address.instance_id
           =link_to_action 'Disassociate', disassociate_address_url(@address.id), :post
         - else
           - if driver.respond_to?(:associate_address)
diff --git a/server/views/api/show.html.haml b/server/views/api/show.html.haml
index 265739d..9a40860 100644
--- a/server/views/api/show.html.haml
+++ b/server/views/api/show.html.haml
@@ -3,8 +3,11 @@
 
 %div{ :'data-role' => :content, :'data-theme' => 'c'}
   %ul{ :'data-role' => :listview, :'data-inset' => 'true'}
-    - @collections.sort_by { |k| k.to_s }.each do |key|
-      %li= link_to key.to_s.gsub('_', ' ').titlecase, api_url_for(key), :'data-icon' => "arrow-r", :'data-ajax' => false
+
+    - Deltacloud.collections.each do |c|
+      - next unless c.operation(:index).has_capability?
+      %li
+        %a{ :href => api_url_for(c.collection_name),  :'data-icon' => "arrow-r"}=c.collection_name.to_s.gsub('_', ' ').titlecase
 
 - if @providers.size > 1
   %div{ :'data-role' => :footer, :'data-theme' => 'a'}
diff --git a/server/views/error.html.haml b/server/views/error.html.haml
index 4911e28..92897e1 100644
--- a/server/views/error.html.haml
+++ b/server/views/error.html.haml
@@ -2,8 +2,8 @@
 %html
   %head
     %title Deltacloud API #{settings.version}
-    = stylesheet_link_tag '/stylesheets/jquery.mobile-1.0.1.min.css'
-    = stylesheet_link_tag '/stylesheets/new.css'
+    %link{ :charset => "utf-8", :href => "/stylesheets/jquery.mobile-1.0.1.min.css", :media => "screen", :rel => "stylesheet", :type => "text/css"}
+    %link{ :charset => "utf-8", :href => "/stylesheets/new.css", :media => "screen", :rel => "stylesheet", :type => "text/css"}
     %script{:type => "text/javascript", :src => "/javascripts/jquery.min.js" }
     %script{:type => "text/javascript", :src => "/javascripts/application.js" }
     %script{:type => "text/javascript", :src => "/javascripts/jquery.mobile-1.0.1.min.js" }
diff --git a/server/views/instances/new.html.haml b/server/views/instances/new.html.haml
index 2347022..5ca775c 100644
--- a/server/views/instances/new.html.haml
+++ b/server/views/instances/new.html.haml
@@ -21,7 +21,7 @@
   %form{ :action => instances_url, :method => :post, :class => :new_instance, :'data-ajax' => 'false'}
     %input{ :name => :image_id, :type => :hidden, :value => @instance.image_id }/
 
-    - if driver_has_feature?(:user_name)
+    - if driver.class.has_feature?(:instances, :user_name)
       %div{ 'data-role' => :fieldcontain }
         %label{ :for => :name} Instance name:
         %input{ :type => :text, :id => :name, :name => :name, :value => '' }
@@ -29,19 +29,19 @@
     %div{ 'data-role' => :collapsible, 'data-collapsed' => "true"}
       %h3 Additional parameters
 
-      - if driver_has_feature?(:user_data)
+      - if driver.class.has_feature?(:instances, :user_data)
         %div{ 'data-role' => :fieldcontain }
           %label{ :for => :user_data} Base64 encoded user-data:
           %textarea{ :id => :user_data, :name => :user_data, :value => '' }
           %br/
           %a{ :href => "", :onclick => 'encodeb64();', :'data-ajax' => 'false'} Encode data
 
-      - if driver_has_feature?(:instance_count)
+      - if driver.class.has_feature?(:instances, :instance_count)
         %div{ 'data-role' => :fieldcontain }
           %label{ :for => :instance_count} # of instances to be launched:
           %input{ :type => :text, :id => :instance_count, :name => :instance_count, :value => '1' }
 
-      - if driver_has_feature?(:authentication_key)
+      - if driver.class.has_feature?(:instances, :authentication_key)
         %div{ 'data-role' => :fieldcontain }
           %label{ :for => :keyname, :class => 'ui-input-text'} Instance SSH key:
           %select{:name => 'keyname', :'data-native-menu' => "true" }
@@ -49,7 +49,7 @@
             - @keys.each do |key|
               %option{ :value => key.id } #{key.id}
 
-      - if driver_has_feature?(:register_to_load_balancer)
+      - if driver.class.has_feature?(:instances, :register_to_load_balancer)
         %div{ 'data-role' => :fieldcontain }
           %label{ :for => :load_balancer_id, :class => 'ui-input-text'} Register to loadbalancer:
           %select{:name => 'load_balancer_id', :'data-native-menu' => "true" }
@@ -57,7 +57,7 @@
             - @load_balancers.each do |load_balancer|
               %option{:value => load_balancer.id} #{load_balancer.id}
 
-      - if driver_has_feature?(:firewalls)
+      - if driver.class.has_feature?(:instances, :firewalls)
         %div{ 'data-role' => :fieldcontain }
           %fieldset{ :'data-role' => 'controlgroup'}
             %legend Register to firewall:
diff --git a/server/views/instances/show.xml.haml b/server/views/instances/show.xml.haml
index b2fd5bf..3a62ed3 100644
--- a/server/views/instances/show.xml.haml
+++ b/server/views/instances/show.xml.haml
@@ -45,7 +45,7 @@
     %storage_volumes<
       - @instance.storage_volumes.each do |volume|
         %storage_volume{:href=> storage_volume_url(volume.keys.first), :id => volume.keys.first, :device => volume.values.first}
-  - if driver_has_auth_features?
+  - if driver.class.has_feature?(:authentication_key) or driver.class.has_feature?(:authentication_password)
     %authentication{ :type => driver_auth_feature_name }
       - if @instance.authn_feature_failed?
         %error  #{@instance.authn_error}
diff --git a/server/views/layout.html.haml b/server/views/layout.html.haml
index bef167d..639c618 100644
--- a/server/views/layout.html.haml
+++ b/server/views/layout.html.haml
@@ -2,16 +2,14 @@
 %html
   %head
     %title Deltacloud API #{settings.version}
-    = stylesheet_link_tag '/stylesheets/jquery.mobile-1.0.1.min.css'
-    = stylesheet_link_tag '/stylesheets/new.css'
+    %link{ :charset => "utf-8", :href => "/stylesheets/jquery.mobile-1.0.1.min.css", :media => "screen", :rel => "stylesheet", :type => "text/css"}
+    %link{ :charset => "utf-8", :href => "/stylesheets/new.css", :media => "screen", :rel => "stylesheet", :type => "text/css"}
     %script{:type => "text/javascript", :src => "/javascripts/jquery.min.js" }
     %script{:type => "text/javascript", :src => "/javascripts/application.js" }
     %script{:type => "text/javascript", :src => "/javascripts/jquery.mobile-1.0.1.min.js" }
     :javascript
       $(document).bind("mobileinit", function(){
-          $.mobile.ajaxEnabled = false;
           $.mobile.hashListeningEnabled = false;
-          $.mobile.selectmenu.prototype.options.nativeMenu = false;
       })
   %body
     %div{ 'data-role' => :page }
diff --git a/server/views/root/index.html.haml b/server/views/root/index.html.haml
index c102a59..cc2d36e 100644
--- a/server/views/root/index.html.haml
+++ b/server/views/root/index.html.haml
@@ -1,4 +1,4 @@
 %h1
   Deltacloud:
   = DRIVER.to_s.titlecase
-= link_to 'API', api_url
+%a{ :href => api_url} API
-- 
1.7.10.1


Mime
View raw message